Research
Security News
Quasar RAT Disguised as an npm Package for Detecting Vulnerabilities in Ethereum Smart Contracts
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Creates a queue of sync or async functions with resolve and reject callback.
move-on
is a module that:
.all
and
.race
methods [sample] [sample] [sample]this
reference
inner context
for all functions in the chain to transmit data between functions [sample] [sample] [sample]Any bugs found? Give me to know on GitHub.
npm install move-on
const moveOn = require('move-on');
Add the move-on.js
library to the HTML file.
The library is located in ./dist/move-on.js
directory.
It is a webpack&babel bundled cross-browser library version.
The library is accessible as moveOn
variable in the global (window) scope.
<script src='move-on.js'></script>
<script>
moveOn(list, config, onDone, onCatch);
</script>
npm test
> git clone https://github.com/devrafalko/move-on.git
> cd move-on
> npm install
> npm test //run tests in node
> npm test err //run tests in node with failed specs shown
> npm test deep //run tests in node with errors' descriptions shown
const moveOn = require('move-on');
/* [Function] moveOn(list, config, onDone, onCatch)
[Function] moveOn.all(list, config, onDone, onCatch)
[Function] moveOn.each(list, config, onDone, onCatch)
[Function] moveOn.first(list, config, onDone, onCatch) */
const list = [retrieveData, computeData, displayData];
const config = { timeout: 5000 };
moveOn(list, config, onDone, onCatch);
function retrieveData(resolve, reject, context){
setTimeout(resolve, 1000); //asynchronous resolve
}
function computeData(resolve, reject, context){
resolve(); //synchronous resolve
}
function displayData(resolve, reject, context){
resolve();
}
function onDone(reject, context){}
function onCatch(context){}
The module's methods expect the [Array]
list
of functions to be passed as the first argument. Each function in the chain has the
resolve
and
reject
parameter, that should be called when ready
(or failed) in order to move the functions execution forward. When the functions chain is successfully executed, the
done
callback function is called finally, otherwise the
catch
callback function is called.
moveOn
The chained functions are executed sequentially
(one after another). Each function is expected to be
resolved
, so that the next chained function was executed. The
done
function is called as the last one, when all previous chained functions resolved. The
catch
function is called instead of
done
function, when at least one chained function failed
(rejected).
See the full description below.
See the samples: [sample] [sample] [sample] [sample] [sample] [sample] [sample]
moveOn.all
The
all
static method of
move-on
module executes all chosen functions at the same time
(similarly to Promises'
.all
method). All chained functions are expected to be
resolved
so that the final
done
function was called. The
catch
function is called instead of
done
function, when at least one chained function failed
(rejected).
See the full description below.
See the samples: [sample]
moveOn.each
The
each
static method of
move-on
module executes all chosen functions at the same time. Each chained function is expected to be either
resolved
or
rejected
, so that the final
done
function was called. The failed
(rejected) function
does not stop the further functions execution. It can be used
eg. to log the warnings in the
catch
callback function.
See the full description below.
See the samples: [sample]
moveOn.first
The
first
static method of
move-on
module executes all chained functions at the same time. It expects the first
(fastest) function to be
resolved
, so that the
done
function was called
(similarly to Promises'
.race
method). When
all functions failed
(rejected), the
catch
function is called instead.
See the full description below.
See the samples: [sample]
list
,
config
,
done
,
catch
)
move-on
module function executes the
list
functions
sequentially
(one after another) in the chainlist
function
resolves
, the next
list
function is called,
and so on...
list
function
resolves
, the
done
function is called
once
(it
ends up the module execution)
list
function
rejects
, the farther
list
functions and the
done
function are
not called in the endlist
function
rejects
, the
catch
function is called instead
once
(it
ends up the module execution)
list
function can be
resolved
and | or
rejected
multiple times. The forks of chain are created and executed then
[read more]
list
function can execute the inner
move-on
module
[read more]
list
,
config
,
done
,
catch
)
move-on
.all
static method executes all the
list
functions
simultaneously
(at the same time)
list
function
resolves
, the
done
is
not called immediatelydone
waits, till
all
list
functions are
resolved
, to be called
(it
ends up the module execution - after that, all
resolve and
reject calls are ignored)
list
function
rejects
, the
done
function is
not called in the endlist
function
rejects
, the
catch
function is called instead
once
(it
ends up the module execution - after that, all
resolve and
reject calls are ignored)
list
function
resolves and | or
rejects
multiple times, only the
first call is respected
[read more]
list
function can execute the inner
move-on
module
[read more]
list
,
config
,
done
,
catch
)
move-on
.each
static method executes all the
list
functions
simultaneously
(at the same time)
list
function
resolves
, the
done
is
not called immediatelydone
waits, till
each
list
function is either
resolved
or
rejected
, to be called
(it
ends up the module execution - after that, all
resolve and
reject calls are ignored)
list
function
rejects
and the
catch
is called, it
does not end up the module executionlist
function
resolves and | or
rejects
multiple times, only the
first call is respected
[read more]
list
function can execute the inner
move-on
module
[read more]
list
,
config
,
done
,
catch
)
move-on
.first
static method executes all the
list
functions
simultaneously
(at the same time)
done
waits, till
the first
(fastest)
list
function is
resolved
, to be called
(it
ends up the module execution - after that, all
resolve and
reject calls are ignored)
list
functions
reject
, the
done
function is
not called in the endlist
functions
reject
, the
catch
function is called instead
once
(it
ends up the module execution - after that, all
resolve and
reject calls are ignored)
list
function
resolves and | or
rejects
multiple times, only the
first call is respected
[read more]
list
function can execute the inner
move-on
module
[read more]
list
[Array: function | array]
list
stores the list of functions, that should be called. It can contain:
const list = [fnA, fnB, fnC];
const list = [fnA, [obj, fnB, fnC], fnD]
const list = [fnA, [obj, 'fnB', 'fnC'], fnD]
list
can contain [Function] items. It may be function, arrow function or object's methodconfig.context
reference
(except arrow functions and already bound functions
[read more])
const retrieveData = function(){};
const computeData = ()=>{};
const displayData = { display:()=>{} };
const list = [retrieveData, computeData, displayData.display];
config.context
referencethis
reference for the chosen functions
(except arrow functions and already bound functions
[read more])
list
:
[0]
item should indicate the
object or value to be the
this
reference for the functions[1]
,
[2]
, etc... item(s) should indicate the
function(s), that will be bound to the
[0]
object or value[0]
object or value instead of the
config.context
config.bind
setting does not affect the individual
this
reference settingconfig.context
parameter
list
can still contain the
[Function] items next to this [Array] itemconst workers = {}, earnings = {}, tasks = {};
const config = {context: tasks}; //the default this reference
const list = [
functionA, //this === tasks
[workers, functionB], //this === workers
[earnings, functionC] //this === earnings
];
moveOn(list, config, onDone, onCatch));
list
loses their
this
reference to the object, they were declared in, what may be undesirable.
const workers = {
addWorker: function(){},
listEarnings: function(){}
};
const list = [
workers.addWorker, //this !== workers
workers.listEarnings //this !== workers
];
this
reference to the object, that the methods are declared in, push [Array] item with methods' [String] names into the
list
:
[0]
item should indicate the
object, that the methods are declared in[1]
,
[2]
, etc... item(s) should indicate the [String]
name(s) of the method(s) declared in the
[0]
objectthis
reference to the
[0]
object and are not
bound to the
config.context
config.bind
setting does not affect the
this
referenceconfig.context
parameter
list
can still contain the
[Function] items or
[Array] items with functions next to this [Array] item with [String] method's namesconst displayData = function(){};
const workers = {
addWorker: function(){},
listEarnings: function(){}
};
const list = [ [workers, 'addWorker', 'listEarnings'], displayData ];
moveOn(list, config, onDone, onCatch));
config
[Object | null]
config
argument allows to set the following
config properties:
timeout
,
bind
,
context
,
passContext
config
is set to
null
or when it does not define the particular config property or when it defines the config property
incorrectly, the
default value is used for this config property
instead [sample] [sample] [sample]
config.timeout
10000
0
, that indicates the
milliseconds
moveOn
:config.timeout
starts out counting down
individually for each chained function immediately after it is called.catch
function with the
timeout error
argument passedmoveOn.all
:config.timeout
starts out counting down
once for all chained functions when the module is fired.catch
function with the
timeout error
argument passedmoveOn.each
:config.timeout
starts out counting down
once for all chained functions when the module is fired.catch
function with the
timeout error
argument passedmoveOn.first
:config.timeout
starts out counting down
once for all chained functions when the module is fired.catch
function with the
timeout error
argument passedresolves
s and
reject
s that are called
after the
config.timeout
pass
are ignored
config.timeout
is set to
null
or
Infinity
, the timeout is
not set at all. If any of the chained function does not
resolve
(or reject), anything happen then and the
done
or
catch
function is never called in the endconfig.timeout
is not defined, or if it is defined with
incorrect value, the
default value is set insteadmessage
:
eg.
"Timeout. The chained function did not respond in the expected time of 10000 ms."
info
:
"timeout"
code
:
"ETIMEDOUT"
config.context
{}
config.context
refers to the object
(or value), that will be used as the
this
reference in all
list
functions,
done
and
catch
config.context
's properties can be defined and got in any functionconfig.context
can be
any value, as any value can be used as the
this
reference in
Function.prototype.bind
[read more]
config.context
is used as the
this
reference by default, unless you set
config.bind
to falseconfig.context
is also accessible as the parameter, unless you set
config.passContext
to falseconfig.passContext
true
config.context
object
(or value) is passed through each
list
function, the
done
and
catch
as the
argument:
config.context
as the argument, set
config.passContext
to
false
config.context
accessible as the parameter is usefull:
list
functions,
done
or
catch
are
arrow functions, that are non-binding and cannot refer to the
config.context
via
this
keywordlist
with
individually bound
functions or
methods names
, that do not refer to the
config.context
via
this
keywordlist
functions,
done
or
catch
are
already boundconfig.bind
true
list
function,
done
and
catch
are bound to the
config.context
object
(or value), thus the
this
keyword refers to the
config.context
this
reference of all functions, set the
config.bind
to
false
this
reference for chosen functions, see the
list
constructing options
this
reference changed anymorereject
,
context
)
[Function]
done
is a callback function, that
(in general) is called as the last one, when the
list
functions have been successfully executed. The
done
is called in a different way and time, depending on which method is called:
moveOn
The
done
is called, when the last function from the
list
collection is resolved.
done
:
[0]
reject
[1]
config.context
[2]
,
[3]
, etc... The arguments passed by the last resolved
list
function moveOn.all
The
done
is called, when all
list
functions are resolved.
done
:
[0]
reject
[1]
config.context
[2]
resolveMap
moveOn.each
The
done
is called, when all
list
functions are either resolved or rejected.
done
:
[0]
reject
[1]
config.context
[2]
resolveMap
moveOn.first
The
done
is called, when the first
(fastest)
list
function is resolved.
done
:
[0]
reject
[1]
config.context
[2]
,
[3]
, etc... The arguments passed by the first
(fastest) resolved
list
function resolveMap
objectresolveMap
object is passed through
done
callback when the
moveOn.all
and
moveOn.each
method is executed. It stores all arguments that have been passed by each
list
function's
resolve
call.resolveMap
contains all
arguments
objects at the
indeces that correspond to the order of
list
functions calling;
the third
list
function's arguments are accessible via
resolveMap[2]
, and so on...
resolveMap
properties:
missing
It returns the [Array] list of those
list
functions' indeces
(due to the order of calling) that have not been resolvedresolveMap
methods:
forEach
arguments
object.
[0]
parameter to be the [Function] callback.
arguments
object.
{0: arguments, 1: argumentsIndex, 2: resolveMap}
resolveMap.forEach((arguments, argumentsIndex, resolveMap) => {} );
forAll
arguments
object.
[0]
parameter to be the [Function] callback.
{0: argument, 1: argumentsIndex, 2: itemIndex, 3: resolveMap}
resolveMap.forAll((argument, argumentsIndex, itemIndex, resolveMap) => {} );
context
)
[Function]
catch
is a callback function, that
(in general) is called as the last one, when the
list
function(s) have failed. The
catch
is called in a different way and time, depending on which method is called:
moveOn
The
catch
is called, when any
list
function rejects.
catch
:
[0]
config.context
[1]
,
[2]
, etc... The arguments passed by the rejected
list
functionmoveOn.all
The
catch
is called, when any
list
function rejects.
catch
:
[0]
config.context
[1]
,
[2]
, etc... The arguments passed by the rejected
list
functionmoveOn.each
The
catch
is called for each
list
function rejection.
catch
:
[0]
config.context
[1]
,
[2]
, etc... The arguments passed by the rejected
list
functionmoveOn.first
The
catch
is called, when all
list
function rejected.
catch
:
[0]
config.context
[1]
rejectMap
rejectMap
objectrejectMap
object is passed through
catch
callback when the
moveOn.first
method is executed. It stores all arguments that have been passed by all
list
functions'
reject
callsrejectMap
contains all
arguments
objects at the
indeces that correspond to the order of
list
functions calling;
the third
list
function's arguments are accessible via
rejectMap[2]
, and so on...
rejectMap
methods:
forEach
arguments
object.
[0]
parameter to be the [Function] callback.arguments
object.
{0: arguments, 1: argumentsIndex, 2: rejectMap}
rejectMap.forEach((arguments, argumentsIndex, rejectMap) => {} );
forAll
arguments
object.[0]
parameter to be the [Function] callback.
{0: argument, 1: argumentsIndex, 2: itemIndex, 3: rejectMap}
rejectMap.forAll((argument, argumentsIndex, itemIndex, rejectMap) => {} );
list
function is called with the following arguments passed:
[0]
resolve
callback function[1]
reject
callback function[2]
config.context
object
(or value)
[3]
,
[4]
, etc...
(for
moveOn
method only) The arguments passed by the
previous
list
functionresolve
and
reject
can be called with any number of arguments [sample] [sample] [sample] [sample]
resolve
is called with arguments, these arguments will be passed:
moveOn
: for the further
list
function
(or for the
done
function, when the last
list
function resolves)
moveOn.first
: for the
done
functionmoveOn.all
,
moveOn.each
: for the
done
function in the
resolveMap
objectreject
is called with arguments, these arguments will be passed:
moveOn
,
moveOn.all
,
moveOn.each
: for the
catch
functionmoveOn.first
: for the
catch
function in the
rejectMap
objectfunction fetchData(resolve, reject, context){
this.someAsyncAjaxHere((err, data) => {
if(err) return reject(new Error('Could not read the data.'));
this.data = data;
return resolve();
});
}
resolve
|
reject
callsresolve
and
reject
do not end function execution. In order to end function execution, use
return resolve();
or
return reject();
moveOn.all
,
moveOn.each
and
moveOn.first
methods expect the
list
functions to call
resolve
or
reject
once
moveOn
method, as it calls the
list
functions sequentially, accepts the multiple
resolve
and
reject
calls:
list
function calls the
resolve
twice, it runs the further
list
functions twice
(the forks are created);
the
resolve
can be called eg. with different arguments
list
function calls the
reject
twice, it calls the
catch
twice;
the
reject
can be called eg. with different [Error] objects
list
function calls both
resolve
and
reject
, it both runs the further
list
functions and calls the
catch
move-on
modulelist
function can also contain the
inner
move-on
module execution, that has the
done
argument set to the
resolve
callback of this
list
functionmove-on
chain of synchronous and asynchronous functionsconst moveOn = require('move-on');
const list = [requestData, parseData, displayData];
const config = {
context:{
table: document.getElementById('list') //accessible in all functions as this.table
}
};
moveOn(list, config, onDone, onCatch);
//asynchronous
function requestData(resolve, reject, context) {
getAjaxData((err, json) => {
if (err) return reject(err);
this.json = json;
resolve();
});
}
//synchronous
function parseData(resolve, reject, context) {
this.data = parseJSON(this.json);
this.employees = getEmployeesList(this.data);
this.earnings = getEarningsList(this.data);
resolve();
}
function displayData(resolve, reject, context) {
table.innerHTML = parseTableContent(this.employees, this.earnings);
resolve();
}
function onDone(reject, context) {
this.table.style.display = "table";
}
function onCatch(context, err) {
throw new Error(`Could not get the data: ${err}`);
}
move-on
module with the user config.context
and the arguments passed through the resolve
and reject
arrow callback functionsconst moveOn = require('move-on');
function check(resolve, reject) {
console.log(this.name); //Jessica
console.log(this.age); //25
//the [String] argument passed through the catch callback function
if (!this.name || !this.age) return reject('The person was not defined.');
return resolve();
}
const config = {
context: {
name: 'Jessica',
age: 25
}
};
moveOn([check], config, (reject, context) => {
//the arrow function could not be bound to the context reference
//but the context is still accessible as the parameter
console.log(`New person added: ${context.name} (${context.age})yo.`);
}, (context, err) => {
console.error(err); //The [String] argument passed through the reject callback function
});
move-on
module that rejectsMind that the second rejected function ends up the execution of further chained functions.
const moveOn = require('move-on');
moveOn([a, b, c], null, onDone, onCatch);
function a(resolve, reject) {
resolve();
}
function b(resolve, reject) {
reject('oops!');
}
function c(resolve, reject) {
//it's been never called!
resolve();
}
function onDone(reject, context) {
//it's been never called!
}
function onCatch(context, message) {
console.log(message); //oops!
}
move-on
instructions after resolve
call
In order to end up the chained function's execution, call return resolve();
const moveOn = require('move-on');
moveOn([a, b, c], null, onDone, onCatch);
/* logs order:
A before
B before
C before
Done!
C after
B after
A after
*/
function a(resolve) {
console.log('A before');
resolve();
console.log('A after');
}
function b(resolve) {
console.log('B before');
resolve();
console.log('B after');
}
function c(resolve) {
console.log('C before');
resolve();
console.log('C after');
}
function onDone(reject, context) {
console.log('Done!');
}
function onCatch(context, msg) {
console.log(msg); //oops!
}
move-on
module and multiple resolve
and reject
callsMind how X, Y and Z functions of the inner module execute between A, B and C chained functions.
Mind how the B and C chained functions are executed twice, by doubleresolve
call in A chained function.
const moveOn = require('move-on');
moveOn([a, b, c], null, onDone, onCatch);
/* The order of functions execution:
A, X, Y, Z, B, C, Done, Catch, B, C, Done, Catch */
function a(resolve, reject) {
console.log('A');
moveOn([x, y, z], null, () => resolve(), () => reject);
resolve();
}
function b(resolve) {
console.log('B');
resolve();
}
function c(resolve, reject) {
console.log('C');
resolve();
reject();
}
function x(resolve) {
console.log('X');
resolve();
}
function y(resolve) {
console.log('Y');
resolve();
}
function z(resolve) {
console.log('Z');
resolve();
}
function onDone() {
console.log('Done');
}
function onCatch() {
console.log('Catch');
}
move-on
.all
chainIt callsdone
callback function right after all chained functions are resolved.
The user's shorterconfig.timeout
is set.
Thereject
callback functions are not used. In case of error, thecatch
callback function will still be called withconfig.timeout
error.
All retrieved data is passed through theresolve
callback and accessible in theResolveMap
done
callback function.
const moveOn = require('move-on');
const list = [getArticle, getTagList, getCommentSection];
moveOn.all(list, { timeout: 5000, passContext: false }, onDone, onCatch);
function getArticle(resolve) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) return resolve(xhr.responseText);
};
xhr.open("GET", "article.js", true);
xhr.send();
}
function getTagList(resolve) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) return resolve(xhr.responseText);
};
xhr.open("GET", "tags.js", true);
xhr.send();
}
function getCommentSection(resolve) {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = () => {
if (xhr.readyState == 4 && xhr.status == 200) return resolve(xhr.responseText);
};
xhr.open("GET", "comments.js", true);
xhr.send();
}
function onDone(reject, context, map) {
let article = JSON.parse(map[0][0]);
let tags = JSON.parse(map[1][0]);
let comments = JSON.parse(map[2][0]);
}
function onCatch(err) {
throw new Error(err);
}
move-on
.each
inner moduleThemove-on
is used to get the files list asynchronously and then to copy all files asynchronously.
The innermove-on
.each
module is injected in the second chained function in order to report the success | failure message for each copied file.
Each copying failure occurrence callsreject
callback and logs the warning.
When all files are (un)successfully copied, thedone
callback function is called, that indicates the end of files copying action.
const moveOn = require('move-on');
const fs = require('fs');
const path = require('path');
const list = [getContentsList, copyFiles];
const config = {
passContext: false,
context: {
copyFrom: './modules',
copyTo: './prod/modules'
}
};
moveOn(list, config, onDone, onCatch);
function getContentsList(resolve, reject) {
fs.readdir(this.copyFrom, (err, files) => {
if (err) return reject(`Could not get the access to the "${this.copyFrom}" path.`);
resolve(files); //the files object will be passed through the second function
});
}
function copyFiles(resolve, reject, files) {
const list = [];
//the moveOn.each will take the same user context to get the access to the paths
const config = { context: this, passContext: false };
//creating the list of chained functions for each files item:
for (let file of files) list.push((resolve, reject) => {
let fromPath = path.resolve(this.copyFrom, file);
let toPath = path.resolve(this.copyTo, file);
fs.copyFile(fromPath, toPath, (err) => {
//the reject call does not abort the module execution in moveOn.each method
if (err) return reject(`The file "${file}" could not be copied.`);
resolve(file); //the file path is added to the [Resolved] map, accessible in the final done callback function
});
});
//the inner moveOn.each module - as the done callback - calls the resolve callback of the second copyFiles function with [Resolved] map argument
moveOn.each(list, config, (reject, map) => resolve(map), (err) => console.warn(err));
}
function onDone(reject, map) {
//the [Resolved] map contains the collection of all passed files paths
//the missing property contains the indeces of all moveOn.each chained functions that have been rejected
let message = !map.missing.length ? 'All files have been successfully moved.' : 'The files have been moved with some errors.';
console.log(message);
}
function onCatch(err) {
throw new Error(err);
}
move-on
.first
moduleIt sends the request for the three urls and waits for the first (fastest) response.
const moveOn = require('move-on');
loadLibrary();
function loadLibrary() {
const list = [], urls = [ 'url-a', 'url-b', 'url-c' ];
for (let url of urls) {
list.push((resolve) => {
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) return resolve(this.responseText);
};
xhr.open("GET", url, true);
xhr.send();
})
}
//all list functions are called simultaneously
//the module expects the first function to be resolved in order to call the done callback
//if any of chained functions resolves in 2000ms, the timeout error will be passed through the catch callback function
moveOn.first(list, { timeout: 2000 }, onDone, onCatch);
function onDone(reject, context, data){
//the data has been passed by the fastest resolved chained function
//the other chained functions are ignored
}
function onCatch(context, err){
throw new Error(err); //timeout error
}
}
Theconfig.context
is set to the class instance'sthis
reference, thus the chained methods still have the access to all instance's properties and methods.
const moveOn = require('move-on');
class Vegetables {
constructor() {
const list = [retrieveData, createTable, generateDiet];
moveOn(list, { context: this }, () => { }, () => { });
}
retrieveData(resolve, reject) {
this._ajax((err, json) => {
if (err) return reject('We have got some problems. Try again later.');
resolve(json);
});
}
createTable(resolve, reject, context, json) {
let data = this._parseJson(json);
this.vegetables = this._generateTable(data);
this._displayTable(this.vegetables);
resolve();
}
generateDiet(resolve, reject) {
this._userData((err, data) => {
if (err) return reject('Register new account first!');
this.diet = this._addIngredients(this.vegetables, data.caloriesDemand);
resolve();
});
}
_parseJson() { }
_generateTable() { }
_userData() { }
_ajax() { }
_displayTable() { }
_addIngredients() { }
}
Mind that chained functions are passed as [String] methods' names to retain the access to thethis
reference to the class instance.
Thedone
andcatch
calls the samecallback function
. Thereject
is used to terminate the further chained functions and theresolve
to continue execution. Mind that isString and isAvailable methods callreject
to stop the module execution.
The [Array]errorMessages
stores all validation error messages, that will be printed out for the user.
The isAvailable chained function is asynchronous and simulates the request sent to the server to check whether the email address is available.
const moveOn = require('move-on');
class EmailValidation {
constructor({ email, callback }) {
this.email = email;
this.errorMessages = [];
const list = [[this, 'isString', 'hasAtSign', 'hasMultipleAtSigns', 'hasSpecialChars',
'hasCapitalLetters', 'hasSpaces', 'hasDoubleDots', 'isAvailable']];
moveOn(list, null, () => callback(this.errorMessages), () => callback(this.errorMessages));
}
isString(resolve, reject) {
if (typeof this.email !== 'string') {
this.errorMessages.push('The value must be a String.');
return reject();
}
resolve();
}
hasAtSign(resolve) {
if (!(/@/).test(this.email)) this.errorMessages.push('The value must contain @ sign.');
resolve();
}
hasMultipleAtSigns(resolve) {
if ((/@.*@/).test(this.email)) this.errorMessages.push('The value can contain only one @ sign.');
resolve();
}
hasSpecialChars(resolve) {
if (!(/^[A-z.\-@_]+$/).test(this.email)) this.errorMessages.push('The value cannot contain special characters.');
resolve();
}
hasCapitalLetters(resolve) {
if ((/[A-Z]/).test(this.email)) this.errorMessages.push('The value cannot contain capital letters.');
resolve();
}
hasSpaces(resolve) {
if ((/\s/).test(this.email)) this.errorMessages.push('The value cannot contain spaces.');
resolve();
}
hasDoubleDots(resolve) {
if ((/\.{2,}/).test(this.email)) this.errorMessages.push('The value cannot contain double dots.');
resolve();
}
isAvailable(resolve, reject) {
if (this.errorMessages.length) return reject();
setTimeout(() => {
if (!Math.random() > .5) { //check the availability
this.errorMessages.push(`The ${this.email} address is unavailable.`);
return reject();
}
resolve();
}, 500);
}
}
const formInput = document.getElementById('email-input');
const formAlert = document.getElementById('form-alert');
formInput.addEventListener('input', (event) => {
new EmailValidation({
email: event.target.value,
callback: (errorList) => {
formAlert.innerHTML = ''; //clear before print new messages
if (!errorList.length) formAlert.innerHTML = 'The address is OK';
else errorList.forEach((err) => formAlert.innerHTML += `${err}<br/>`);
}
});
});
FAQs
Creates a queue of sync or async functions with resolve and reject callback.
The npm package move-on receives a total of 2,855 weekly downloads. As such, move-on popularity was classified as popular.
We found that move-on demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer 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.
Research
Security News
Socket researchers uncover a malicious npm package posing as a tool for detecting vulnerabilities in Etherium smart contracts.
Security News
Research
A supply chain attack on Rspack's npm packages injected cryptomining malware, potentially impacting thousands of developers.
Research
Security News
Socket researchers discovered a malware campaign on npm delivering the Skuld infostealer via typosquatted packages, exposing sensitive data.