Skip to content

Instantly share code, notes, and snippets.

@burdiuz
Created December 27, 2019 18:59
Show Gist options
  • Save burdiuz/18a73e3385bc2e25bed620b712345244 to your computer and use it in GitHub Desktop.
Save burdiuz/18a73e3385bc2e25bed620b712345244 to your computer and use it in GitHub Desktop.
Couple utils made to try TransformStream from Node.js core package
/*
echo "48656c6c6f20576f726c64210a" | node encode.js -f hex
echo "€~𝘈Ḇ𝖢𝕯٤ḞԍНǏ𝙅ƘԸ<2c98>𝙉০Ρ𝗤Ɍ𝓢ȚЦ𝒱Ѡ𝓧ƳȤѧᖯć𝗱ễ𝑓𝙜Ⴙ𝞲𝑗𝒌ļṃʼnо𝞎𝒒<1d72><a731>𝙩ừ𝗏ŵ𝒙𝒚ź1234567890" | node encode.js -t hex | node encode.js -f hex
*/
const { Transform } = require('stream');
const { readArgs } = require('./util');
class ConvertEncoding extends Transform {
constructor(from = 'utf8', to = 'utf8') {
super();
this.from = from;
this.to = to;
}
_transform(data, _, callback) {
const str = Buffer.from(data.toString(), this.from);
callback(null, Buffer.from(str).toString(this.to));
}
}
const { from, to } = readArgs(process.argv, {
f: 'from',
t: 'to',
});
const convertStream = new ConvertEncoding(from, to);
process.stdin.pipe(convertStream).pipe(process.stdout);
/*
echo "In nec erat urna, lorem aliquet vitae lorem, laoreet felis. Lorem, lorem" | node replace.js -s lorem -r ZORG -m i | node replace.js -s \s+ -r +
*/
const { Transform } = require('stream');
const { readArgs } = require('./util');
const mapLineReplace = (str, searchRgx, replaceStr) =>
str
.split('\n')
.map((line) => line.replace(searchRgx, replaceStr))
.join('\n');
class ReplaceSymbols extends Transform {
constructor(searchRgx, replaceStr) {
super();
this.searchRgx = searchRgx;
this.replaceStr = replaceStr;
this.leftovers = '';
}
_transform(data, encoding, callback) {
const str = `${this.leftovers}${data.toString()}`;
const lastLine = str.indexOf('\n');
let lines = str;
if (lastLine >= 0) {
lines = str.substr(0, lastLine);
this.leftovers = str.substr(lastLine + 1);
} else {
this.leftovers = '';
}
callback(null, Buffer.from(mapLineReplace(lines, this.searchRgx, this.replaceStr)));
}
_flush(callback) {
callback(null, Buffer.from(mapLineReplace(this.leftovers, this.searchRgx, this.replaceStr)));
}
}
const { search, replace = '', modifiers = '' } = readArgs(process.argv, {
s: 'search',
r: 'replace',
m: 'modifiers',
});
if (!search) {
console.error('"--search" argument is required.');
process.exit(1);
}
const replaceStream = new ReplaceSymbols(new RegExp(search, `${modifiers.replace('g', '')}g`), replace);
process.stdin.pipe(replaceStream).pipe(process.stdout);
/*
Using IBM Watsons Translation service because it does not require credit card information to use free version
echo "Hola Mundo!" | node translate.js -s es -t en
*/
const https = require('https');
const { Transform } = require('stream');
const { readArgs } = require('./util');
const API_KEY = '<YOUR IBM WATSONS API KEY>';
// London location URL
const BASE_URL =
'https://api.eu-gb.language-translator.watson.cloud.ibm.com/instances/<YOUR PROJECT ID>';
const API_VERSION = '2018-05-01';
// THere are API to identify source language, so it may be optional
const { source = 'en', target } = readArgs(process.argv, {
s: 'source',
t: 'target',
a: 'apikey',
});
if (!target) {
console.error('"--target" argument specifies target locale for translation and is required.');
process.exit(1);
}
const fetch = (text, source, target) =>
new Promise((resolve, reject) => {
let str = '';
const request = https.request(
`${BASE_URL}/v3/translate?version=${API_VERSION}`,
{
auth: `apikey:${API_KEY}`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
},
(response) => {
response.setEncoding('utf8');
response.on('data', (chunk) => {
str = `${str}${chunk.toString()}`;
});
response.on('error', reject);
response.on('end', () => {
let data;
try {
data = JSON.parse(str);
if (data.error) {
reject(data);
return;
}
const {
translations: [{ translation }],
} = data;
resolve(translation);
} catch (error) {
reject(error);
}
});
}
);
request.on('error', reject);
request.write(JSON.stringify({ text: [text], source, target }, null, 2));
request.end();
});
class TranslateText extends Transform {
constructor(sourceLocale, targetLocale) {
super();
this.sourceLocale = sourceLocale;
this.targetLocale = targetLocale;
}
_transform(data, _, callback) {
fetch(data.toString(), this.sourceLocale, this.targetLocale)
.then((translation) => callback(null, Buffer.from(translation)))
.catch((error) => callback(error));
}
}
const translationStream = new TranslateText(source, target);
translationStream.on('error', (error) => {
console.error(error);
process.exit(1);
});
process.stdin.pipe(translationStream).pipe(process.stdout);
const readArgs = (args, aliases = {}, valueTransform = (v) => v) =>
args.reduce((result, arg, index) => {
if (arg.charAt() !== '-') {
return result;
}
let name;
let value;
let checkAlias = false;
if (arg.charAt(1) === '-') {
name = arg.substr(2);
} else {
name = arg.substr(1);
checkAlias = true;
}
const equalsIndex = name.indexOf('=');
if (equalsIndex >= 0) {
value = name.substr(equalsIndex + 1);
name = name.substr(0, equalsIndex);
} else {
value = args[index + 1];
value = value === undefined || value.charAt() === '-' ? true : value;
}
if (checkAlias) {
const alias = aliases[name];
name = alias || name;
}
return {
...result,
[name]: valueTransform(value, name),
};
}, {});
exports.readArgs = readArgs;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment