pax_global_header00006660000000000000000000000064131254131050014505gustar00rootroot0000000000000052 comment=b4743108b75bec743c815691e958c934bcab2137 babel-plugin-transform-async-to-bluebird-1.1.1/000077500000000000000000000000001312541310500214005ustar00rootroot00000000000000babel-plugin-transform-async-to-bluebird-1.1.1/.babelrc000066400000000000000000000001071312541310500227710ustar00rootroot00000000000000{ "presets": ["es2015"], "plugins": ["transform-flow-strip-types"] } babel-plugin-transform-async-to-bluebird-1.1.1/.editorconfig000066400000000000000000000003021312541310500240500ustar00rootroot00000000000000root = true [*] indent_style = tab end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [{.eslintrc,package.json}] indent_style = space indent_size = 2 babel-plugin-transform-async-to-bluebird-1.1.1/.eslintrc000066400000000000000000000000451312541310500232230ustar00rootroot00000000000000extends: sudeti parser: babel-eslint babel-plugin-transform-async-to-bluebird-1.1.1/.flowconfig000066400000000000000000000000001312541310500235240ustar00rootroot00000000000000babel-plugin-transform-async-to-bluebird-1.1.1/.gitignore000066400000000000000000000000351312541310500233660ustar00rootroot00000000000000/node_modules/ /main.es5.js* babel-plugin-transform-async-to-bluebird-1.1.1/.npmignore000066400000000000000000000000211312541310500233700ustar00rootroot00000000000000* !/main.es5.js* babel-plugin-transform-async-to-bluebird-1.1.1/README.md000066400000000000000000000030501312541310500226550ustar00rootroot00000000000000# babel-plugin-transform-async-to-bluebird This plugin transforms `async` to `bluebird`. ## Examples An *async* function containing **no** *await* gets wrapped by *bluebird*s [*method*](http://bluebirdjs.com/docs/api/promise.method.html) function without using the generator, resulting in less overhead. All returned or thrown values are wrapped by *Promis*es and then returned. ```javascript async function myFunction(input) { if (input === 0) throw new TypeError('Invalid input'); if (input === 42) return promiseReturningFunction(input); return input + 10; } myFunction(0); // Returns a Promise, rejecting into an TypeError('Invalid input') myFunction(42); // Returns a Promise myFunction($other_value); // Returns a Promise, resolving into $other_value + 10 ``` On the other side an *async* + *await* function gets wrapped by *bluebird*s [*coroutine*](http://bluebirdjs.com/docs/api/promise.coroutine.html); it's using the generator. ```javascript async function myFunction(input) { if (input === 0) throw new TypeError('Invalid input'); const res = await promiseReturningFunction(input); return res + 10; } ``` ## Usage 1. Install *bluebird*: `npm install --save bluebird` 2. Install the plugin: `npm install --save-dev babel-plugin-transform-async-to-bluebird` 3. Add *transform-async-to-bluebird* to your *.babelrc* file: ```json { "plugins": ["transform-async-to-bluebird"] } ``` ## Credits This babel plugin is based on [babel-helper-remap-async-to-generator](https://github.com/babel/babel/tree/master/packages/babel-helper-remap-async-to-generator) babel-plugin-transform-async-to-bluebird-1.1.1/main.es2015.js000066400000000000000000000072111312541310500236010ustar00rootroot00000000000000// @flow import syntaxAsyncFunctions from 'babel-plugin-syntax-async-functions'; import type {NodePath} from 'babel-traverse'; import traverse from 'babel-traverse'; import nameFunction from 'babel-helper-function-name'; import template from 'babel-template'; const FUNCTION_TYPES = [ 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression', ]; const BUILD_WRAPPER = template(` (() => { var REF = FUNCTION; return function NAME(PARAMS) { return REF.apply(this, arguments); }; }) `); const NAMED_BUILD_WRAPPER = template(` (() => { var REF = FUNCTION; function NAME(PARAMS) { return REF.apply(this, arguments); } return NAME; }) `); export default function asyncToBluebird(pluginArg: any) { const {types: t} = pluginArg; function classOrObjectMethod(path: NodePath, state: any, hasAwait: boolean) { const {node} = path; const {body} = node; node.async = false; node.generator = false; const container = t.functionExpression(null, [], t.blockStatement(body.body), true); container.shadow = true; container.generator = hasAwait; const bbImport = state.addImport('bluebird', hasAwait ? 'coroutine' : 'method'); body.body = [ t.returnStatement( t.callExpression( t.callExpression( bbImport, [container] ), [] ) ), ]; } function plainFunction(path: NodePath, state: any, hasAwait: boolean) { const {node} = path; const isDeclaration = path.isFunctionDeclaration(); const asyncFnId = node.id; let wrapper = BUILD_WRAPPER; if (path.isArrowFunctionExpression()) path.arrowFunctionToShadowed(); else if (!isDeclaration && asyncFnId) wrapper = NAMED_BUILD_WRAPPER; node.async = false; node.generator = hasAwait; node.id = null; if (isDeclaration) node.type = 'FunctionExpression'; const bbImport = state.addImport('bluebird', hasAwait ? 'coroutine' : 'method'); const built = t.callExpression(bbImport, [node]); const container = wrapper({ NAME: asyncFnId, REF: path.scope.generateUidIdentifier('ref'), FUNCTION: built, PARAMS: node.params.map(() => path.scope.generateUidIdentifier('x')), }).expression; if (isDeclaration) { const declar = t.variableDeclaration('let', [ t.variableDeclarator( t.identifier(asyncFnId.name), t.callExpression(container, []) ), ]); declar._blockHoist = true; path.replaceWith(declar); } else { const retFunction = container.body.body[1].argument; if (!asyncFnId) { nameFunction({ node: retFunction, parent: path.parent, scope: path.scope, }); } if (!retFunction || retFunction.id || node.params.length) { // we have an inferred function id or params so we need this wrapper path.replaceWith(t.callExpression(container, [])); } else { // we can omit this wrapper as the conditions it protects for do not apply path.replaceWith(built); } } } return { inherits: syntaxAsyncFunctions, visitor: { Function(path: NodePath, state: any) { const {node, scope} = path; if (!node.async || node.generator) return; const hasAwait = traverse.hasType(node.body, scope, 'AwaitExpression', FUNCTION_TYPES); traverse(node, { blacklist: FUNCTION_TYPES, AwaitExpression(path2: NodePath) { // eslint-disable-next-line no-param-reassign path2.node.type = 'YieldExpression'; path2.node.argument = t.callExpression( state.addImport('bluebird', 'resolve'), [path2.node.argument] ); }, }, scope); const isClassOrObjectMethod = path.isClassMethod() || path.isObjectMethod(); (isClassOrObjectMethod ? classOrObjectMethod : plainFunction)(path, state, hasAwait); }, }, }; } babel-plugin-transform-async-to-bluebird-1.1.1/package.json000066400000000000000000000022221312541310500236640ustar00rootroot00000000000000{ "name": "babel-plugin-transform-async-to-bluebird", "version": "1.1.1", "description": "Transforms *async* to *bluebird*", "main": "main.es5.js", "dependencies": { "babel-helper-function-name": "^6.8.0", "babel-plugin-syntax-async-functions": "^6.8.0", "babel-template": "^6.9.0", "babel-traverse": "^6.10.4" }, "devDependencies": { "babel-cli": "^6.10.1", "babel-core": "^6.24.1", "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", "babel-plugin-transform-flow-strip-types": "^6.8.0", "babel-preset-es2015": "^6.9.0", "babel-register": "^6.24.1", "bluebird": "^3.5.0", "mocha": "^3.3.0" }, "scripts": { "test": "mocha --require babel-register", "prepublish": "babel main.es2015.js --out-file main.es5.js --source-maps" }, "repository": { "type": "git", "url": "git+https://github.com/chpio/babel-plugin-transform-async-to-bluebird.git" }, "author": "", "license": "MIT", "bugs": { "url": "https://github.com/chpio/babel-plugin-transform-async-to-bluebird/issues" }, "homepage": "https://github.com/chpio/babel-plugin-transform-async-to-bluebird#readme" } babel-plugin-transform-async-to-bluebird-1.1.1/test/000077500000000000000000000000001312541310500223575ustar00rootroot00000000000000babel-plugin-transform-async-to-bluebird-1.1.1/test/test.js000066400000000000000000000024251312541310500236770ustar00rootroot00000000000000import {transform} from 'babel-core'; import assert from 'assert'; import {Script, createContext} from 'vm'; import asyncToBluebird from '../main.es2015.js'; const VM_CONTEXT = new createContext({require}); function run(code) { const result = transform(code, { code: true, ast: false, sourceMaps: false, babelrc: false, plugins: [ 'transform-flow-strip-types', asyncToBluebird, 'transform-es2015-modules-commonjs' ], }); return new Script(result.code, {}).runInContext(VM_CONTEXT).then(res => [res, result.code]); } function runEq(desiredRes, code) { return run(code).then(([res, resCode]) => assert.deepEqual(desiredRes, res, resCode)); } it('resolve non promises', () => { return runEq(1337, ` (async () => { return await 1337; })(); `); }); it('async methods', () => { return runEq([ 'begin', 'wa_begin', 'wa_resolve', 'wa_end', 'woa', 'end', ], ` class Test { async with_await() { let ret = ['wa_begin']; ret.push(await 'wa_resolve'); ret.push('wa_end'); return ret; } async without_await() { return ['woa']; } } (async () => { let ret = ['begin']; ret.push(...(await new Test().with_await())); ret.push(...(await new Test().without_await())); ret.push('end'); return ret; })(); `); });