Security News
GitHub Removes Malicious Pull Requests Targeting Open Source Repositories
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Collection of Node.js / ECMAScript Mini Modules
The name jinang is abbreviation of "Jin-Nang", which in chinese means a magic box. The modules in jinang are independent for each other, and are for different usage.
jinang is an incubator. Successful sub modules may be encouraged to be published as independent NPM packages.
// Modules are independent for each other and are suggested to be required independently.
const defineError = require('jinang/defineError');
const MyError = defineError('MyError', Error, function(message) {
this.code = 'SOMETHING_IS_WRONG';
this.message = message;
});
// ...
throw new MyError('Helo word!');
All sub-modules in jinang are independent from each other. Use require('jinang/<subModuleName>')
to require the sub-modules.
For your convenience, avaiable modules included in jinang are listed here,
Object cloneObject( object source )
Object cloneObject( object source, Array keynames )
Item of keynames may be string or RegExp instance. If item is a string, key in source which strictly equals to the keyname will be cloned. However, if it is a RegExp instance, all keys in source will be iterated and those matched will be cloned.
Object cloneObject( object source, Function mapper )
The mapper SHOULD be a function who accepts two arguments (key, value)
and return an array [ newKey, newValue ]
.
Transform a normal function to a curried one.
const currying = require('jinang/currying');
function plus(a, b, c) {
return a + b + c;
}
// Create a curried function.
// 3 means that the original function plus() should be invoked with 3 arguments.
var curriedPlus = currying(plus, 3);
// Curried function accepts one and only one argument.
// It may return a new curried function, or the result returned by the original function.
curriedPlus(1); // RETURN a new function.
curriedPlus(1)(2); // RETURN a new function.
curriedPlus(1)(2)(3); // RETURN 6.
ATTENTION: Although Currying and Partial Application are mutually related, they are DIFFERENT. If you wanna create a new function which is based on an existing function and with some arguments predefined, use papply.
Read more about currying:
E.g.
// Modules are independent for each other and are suggested to be required independently.
const defineError = require('jinang/defineError');
const MyError = defineError('MyError', Error, function(message) {
this.code = 'SOMETHING_IS_WRONG';
this.message = message;
});
// ...
throw new MyError('Helo word!');
E.g.
const forInObject = require('jinang/forInObject');
forInObject({ name: 'YounGoat' }, (name, value) {
console.log(name);
console.log(value);
});
E.g.
const jointString = require('jinang/jointString');
jointString('/', 'a/', '/b');
jointString('/', 'a' , '/b');
jointString('/', 'a/', 'b');
jointString('/', 'a' , 'b');
// All return 'a/b'.
Word "papply" is abbreviation of Partial Application, which means to apply a function to some of its arguments and return a new function with fewer parameters.
papply offers three styles:
Function papply(Function fn, any leading_argument, ...)
Create a new function based on fn with leading arguments predefined by any number of leading_argument.
Function papply.tail(Function fn, any tailing_argument, ...)
Create a new function based on fn with tailing arguments predefined by any number of tailing_argument. The last tailing_argument will also be the last argument finally passed into fn.
Function papply.position(Function fn, [ number position, any value ] positioned_argument, ...)
Create a new function based on fn with some position(s) of argument list predefined by any number of positioned_argument.
The final arguments passed into fn will be the shortest list which contains all positioned arguments and real arguments. Sometimes the final arguments will be tailed with one or more undefined
.
If position is 0 or positive integer, it indicates the position from left (starts with 0). Otherwise, if position is negative integer, it indicates the position from right (starts with -1).
const papply = require('jinang/papply');
// -- papply --
// Suppose a function with three parameters.
function add(a, b, c) {
return a + b + c;
}
// Run partial application and return a new function.
const add2 = papply(add, 2);
add2(3, 4); // RETURN 2 + 3 + 4
const add2_3 = papply(add, 2, 3);
add2_3(4); // RETURN 2 + 3 + 4
// -- papply.tail --
function minus(a, b, c) {
return a - b*1 - c*2;
}
const minus2 = papply.tail(minus, 2);
minus2(9, 3); // RETURN 9 - 3 - 2*2 = 2
const minus2_3 = papply.tail(minus, 2, 3);
minus2_3(9); // RETURN 9 - 2 - 3*2 = 1
// -- papply.position --
function join() {
let args = Array.from(arguments);
let chars = args.map(n => typeof n == 'undefined' ? '-' : n);
return chars.join('');
}
const join_z = papply.position(join, [ -1, 'z' ]);
join_z('a');
Read more about partial application:
To normalise options argument.
const parseOptions = requrie('jinang/parseOptions');
const options = {
Domain: 'www.example.com',
Port: 8080,
path: '/index.html',
};
const def = {
// Whether the property names of *options* are case sensitive.
// DEFAULT false
caseSensitive: false,
// Whether the property names of returned (parsed) object may keep the case
// as what column names look like, even *def.caseSensitive* is false.
// DEFAULT false
keepNameCase: false,
// If set true, properties not explicitly declared will be ignored.
// DEFAULT false
explicit: true,
// Declare properties in *options*.
columns: [
'port',
{ name: 'Hostname', alias: 'domain' }
],
};
const po = parseOptions(options, def);
// RETURN {
// Hostname: 'www.example.com',
// port: 8080
// }
parseOptions is an easy way to make your function paramemters more friendly.
function formatUrl(options) {
const optionsDef = {
caseSensitive: false,
explicit: true,
// Property *columns* of definition may be an array or object.
columns: [
// Use object to define/declare a column.
{ name: 'protocol', default: 'http' },
{ name: 'query', alias: [ 'querystring', 'queries' ] },
// Use description string to define/declare a column.
'hostname required alias(domain, domainName)',
// Only column name is also OK.
'port',
'path',
'search',
'hash'
]
};
options = parseOptions(options, optionsDef);
// ...
}
PoC means Promise or Callback. It may be invoked in an asychronuous function to create an return an instance of Promise
or to invoke the callback
function if passed.
const PoC = require('jinang/PoC');
function asyncDemo(params, callback) {
return PoC((done) => {
// ...
done(error, data);
}, callback);
};
asyncDemo(params)
.then((data) => { /* ... */ })
.catch((error) => { /* ... */ })
;
// When callback passed, PoC will return void.
asyncDemo(params, (error, data) => { /* ... */ });
const Progress = require('jinang/Progress');
const progress = new Progress();
// Progress inherits class events.EventEmitter.
progress.on('error', function(ex) {
// ...
});
progress.emit('error', ex);
// Progress may send/change its signal via homonymous methods.
progress.on('signal', function(signal) {
// ...
});
progress.abort();
class Progress
number Progress.SIGABRT
number Progress.SIGHUP
number Progress.SIGINT
number Progress.SIGKILL
number Progress.SIGQUIT
number Progress.SIGTERM
void <instance>.raise(number signal )
void <instance>.signal(number signal, Function catcher)
void <instance>.abort()
Send signal SIGABRT to progress and emit a signal event.
void <instance>.hangup()
Send signal SIGHUP to progress and emit a signal event.
void <instance>.interrupt()
Send signal SIGINT to progress and emit a signal event.
void <instance>.kill()
Send signal SIGKILL to progress and emit a signal event.
void <instance>.quit()
Send signal SIGQUIT to progress and emit a signal event.
void <instance>.terminate()
Send signal SIGTERM to progress and emit a signal event.
safeClone is deep and partial clone method. The skeleton of the original argument will be kept and the primitive items or properties will be copied, while the complex values will be ignored. Whatever you do with the returned value, the original will not be affected.
const safeClone = require('jinang/safeClone');
const foo = {
a: undefined,
b: null,
c: 1, // number
d: 'foobar', // string
e: true, // boolean
f: function() {}, // function
g: [ , , 2, ], // Array
}
let bar = safeClone(foo);
bar.a === undefined;
bar.b === null;
bar.c === 1;
bar.d === 'foobar';
bar.e === true;
bar.hasOwnProperty('f') === false;
bar.g.length === 3;
// The original will not change when the cloned changed.
bar.g.pop();
foo.g.length === 3;
Read unit test code for more examples.
Make current process to "sleep" for a while.
const sleep = require('jinang/sleep');
// Block the current process for 2000 milliseconds (2 seconds).
sleep(2000);
In co(function*() { /* ... */ })
code block, sleep.promise()
is recommended because it is more precise.
const sleep = require('jinang/sleep');
const co = require('co');
co(function*() {
yield sleep.promise(2000);
});
Split string in different ways.
Array split(string s, string | RegExp seperator)
The first parameter is the string to be split.
seperator may be a string or a regular expression object.
Array split(string s, string | RegExp seperator, string | Array delimiter)
Substring enbraced by SAME delimiter will not be split. Each delimiter SHOULD be a character (1-length string).
Array split(string s, string | RegExp seperator, string | Array delimiter, string escaper)
const split = require('jinang/split');
split('foo bar baz', ' ');
// RETURN: [ "foo", "bar", "baz" ]
split('foo==bar==baz', '==');
// RETURN: [ "foo", "bar", "baz" ]
split('foo "bar baz"', ' ', '"');
// RETURN: [ "foo", "bar baz" ]
split('foo "bar\\"baz"', ' ', '"');
// RETURN: [ "foo", "bar\\"baz" ]
Read unit test code for more examples.
jinang is an incubator for creatives which will make programming with Node.js much easier.
FAQs
Collection of Node.js / ECMAScript Gists
We found that jinang demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
GitHub removed 27 malicious pull requests attempting to inject harmful code across multiple open source repositories, in another round of low-effort attacks.
Security News
RubyGems.org has added a new "maintainer" role that allows for publishing new versions of gems. This new permission type is aimed at improving security for gem owners and the service overall.
Security News
Node.js will be enforcing stricter semver-major PR policies a month before major releases to enhance stability and ensure reliable release candidates.