update
This commit is contained in:
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"K D E F A B mC"},B:{"1":"0 9 O P Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I","2":"C L M G N"},C:{"1":"0 9 gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC","2":"1 2 3 4 5 6 7 8 nC LC J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB qC rC"},D:{"1":"0 9 iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","2":"1 2 3 4 5 6 7 8 J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB"},E:{"1":"B C L M G FC GC xC yC zC UC VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC 3C","2":"J PB K D E F A sC SC tC uC vC wC TC"},F:{"1":"0 VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z","2":"1 2 3 4 5 6 7 8 F B C G N O P QB RB SB TB UB 4C 5C 6C 7C FC kC 8C GC"},G:{"1":"JD KD LD MD ND OD PD QD RD SD UC VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC","2":"E SC 9C lC AD BD CD DD ED FD GD HD","194":"ID"},H:{"2":"WD"},I:{"1":"I","2":"LC J XD YD ZD aD lC bD cD"},J:{"2":"D A"},K:{"1":"H","2":"A B C FC kC GC"},L:{"1":"I"},M:{"1":"EC"},N:{"2":"A B"},O:{"1":"HC"},P:{"1":"1 2 3 4 5 6 7 8 dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD","2":"J"},Q:{"1":"oD"},R:{"1":"pD"},S:{"1":"qD rD"}},B:2,C:"Subresource Integrity",D:true};
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"K D E F A B mC"},B:{"1":"0 9 Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I","2":"C L M G N O P"},C:{"1":"0 9 kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC","2":"1 2 3 4 5 6 7 8 nC LC J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB qC rC"},D:{"1":"0 9 mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","2":"1 2 3 4 5 6 7 8 J PB K D E F A B C L M G N O P QB RB SB TB UB VB","129":"WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB"},E:{"1":"C L M G FC GC xC yC zC UC VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC 3C","2":"J PB K D E F A B sC SC tC uC vC wC TC"},F:{"1":"0 ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z","2":"1 2 3 4 5 6 7 8 F B C G N O P QB RB SB TB UB VB WB XB YB 4C 5C 6C 7C FC kC 8C GC"},G:{"1":"ID JD KD LD MD ND OD PD QD RD SD UC VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC","2":"E SC 9C lC AD BD CD DD ED FD GD HD"},H:{"2":"WD"},I:{"1":"I","2":"LC J XD YD ZD aD lC bD","16":"cD"},J:{"2":"D A"},K:{"1":"H","2":"A B C FC kC GC"},L:{"1":"I"},M:{"1":"EC"},N:{"2":"A B"},O:{"1":"HC"},P:{"1":"1 2 3 4 5 6 7 8 J dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD"},Q:{"1":"oD"},R:{"1":"pD"},S:{"1":"qD rD"}},B:6,C:"ChaCha20-Poly1305 cipher suites for TLS",D:true};
|
||||
@@ -0,0 +1,8 @@
|
||||
import * as React from 'react';
|
||||
export declare const Match: React.NamedExoticComponent<{
|
||||
matchId: string;
|
||||
}>;
|
||||
export declare const MatchInner: React.NamedExoticComponent<{
|
||||
matchId: string;
|
||||
}>;
|
||||
export declare const Outlet: React.NamedExoticComponent<object>;
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"K D E F A B mC"},B:{"1":"0 9 M G N O P Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I","2":"C L"},C:{"1":"0 9 UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC","2":"1 2 3 4 5 6 7 8 nC LC J PB K D E F A B C L M G N O P QB RB SB TB qC rC"},D:{"1":"0 9 cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","2":"1 2 3 4 5 6 7 8 J PB K D E F A B C L M G N O P QB RB SB TB UB VB WB XB YB ZB aB bB"},E:{"1":"C L M G FC GC xC yC zC UC VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC 3C","2":"J PB K D E F A B sC SC tC uC vC wC TC"},F:{"1":"0 7 8 RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z","2":"1 2 3 4 5 6 F B C G N O P QB 4C 5C 6C 7C FC kC 8C GC"},G:{"1":"JD KD LD MD ND OD PD QD RD SD UC VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC","2":"E SC 9C lC AD BD CD DD ED FD GD HD ID"},H:{"2":"WD"},I:{"1":"I","2":"LC J XD YD ZD aD lC bD cD"},J:{"2":"D A"},K:{"1":"H","2":"A B C FC kC GC"},L:{"1":"I"},M:{"1":"EC"},N:{"2":"A B"},O:{"1":"HC"},P:{"1":"1 2 3 4 5 6 7 8 J dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD"},Q:{"1":"oD"},R:{"1":"pD"},S:{"1":"qD rD"}},B:4,C:"Beacon API",D:true};
|
||||
@@ -0,0 +1,12 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = isNode;
|
||||
var _index = require("../definitions/index.js");
|
||||
function isNode(node) {
|
||||
return !!(node && _index.VISITOR_KEYS[node.type]);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=isNode.js.map
|
||||
@@ -0,0 +1,9 @@
|
||||
'use strict';
|
||||
|
||||
var util = require('./util');
|
||||
|
||||
module.exports = SchemaObject;
|
||||
|
||||
function SchemaObject(obj) {
|
||||
util.copy(obj, this);
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
const compare = require('./compare')
|
||||
const gte = (a, b, loose) => compare(a, b, loose) >= 0
|
||||
module.exports = gte
|
||||
@@ -0,0 +1,67 @@
|
||||
# Browserslist [![Cult Of Martians][cult-img]][cult]
|
||||
|
||||
<img width="120" height="120" alt="Browserslist logo by Anton Popov"
|
||||
src="https://browsersl.ist/logo.svg" align="right">
|
||||
|
||||
The config to share target browsers and Node.js versions between different
|
||||
front-end tools. It is used in:
|
||||
|
||||
* [Autoprefixer]
|
||||
* [Babel]
|
||||
* [postcss-preset-env]
|
||||
* [eslint-plugin-compat]
|
||||
* [stylelint-no-unsupported-browser-features]
|
||||
* [postcss-normalize]
|
||||
* [obsolete-webpack-plugin]
|
||||
|
||||
All tools will find target browsers automatically,
|
||||
when you add the following to `package.json`:
|
||||
|
||||
```json
|
||||
"browserslist": [
|
||||
"defaults and fully supports es6-module",
|
||||
"maintained node versions"
|
||||
]
|
||||
```
|
||||
|
||||
Or in `.browserslistrc` config:
|
||||
|
||||
```yaml
|
||||
# Browsers that we support
|
||||
|
||||
defaults and fully supports es6-module
|
||||
maintained node versions
|
||||
```
|
||||
|
||||
Developers set their version lists using queries like `last 2 versions`
|
||||
to be free from updating versions manually.
|
||||
Browserslist will use [`caniuse-lite`] with [Can I Use] data for this queries.
|
||||
|
||||
You can check how config works at our playground: [`browsersl.ist`](https://browsersl.ist/)
|
||||
|
||||
<a href="https://browsersl.ist/">
|
||||
<img src="/img/screenshot.webp" alt="browsersl.ist website">
|
||||
</a>
|
||||
|
||||
<br>
|
||||
<br>
|
||||
<div align="center">
|
||||
<a href="https://evilmartians.com/?utm_source=browserslist"><img src="https://evilmartians.com/badges/sponsored-by-evil-martians.svg" alt="Sponsored by Evil Martians" width="236" height="54"></a> <a href="https://cube.dev/?ref=eco-browserslist-github"><img src="https://user-images.githubusercontent.com/986756/154330861-d79ab8ec-aacb-4af8-9e17-1b28f1eccb01.svg" alt="Supported by Cube" width="227" height="46"></a>
|
||||
</div>
|
||||
|
||||
[stylelint-no-unsupported-browser-features]: https://github.com/ismay/stylelint-no-unsupported-browser-features
|
||||
[obsolete-webpack-plugin]: https://github.com/ElemeFE/obsolete-webpack-plugin
|
||||
[eslint-plugin-compat]: https://github.com/amilajack/eslint-plugin-compat
|
||||
[Browserslist Example]: https://github.com/browserslist/browserslist-example
|
||||
[postcss-preset-env]: https://github.com/csstools/postcss-plugins/tree/main/plugin-packs/postcss-preset-env
|
||||
[postcss-normalize]: https://github.com/csstools/postcss-normalize
|
||||
[`browsersl.ist`]: https://browsersl.ist/
|
||||
[`caniuse-lite`]: https://github.com/ben-eb/caniuse-lite
|
||||
[Autoprefixer]: https://github.com/postcss/autoprefixer
|
||||
[Can I Use]: https://caniuse.com/
|
||||
[Babel]: https://github.com/babel/babel/tree/master/packages/babel-preset-env
|
||||
[cult-img]: https://cultofmartians.com/assets/badges/badge.svg
|
||||
[cult]: https://cultofmartians.com/done.html
|
||||
|
||||
## Docs
|
||||
Read full docs **[here](https://github.com/browserslist/browserslist#readme)**.
|
||||
@@ -0,0 +1,260 @@
|
||||
export declare function createJiti(id: string, userOptions?: JitiOptions): Jiti;
|
||||
|
||||
/**
|
||||
* Jiti instance
|
||||
*
|
||||
* Calling jiti() is similar to CommonJS require() but adds extra features such as Typescript and ESM compatibility.
|
||||
*
|
||||
* **Note:**It is recommended to use `await jiti.import` instead
|
||||
*/
|
||||
export interface Jiti extends NodeRequire {
|
||||
/**
|
||||
* Resolved options
|
||||
*/
|
||||
options: JitiOptions;
|
||||
|
||||
/**
|
||||
* ESM import a module with additional Typescript and ESM compatibility.
|
||||
*
|
||||
* If you need the default export of module, you can use `jiti.import(id, { default: true })` as shortcut to `mod?.default ?? mod`.
|
||||
*/
|
||||
import<T = unknown>(
|
||||
id: string,
|
||||
opts?: JitiResolveOptions & { default?: true },
|
||||
): Promise<T>;
|
||||
|
||||
/**
|
||||
* Resolve with ESM import conditions.
|
||||
*/
|
||||
esmResolve(id: string, parentURL?: string): string;
|
||||
esmResolve<T extends JitiResolveOptions = JitiResolveOptions>(
|
||||
id: string,
|
||||
opts?: T,
|
||||
): T["try"] extends true ? string | undefined : string;
|
||||
|
||||
/**
|
||||
* Transform source code
|
||||
*/
|
||||
transform: (opts: TransformOptions) => string;
|
||||
|
||||
/**
|
||||
* Evaluate transformed code as a module
|
||||
*/
|
||||
evalModule: (source: string, options?: EvalModuleOptions) => unknown;
|
||||
}
|
||||
|
||||
/**
|
||||
* Jiti instance options
|
||||
*/
|
||||
export interface JitiOptions {
|
||||
/**
|
||||
* Filesystem source cache (enabled by default)
|
||||
*
|
||||
* An string can be passed to set the custom cache directory.
|
||||
*
|
||||
* By default (when is `true`), jiti uses `node_modules/.cache/jiti` (if exists) or `{TMP_DIR}/jiti`.
|
||||
*
|
||||
* This option can also be disabled using `JITI_FS_CACHE=false` environment variable.
|
||||
*
|
||||
* **Note:** It is recommended to keep this option enabled for better performance.
|
||||
*/
|
||||
fsCache?: boolean | string;
|
||||
|
||||
/** @deprecated Use `fsCache` option. */
|
||||
cache?: boolean | string;
|
||||
|
||||
/**
|
||||
* Runtime module cache (enabled by default)
|
||||
*
|
||||
* Disabling allows editing code and importing same module multiple times.
|
||||
*
|
||||
* When enabled, jiti integrates with Node.js native CommonJS cache store.
|
||||
*
|
||||
* This option can also be disabled using `JITI_MODULE_CACHE=false` environment variable.
|
||||
*/
|
||||
moduleCache?: boolean;
|
||||
|
||||
/** @deprecated Use `moduleCache` option. */
|
||||
requireCache?: boolean;
|
||||
|
||||
/**
|
||||
* Custom transform function
|
||||
*/
|
||||
transform?: (opts: TransformOptions) => TransformResult;
|
||||
|
||||
/**
|
||||
* Enable verbose debugging (disabled by default).
|
||||
*
|
||||
* Can also be enabled using `JITI_DEBUG=1` environment variable.
|
||||
*/
|
||||
debug?: boolean;
|
||||
|
||||
/**
|
||||
* Enable sourcemaps (enabled by default)
|
||||
*
|
||||
* Can also be disabled using `JITI_SOURCE_MAPS=0` environment variable.
|
||||
*/
|
||||
sourceMaps?: boolean;
|
||||
|
||||
/**
|
||||
* Jiti combines module exports with the `default` export using an internal Proxy to improve compatibility with mixed CJS/ESM usage. You can check the current implementation [here](https://github.com/unjs/jiti/blob/main/src/utils.ts#L105).
|
||||
*
|
||||
* Can be disabled using `JITI_INTEROP_DEFAULT=0` environment variable.
|
||||
*/
|
||||
interopDefault?: boolean;
|
||||
|
||||
/**
|
||||
* Jiti hard source cache version (internal)
|
||||
*/
|
||||
cacheVersion?: string;
|
||||
|
||||
/**
|
||||
* Supported extensions to resolve.
|
||||
*
|
||||
* Default `[".js", ".mjs", ".cjs", ".ts", ".mts", ".cts", ".json"]`
|
||||
*/
|
||||
extensions?: string[];
|
||||
|
||||
/**
|
||||
* Transform options
|
||||
*/
|
||||
transformOptions?: Omit<TransformOptions, "source">;
|
||||
|
||||
/**
|
||||
* Resolve aliases
|
||||
*
|
||||
* You can use `JITI_ALIAS` environment variable to set aliases as a JSON string.
|
||||
*/
|
||||
alias?: Record<string, string>;
|
||||
|
||||
/**
|
||||
* List of modules (within `node_modules`) to always use native require/import for them.
|
||||
*
|
||||
* You can use `JITI_NATIVE_MODULES` environment variable to set native modules as a JSON string.
|
||||
*
|
||||
*/
|
||||
nativeModules?: string[];
|
||||
|
||||
/**
|
||||
* List of modules (within `node_modules`) to transform them regardless of syntax.
|
||||
*
|
||||
* You can use `JITI_TRANSFORM_MODULES` environment variable to set transform modules as a JSON string.
|
||||
*/
|
||||
transformModules?: string[];
|
||||
|
||||
/**
|
||||
* Parent module's import.meta context to use for ESM resolution.
|
||||
*
|
||||
* (Only used for `jiti/native` import)
|
||||
*/
|
||||
importMeta?: ImportMeta;
|
||||
|
||||
/**
|
||||
* Try to use native require and import without jiti transformations first.
|
||||
*
|
||||
* Enabled if Bun is detected.
|
||||
*/
|
||||
tryNative?: boolean;
|
||||
|
||||
/**
|
||||
* Enable JSX support Enable JSX support using [`@babel/plugin-transform-react-jsx`](https://babeljs.io/docs/babel-plugin-transform-react-jsx).
|
||||
*
|
||||
* @default false
|
||||
*
|
||||
* You can also use `JITI_JSX=1` environment variable to enable JSX support.
|
||||
*/
|
||||
jsx?: boolean | JSXOptions;
|
||||
}
|
||||
|
||||
interface NodeRequire {
|
||||
/**
|
||||
* Module cache
|
||||
*/
|
||||
cache: ModuleCache;
|
||||
|
||||
/** @deprecated Prefer `await jiti.import()` for better compatibility. */
|
||||
(id: string): any;
|
||||
|
||||
/** @deprecated Prefer `jiti.esmResolve` for better compatibility. */
|
||||
resolve: {
|
||||
/** @deprecated */
|
||||
(id: string, options?: { paths?: string[] | undefined }): string;
|
||||
/** @deprecated */
|
||||
paths(request: string): string[] | null;
|
||||
};
|
||||
|
||||
/** @deprecated CommonJS API */
|
||||
extensions: Record<
|
||||
".js" | ".json" | ".node",
|
||||
(m: NodeModule, filename: string) => any | undefined
|
||||
>;
|
||||
|
||||
/** @deprecated CommonJS API */
|
||||
main: NodeModule | undefined;
|
||||
}
|
||||
|
||||
export interface NodeModule {
|
||||
/**
|
||||
* `true` if the module is running during the Node.js preload
|
||||
*/
|
||||
isPreloading: boolean;
|
||||
exports: any;
|
||||
require: NodeRequire;
|
||||
id: string;
|
||||
filename: string;
|
||||
loaded: boolean;
|
||||
/** @deprecated since v14.6.0 Please use `require.main` and `module.children` instead. */
|
||||
parent: NodeModule | null | undefined;
|
||||
children: NodeModule[];
|
||||
/**
|
||||
* @since v11.14.0
|
||||
*
|
||||
* The directory name of the module. This is usually the same as the path.dirname() of the module.id.
|
||||
*/
|
||||
path: string;
|
||||
paths: string[];
|
||||
}
|
||||
|
||||
export type ModuleCache = Record<string, NodeModule>;
|
||||
|
||||
export type EvalModuleOptions = Partial<{
|
||||
id: string;
|
||||
filename: string;
|
||||
ext: string;
|
||||
cache: ModuleCache;
|
||||
async: boolean;
|
||||
forceTranspile: boolean;
|
||||
}>;
|
||||
|
||||
export interface TransformOptions {
|
||||
source: string;
|
||||
filename?: string;
|
||||
ts?: boolean;
|
||||
retainLines?: boolean;
|
||||
interopDefault?: boolean;
|
||||
async?: boolean;
|
||||
jsx?: boolean | JSXOptions;
|
||||
babel?: Record<string, any>;
|
||||
}
|
||||
|
||||
export interface TransformResult {
|
||||
code: string;
|
||||
error?: any;
|
||||
}
|
||||
|
||||
export interface JitiResolveOptions {
|
||||
conditions?: string[];
|
||||
parentURL?: string | URL;
|
||||
try?: boolean;
|
||||
}
|
||||
|
||||
/** Reference: https://babeljs.io/docs/babel-plugin-transform-react-jsx#options */
|
||||
export interface JSXOptions {
|
||||
throwIfNamespace?: boolean;
|
||||
runtime?: "classic" | "automatic";
|
||||
importSource?: string;
|
||||
pragma?: string;
|
||||
pragmaFrag?: string;
|
||||
useBuiltIns?: boolean;
|
||||
useSpread?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,332 @@
|
||||
/**
|
||||
* @fileoverview A class of the code path.
|
||||
* @author Toru Nagashima
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Requirements
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
const CodePathState = require("./code-path-state");
|
||||
const IdGenerator = require("./id-generator");
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
// Public Interface
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* A code path.
|
||||
*/
|
||||
class CodePath {
|
||||
/**
|
||||
* Creates a new instance.
|
||||
* @param {Object} options Options for the function (see below).
|
||||
* @param {string} options.id An identifier.
|
||||
* @param {string} options.origin The type of code path origin.
|
||||
* @param {CodePath|null} options.upper The code path of the upper function scope.
|
||||
* @param {Function} options.onLooped A callback function to notify looping.
|
||||
*/
|
||||
constructor({ id, origin, upper, onLooped }) {
|
||||
/**
|
||||
* The identifier of this code path.
|
||||
* Rules use it to store additional information of each rule.
|
||||
* @type {string}
|
||||
*/
|
||||
this.id = id;
|
||||
|
||||
/**
|
||||
* The reason that this code path was started. May be "program",
|
||||
* "function", "class-field-initializer", or "class-static-block".
|
||||
* @type {string}
|
||||
*/
|
||||
this.origin = origin;
|
||||
|
||||
/**
|
||||
* The code path of the upper function scope.
|
||||
* @type {CodePath|null}
|
||||
*/
|
||||
this.upper = upper;
|
||||
|
||||
/**
|
||||
* The code paths of nested function scopes.
|
||||
* @type {CodePath[]}
|
||||
*/
|
||||
this.childCodePaths = [];
|
||||
|
||||
// Initializes internal state.
|
||||
Object.defineProperty(this, "internal", {
|
||||
value: new CodePathState(new IdGenerator(`${id}_`), onLooped),
|
||||
});
|
||||
|
||||
// Adds this into `childCodePaths` of `upper`.
|
||||
if (upper) {
|
||||
upper.childCodePaths.push(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the state of a given code path.
|
||||
* @param {CodePath} codePath A code path to get.
|
||||
* @returns {CodePathState} The state of the code path.
|
||||
*/
|
||||
static getState(codePath) {
|
||||
return codePath.internal;
|
||||
}
|
||||
|
||||
/**
|
||||
* The initial code path segment. This is the segment that is at the head
|
||||
* of the code path.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment}
|
||||
*/
|
||||
get initialSegment() {
|
||||
return this.internal.initialSegment;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments. These are the terminal (tail) segments in the
|
||||
* code path, which is the combination of `returnedSegments` and `thrownSegments`.
|
||||
* All segments in this array are reachable.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get finalSegments() {
|
||||
return this.internal.finalSegments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments that represent normal completion of the code path.
|
||||
* For functions, this means both explicit `return` statements and implicit returns,
|
||||
* such as the last reachable segment in a function that does not have an
|
||||
* explicit `return` as this implicitly returns `undefined`. For scripts,
|
||||
* modules, class field initializers, and class static blocks, this means
|
||||
* all lines of code have been executed.
|
||||
* These segments are also present in `finalSegments`.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get returnedSegments() {
|
||||
return this.internal.returnedForkContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Final code path segments that represent `throw` statements.
|
||||
* This is a passthrough to the underlying `CodePathState`.
|
||||
* These segments are also present in `finalSegments`.
|
||||
* @type {CodePathSegment[]}
|
||||
*/
|
||||
get thrownSegments() {
|
||||
return this.internal.thrownForkContext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Traverses all segments in this code path.
|
||||
*
|
||||
* codePath.traverseSegments((segment, controller) => {
|
||||
* // do something.
|
||||
* });
|
||||
*
|
||||
* This method enumerates segments in order from the head.
|
||||
*
|
||||
* The `controller` argument has two methods:
|
||||
*
|
||||
* - `skip()` - skips the following segments in this branch
|
||||
* - `break()` - skips all following segments in the traversal
|
||||
*
|
||||
* A note on the parameters: the `options` argument is optional. This means
|
||||
* the first argument might be an options object or the callback function.
|
||||
* @param {Object} [optionsOrCallback] Optional first and last segments to traverse.
|
||||
* @param {CodePathSegment} [optionsOrCallback.first] The first segment to traverse.
|
||||
* @param {CodePathSegment} [optionsOrCallback.last] The last segment to traverse.
|
||||
* @param {Function} callback A callback function.
|
||||
* @returns {void}
|
||||
*/
|
||||
traverseSegments(optionsOrCallback, callback) {
|
||||
// normalize the arguments into a callback and options
|
||||
let resolvedOptions;
|
||||
let resolvedCallback;
|
||||
|
||||
if (typeof optionsOrCallback === "function") {
|
||||
resolvedCallback = optionsOrCallback;
|
||||
resolvedOptions = {};
|
||||
} else {
|
||||
resolvedOptions = optionsOrCallback || {};
|
||||
resolvedCallback = callback;
|
||||
}
|
||||
|
||||
// determine where to start traversing from based on the options
|
||||
const startSegment =
|
||||
resolvedOptions.first || this.internal.initialSegment;
|
||||
const lastSegment = resolvedOptions.last;
|
||||
|
||||
// set up initial location information
|
||||
let record;
|
||||
let index;
|
||||
let end;
|
||||
let segment = null;
|
||||
|
||||
// segments that have already been visited during traversal
|
||||
const visited = new Set();
|
||||
|
||||
// tracks the traversal steps
|
||||
const stack = [[startSegment, 0]];
|
||||
|
||||
// segments that have been skipped during traversal
|
||||
const skipped = new Set();
|
||||
|
||||
// indicates if we exited early from the traversal
|
||||
let broken = false;
|
||||
|
||||
/**
|
||||
* Maintains traversal state.
|
||||
*/
|
||||
const controller = {
|
||||
/**
|
||||
* Skip the following segments in this branch.
|
||||
* @returns {void}
|
||||
*/
|
||||
skip() {
|
||||
skipped.add(segment);
|
||||
},
|
||||
|
||||
/**
|
||||
* Stop traversal completely - do not traverse to any
|
||||
* other segments.
|
||||
* @returns {void}
|
||||
*/
|
||||
break() {
|
||||
broken = true;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* Checks if a given previous segment has been visited.
|
||||
* @param {CodePathSegment} prevSegment A previous segment to check.
|
||||
* @returns {boolean} `true` if the segment has been visited.
|
||||
*/
|
||||
function isVisited(prevSegment) {
|
||||
return (
|
||||
visited.has(prevSegment) ||
|
||||
segment.isLoopedPrevSegment(prevSegment)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a given previous segment has been skipped.
|
||||
* @param {CodePathSegment} prevSegment A previous segment to check.
|
||||
* @returns {boolean} `true` if the segment has been skipped.
|
||||
*/
|
||||
function isSkipped(prevSegment) {
|
||||
return (
|
||||
skipped.has(prevSegment) ||
|
||||
segment.isLoopedPrevSegment(prevSegment)
|
||||
);
|
||||
}
|
||||
|
||||
// the traversal
|
||||
while (stack.length > 0) {
|
||||
/*
|
||||
* This isn't a pure stack. We use the top record all the time
|
||||
* but don't always pop it off. The record is popped only if
|
||||
* one of the following is true:
|
||||
*
|
||||
* 1) We have already visited the segment.
|
||||
* 2) We have not visited *all* of the previous segments.
|
||||
* 3) We have traversed past the available next segments.
|
||||
*
|
||||
* Otherwise, we just read the value and sometimes modify the
|
||||
* record as we traverse.
|
||||
*/
|
||||
record = stack.at(-1);
|
||||
segment = record[0];
|
||||
index = record[1];
|
||||
|
||||
if (index === 0) {
|
||||
// Skip if this segment has been visited already.
|
||||
if (visited.has(segment)) {
|
||||
stack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
// Skip if all previous segments have not been visited.
|
||||
if (
|
||||
segment !== startSegment &&
|
||||
segment.prevSegments.length > 0 &&
|
||||
!segment.prevSegments.every(isVisited)
|
||||
) {
|
||||
stack.pop();
|
||||
continue;
|
||||
}
|
||||
|
||||
visited.add(segment);
|
||||
|
||||
// Skips the segment if all previous segments have been skipped.
|
||||
const shouldSkip =
|
||||
skipped.size > 0 &&
|
||||
segment.prevSegments.length > 0 &&
|
||||
segment.prevSegments.every(isSkipped);
|
||||
|
||||
/*
|
||||
* If the most recent segment hasn't been skipped, then we call
|
||||
* the callback, passing in the segment and the controller.
|
||||
*/
|
||||
if (!shouldSkip) {
|
||||
resolvedCallback.call(this, segment, controller);
|
||||
|
||||
// exit if we're at the last segment
|
||||
if (segment === lastSegment) {
|
||||
controller.skip();
|
||||
}
|
||||
|
||||
/*
|
||||
* If the previous statement was executed, or if the callback
|
||||
* called a method on the controller, we might need to exit the
|
||||
* loop, so check for that and break accordingly.
|
||||
*/
|
||||
if (broken) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
// If the most recent segment has been skipped, then mark it as skipped.
|
||||
skipped.add(segment);
|
||||
}
|
||||
}
|
||||
|
||||
// Update the stack.
|
||||
end = segment.nextSegments.length - 1;
|
||||
if (index < end) {
|
||||
/*
|
||||
* If we haven't yet visited all of the next segments, update
|
||||
* the current top record on the stack to the next index to visit
|
||||
* and then push a record for the current segment on top.
|
||||
*
|
||||
* Setting the current top record's index lets us know how many
|
||||
* times we've been here and ensures that the segment won't be
|
||||
* reprocessed (because we only process segments with an index
|
||||
* of 0).
|
||||
*/
|
||||
record[1] += 1;
|
||||
stack.push([segment.nextSegments[index], 0]);
|
||||
} else if (index === end) {
|
||||
/*
|
||||
* If we are at the last next segment, then reset the top record
|
||||
* in the stack to next segment and set its index to 0 so it will
|
||||
* be processed next.
|
||||
*/
|
||||
record[0] = segment.nextSegments[index];
|
||||
record[1] = 0;
|
||||
} else {
|
||||
/*
|
||||
* If index > end, that means we have no more segments that need
|
||||
* processing. So, we pop that record off of the stack in order to
|
||||
* continue traversing at the next level up.
|
||||
*/
|
||||
stack.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CodePath;
|
||||
@@ -0,0 +1 @@
|
||||
module.exports={A:{A:{"2":"K D E F A B mC"},B:{"1":"0 9 C L M G N O P Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I"},C:{"1":"0 9 SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC oC pC","2":"1 2 3 4 5 6 7 8 nC LC J PB K D E F A B C L M G N O P QB RB qC rC"},D:{"1":"0 6 7 8 9 RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB MC wB NC xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z AB BB CB DB EB FB GB HB IB JB KB LB MB NB OB I PC EC QC RC","2":"1 J PB K D E F A B C L M G N O P QB","33":"2 3 4 5"},E:{"1":"B C L M G TC FC GC xC yC zC UC VC HC 0C IC WC XC YC ZC aC 1C JC bC cC dC eC fC 2C KC gC hC iC jC 3C","2":"J PB K D E F A sC SC tC uC vC wC"},F:{"1":"0 5 6 7 8 RB SB TB UB VB WB XB YB ZB aB bB cB dB eB fB gB hB iB jB kB lB mB nB oB pB qB rB sB tB uB vB wB xB yB zB 0B 1B 2B 3B 4B 5B 6B 7B 8B 9B AC BC CC DC Q H R OC S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z","2":"1 2 3 4 F B C G N O P QB 4C 5C 6C 7C FC kC 8C GC"},G:{"1":"HD ID JD KD LD MD ND OD PD QD RD SD UC VC HC TD IC WC XC YC ZC aC UD JC bC cC dC eC fC VD KC gC hC iC jC","2":"E SC 9C lC AD BD CD DD ED FD GD"},H:{"2":"WD"},I:{"2":"LC J I XD YD ZD aD lC bD cD"},J:{"2":"D A"},K:{"1":"H","2":"A B C FC kC GC"},L:{"1":"I"},M:{"1":"EC"},N:{"2":"A B"},O:{"1":"HC"},P:{"1":"1 2 3 4 5 6 7 8 J dD eD fD gD hD TC iD jD kD lD mD IC JC KC nD"},Q:{"1":"oD"},R:{"1":"pD"},S:{"1":"rD","2":"qD"}},B:5,C:"Gamepad API",D:true};
|
||||
@@ -0,0 +1,8 @@
|
||||
const Range = require('../classes/range')
|
||||
|
||||
// Mostly just for testing and legacy API reasons
|
||||
const toComparators = (range, options) =>
|
||||
new Range(range, options).set
|
||||
.map(comp => comp.map(c => c.value).join(' ').trim().split(' '))
|
||||
|
||||
module.exports = toComparators
|
||||
@@ -0,0 +1,50 @@
|
||||
{
|
||||
"name": "acorn",
|
||||
"description": "ECMAScript parser",
|
||||
"homepage": "https://github.com/acornjs/acorn",
|
||||
"main": "dist/acorn.js",
|
||||
"types": "dist/acorn.d.ts",
|
||||
"module": "dist/acorn.mjs",
|
||||
"exports": {
|
||||
".": [
|
||||
{
|
||||
"import": "./dist/acorn.mjs",
|
||||
"require": "./dist/acorn.js",
|
||||
"default": "./dist/acorn.js"
|
||||
},
|
||||
"./dist/acorn.js"
|
||||
],
|
||||
"./package.json": "./package.json"
|
||||
},
|
||||
"version": "8.14.1",
|
||||
"engines": {
|
||||
"node": ">=0.4.0"
|
||||
},
|
||||
"maintainers": [
|
||||
{
|
||||
"name": "Marijn Haverbeke",
|
||||
"email": "marijnh@gmail.com",
|
||||
"web": "https://marijnhaverbeke.nl"
|
||||
},
|
||||
{
|
||||
"name": "Ingvar Stepanyan",
|
||||
"email": "me@rreverser.com",
|
||||
"web": "https://rreverser.com/"
|
||||
},
|
||||
{
|
||||
"name": "Adrian Heine",
|
||||
"web": "http://adrianheine.de"
|
||||
}
|
||||
],
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/acornjs/acorn.git"
|
||||
},
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"prepare": "cd ..; npm run build:main"
|
||||
},
|
||||
"bin": {
|
||||
"acorn": "bin/acorn"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,206 @@
|
||||
# convert-source-map [![Build Status][ci-image]][ci-url]
|
||||
|
||||
Converts a source-map from/to different formats and allows adding/changing properties.
|
||||
|
||||
```js
|
||||
var convert = require('convert-source-map');
|
||||
|
||||
var json = convert
|
||||
.fromComment('//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQvZm9vLm1pbi5qcyIsInNvdXJjZXMiOlsic3JjL2Zvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIvIn0=')
|
||||
.toJSON();
|
||||
|
||||
var modified = convert
|
||||
.fromComment('//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVpbGQvZm9vLm1pbi5qcyIsInNvdXJjZXMiOlsic3JjL2Zvby5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSIsInNvdXJjZVJvb3QiOiIvIn0=')
|
||||
.setProperty('sources', [ 'SRC/FOO.JS' ])
|
||||
.toJSON();
|
||||
|
||||
console.log(json);
|
||||
console.log(modified);
|
||||
```
|
||||
|
||||
```json
|
||||
{"version":3,"file":"build/foo.min.js","sources":["src/foo.js"],"names":[],"mappings":"AAAA","sourceRoot":"/"}
|
||||
{"version":3,"file":"build/foo.min.js","sources":["SRC/FOO.JS"],"names":[],"mappings":"AAAA","sourceRoot":"/"}
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
Prior to v2.0.0, the `fromMapFileComment` and `fromMapFileSource` functions took a String directory path and used that to resolve & read the source map file from the filesystem. However, this made the library limited to nodejs environments and broke on sources with querystrings.
|
||||
|
||||
In v2.0.0, you now need to pass a function that does the file reading. It will receive the source filename as a String that you can resolve to a filesystem path, URL, or anything else.
|
||||
|
||||
If you are using `convert-source-map` in nodejs and want the previous behavior, you'll use a function like such:
|
||||
|
||||
```diff
|
||||
+ var fs = require('fs'); // Import the fs module to read a file
|
||||
+ var path = require('path'); // Import the path module to resolve a path against your directory
|
||||
- var conv = convert.fromMapFileSource(css, '../my-dir');
|
||||
+ var conv = convert.fromMapFileSource(css, function (filename) {
|
||||
+ return fs.readFileSync(path.resolve('../my-dir', filename), 'utf-8');
|
||||
+ });
|
||||
```
|
||||
|
||||
## API
|
||||
|
||||
### fromObject(obj)
|
||||
|
||||
Returns source map converter from given object.
|
||||
|
||||
### fromJSON(json)
|
||||
|
||||
Returns source map converter from given json string.
|
||||
|
||||
### fromURI(uri)
|
||||
|
||||
Returns source map converter from given uri encoded json string.
|
||||
|
||||
### fromBase64(base64)
|
||||
|
||||
Returns source map converter from given base64 encoded json string.
|
||||
|
||||
### fromComment(comment)
|
||||
|
||||
Returns source map converter from given base64 or uri encoded json string prefixed with `//# sourceMappingURL=...`.
|
||||
|
||||
### fromMapFileComment(comment, readMap)
|
||||
|
||||
Returns source map converter from given `filename` by parsing `//# sourceMappingURL=filename`.
|
||||
|
||||
`readMap` must be a function which receives the source map filename and returns either a String or Buffer of the source map (if read synchronously), or a `Promise` containing a String or Buffer of the source map (if read asynchronously).
|
||||
|
||||
If `readMap` doesn't return a `Promise`, `fromMapFileComment` will return a source map converter synchronously.
|
||||
|
||||
If `readMap` returns a `Promise`, `fromMapFileComment` will also return `Promise`. The `Promise` will be either resolved with the source map converter or rejected with an error.
|
||||
|
||||
#### Examples
|
||||
|
||||
**Synchronous read in Node.js:**
|
||||
|
||||
```js
|
||||
var convert = require('convert-source-map');
|
||||
var fs = require('fs');
|
||||
|
||||
function readMap(filename) {
|
||||
return fs.readFileSync(filename, 'utf8');
|
||||
}
|
||||
|
||||
var json = convert
|
||||
.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap)
|
||||
.toJSON();
|
||||
console.log(json);
|
||||
```
|
||||
|
||||
|
||||
**Asynchronous read in Node.js:**
|
||||
|
||||
```js
|
||||
var convert = require('convert-source-map');
|
||||
var { promises: fs } = require('fs'); // Notice the `promises` import
|
||||
|
||||
function readMap(filename) {
|
||||
return fs.readFile(filename, 'utf8');
|
||||
}
|
||||
|
||||
var converter = await convert.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap)
|
||||
var json = converter.toJSON();
|
||||
console.log(json);
|
||||
```
|
||||
|
||||
**Asynchronous read in the browser:**
|
||||
|
||||
```js
|
||||
var convert = require('convert-source-map');
|
||||
|
||||
async function readMap(url) {
|
||||
const res = await fetch(url);
|
||||
return res.text();
|
||||
}
|
||||
|
||||
const converter = await convert.fromMapFileComment('//# sourceMappingURL=map-file-comment.css.map', readMap)
|
||||
var json = converter.toJSON();
|
||||
console.log(json);
|
||||
```
|
||||
|
||||
### fromSource(source)
|
||||
|
||||
Finds last sourcemap comment in file and returns source map converter or returns `null` if no source map comment was found.
|
||||
|
||||
### fromMapFileSource(source, readMap)
|
||||
|
||||
Finds last sourcemap comment in file and returns source map converter or returns `null` if no source map comment was found.
|
||||
|
||||
`readMap` must be a function which receives the source map filename and returns either a String or Buffer of the source map (if read synchronously), or a `Promise` containing a String or Buffer of the source map (if read asynchronously).
|
||||
|
||||
If `readMap` doesn't return a `Promise`, `fromMapFileSource` will return a source map converter synchronously.
|
||||
|
||||
If `readMap` returns a `Promise`, `fromMapFileSource` will also return `Promise`. The `Promise` will be either resolved with the source map converter or rejected with an error.
|
||||
|
||||
### toObject()
|
||||
|
||||
Returns a copy of the underlying source map.
|
||||
|
||||
### toJSON([space])
|
||||
|
||||
Converts source map to json string. If `space` is given (optional), this will be passed to
|
||||
[JSON.stringify](https://developer.mozilla.org/en-US/docs/JavaScript/Reference/Global_Objects/JSON/stringify) when the
|
||||
JSON string is generated.
|
||||
|
||||
### toURI()
|
||||
|
||||
Converts source map to uri encoded json string.
|
||||
|
||||
### toBase64()
|
||||
|
||||
Converts source map to base64 encoded json string.
|
||||
|
||||
### toComment([options])
|
||||
|
||||
Converts source map to an inline comment that can be appended to the source-file.
|
||||
|
||||
By default, the comment is formatted like: `//# sourceMappingURL=...`, which you would
|
||||
normally see in a JS source file.
|
||||
|
||||
When `options.encoding == 'uri'`, the data will be uri encoded, otherwise they will be base64 encoded.
|
||||
|
||||
When `options.multiline == true`, the comment is formatted like: `/*# sourceMappingURL=... */`, which you would find in a CSS source file.
|
||||
|
||||
### addProperty(key, value)
|
||||
|
||||
Adds given property to the source map. Throws an error if property already exists.
|
||||
|
||||
### setProperty(key, value)
|
||||
|
||||
Sets given property to the source map. If property doesn't exist it is added, otherwise its value is updated.
|
||||
|
||||
### getProperty(key)
|
||||
|
||||
Gets given property of the source map.
|
||||
|
||||
### removeComments(src)
|
||||
|
||||
Returns `src` with all source map comments removed
|
||||
|
||||
### removeMapFileComments(src)
|
||||
|
||||
Returns `src` with all source map comments pointing to map files removed.
|
||||
|
||||
### commentRegex
|
||||
|
||||
Provides __a fresh__ RegExp each time it is accessed. Can be used to find source map comments.
|
||||
|
||||
Breaks down a source map comment into groups: Groups: 1: media type, 2: MIME type, 3: charset, 4: encoding, 5: data.
|
||||
|
||||
### mapFileCommentRegex
|
||||
|
||||
Provides __a fresh__ RegExp each time it is accessed. Can be used to find source map comments pointing to map files.
|
||||
|
||||
### generateMapFileComment(file, [options])
|
||||
|
||||
Returns a comment that links to an external source map via `file`.
|
||||
|
||||
By default, the comment is formatted like: `//# sourceMappingURL=...`, which you would normally see in a JS source file.
|
||||
|
||||
When `options.multiline == true`, the comment is formatted like: `/*# sourceMappingURL=... */`, which you would find in a CSS source file.
|
||||
|
||||
[ci-url]: https://github.com/thlorenz/convert-source-map/actions?query=workflow:ci
|
||||
[ci-image]: https://img.shields.io/github/workflow/status/thlorenz/convert-source-map/CI?style=flat-square
|
||||
@@ -0,0 +1,333 @@
|
||||
# simple-get [![ci][ci-image]][ci-url] [![npm][npm-image]][npm-url] [![downloads][downloads-image]][downloads-url] [![javascript style guide][standard-image]][standard-url]
|
||||
|
||||
[ci-image]: https://img.shields.io/github/workflow/status/feross/simple-get/ci/master
|
||||
[ci-url]: https://github.com/feross/simple-get/actions
|
||||
[npm-image]: https://img.shields.io/npm/v/simple-get.svg
|
||||
[npm-url]: https://npmjs.org/package/simple-get
|
||||
[downloads-image]: https://img.shields.io/npm/dm/simple-get.svg
|
||||
[downloads-url]: https://npmjs.org/package/simple-get
|
||||
[standard-image]: https://img.shields.io/badge/code_style-standard-brightgreen.svg
|
||||
[standard-url]: https://standardjs.com
|
||||
|
||||
### Simplest way to make http get requests
|
||||
|
||||
## features
|
||||
|
||||
This module is the lightest possible wrapper on top of node.js `http`, but supporting these essential features:
|
||||
|
||||
- follows redirects
|
||||
- automatically handles gzip/deflate responses
|
||||
- supports HTTPS
|
||||
- supports specifying a timeout
|
||||
- supports convenience `url` key so there's no need to use `url.parse` on the url when specifying options
|
||||
- composes well with npm packages for features like cookies, proxies, form data, & OAuth
|
||||
|
||||
All this in < 100 lines of code.
|
||||
|
||||
## install
|
||||
|
||||
```
|
||||
npm install simple-get
|
||||
```
|
||||
|
||||
## usage
|
||||
|
||||
Note, all these examples also work in the browser with [browserify](http://browserify.org/).
|
||||
|
||||
### simple GET request
|
||||
|
||||
Doesn't get easier than this:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
get('http://example.com', function (err, res) {
|
||||
if (err) throw err
|
||||
console.log(res.statusCode) // 200
|
||||
res.pipe(process.stdout) // `res` is a stream
|
||||
})
|
||||
```
|
||||
|
||||
### even simpler GET request
|
||||
|
||||
If you just want the data, and don't want to deal with streams:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
get.concat('http://example.com', function (err, res, data) {
|
||||
if (err) throw err
|
||||
console.log(res.statusCode) // 200
|
||||
console.log(data) // Buffer('this is the server response')
|
||||
})
|
||||
```
|
||||
|
||||
### POST, PUT, PATCH, HEAD, DELETE support
|
||||
|
||||
For `POST`, call `get.post` or use option `{ method: 'POST' }`.
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
body: 'this is the POST body'
|
||||
}
|
||||
get.post(opts, function (err, res) {
|
||||
if (err) throw err
|
||||
res.pipe(process.stdout) // `res` is a stream
|
||||
})
|
||||
```
|
||||
|
||||
#### A more complex example:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
get({
|
||||
url: 'http://example.com',
|
||||
method: 'POST',
|
||||
body: 'this is the POST body',
|
||||
|
||||
// simple-get accepts all options that node.js `http` accepts
|
||||
// See: http://nodejs.org/api/http.html#http_http_request_options_callback
|
||||
headers: {
|
||||
'user-agent': 'my cool app'
|
||||
}
|
||||
}, function (err, res) {
|
||||
if (err) throw err
|
||||
|
||||
// All properties/methods from http.IncomingResponse are available,
|
||||
// even if a gunzip/inflate transform stream was returned.
|
||||
// See: http://nodejs.org/api/http.html#http_http_incomingmessage
|
||||
res.setTimeout(10000)
|
||||
console.log(res.headers)
|
||||
|
||||
res.on('data', function (chunk) {
|
||||
// `chunk` is the decoded response, after it's been gunzipped or inflated
|
||||
// (if applicable)
|
||||
console.log('got a chunk of the response: ' + chunk)
|
||||
}))
|
||||
|
||||
})
|
||||
```
|
||||
|
||||
### JSON
|
||||
|
||||
You can serialize/deserialize request and response with JSON:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
const opts = {
|
||||
method: 'POST',
|
||||
url: 'http://example.com',
|
||||
body: {
|
||||
key: 'value'
|
||||
},
|
||||
json: true
|
||||
}
|
||||
get.concat(opts, function (err, res, data) {
|
||||
if (err) throw err
|
||||
console.log(data.key) // `data` is an object
|
||||
})
|
||||
```
|
||||
|
||||
### Timeout
|
||||
|
||||
You can set a timeout (in milliseconds) on the request with the `timeout` option.
|
||||
If the request takes longer than `timeout` to complete, then the entire request
|
||||
will fail with an `Error`.
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
timeout: 2000 // 2 second timeout
|
||||
}
|
||||
|
||||
get(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### One Quick Tip
|
||||
|
||||
It's a good idea to set the `'user-agent'` header so the provider can more easily
|
||||
see how their resource is used.
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
const pkg = require('./package.json')
|
||||
|
||||
get('http://example.com', {
|
||||
headers: {
|
||||
'user-agent': `my-module/${pkg.version} (https://github.com/username/my-module)`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Proxies
|
||||
|
||||
You can use the [`tunnel`](https://github.com/koichik/node-tunnel) module with the
|
||||
`agent` option to work with proxies:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
const tunnel = require('tunnel')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
agent: tunnel.httpOverHttp({
|
||||
proxy: {
|
||||
host: 'localhost'
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
get(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### Cookies
|
||||
|
||||
You can use the [`cookie`](https://github.com/jshttp/cookie) module to include
|
||||
cookies in a request:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
const cookie = require('cookie')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
headers: {
|
||||
cookie: cookie.serialize('foo', 'bar')
|
||||
}
|
||||
}
|
||||
|
||||
get(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### Form data
|
||||
|
||||
You can use the [`form-data`](https://github.com/form-data/form-data) module to
|
||||
create POST request with form data:
|
||||
|
||||
```js
|
||||
const fs = require('fs')
|
||||
const get = require('simple-get')
|
||||
const FormData = require('form-data')
|
||||
const form = new FormData()
|
||||
|
||||
form.append('my_file', fs.createReadStream('/foo/bar.jpg'))
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
body: form
|
||||
}
|
||||
|
||||
get.post(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
#### Or, include `application/x-www-form-urlencoded` form data manually:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com',
|
||||
form: {
|
||||
key: 'value'
|
||||
}
|
||||
}
|
||||
get.post(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### Specifically disallowing redirects
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
|
||||
const opts = {
|
||||
url: 'http://example.com/will-redirect-elsewhere',
|
||||
followRedirects: false
|
||||
}
|
||||
// res.statusCode will be 301, no error thrown
|
||||
get(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### Basic Auth
|
||||
|
||||
```js
|
||||
const user = 'someuser'
|
||||
const pass = 'pa$$word'
|
||||
const encodedAuth = Buffer.from(`${user}:${pass}`).toString('base64')
|
||||
|
||||
get('http://example.com', {
|
||||
headers: {
|
||||
authorization: `Basic ${encodedAuth}`
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### OAuth
|
||||
|
||||
You can use the [`oauth-1.0a`](https://github.com/ddo/oauth-1.0a) module to create
|
||||
a signed OAuth request:
|
||||
|
||||
```js
|
||||
const get = require('simple-get')
|
||||
const crypto = require('crypto')
|
||||
const OAuth = require('oauth-1.0a')
|
||||
|
||||
const oauth = OAuth({
|
||||
consumer: {
|
||||
key: process.env.CONSUMER_KEY,
|
||||
secret: process.env.CONSUMER_SECRET
|
||||
},
|
||||
signature_method: 'HMAC-SHA1',
|
||||
hash_function: (baseString, key) => crypto.createHmac('sha1', key).update(baseString).digest('base64')
|
||||
})
|
||||
|
||||
const token = {
|
||||
key: process.env.ACCESS_TOKEN,
|
||||
secret: process.env.ACCESS_TOKEN_SECRET
|
||||
}
|
||||
|
||||
const url = 'https://api.twitter.com/1.1/statuses/home_timeline.json'
|
||||
|
||||
const opts = {
|
||||
url: url,
|
||||
headers: oauth.toHeader(oauth.authorize({url, method: 'GET'}, token)),
|
||||
json: true
|
||||
}
|
||||
|
||||
get(opts, function (err, res) {})
|
||||
```
|
||||
|
||||
### Throttle requests
|
||||
|
||||
You can use [limiter](https://github.com/jhurliman/node-rate-limiter) to throttle requests. This is useful when calling an API that is rate limited.
|
||||
|
||||
```js
|
||||
const simpleGet = require('simple-get')
|
||||
const RateLimiter = require('limiter').RateLimiter
|
||||
const limiter = new RateLimiter(1, 'second')
|
||||
|
||||
const get = (opts, cb) => limiter.removeTokens(1, () => simpleGet(opts, cb))
|
||||
get.concat = (opts, cb) => limiter.removeTokens(1, () => simpleGet.concat(opts, cb))
|
||||
|
||||
var opts = {
|
||||
url: 'http://example.com'
|
||||
}
|
||||
|
||||
get.concat(opts, processResult)
|
||||
get.concat(opts, processResult)
|
||||
|
||||
function processResult (err, res, data) {
|
||||
if (err) throw err
|
||||
console.log(data.toString())
|
||||
}
|
||||
```
|
||||
|
||||
## license
|
||||
|
||||
MIT. Copyright (c) [Feross Aboukhadijeh](http://feross.org).
|
||||
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const DescriptionFileUtils = require("./DescriptionFileUtils");
|
||||
|
||||
/** @typedef {import("./Resolver")} Resolver */
|
||||
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
|
||||
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
|
||||
|
||||
module.exports = class DescriptionFilePlugin {
|
||||
/**
|
||||
* @param {string | ResolveStepHook} source source
|
||||
* @param {string[]} filenames filenames
|
||||
* @param {boolean} pathIsFile pathIsFile
|
||||
* @param {string | ResolveStepHook} target target
|
||||
*/
|
||||
constructor(source, filenames, pathIsFile, target) {
|
||||
this.source = source;
|
||||
this.filenames = filenames;
|
||||
this.pathIsFile = pathIsFile;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Resolver} resolver the resolver
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(resolver) {
|
||||
const target = resolver.ensureHook(this.target);
|
||||
resolver
|
||||
.getHook(this.source)
|
||||
.tapAsync(
|
||||
"DescriptionFilePlugin",
|
||||
(request, resolveContext, callback) => {
|
||||
const path = request.path;
|
||||
if (!path) return callback();
|
||||
const directory = this.pathIsFile
|
||||
? DescriptionFileUtils.cdUp(path)
|
||||
: path;
|
||||
if (!directory) return callback();
|
||||
DescriptionFileUtils.loadDescriptionFile(
|
||||
resolver,
|
||||
directory,
|
||||
this.filenames,
|
||||
request.descriptionFilePath
|
||||
? {
|
||||
path: request.descriptionFilePath,
|
||||
content: request.descriptionFileData,
|
||||
directory: /** @type {string} */ (request.descriptionFileRoot)
|
||||
}
|
||||
: undefined,
|
||||
resolveContext,
|
||||
(err, result) => {
|
||||
if (err) return callback(err);
|
||||
if (!result) {
|
||||
if (resolveContext.log)
|
||||
resolveContext.log(
|
||||
`No description file found in ${directory} or above`
|
||||
);
|
||||
return callback();
|
||||
}
|
||||
const relativePath =
|
||||
"." + path.slice(result.directory.length).replace(/\\/g, "/");
|
||||
/** @type {ResolveRequest} */
|
||||
const obj = {
|
||||
...request,
|
||||
descriptionFilePath: result.path,
|
||||
descriptionFileData: result.content,
|
||||
descriptionFileRoot: result.directory,
|
||||
relativePath: relativePath
|
||||
};
|
||||
resolver.doResolve(
|
||||
target,
|
||||
obj,
|
||||
"using description file: " +
|
||||
result.path +
|
||||
" (relative path: " +
|
||||
relativePath +
|
||||
")",
|
||||
resolveContext,
|
||||
(err, result) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
// Don't allow other processing
|
||||
if (result === undefined) return callback(null, null);
|
||||
callback(null, result);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,38 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = _wrapNativeSuper;
|
||||
var _getPrototypeOf = require("./getPrototypeOf.js");
|
||||
var _setPrototypeOf = require("./setPrototypeOf.js");
|
||||
var _isNativeFunction = require("./isNativeFunction.js");
|
||||
var _construct = require("./construct.js");
|
||||
function _wrapNativeSuper(Class) {
|
||||
var _cache = typeof Map === "function" ? new Map() : undefined;
|
||||
exports.default = _wrapNativeSuper = function _wrapNativeSuper(Class) {
|
||||
if (Class === null || !(0, _isNativeFunction.default)(Class)) return Class;
|
||||
if (typeof Class !== "function") {
|
||||
throw new TypeError("Super expression must either be null or a function");
|
||||
}
|
||||
if (_cache !== undefined) {
|
||||
if (_cache.has(Class)) return _cache.get(Class);
|
||||
_cache.set(Class, Wrapper);
|
||||
}
|
||||
function Wrapper() {
|
||||
return (0, _construct.default)(Class, arguments, (0, _getPrototypeOf.default)(this).constructor);
|
||||
}
|
||||
Wrapper.prototype = Object.create(Class.prototype, {
|
||||
constructor: {
|
||||
value: Wrapper,
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
configurable: true
|
||||
}
|
||||
});
|
||||
return (0, _setPrototypeOf.default)(Wrapper, Class);
|
||||
};
|
||||
return _wrapNativeSuper(Class);
|
||||
}
|
||||
|
||||
//# sourceMappingURL=wrapNativeSuper.js.map
|
||||
@@ -0,0 +1,17 @@
|
||||
"use strict";
|
||||
|
||||
Object.defineProperty(exports, "__esModule", {
|
||||
value: true
|
||||
});
|
||||
exports.default = prependToMemberExpression;
|
||||
var _index = require("../builders/generated/index.js");
|
||||
var _index2 = require("../index.js");
|
||||
function prependToMemberExpression(member, prepend) {
|
||||
if ((0, _index2.isSuper)(member.object)) {
|
||||
throw new Error("Cannot prepend node to super property access (`super.foo`).");
|
||||
}
|
||||
member.object = (0, _index.memberExpression)(prepend, member.object);
|
||||
return member;
|
||||
}
|
||||
|
||||
//# sourceMappingURL=prependToMemberExpression.js.map
|
||||
@@ -0,0 +1,57 @@
|
||||
var fs = require('fs')
|
||||
var core
|
||||
if (process.platform === 'win32' || global.TESTING_WINDOWS) {
|
||||
core = require('./windows.js')
|
||||
} else {
|
||||
core = require('./mode.js')
|
||||
}
|
||||
|
||||
module.exports = isexe
|
||||
isexe.sync = sync
|
||||
|
||||
function isexe (path, options, cb) {
|
||||
if (typeof options === 'function') {
|
||||
cb = options
|
||||
options = {}
|
||||
}
|
||||
|
||||
if (!cb) {
|
||||
if (typeof Promise !== 'function') {
|
||||
throw new TypeError('callback not provided')
|
||||
}
|
||||
|
||||
return new Promise(function (resolve, reject) {
|
||||
isexe(path, options || {}, function (er, is) {
|
||||
if (er) {
|
||||
reject(er)
|
||||
} else {
|
||||
resolve(is)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
core(path, options || {}, function (er, is) {
|
||||
// ignore EACCES because that just means we aren't allowed to run it
|
||||
if (er) {
|
||||
if (er.code === 'EACCES' || options && options.ignoreErrors) {
|
||||
er = null
|
||||
is = false
|
||||
}
|
||||
}
|
||||
cb(er, is)
|
||||
})
|
||||
}
|
||||
|
||||
function sync (path, options) {
|
||||
// my kingdom for a filtered catch
|
||||
try {
|
||||
return core.sync(path, options || {})
|
||||
} catch (er) {
|
||||
if (options && options.ignoreErrors || er.code === 'EACCES') {
|
||||
return false
|
||||
} else {
|
||||
throw er
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
"use strict";
|
||||
|
||||
class HookCodeFactory {
|
||||
constructor(config) {
|
||||
this.config = config;
|
||||
this.options = undefined;
|
||||
this._args = undefined;
|
||||
}
|
||||
|
||||
create(options) {
|
||||
this.init(options);
|
||||
let fn;
|
||||
switch (this.options.type) {
|
||||
case "sync":
|
||||
fn = new Function(
|
||||
this.args(),
|
||||
'"use strict";\n' +
|
||||
this.header() +
|
||||
this.contentWithInterceptors({
|
||||
onError: err => `throw ${err};\n`,
|
||||
onResult: result => `return ${result};\n`,
|
||||
resultReturns: true,
|
||||
onDone: () => "",
|
||||
rethrowIfPossible: true
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "async":
|
||||
fn = new Function(
|
||||
this.args({
|
||||
after: "_callback"
|
||||
}),
|
||||
'"use strict";\n' +
|
||||
this.header() +
|
||||
this.contentWithInterceptors({
|
||||
onError: err => `_callback(${err});\n`,
|
||||
onResult: result => `_callback(null, ${result});\n`,
|
||||
onDone: () => "_callback();\n"
|
||||
})
|
||||
);
|
||||
break;
|
||||
case "promise":
|
||||
let errorHelperUsed = false;
|
||||
const content = this.contentWithInterceptors({
|
||||
onError: err => {
|
||||
errorHelperUsed = true;
|
||||
return `_error(${err});\n`;
|
||||
},
|
||||
onResult: result => `_resolve(${result});\n`,
|
||||
onDone: () => "_resolve();\n"
|
||||
});
|
||||
let code = "";
|
||||
code += '"use strict";\n';
|
||||
code += this.header();
|
||||
code += "return new Promise((function(_resolve, _reject) {\n";
|
||||
if (errorHelperUsed) {
|
||||
code += "var _sync = true;\n";
|
||||
code += "function _error(_err) {\n";
|
||||
code += "if(_sync)\n";
|
||||
code +=
|
||||
"_resolve(Promise.resolve().then((function() { throw _err; })));\n";
|
||||
code += "else\n";
|
||||
code += "_reject(_err);\n";
|
||||
code += "};\n";
|
||||
}
|
||||
code += content;
|
||||
if (errorHelperUsed) {
|
||||
code += "_sync = false;\n";
|
||||
}
|
||||
code += "}));\n";
|
||||
fn = new Function(this.args(), code);
|
||||
break;
|
||||
}
|
||||
this.deinit();
|
||||
return fn;
|
||||
}
|
||||
|
||||
setup(instance, options) {
|
||||
instance._x = options.taps.map(t => t.fn);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {{ type: "sync" | "promise" | "async", taps: Array<Tap>, interceptors: Array<Interceptor> }} options
|
||||
*/
|
||||
init(options) {
|
||||
this.options = options;
|
||||
this._args = options.args.slice();
|
||||
}
|
||||
|
||||
deinit() {
|
||||
this.options = undefined;
|
||||
this._args = undefined;
|
||||
}
|
||||
|
||||
contentWithInterceptors(options) {
|
||||
if (this.options.interceptors.length > 0) {
|
||||
const onError = options.onError;
|
||||
const onResult = options.onResult;
|
||||
const onDone = options.onDone;
|
||||
let code = "";
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.call) {
|
||||
code += `${this.getInterceptor(i)}.call(${this.args({
|
||||
before: interceptor.context ? "_context" : undefined
|
||||
})});\n`;
|
||||
}
|
||||
}
|
||||
code += this.content(
|
||||
Object.assign(options, {
|
||||
onError:
|
||||
onError &&
|
||||
(err => {
|
||||
let code = "";
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.error) {
|
||||
code += `${this.getInterceptor(i)}.error(${err});\n`;
|
||||
}
|
||||
}
|
||||
code += onError(err);
|
||||
return code;
|
||||
}),
|
||||
onResult:
|
||||
onResult &&
|
||||
(result => {
|
||||
let code = "";
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.result) {
|
||||
code += `${this.getInterceptor(i)}.result(${result});\n`;
|
||||
}
|
||||
}
|
||||
code += onResult(result);
|
||||
return code;
|
||||
}),
|
||||
onDone:
|
||||
onDone &&
|
||||
(() => {
|
||||
let code = "";
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.done) {
|
||||
code += `${this.getInterceptor(i)}.done();\n`;
|
||||
}
|
||||
}
|
||||
code += onDone();
|
||||
return code;
|
||||
})
|
||||
})
|
||||
);
|
||||
return code;
|
||||
} else {
|
||||
return this.content(options);
|
||||
}
|
||||
}
|
||||
|
||||
header() {
|
||||
let code = "";
|
||||
if (this.needContext()) {
|
||||
code += "var _context = {};\n";
|
||||
} else {
|
||||
code += "var _context;\n";
|
||||
}
|
||||
code += "var _x = this._x;\n";
|
||||
if (this.options.interceptors.length > 0) {
|
||||
code += "var _taps = this.taps;\n";
|
||||
code += "var _interceptors = this.interceptors;\n";
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
needContext() {
|
||||
for (const tap of this.options.taps) if (tap.context) return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
callTap(tapIndex, { onError, onResult, onDone, rethrowIfPossible }) {
|
||||
let code = "";
|
||||
let hasTapCached = false;
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.tap) {
|
||||
if (!hasTapCached) {
|
||||
code += `var _tap${tapIndex} = ${this.getTap(tapIndex)};\n`;
|
||||
hasTapCached = true;
|
||||
}
|
||||
code += `${this.getInterceptor(i)}.tap(${
|
||||
interceptor.context ? "_context, " : ""
|
||||
}_tap${tapIndex});\n`;
|
||||
}
|
||||
}
|
||||
code += `var _fn${tapIndex} = ${this.getTapFn(tapIndex)};\n`;
|
||||
const tap = this.options.taps[tapIndex];
|
||||
switch (tap.type) {
|
||||
case "sync":
|
||||
if (!rethrowIfPossible) {
|
||||
code += `var _hasError${tapIndex} = false;\n`;
|
||||
code += "try {\n";
|
||||
}
|
||||
if (onResult) {
|
||||
code += `var _result${tapIndex} = _fn${tapIndex}(${this.args({
|
||||
before: tap.context ? "_context" : undefined
|
||||
})});\n`;
|
||||
} else {
|
||||
code += `_fn${tapIndex}(${this.args({
|
||||
before: tap.context ? "_context" : undefined
|
||||
})});\n`;
|
||||
}
|
||||
if (!rethrowIfPossible) {
|
||||
code += "} catch(_err) {\n";
|
||||
code += `_hasError${tapIndex} = true;\n`;
|
||||
code += onError("_err");
|
||||
code += "}\n";
|
||||
code += `if(!_hasError${tapIndex}) {\n`;
|
||||
}
|
||||
if (onResult) {
|
||||
code += onResult(`_result${tapIndex}`);
|
||||
}
|
||||
if (onDone) {
|
||||
code += onDone();
|
||||
}
|
||||
if (!rethrowIfPossible) {
|
||||
code += "}\n";
|
||||
}
|
||||
break;
|
||||
case "async":
|
||||
let cbCode = "";
|
||||
if (onResult)
|
||||
cbCode += `(function(_err${tapIndex}, _result${tapIndex}) {\n`;
|
||||
else cbCode += `(function(_err${tapIndex}) {\n`;
|
||||
cbCode += `if(_err${tapIndex}) {\n`;
|
||||
cbCode += onError(`_err${tapIndex}`);
|
||||
cbCode += "} else {\n";
|
||||
if (onResult) {
|
||||
cbCode += onResult(`_result${tapIndex}`);
|
||||
}
|
||||
if (onDone) {
|
||||
cbCode += onDone();
|
||||
}
|
||||
cbCode += "}\n";
|
||||
cbCode += "})";
|
||||
code += `_fn${tapIndex}(${this.args({
|
||||
before: tap.context ? "_context" : undefined,
|
||||
after: cbCode
|
||||
})});\n`;
|
||||
break;
|
||||
case "promise":
|
||||
code += `var _hasResult${tapIndex} = false;\n`;
|
||||
code += `var _promise${tapIndex} = _fn${tapIndex}(${this.args({
|
||||
before: tap.context ? "_context" : undefined
|
||||
})});\n`;
|
||||
code += `if (!_promise${tapIndex} || !_promise${tapIndex}.then)\n`;
|
||||
code += ` throw new Error('Tap function (tapPromise) did not return promise (returned ' + _promise${tapIndex} + ')');\n`;
|
||||
code += `_promise${tapIndex}.then((function(_result${tapIndex}) {\n`;
|
||||
code += `_hasResult${tapIndex} = true;\n`;
|
||||
if (onResult) {
|
||||
code += onResult(`_result${tapIndex}`);
|
||||
}
|
||||
if (onDone) {
|
||||
code += onDone();
|
||||
}
|
||||
code += `}), function(_err${tapIndex}) {\n`;
|
||||
code += `if(_hasResult${tapIndex}) throw _err${tapIndex};\n`;
|
||||
code += onError(`_err${tapIndex}`);
|
||||
code += "});\n";
|
||||
break;
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
callTapsSeries({
|
||||
onError,
|
||||
onResult,
|
||||
resultReturns,
|
||||
onDone,
|
||||
doneReturns,
|
||||
rethrowIfPossible
|
||||
}) {
|
||||
if (this.options.taps.length === 0) return onDone();
|
||||
const firstAsync = this.options.taps.findIndex(t => t.type !== "sync");
|
||||
const somethingReturns = resultReturns || doneReturns;
|
||||
let code = "";
|
||||
let current = onDone;
|
||||
let unrollCounter = 0;
|
||||
for (let j = this.options.taps.length - 1; j >= 0; j--) {
|
||||
const i = j;
|
||||
const unroll =
|
||||
current !== onDone &&
|
||||
(this.options.taps[i].type !== "sync" || unrollCounter++ > 20);
|
||||
if (unroll) {
|
||||
unrollCounter = 0;
|
||||
code += `function _next${i}() {\n`;
|
||||
code += current();
|
||||
code += `}\n`;
|
||||
current = () => `${somethingReturns ? "return " : ""}_next${i}();\n`;
|
||||
}
|
||||
const done = current;
|
||||
const doneBreak = skipDone => {
|
||||
if (skipDone) return "";
|
||||
return onDone();
|
||||
};
|
||||
const content = this.callTap(i, {
|
||||
onError: error => onError(i, error, done, doneBreak),
|
||||
onResult:
|
||||
onResult &&
|
||||
(result => {
|
||||
return onResult(i, result, done, doneBreak);
|
||||
}),
|
||||
onDone: !onResult && done,
|
||||
rethrowIfPossible:
|
||||
rethrowIfPossible && (firstAsync < 0 || i < firstAsync)
|
||||
});
|
||||
current = () => content;
|
||||
}
|
||||
code += current();
|
||||
return code;
|
||||
}
|
||||
|
||||
callTapsLooping({ onError, onDone, rethrowIfPossible }) {
|
||||
if (this.options.taps.length === 0) return onDone();
|
||||
const syncOnly = this.options.taps.every(t => t.type === "sync");
|
||||
let code = "";
|
||||
if (!syncOnly) {
|
||||
code += "var _looper = (function() {\n";
|
||||
code += "var _loopAsync = false;\n";
|
||||
}
|
||||
code += "var _loop;\n";
|
||||
code += "do {\n";
|
||||
code += "_loop = false;\n";
|
||||
for (let i = 0; i < this.options.interceptors.length; i++) {
|
||||
const interceptor = this.options.interceptors[i];
|
||||
if (interceptor.loop) {
|
||||
code += `${this.getInterceptor(i)}.loop(${this.args({
|
||||
before: interceptor.context ? "_context" : undefined
|
||||
})});\n`;
|
||||
}
|
||||
}
|
||||
code += this.callTapsSeries({
|
||||
onError,
|
||||
onResult: (i, result, next, doneBreak) => {
|
||||
let code = "";
|
||||
code += `if(${result} !== undefined) {\n`;
|
||||
code += "_loop = true;\n";
|
||||
if (!syncOnly) code += "if(_loopAsync) _looper();\n";
|
||||
code += doneBreak(true);
|
||||
code += `} else {\n`;
|
||||
code += next();
|
||||
code += `}\n`;
|
||||
return code;
|
||||
},
|
||||
onDone:
|
||||
onDone &&
|
||||
(() => {
|
||||
let code = "";
|
||||
code += "if(!_loop) {\n";
|
||||
code += onDone();
|
||||
code += "}\n";
|
||||
return code;
|
||||
}),
|
||||
rethrowIfPossible: rethrowIfPossible && syncOnly
|
||||
});
|
||||
code += "} while(_loop);\n";
|
||||
if (!syncOnly) {
|
||||
code += "_loopAsync = true;\n";
|
||||
code += "});\n";
|
||||
code += "_looper();\n";
|
||||
}
|
||||
return code;
|
||||
}
|
||||
|
||||
callTapsParallel({
|
||||
onError,
|
||||
onResult,
|
||||
onDone,
|
||||
rethrowIfPossible,
|
||||
onTap = (i, run) => run()
|
||||
}) {
|
||||
if (this.options.taps.length <= 1) {
|
||||
return this.callTapsSeries({
|
||||
onError,
|
||||
onResult,
|
||||
onDone,
|
||||
rethrowIfPossible
|
||||
});
|
||||
}
|
||||
let code = "";
|
||||
code += "do {\n";
|
||||
code += `var _counter = ${this.options.taps.length};\n`;
|
||||
if (onDone) {
|
||||
code += "var _done = (function() {\n";
|
||||
code += onDone();
|
||||
code += "});\n";
|
||||
}
|
||||
for (let i = 0; i < this.options.taps.length; i++) {
|
||||
const done = () => {
|
||||
if (onDone) return "if(--_counter === 0) _done();\n";
|
||||
else return "--_counter;";
|
||||
};
|
||||
const doneBreak = skipDone => {
|
||||
if (skipDone || !onDone) return "_counter = 0;\n";
|
||||
else return "_counter = 0;\n_done();\n";
|
||||
};
|
||||
code += "if(_counter <= 0) break;\n";
|
||||
code += onTap(
|
||||
i,
|
||||
() =>
|
||||
this.callTap(i, {
|
||||
onError: error => {
|
||||
let code = "";
|
||||
code += "if(_counter > 0) {\n";
|
||||
code += onError(i, error, done, doneBreak);
|
||||
code += "}\n";
|
||||
return code;
|
||||
},
|
||||
onResult:
|
||||
onResult &&
|
||||
(result => {
|
||||
let code = "";
|
||||
code += "if(_counter > 0) {\n";
|
||||
code += onResult(i, result, done, doneBreak);
|
||||
code += "}\n";
|
||||
return code;
|
||||
}),
|
||||
onDone:
|
||||
!onResult &&
|
||||
(() => {
|
||||
return done();
|
||||
}),
|
||||
rethrowIfPossible
|
||||
}),
|
||||
done,
|
||||
doneBreak
|
||||
);
|
||||
}
|
||||
code += "} while(false);\n";
|
||||
return code;
|
||||
}
|
||||
|
||||
args({ before, after } = {}) {
|
||||
let allArgs = this._args;
|
||||
if (before) allArgs = [before].concat(allArgs);
|
||||
if (after) allArgs = allArgs.concat(after);
|
||||
if (allArgs.length === 0) {
|
||||
return "";
|
||||
} else {
|
||||
return allArgs.join(", ");
|
||||
}
|
||||
}
|
||||
|
||||
getTapFn(idx) {
|
||||
return `_x[${idx}]`;
|
||||
}
|
||||
|
||||
getTap(idx) {
|
||||
return `_taps[${idx}]`;
|
||||
}
|
||||
|
||||
getInterceptor(idx) {
|
||||
return `_interceptors[${idx}]`;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = HookCodeFactory;
|
||||
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||
Author Tobias Koppers @sokra
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
/** @typedef {import("./Resolver")} Resolver */
|
||||
/** @typedef {import("./Resolver").ResolveRequest} ResolveRequest */
|
||||
/** @typedef {import("./Resolver").ResolveStepHook} ResolveStepHook */
|
||||
|
||||
module.exports = class ConditionalPlugin {
|
||||
/**
|
||||
* @param {string | ResolveStepHook} source source
|
||||
* @param {Partial<ResolveRequest>} test compare object
|
||||
* @param {string | null} message log message
|
||||
* @param {boolean} allowAlternatives when false, do not continue with the current step when "test" matches
|
||||
* @param {string | ResolveStepHook} target target
|
||||
*/
|
||||
constructor(source, test, message, allowAlternatives, target) {
|
||||
this.source = source;
|
||||
this.test = test;
|
||||
this.message = message;
|
||||
this.allowAlternatives = allowAlternatives;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {Resolver} resolver the resolver
|
||||
* @returns {void}
|
||||
*/
|
||||
apply(resolver) {
|
||||
const target = resolver.ensureHook(this.target);
|
||||
const { test, message, allowAlternatives } = this;
|
||||
const keys = /** @type {(keyof ResolveRequest)[]} */ (Object.keys(test));
|
||||
resolver
|
||||
.getHook(this.source)
|
||||
.tapAsync("ConditionalPlugin", (request, resolveContext, callback) => {
|
||||
for (const prop of keys) {
|
||||
if (request[prop] !== test[prop]) return callback();
|
||||
}
|
||||
resolver.doResolve(
|
||||
target,
|
||||
request,
|
||||
message,
|
||||
resolveContext,
|
||||
allowAlternatives
|
||||
? callback
|
||||
: (err, result) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
// Don't allow other alternatives
|
||||
if (result === undefined) return callback(null, null);
|
||||
callback(null, result);
|
||||
}
|
||||
);
|
||||
});
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user