Skip to content
This repository has been archived by the owner on Dec 13, 2020. It is now read-only.

Commit

Permalink
Merge pull request #3 from epoberezkin/beta
Browse files Browse the repository at this point in the history
1.0.0
  • Loading branch information
epoberezkin authored Jan 7, 2018
2 parents 4ad5ef1 + 30a5925 commit 089bdd7
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 127 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,8 @@ jspm_packages

# Optional REPL history
.node_repl_history

# browser bundles
dist/

package-lock.json
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
language: node_js
node_js:
- "4"
- "6"
after_script:
- coveralls < coverage/lcov.info
136 changes: 15 additions & 121 deletions index.js
Original file line number Diff line number Diff line change
@@ -1,139 +1,33 @@
'use strict';

module.exports = function (ajv) {
setupAsyncOpts(ajv._opts, true);
return ajv;
};

var ASYNC = {
'*': checkGenerators,
'co*': checkGenerators,
'es7': checkAsyncFunction
};

var TRANSPILE = {
'nodent': getNodent,
'regenerator': getRegenerator
};

var MODES = [
{ async: 'es7' },
{ async: 'co*' },
{ async: 'es7', transpile: 'nodent' },
{ async: 'co*', transpile: 'regenerator' }
];


var regenerator, nodent;

var nodent = require('nodent')({ log: false, dontInstallRequireHook: true });

function setupAsyncOpts(opts, required) {
var async = opts.async
, transpile = opts.transpile
, check;

switch (typeof transpile) {
case 'string':
var get = TRANSPILE[transpile];
if (!get) throw new Error('bad transpiler: ' + transpile);
return (opts.processCode = get(opts, required));
case 'undefined':
case 'boolean':
if (typeof async == 'string') {
check = ASYNC[async];
if (!check) throw new Error('bad async mode: ' + async);
return (opts.transpile = check(opts, required));
}

for (var i=0; i<MODES.length; i++) {
var _opts = MODES[i];
if (setupAsyncOpts(_opts, false)) {
copy(_opts, opts);
return opts.transpile;
}
}
/* istanbul ignore next */
throw new Error('generators, nodent and regenerator are not available');
case 'function':
return (opts.processCode = opts.transpile);
default:
throw new Error('bad transpiler: ' + transpile);
}
}


function checkGenerators(opts, required) {
/* jshint evil: true */
try {
(new Function('(function*(){})()'))();
return true;
} catch(e) {
/* istanbul ignore next */
if (required) throw new Error('generators not supported');
module.exports = function (ajv) {
var opts = ajv._opts;
var t = opts.transpile;
if (typeof t != 'boolean' && t !== undefined)
throw new TypeError('transpile option must be boolean or undefined');
if (t) {
opts.processCode = nodentTranspile;
} else if (!checkAsync()) {
if (t === false) throw new Error('async functions not supported');
opts.processCode = nodentTranspile;
}
}
return ajv;
};


function checkAsyncFunction(opts, required) {
function checkAsync() {
/* jshint evil: true */
try {
(new Function('(async function(){})()'))();
/* istanbul ignore next */
return true;
} catch(e) {
if (required) throw new Error('es7 async functions not supported');
}
}


function getRegenerator(opts, required) {
try {
if (!regenerator) {
var name = 'regenerator';
regenerator = require(name);
regenerator.runtime();
}
if (!opts.async || opts.async === true)
opts.async = 'es7';
return regeneratorTranspile;
} catch(e) {
/* istanbul ignore next */
if (required) throw new Error('regenerator not available');
}
}


function regeneratorTranspile(code) {
return regenerator.compile(code).code;
}


function getNodent(opts, required) {
/* jshint evil: true */
try {
if (!nodent) {
var name = 'nodent';
nodent = require(name)({ log: false, dontInstallRequireHook: true });
}
if (opts.async != 'es7') {
if (opts.async && opts.async !== true) console.warn('nodent transpiles only es7 async functions');
opts.async = 'es7';
}
return nodentTranspile;
} catch(e) {
/* istanbul ignore next */
if (required) throw new Error('nodent not available');
}
} catch(e) {}
}


function nodentTranspile(code) {
return nodent.compile(code, '', { promises: true, sourcemap: false }).code;
}


function copy(o, to) {
to = to || {};
for (var key in o) to[key] = o[key];
return to;
}
37 changes: 31 additions & 6 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
{
"name": "ajv-async",
"version": "0.1.1",
"version": "1.0.0",
"description": "Configure async validation mode in Ajv - JSON-Schema validator",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
"bundle": "rm -rf dist && ./scripts/bundle",
"prepublish": "npm run bundle",
"test-spec": "mocha spec/*.spec.js -R spec",
"test-cov": "nyc npm run test-spec",
"test": "npm run test-cov"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -35,11 +39,32 @@
"url": "https://github.com/epoberezkin/ajv-async/issues"
},
"homepage": "https://github.com/epoberezkin/ajv-async#readme",
"peerDependencies": {
"ajv": "^6.0.0"
},
"dependencies": {
"nodent": "^3.1.3"
},
"devDependencies": {
"nodent": "^3.0.7",
"regenerator": "^0.9.5"
"ajv": "^6.0.0",
"browserify": "^14.5.0",
"mocha": "^4.0.1",
"nyc": "^11.3.0",
"pre-commit": "^1.2.2",
"uglify-js": "^3.1.8"
},
"peerDependencies": {
"ajv": "^5.0.0"
"files": [
"index.js",
"dist/"
],
"nyc": {
"exclude": [
"**/spec/**",
"node_modules"
],
"reporter": [
"lcov",
"text-summary"
]
}
}
18 changes: 18 additions & 0 deletions scripts/bundle
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/usr/bin/env sh

set -e

name=$(./scripts/info name)
main=$(./scripts/info main)
version=$(./scripts/info version)
description=$(./scripts/info description)

mkdir -p dist

browserify -r "./$main:$name" \
-o "dist/$name.bundle.js" \
-s ajvAsync

uglifyjs "dist/$name.bundle.js" -o "dist/$name.min.js" \
-c -m --source-map \
-b "beautify=false, preamble='/* $name $version: $description */'"
10 changes: 10 additions & 0 deletions scripts/info
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/usr/bin/env node

'use strict';

var fs = require('fs');
var property = process.argv[2] || 'version';
var name = process.argv[3] || '.';
if (name != '.') name = 'node_modules/' + name;
var json = JSON.parse(fs.readFileSync(name + '/package.json', 'utf8'));
console.log(json[property]);
45 changes: 45 additions & 0 deletions spec/transpile.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
'use strict';

var Ajv = require('ajv');
var setupAsync = require('../index.js');
var assert = require('assert');


describe('transpile option', function() {
var majorNodeVersion;
if (typeof process != 'undefined')
majorNodeVersion = +process.versions.node.split('.')[0];

it('should set processCode if async not supported', function() {
var ajv = setupAsync(new Ajv);
if (majorNodeVersion >= 7)
assert.strictEqual(ajv._opts.processCode, undefined);
else
assert.equal(typeof ajv._opts.processCode, 'function');
});

it('should always set processCode if transpile: true', function() {
var ajv = setupAsync(new Ajv({ transpile: true }));
assert.equal(typeof ajv._opts.processCode, 'function');
});

it('should throw error if async not supported and transpile: false', function() {
if (majorNodeVersion >= 7) assert.doesNotThrow(test);
else assert.throws(test, /async functions not supported/);

function test() {
setupAsync(new Ajv({ transpile: false }));
}
});

it('should throw error with unknown transpile option', function() {
test('nodent');
test({});

function test(transpile) {
assert.throws(function() {
setupAsync(new Ajv({ transpile: transpile }));
}, /transpile option must be boolean or undefined/);
}
});
});

0 comments on commit 089bdd7

Please sign in to comment.