mirror of
https://github.com/arthur-pbty/portfolio2023.git
synced 2026-06-07 23:04:51 +02:00
modified
This commit is contained in:
-21
@@ -1,21 +0,0 @@
|
||||
The MIT License (MIT)
|
||||
|
||||
Copyright Ayon Lee and other Node contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
-62
@@ -1,62 +0,0 @@
|
||||
# Node's processTopLevelAwait
|
||||
|
||||
Standalone util function from Node.js core to process await statements in REPL.
|
||||
|
||||
Since v10.0.0, Node.js introduced a new experimental feature to support `await`
|
||||
keyword in the REPL by using the argument `--experimental-repl-await`, however,
|
||||
if a user wants to implement a custom REPL console, there would be no
|
||||
await-support at all, to achieve such a goal, this package clones the internal
|
||||
module of await-support to form a standalone version, allowing users share the
|
||||
benefits of await-support in their own REPL environments.
|
||||
|
||||
See
|
||||
[Node.js docs](https://nodejs.org/dist/latest-v11.x/docs/api/repl.html#repl_await_keyword)
|
||||
for more details, and contribute to the
|
||||
[original source](https://github.com/nodejs/node/blob/master/lib/internal/repl/await.js).
|
||||
|
||||
## Example
|
||||
|
||||
```javascript
|
||||
const repl = require("repl");
|
||||
const vm = require("vm");
|
||||
const { processTopLevelAwait } = require("node-repl-await");
|
||||
|
||||
function isRecoverableError(error) {
|
||||
if (error.name === 'SyntaxError') {
|
||||
return /^(Unexpected end of input|Unexpected token)/.test(error.message);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async function myEval(code, context, filename, callback) {
|
||||
code = processTopLevelAwait(code) || code;
|
||||
|
||||
try {
|
||||
let result = await vm.runInNewContext(code, context);
|
||||
callback(null, result);
|
||||
} catch (e) {
|
||||
if (isRecoverableError(e)) {
|
||||
callback(new repl.Recoverable(e));
|
||||
} else {
|
||||
console.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repl.start({ prompt: '> ', eval: myEval });
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
```typescript
|
||||
function processTopLevelAwait(src: string): string | void
|
||||
```
|
||||
|
||||
Tries to wrap the given source code to an immediately-invoked function if it
|
||||
contains any top level `await` statement in the form of
|
||||
|
||||
```js
|
||||
(async () => { /* source code */ })()
|
||||
```
|
||||
|
||||
If no `await` presents or processing failed, the function returns `null`.
|
||||
-1
@@ -1 +0,0 @@
|
||||
export function processTopLevelAwait(src: string): string | void;
|
||||
-143
@@ -1,143 +0,0 @@
|
||||
'use strict';
|
||||
|
||||
const acorn = require('acorn');
|
||||
const walk = require('acorn-walk');
|
||||
const privateMethods = require('acorn-private-methods');
|
||||
const classFields = require('acorn-class-fields');
|
||||
const staticClassFeatures = require('acorn-static-class-features');
|
||||
|
||||
const parser = acorn.Parser.extend(
|
||||
privateMethods,
|
||||
classFields,
|
||||
staticClassFeatures
|
||||
);
|
||||
|
||||
const noop = () => { };
|
||||
const visitorsWithoutAncestors = {
|
||||
ClassDeclaration(node, state, c) {
|
||||
if (state.ancestors[state.ancestors.length - 2] === state.body) {
|
||||
state.prepend(node, `${node.id.name}=`);
|
||||
}
|
||||
walk.base.ClassDeclaration(node, state, c);
|
||||
},
|
||||
ForOfStatement(node, state, c) {
|
||||
if (node.await === true) {
|
||||
state.containsAwait = true;
|
||||
}
|
||||
walk.base.ForOfStatement(node, state, c);
|
||||
},
|
||||
FunctionDeclaration(node, state, c) {
|
||||
state.prepend(node, `${node.id.name}=`);
|
||||
},
|
||||
FunctionExpression: noop,
|
||||
ArrowFunctionExpression: noop,
|
||||
MethodDefinition: noop,
|
||||
AwaitExpression(node, state, c) {
|
||||
state.containsAwait = true;
|
||||
walk.base.AwaitExpression(node, state, c);
|
||||
},
|
||||
ReturnStatement(node, state, c) {
|
||||
state.containsReturn = true;
|
||||
walk.base.ReturnStatement(node, state, c);
|
||||
},
|
||||
VariableDeclaration(node, state, c) {
|
||||
if (node.kind === 'var' ||
|
||||
state.ancestors[state.ancestors.length - 2] === state.body) {
|
||||
if (node.declarations.length === 1) {
|
||||
state.replace(node.start, node.start + node.kind.length, 'void');
|
||||
} else {
|
||||
state.replace(node.start, node.start + node.kind.length, 'void (');
|
||||
}
|
||||
|
||||
for (const decl of node.declarations) {
|
||||
state.prepend(decl, '(');
|
||||
state.append(decl, decl.init ? ')' : '=undefined)');
|
||||
}
|
||||
|
||||
if (node.declarations.length !== 1) {
|
||||
state.append(node.declarations[node.declarations.length - 1], ')');
|
||||
}
|
||||
}
|
||||
|
||||
walk.base.VariableDeclaration(node, state, c);
|
||||
}
|
||||
};
|
||||
|
||||
const visitors = {};
|
||||
for (const nodeType of Object.keys(walk.base)) {
|
||||
const callback = visitorsWithoutAncestors[nodeType] || walk.base[nodeType];
|
||||
visitors[nodeType] = (node, state, c) => {
|
||||
const isNew = node !== state.ancestors[state.ancestors.length - 1];
|
||||
if (isNew) {
|
||||
state.ancestors.push(node);
|
||||
}
|
||||
callback(node, state, c);
|
||||
if (isNew) {
|
||||
state.ancestors.pop();
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function processTopLevelAwait(src) {
|
||||
const wrapped = `(async () => { ${src} })()`;
|
||||
const wrappedArray = wrapped.split('');
|
||||
let root;
|
||||
try {
|
||||
root = parser.parse(wrapped, { ecmaVersion: 11 });
|
||||
} catch (e) {
|
||||
return null;
|
||||
}
|
||||
const body = root.body[0].expression.callee.body;
|
||||
const state = {
|
||||
body,
|
||||
ancestors: [],
|
||||
replace(from, to, str) {
|
||||
for (var i = from; i < to; i++) {
|
||||
wrappedArray[i] = '';
|
||||
}
|
||||
if (from === to) str += wrappedArray[from];
|
||||
wrappedArray[from] = str;
|
||||
},
|
||||
prepend(node, str) {
|
||||
wrappedArray[node.start] = str + wrappedArray[node.start];
|
||||
},
|
||||
append(node, str) {
|
||||
wrappedArray[node.end - 1] += str;
|
||||
},
|
||||
containsAwait: false,
|
||||
containsReturn: false
|
||||
};
|
||||
|
||||
walk.recursive(body, state, visitors);
|
||||
|
||||
// Do not transform if
|
||||
// 1. False alarm: there isn't actually an await expression.
|
||||
// 2. There is a top-level return, which is not allowed.
|
||||
if (!state.containsAwait || state.containsReturn) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const last = body.body[body.body.length - 1];
|
||||
if (last.type === 'ExpressionStatement') {
|
||||
// For an expression statement of the form
|
||||
// ( expr ) ;
|
||||
// ^^^^^^^^^^ // last
|
||||
// ^^^^ // last.expression
|
||||
//
|
||||
// We do not want the left parenthesis before the `return` keyword;
|
||||
// therefore we prepend the `return (` to `last`.
|
||||
//
|
||||
// On the other hand, we do not want the right parenthesis after the
|
||||
// semicolon. Since there can only be more right parentheses between
|
||||
// last.expression.end and the semicolon, appending one more to
|
||||
// last.expression should be fine.
|
||||
state.prepend(last, 'return (');
|
||||
state.append(last.expression, ')');
|
||||
}
|
||||
|
||||
return wrappedArray.join('');
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
processTopLevelAwait
|
||||
};
|
||||
-38
@@ -1,38 +0,0 @@
|
||||
{
|
||||
"name": "node-repl-await",
|
||||
"version": "0.1.2",
|
||||
"description": "Standalone util function from Node.js core to process await statements in REPL.",
|
||||
"main": "index.js",
|
||||
"types": "index.d.ts",
|
||||
"scripts": {
|
||||
"test": "mocha"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/hyurl/node-repl-await.git"
|
||||
},
|
||||
"keywords": [
|
||||
"repl",
|
||||
"await",
|
||||
"async",
|
||||
"shell",
|
||||
"console",
|
||||
"terminal"
|
||||
],
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/nodejs/node/issues"
|
||||
},
|
||||
"homepage": "https://nodejs.org",
|
||||
"dependencies": {
|
||||
"acorn": "^8.0.5",
|
||||
"acorn-class-fields": "^1.0.0",
|
||||
"acorn-private-methods": "^1.0.0",
|
||||
"acorn-static-class-features": "^1.0.0",
|
||||
"acorn-walk": "^8.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^11.15.2",
|
||||
"mocha": "^6.2.2"
|
||||
}
|
||||
}
|
||||
-21
@@ -1,21 +0,0 @@
|
||||
/* global describe, it */
|
||||
const assert = require("assert");
|
||||
const { processTopLevelAwait } = require(".");
|
||||
|
||||
describe("processTopLevelAwait", () => {
|
||||
it("should process statements with leading await keywords", () => {
|
||||
assert.strictEqual(processTopLevelAwait("await 123"), "(async () => { return (await 123) })()");
|
||||
assert.strictEqual(processTopLevelAwait("await 123;"), "(async () => { return (await 123); })()");
|
||||
});
|
||||
|
||||
it("should process statements with await keywords in the middle", () => {
|
||||
assert.strictEqual(processTopLevelAwait("foo = await 123"), "(async () => { return (foo = await 123) })()");
|
||||
assert.strictEqual(processTopLevelAwait("foo = await 123;"), "(async () => { return (foo = await 123); })()");
|
||||
assert.strictEqual(processTopLevelAwait("let foo; foo = await 123;"), "(async () => { void (foo=undefined); return (foo = await 123); })()");
|
||||
});
|
||||
|
||||
it("should not process any statement without top level await keyword", () => {
|
||||
assert.strictEqual(processTopLevelAwait("let foo = 123"), null);
|
||||
assert.strictEqual(processTopLevelAwait("async function () { await 123; }"), null);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user