Update dependencies and switch to @sveltejs/adapter-node for SvelteKit project
CI / build (push) Has been skipped
CI / deploy (push) Successful in 1m33s

This commit is contained in:
eewing
2026-02-17 14:25:23 -06:00
parent cf73cd3b4c
commit 6cc5928770
413 changed files with 51926 additions and 322 deletions
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../acorn/bin/acorn
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@esbuild/darwin-arm64/bin/esbuild
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../jiti/lib/jiti-cli.mjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../lz-string/bin/bin.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../nanoid/bin/nanoid.cjs
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../resolve/bin/resolve
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../rollup/dist/bin/rollup
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../svelte-check/bin/svelte-check
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../@sveltejs/kit/svelte-kit.js
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsc
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../typescript/bin/tsserver
Generated Vendored Symlink
+1
View File
@@ -0,0 +1 @@
../vite/bin/vite.js
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/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.
+507
View File
@@ -0,0 +1,507 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-commonjs
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-commonjs
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-commonjs
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-commonjs
[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)
# @rollup/plugin-commonjs
🍣 A Rollup plugin to convert CommonJS modules to ES6, so they can be included in a Rollup bundle
## Requirements
This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v2.68.0+. If you are using [`@rollup/plugin-node-resolve`](https://github.com/rollup/plugins/tree/master/packages/node-resolve), it should be v13.0.6+.
## Install
Using npm:
```bash
npm install @rollup/plugin-commonjs --save-dev
```
## Usage
Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
```js
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [commonjs()]
};
```
Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
When used together with the node-resolve plugin
## Options
### `strictRequires`
Type: `"auto" | boolean | "debug" | string[]`<br>
Default: `true`
Historically, this plugin tried to hoist `require` statements as imports to the top of each file. While this works well for many code bases and allows for very efficient ESM output, it does not perfectly capture CommonJS semantics as the initialisation order of required modules will be different. The resultant side effects can include log statements being emitted in a different order, and some code that is dependent on the initialisation order of polyfills in require statements may not work. But it is especially problematic when there are circular `require` calls between CommonJS modules as those often rely on the lazy execution of nested `require` calls.
The default value of `true` will wrap all CommonJS files in functions which are executed when they are required for the first time, preserving NodeJS semantics. This is the safest setting and should be used if the generated code does not work correctly with `"auto"`. Note that `strictRequires: true` can have a small impact on the size and performance of generated code, but less so if the code is minified.
Setting this option to `"auto"` will only wrap CommonJS files when they are part of a CommonJS dependency cycle, e.g. an index file that is required by some of its dependencies, or if they are only required in a potentially "conditional" way like from within an if-statement or a function. All other CommonJS files are hoisted. This is the recommended setting for most code bases. Note that the detection of conditional requires can be subject to race conditions if there are both conditional and unconditional requires of the same file, which in edge cases may result in inconsistencies between builds. If you think this is a problem for you, you can avoid this by using any value other than `"auto"` or `"debug"`.
`false` will entirely prevent wrapping and hoist all files. This may still work depending on the nature of cyclic dependencies but will often cause problems.
You can also provide a [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, to only specify a subset of files which should be wrapped in functions for proper `require` semantics.
`"debug"` works like `"auto"` but after bundling, it will display a warning containing a list of ids that have been wrapped which can be used as picomatch pattern for fine-tuning or to avoid the potential race conditions mentioned for `"auto"`.
### `requireNodeBuiltins`
Type: `boolean`<br>
Default: `false`
When enabled, external Node built-ins (e.g., `node:fs`, `node:path`) required from wrapped CommonJS modules will use `createRequire(import.meta.url)` instead of being hoisted as ESM imports. This prevents eager loading of Node built-ins at module initialization time and preserves the lazy execution semantics of `require()`.
**Important:** Enabling this option adds a dependency on `node:module` in the output bundle, which may not be available in some environments like edge runtimes (Cloudflare Workers, Vercel Edge Runtime). Only enable this option if you are targeting Node.js environments and need the lazy loading behavior for Node built-ins.
Example:
```js
commonjs({
strictRequires: true,
requireNodeBuiltins: true
});
```
With `requireNodeBuiltins: true`, code like:
```js
if (condition) {
require('node:fs');
}
```
will generate output using `createRequire` instead of hoisting the import to the top of the file.
### `dynamicRequireTargets`
Type: `string | string[]`<br>
Default: `[]`
_Note: In previous versions, this option would spin up a rather comprehensive mock environment that was capable of handling modules that manipulate `require.cache`. This is no longer supported. If you rely on this e.g. when using request-promise-native, use version 21 of this plugin._
Some modules contain dynamic `require` calls, or require modules that contain circular dependencies, which are not handled well by static imports.
Including those modules as `dynamicRequireTargets` will simulate a CommonJS (NodeJS-like) environment for them with support for dynamic dependencies. It also enables `strictRequires` for those modules, see above.
_Note: In extreme cases, this feature may result in some paths being rendered as absolute in the final bundle. The plugin tries to avoid exposing paths from the local machine, but if you are `dynamicRequirePaths` with paths that are far away from your project's folder, that may require replacing strings like `"/Users/John/Desktop/foo-project/"` -> `"/"`._
Example:
```js
commonjs({
dynamicRequireTargets: [
// include using a glob pattern (either a string or an array of strings)
'node_modules/logform/*.js',
// exclude files that are known to not be required dynamically, this allows for better optimizations
'!node_modules/logform/index.js',
'!node_modules/logform/format.js',
'!node_modules/logform/levels.js',
'!node_modules/logform/browser.js'
]
});
```
### `dynamicRequireRoot`
Type: `string`<br>
Default: `process.cwd()`
To avoid long paths when using the `dynamicRequireTargets` option, you can use this option to specify a directory that is a common parent for all files that use dynamic require statements. Using a directory higher up such as `/` may lead to unnecessarily long paths in the generated code and may expose directory names on your machine like your home directory name. By default it uses the current working directory.
### `exclude`
Type: `string | string[]`<br>
Default: `null`
A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files in the build the plugin should _ignore_. By default, all files with extensions other than those in `extensions` or `".cjs"` are ignored, but you can exclude additional files. See also the `include` option.
### `include`
Type: `string | string[]`<br>
Default: `null`
A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files in the build the plugin should operate on. By default, all files with extension `".cjs"` or those in `extensions` are included, but you can narrow this list by only including specific files. These files will be analyzed and transpiled if either the analysis does not find ES module specific statements or `transformMixedEsModules` is `true`.
### `extensions`
Type: `string[]`<br>
Default: `['.js']`
For extensionless imports, search for extensions other than .js in the order specified. Note that you need to make sure that non-JavaScript files are transpiled by another plugin first.
### `ignoreGlobal`
Type: `boolean`<br>
Default: `false`
If true, uses of `global` won't be dealt with by this plugin.
### `sourceMap`
Type: `boolean`<br>
Default: `true`
If false, skips source map generation for CommonJS modules. This will improve performance.
### `transformMixedEsModules`
Type: `boolean`<br>
Default: `false`
Instructs the plugin whether to enable mixed module transformations. This is useful in scenarios with modules that contain a mix of ES `import` statements and CommonJS `require` expressions. Set to `true` if `require` calls should be transformed to imports in mixed modules, or `false` if the `require` expressions should survive the transformation. The latter can be important if the code contains environment detection, or you are coding for an environment with special treatment for `require` calls such as [ElectronJS](https://www.electronjs.org/). See also the "ignore" option.
### `ignore`
Type: `string[] | ((id: string) => boolean)`<br>
Default: `[]`
Sometimes you have to leave require statements unconverted. Pass an array containing the IDs or an `id => boolean` function.
### `ignoreTryCatch`
Type: `boolean | 'remove' | string[] | ((id: string) => boolean)`<br>
Default: `true`
In most cases, where `require` calls to external dependencies are inside a `try-catch` clause, they should be left unconverted as it requires an optional dependency that may or may not be installed beside the rolled up package.
Due to the conversion of `require` to a static `import` - the call is hoisted to the top of the file, outside of the `try-catch` clause.
- `true`: All external `require` calls inside a `try` will be left unconverted.
- `false`: All external `require` calls inside a `try` will be converted as if the `try-catch` clause is not there.
- `remove`: Remove all external `require` calls from inside any `try` block.
- `string[]`: Pass an array containing the IDs to left unconverted.
- `((id: string) => boolean|'remove')`: Pass a function that control individual IDs.
Note that non-external requires will not be ignored by this option.
### `ignoreDynamicRequires`
Type: `boolean`
Default: false
Some `require` calls cannot be resolved statically to be translated to imports, e.g.
```js
function wrappedRequire(target) {
return require(target);
}
wrappedRequire('foo');
wrappedRequire('bar');
```
When this option is set to `false`, the generated code will either directly throw an error when such a call is encountered or, when `dynamicRequireTargets` is used, when such a call cannot be resolved with a configured dynamic require target.
Setting this option to `true` will instead leave the `require` call in the code or use it as a fallback for `dynamicRequireTargets`.
### `esmExternals`
Type: `boolean | string[] | ((id: string) => boolean)`
Default: `false`
Controls how to render imports from external dependencies. By default, this plugin assumes that all external dependencies are CommonJS. This means they are rendered as default imports to be compatible with e.g. NodeJS where ES modules can only import a default export from a CommonJS dependency:
```js
// input
const foo = require('foo');
// output
import foo from 'foo';
```
This is likely not desired for ES module dependencies: Here `require` should usually return the namespace to be compatible with how bundled modules are handled.
If you set `esmExternals` to `true`, this plugins assumes that all external dependencies are ES modules and will adhere to the `requireReturnsDefault` option. If that option is not set, they will be rendered as namespace imports.
You can also supply an array of ids to be treated as ES modules, or a function that will be passed each external id to determine if it is an ES module.
### `defaultIsModuleExports`
Type: `boolean | "auto"`<br>
Default: `"auto"`
Controls what is the default export when importing a CommonJS file from an ES module.
- `true`: The value of the default export is `module.exports`. This currently matches the behavior of Node.js when importing a CommonJS file.
```js
// mod.cjs
exports.default = 3;
```
```js
import foo from './mod.cjs';
console.log(foo); // { default: 3 }
```
- `false`: The value of the default export is `exports.default`.
```js
// mod.cjs
exports.default = 3;
```
```js
import foo from './mod.cjs';
console.log(foo); // 3
```
- `"auto"`: The value of the default export is `exports.default` if the CommonJS file has an `exports.__esModule === true` property; otherwise it's `module.exports`. This makes it possible to import
the default export of ES modules compiled to CommonJS as if they were not compiled.
```js
// mod.cjs
exports.default = 3;
```
```js
// mod-compiled.cjs
exports.__esModule = true;
exports.default = 3;
```
```js
import foo from './mod.cjs';
import bar from './mod-compiled.cjs';
console.log(foo); // { default: 3 }
console.log(bar); // 3
```
### `requireReturnsDefault`
Type: `boolean | "namespace" | "auto" | "preferred" | ((id: string) => boolean | "auto" | "preferred")`<br>
Default: `false`
Controls what is returned when requiring an ES module from a CommonJS file. When using the `esmExternals` option, this will also apply to external modules. By default, this plugin will render those imports as namespace imports, i.e.
```js
// input
const foo = require('foo');
// output
import * as foo from 'foo';
```
This is in line with how other bundlers handle this situation and is also the most likely behaviour in case Node should ever support this. However there are some situations where this may not be desired:
- There is code in an external dependency that cannot be changed where a `require` statement expects the default export to be returned from an ES module.
- If the imported module is in the same bundle, Rollup will generate a namespace object for the imported module which can increase bundle size unnecessarily:
```js
// input: main.js
const dep = require('./dep.js');
console.log(dep.default);
// input: dep.js
export default 'foo';
// output
var dep = 'foo';
var dep$1 = /*#__PURE__*/ Object.freeze({
__proto__: null,
default: dep
});
console.log(dep$1.default);
```
For these situations, you can change Rollup's behaviour either globally or per module. To change it globally, set the `requireReturnsDefault` option to one of the following values:
- `false`: This is the default, requiring an ES module returns its namespace. This is the only option that will also add a marker `__esModule: true` to the namespace to support interop patterns in CommonJS modules that are transpiled ES modules.
```js
// input
const dep = require('dep');
console.log(dep);
// output
import * as dep$1 from 'dep';
function getAugmentedNamespace(n) {
if (n.__esModule) return n;
var f = n.default;
if (typeof f == 'function') {
var a = function a() {
var isInstance = false;
try {
isInstance = this instanceof a;
} catch {}
if (isInstance) {
return Reflect.construct(f, arguments, this.constructor);
}
return f.apply(this, arguments);
};
a.prototype = f.prototype;
} else a = {};
Object.defineProperty(a, '__esModule', { value: true });
Object.keys(n).forEach(function (k) {
var d = Object.getOwnPropertyDescriptor(n, k);
Object.defineProperty(
a,
k,
d.get
? d
: {
enumerable: true,
get: function () {
return n[k];
}
}
);
});
return a;
}
var dep = /*@__PURE__*/ getAugmentedNamespace(dep$1);
console.log(dep);
```
- `"namespace"`: Like `false`, requiring an ES module returns its namespace, but the plugin does not add the `__esModule` marker and thus creates more efficient code. For external dependencies when using `esmExternals: true`, no additional interop code is generated.
```js
// output
import * as dep from 'dep';
console.log(dep);
```
- `"auto"`: This is complementary to how [`output.exports`](https://rollupjs.org/guide/en/#outputexports): `"auto"` works in Rollup: If a module has a default export and no named exports, requiring that module returns the default export. In all other cases, the namespace is returned. For external dependencies when using `esmExternals: true`, a corresponding interop helper is added:
```js
// output
import * as dep$1 from 'dep';
function getDefaultExportFromNamespaceIfNotNamed(n) {
return n && Object.prototype.hasOwnProperty.call(n, 'default') && Object.keys(n).length === 1
? n['default']
: n;
}
var dep = getDefaultExportFromNamespaceIfNotNamed(dep$1);
console.log(dep);
```
- `"preferred"`: If a module has a default export, requiring that module always returns the default export, no matter whether additional named exports exist. This is similar to how previous versions of this plugin worked. Again for external dependencies when using `esmExternals: true`, an interop helper is added:
```js
// output
import * as dep$1 from 'dep';
function getDefaultExportFromNamespaceIfPresent(n) {
return n && Object.prototype.hasOwnProperty.call(n, 'default') ? n['default'] : n;
}
var dep = getDefaultExportFromNamespaceIfPresent(dep$1);
console.log(dep);
```
- `true`: This will always try to return the default export on require without checking if it actually exists. This can throw at build time if there is no default export. This is how external dependencies are handled when `esmExternals` is not used. The advantage over the other options is that, like `false`, this does not add an interop helper for external dependencies, keeping the code lean:
```js
// output
import dep from 'dep';
console.log(dep);
```
To change this for individual modules, you can supply a function for `requireReturnsDefault` instead. This function will then be called once for each required ES module or external dependency with the corresponding id and allows you to return different values for different modules.
## Using CommonJS files as entry points
With this plugin, you can also use CommonJS files as entry points. This means, however, that when you are bundling to an ES module, your bundle will only have a default export. If you want named exports instead, you should use an ES module entry point instead that reexports from your CommonJS entry point, e.g.
```js
// main.cjs, the CommonJS entry
exports.foo = 'foo';
exports.bar = 'bar';
// main.mjs, the ES module entry
export { foo, bar } from './main.cjs';
// rollup.config.mjs
export default {
input: 'main.mjs',
output: {
format: 'es',
file: 'bundle.mjs'
}
};
```
When bundling to CommonJS or IIFE, i.e `output.format === 'cjs'` / `output.format === 'iife'`, make sure that you do not set `output.exports` to `'named'`. The default value of `'auto'` will usually work, but you can also set it explicitly to `'default'`. That makes sure that Rollup assigns the default export that was generated for your CommonJS entry point to `module.exports`, and semantics do not change.
## Using with @rollup/plugin-node-resolve
Since most CommonJS packages you are importing are probably dependencies in `node_modules`, you may need to use [@rollup/plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve):
```js
// rollup.config.js
import resolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'main.js',
output: {
file: 'bundle.js',
format: 'iife',
name: 'MyModule'
},
plugins: [commonjs(), resolve()]
};
```
## Usage with symlinks
Symlinks are common in monorepos and are also created by the `npm link` command. Rollup with `@rollup/plugin-node-resolve` resolves modules to their real paths by default. So `include` and `exclude` paths should handle real paths rather than symlinked paths (e.g. `../common/node_modules/**` instead of `node_modules/**`). You may also use a regular expression for `include` that works regardless of base path. Try this:
```js
commonjs({
include: /node_modules/
});
```
Whether symlinked module paths are [realpathed](http://man7.org/linux/man-pages/man3/realpath.3.html) or preserved depends on Rollup's `preserveSymlinks` setting, which is false by default, matching Node.js' default behavior. Setting `preserveSymlinks` to true in your Rollup config will cause `import` and `export` to match based on symlinked paths instead.
## Strict mode
ES modules are _always_ parsed in strict mode. That means that certain non-strict constructs (like octal literals) will be treated as syntax errors when Rollup parses modules that use them. Some older CommonJS modules depend on those constructs, and if you depend on them your bundle will blow up. There's basically nothing we can do about that.
Luckily, there is absolutely no good reason _not_ to use strict mode for everything — so the solution to this problem is to lobby the authors of those modules to update them.
## Inter-plugin-communication
This plugin exposes the result of its CommonJS file type detection for other plugins to use. You can access it via `this.getModuleInfo` or the `moduleParsed` hook:
```js
function cjsDetectionPlugin() {
return {
name: 'cjs-detection',
moduleParsed({
id,
meta: {
commonjs: { isCommonJS }
}
}) {
console.log(`File ${id} is CommonJS: ${isCommonJS}`);
}
};
}
```
## Meta
[CONTRIBUTING](/.github/CONTRIBUTING.md)
[LICENSE (MIT)](/LICENSE)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"type":"module"}
@@ -0,0 +1,37 @@
# is-reference changelog
## 1.2.1
* Relax version range for `@types/estree`
## 1.2.0
* Handle class fields ([#](https://github.com/Rich-Harris/is-reference/pull/8))
## 1.1.4
* Disregarded imported specifiers if they differ from local specifiers
## 1.1.3
* Handle expressions without a Program
## 1.1.2
* Ignore labels in break/continue statements ([#4](https://github.com/Rich-Harris/is-reference/pull/4))
## 1.1.1
* Prevent false positives with labeled statements
## 1.1.0
* Rewrite in TypeScript, add declarations
## 1.0.1
* Ensure `isReference` returns a boolean
## 1.0.0
* First release
@@ -0,0 +1,61 @@
# is-reference
Utility for determining whether an AST node is a reference.
`foo` is a reference in these cases:
```js
console.log( foo );
var foo;
function foo () {}
function bar ( foo ) {}
export { foo as x };
```
`foo` is *not* a reference in these cases:
```js
var obj = { foo: 1 };
console.log( obj.foo );
export { x as foo };
```
In all cases, `foo` is an `Identifier` node, but the two kinds must be treated differently for the purposes of scope analysis etc. (The examples are non-exhaustive.)
## Installation
```bash
npm install is-reference
```
## Usage
Example using [Acorn](https://github.com/ternjs/acorn) and [estree-walker](https://github.com/Rich-Harris/estree-walker):
```js
const { parse } = require( 'acorn' );
const { walk } = require( 'estree-walker' );
const isReference = require( 'is-reference' );
const identifiers = [];
const references = [];
const ast = parse( `var a = b.c;` );
walk( ast, {
enter ( node, parent ) {
if ( node.type === 'Identifier' ) identifiers.push( node );
if ( isReference( node, parent ) ) references.push( node );
}
});
identifiers.forEach( node => console.log( node.name ) ); // a, b, c
references.forEach( node => console.log( node.name ) ); // a, b
```
## License
MIT
@@ -0,0 +1,31 @@
function isReference(node, parent) {
if (node.type === 'MemberExpression') {
return !node.computed && isReference(node.object, node);
}
if (node.type === 'Identifier') {
if (!parent)
return true;
switch (parent.type) {
// disregard `bar` in `foo.bar`
case 'MemberExpression': return parent.computed || node === parent.object;
// disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
case 'MethodDefinition': return parent.computed;
// disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
case 'FieldDefinition': return parent.computed || node === parent.value;
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
case 'Property': return parent.computed || node === parent.value;
// disregard the `bar` in `export { foo as bar }` or
// the foo in `import { foo as bar }`
case 'ExportSpecifier':
case 'ImportSpecifier': return node === parent.local;
// disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
case 'LabeledStatement':
case 'BreakStatement':
case 'ContinueStatement': return false;
default: return true;
}
}
return false;
}
export default isReference;
@@ -0,0 +1,39 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
typeof define === 'function' && define.amd ? define(factory) :
(global = global || self, global.isReference = factory());
}(this, (function () { 'use strict';
function isReference(node, parent) {
if (node.type === 'MemberExpression') {
return !node.computed && isReference(node.object, node);
}
if (node.type === 'Identifier') {
if (!parent)
return true;
switch (parent.type) {
// disregard `bar` in `foo.bar`
case 'MemberExpression': return parent.computed || node === parent.object;
// disregard the `foo` in `class {foo(){}}` but keep it in `class {[foo](){}}`
case 'MethodDefinition': return parent.computed;
// disregard the `foo` in `class {foo=bar}` but keep it in `class {[foo]=bar}` and `class {bar=foo}`
case 'FieldDefinition': return parent.computed || node === parent.value;
// disregard the `bar` in `{ bar: foo }`, but keep it in `{ [bar]: foo }`
case 'Property': return parent.computed || node === parent.value;
// disregard the `bar` in `export { foo as bar }` or
// the foo in `import { foo as bar }`
case 'ExportSpecifier':
case 'ImportSpecifier': return node === parent.local;
// disregard the `foo` in `foo: while (...) { ... break foo; ... continue foo;}`
case 'LabeledStatement':
case 'BreakStatement':
case 'ContinueStatement': return false;
default: return true;
}
}
return false;
}
return isReference;
})));
@@ -0,0 +1,2 @@
import { Node } from 'estree';
export default function isReference(node: Node, parent: Node): boolean;
@@ -0,0 +1,49 @@
{
"name": "is-reference",
"version": "1.2.1",
"description": "Determine whether an AST node is a reference",
"main": "dist/is-reference.js",
"module": "dist/is-reference.es.js",
"types": "dist/types/index.d.ts",
"files": [
"dist/*.js",
"dist/types/**/*.d.ts"
],
"scripts": {
"test": "mocha",
"build": "rollup -c && tsc --emitDeclarationOnly",
"pretest": "npm run build",
"prepare": "npm run build",
"prepublishOnly": "npm test"
},
"repository": {
"type": "git",
"url": "git+https://github.com/Rich-Harris/is-reference.git"
},
"keywords": [
"ast",
"javascript",
"estree",
"acorn"
],
"author": "Rich Harris",
"license": "MIT",
"bugs": {
"url": "https://github.com/Rich-Harris/is-reference/issues"
},
"homepage": "https://github.com/Rich-Harris/is-reference#readme",
"dependencies": {
"@types/estree": "*"
},
"devDependencies": {
"acorn": "^7.2.0",
"acorn-class-fields": "^0.3.2",
"acorn-static-class-features": "^0.2.1",
"estree-walker": "^2.0.1",
"mocha": "^7.1.2",
"rollup": "^2.10.3",
"rollup-plugin-typescript": "^1.0.1",
"tslib": "^2.0.0",
"typescript": "^3.9.2"
}
}
+91
View File
@@ -0,0 +1,91 @@
{
"name": "@rollup/plugin-commonjs",
"version": "29.0.0",
"publishConfig": {
"access": "public"
},
"description": "Convert CommonJS modules to ES2015",
"license": "MIT",
"repository": {
"url": "rollup/plugins",
"directory": "packages/commonjs"
},
"author": "Rich Harris <richard.a.harris@gmail.com>",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/commonjs/#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"exports": {
"types": "./types/index.d.ts",
"import": "./dist/es/index.js",
"default": "./dist/cjs/index.js"
},
"engines": {
"node": ">=16.0.0 || 14 >= 14.17"
},
"files": [
"dist",
"!dist/**/*.map",
"types",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"npm",
"modules",
"commonjs",
"require"
],
"peerDependencies": {
"rollup": "^2.68.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
},
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"commondir": "^1.0.1",
"estree-walker": "^2.0.2",
"fdir": "^6.2.0",
"is-reference": "1.2.1",
"magic-string": "^0.30.3",
"picomatch": "^4.0.2"
},
"devDependencies": {
"@rollup/plugin-json": "^5.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"locate-character": "^2.0.5",
"require-relative": "^0.8.7",
"rollup": "^4.0.0-24",
"source-map": "^0.7.4",
"source-map-support": "^0.5.21",
"typescript": "^4.8.3"
},
"types": "./types/index.d.ts",
"ava": {
"workerThreads": false,
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm build && pnpm lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm test -- --verbose && pnpm test:ts",
"prebuild": "del-cli dist",
"prerelease": "pnpm build",
"pretest": "pnpm build",
"release": "pnpm --workspace-root package:release $(pwd)",
"test": "ava",
"test:ts": "tsc types/index.d.ts test/types.ts --noEmit"
}
}
+244
View File
@@ -0,0 +1,244 @@
import type { FilterPattern } from '@rollup/pluginutils';
import type { Plugin } from 'rollup';
type RequireReturnsDefaultOption = boolean | 'auto' | 'preferred' | 'namespace';
type DefaultIsModuleExportsOption = boolean | 'auto';
interface RollupCommonJSOptions {
/**
* A picomatch pattern, or array of patterns, which specifies the files in
* the build the plugin should operate on. By default, all files with
* extension `".cjs"` or those in `extensions` are included, but you can
* narrow this list by only including specific files. These files will be
* analyzed and transpiled if either the analysis does not find ES module
* specific statements or `transformMixedEsModules` is `true`.
* @default undefined
*/
include?: FilterPattern;
/**
* A picomatch pattern, or array of patterns, which specifies the files in
* the build the plugin should _ignore_. By default, all files with
* extensions other than those in `extensions` or `".cjs"` are ignored, but you
* can exclude additional files. See also the `include` option.
* @default undefined
*/
exclude?: FilterPattern;
/**
* For extensionless imports, search for extensions other than .js in the
* order specified. Note that you need to make sure that non-JavaScript files
* are transpiled by another plugin first.
* @default [ '.js' ]
*/
extensions?: ReadonlyArray<string>;
/**
* If true then uses of `global` won't be dealt with by this plugin
* @default false
*/
ignoreGlobal?: boolean;
/**
* If false, skips source map generation for CommonJS modules. This will
* improve performance.
* @default true
*/
sourceMap?: boolean;
/**
* Some `require` calls cannot be resolved statically to be translated to
* imports.
* When this option is set to `false`, the generated code will either
* directly throw an error when such a call is encountered or, when
* `dynamicRequireTargets` is used, when such a call cannot be resolved with a
* configured dynamic require target.
* Setting this option to `true` will instead leave the `require` call in the
* code or use it as a fallback for `dynamicRequireTargets`.
* @default false
*/
ignoreDynamicRequires?: boolean;
/**
* Instructs the plugin whether to enable mixed module transformations. This
* is useful in scenarios with modules that contain a mix of ES `import`
* statements and CommonJS `require` expressions. Set to `true` if `require`
* calls should be transformed to imports in mixed modules, or `false` if the
* `require` expressions should survive the transformation. The latter can be
* important if the code contains environment detection, or you are coding
* for an environment with special treatment for `require` calls such as
* ElectronJS. See also the `ignore` option.
* @default false
*/
transformMixedEsModules?: boolean;
/**
* By default, this plugin will try to hoist `require` statements as imports
* to the top of each file. While this works well for many code bases and
* allows for very efficient ESM output, it does not perfectly capture
* CommonJS semantics as the order of side effects like log statements may
* change. But it is especially problematic when there are circular `require`
* calls between CommonJS modules as those often rely on the lazy execution of
* nested `require` calls.
*
* Setting this option to `true` will wrap all CommonJS files in functions
* which are executed when they are required for the first time, preserving
* NodeJS semantics. Note that this can have an impact on the size and
* performance of the generated code.
*
* The default value of `"auto"` will only wrap CommonJS files when they are
* part of a CommonJS dependency cycle, e.g. an index file that is required by
* many of its dependencies. All other CommonJS files are hoisted. This is the
* recommended setting for most code bases.
*
* `false` will entirely prevent wrapping and hoist all files. This may still
* work depending on the nature of cyclic dependencies but will often cause
* problems.
*
* You can also provide a picomatch pattern, or array of patterns, to only
* specify a subset of files which should be wrapped in functions for proper
* `require` semantics.
*
* `"debug"` works like `"auto"` but after bundling, it will display a warning
* containing a list of ids that have been wrapped which can be used as
* picomatch pattern for fine-tuning.
* @default "auto"
*/
strictRequires?: boolean | FilterPattern;
/**
* Sometimes you have to leave require statements unconverted. Pass an array
* containing the IDs or a `id => boolean` function.
* @default []
*/
ignore?: ReadonlyArray<string> | ((id: string) => boolean);
/**
* In most cases, where `require` calls are inside a `try-catch` clause,
* they should be left unconverted as it requires an optional dependency
* that may or may not be installed beside the rolled up package.
* Due to the conversion of `require` to a static `import` - the call is
* hoisted to the top of the file, outside the `try-catch` clause.
*
* - `true`: Default. All `require` calls inside a `try` will be left unconverted.
* - `false`: All `require` calls inside a `try` will be converted as if the
* `try-catch` clause is not there.
* - `remove`: Remove all `require` calls from inside any `try` block.
* - `string[]`: Pass an array containing the IDs to left unconverted.
* - `((id: string) => boolean|'remove')`: Pass a function that controls
* individual IDs.
*
* @default true
*/
ignoreTryCatch?:
| boolean
| 'remove'
| ReadonlyArray<string>
| ((id: string) => boolean | 'remove');
/**
* Controls how to render imports from external dependencies. By default,
* this plugin assumes that all external dependencies are CommonJS. This
* means they are rendered as default imports to be compatible with e.g.
* NodeJS where ES modules can only import a default export from a CommonJS
* dependency.
*
* If you set `esmExternals` to `true`, this plugin assumes that all
* external dependencies are ES modules and respect the
* `requireReturnsDefault` option. If that option is not set, they will be
* rendered as namespace imports.
*
* You can also supply an array of ids to be treated as ES modules, or a
* function that will be passed each external id to determine whether it is
* an ES module.
* @default false
*/
esmExternals?: boolean | ReadonlyArray<string> | ((id: string) => boolean);
/**
* Controls what is returned when requiring an ES module from a CommonJS file.
* When using the `esmExternals` option, this will also apply to external
* modules. By default, this plugin will render those imports as namespace
* imports i.e.
*
* ```js
* // input
* const foo = require('foo');
*
* // output
* import * as foo from 'foo';
* ```
*
* However, there are some situations where this may not be desired.
* For these situations, you can change Rollup's behaviour either globally or
* per module. To change it globally, set the `requireReturnsDefault` option
* to one of the following values:
*
* - `false`: This is the default, requiring an ES module returns its
* namespace. This is the only option that will also add a marker
* `__esModule: true` to the namespace to support interop patterns in
* CommonJS modules that are transpiled ES modules.
* - `"namespace"`: Like `false`, requiring an ES module returns its
* namespace, but the plugin does not add the `__esModule` marker and thus
* creates more efficient code. For external dependencies when using
* `esmExternals: true`, no additional interop code is generated.
* - `"auto"`: This is complementary to how `output.exports: "auto"` works in
* Rollup: If a module has a default export and no named exports, requiring
* that module returns the default export. In all other cases, the namespace
* is returned. For external dependencies when using `esmExternals: true`, a
* corresponding interop helper is added.
* - `"preferred"`: If a module has a default export, requiring that module
* always returns the default export, no matter whether additional named
* exports exist. This is similar to how previous versions of this plugin
* worked. Again for external dependencies when using `esmExternals: true`,
* an interop helper is added.
* - `true`: This will always try to return the default export on require
* without checking if it actually exists. This can throw at build time if
* there is no default export. This is how external dependencies are handled
* when `esmExternals` is not used. The advantage over the other options is
* that, like `false`, this does not add an interop helper for external
* dependencies, keeping the code lean.
*
* To change this for individual modules, you can supply a function for
* `requireReturnsDefault` instead. This function will then be called once for
* each required ES module or external dependency with the corresponding id
* and allows you to return different values for different modules.
* @default false
*/
requireReturnsDefault?:
| RequireReturnsDefaultOption
| ((id: string) => RequireReturnsDefaultOption);
/**
* @default "auto"
*/
defaultIsModuleExports?:
| DefaultIsModuleExportsOption
| ((id: string) => DefaultIsModuleExportsOption);
/**
* Some modules contain dynamic `require` calls, or require modules that
* contain circular dependencies, which are not handled well by static
* imports. Including those modules as `dynamicRequireTargets` will simulate a
* CommonJS (NodeJS-like) environment for them with support for dynamic
* dependencies. It also enables `strictRequires` for those modules.
*
* Note: In extreme cases, this feature may result in some paths being
* rendered as absolute in the final bundle. The plugin tries to avoid
* exposing paths from the local machine, but if you are `dynamicRequirePaths`
* with paths that are far away from your project's folder, that may require
* replacing strings like `"/Users/John/Desktop/foo-project/"` -> `"/"`.
*/
dynamicRequireTargets?: string | ReadonlyArray<string>;
/**
* To avoid long paths when using the `dynamicRequireTargets` option, you can use this option to specify a directory
* that is a common parent for all files that use dynamic require statements. Using a directory higher up such as `/`
* may lead to unnecessarily long paths in the generated code and may expose directory names on your machine like your
* home directory name. By default, it uses the current working directory.
*/
dynamicRequireRoot?: string;
/**
* When enabled, external Node built-ins (e.g., `node:fs`) required from wrapped CommonJS modules
* will use `createRequire(import.meta.url)` instead of being hoisted as ESM imports. This prevents
* eager loading of Node built-ins at module initialization time.
*
* Note: This option adds a dependency on `node:module` in the output, which may not be available
* in some environments like edge runtimes (Cloudflare Workers, Vercel Edge Runtime).
*
* @default false
*/
requireNodeBuiltins?: boolean;
}
/**
* Convert CommonJS modules to ES6, so they can be included in a Rollup bundle
*/
export default function commonjs(options?: RollupCommonJSOptions): Plugin;
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/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.
+110
View File
@@ -0,0 +1,110 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-json
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-json
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-json
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-json
[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)
# @rollup/plugin-json
🍣 A Rollup plugin which Converts .json files to ES6 modules.
## Requirements
This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v1.20.0+.
## Install
Using npm:
```console
npm install @rollup/plugin-json --save-dev
```
## Usage
Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
```js
import json from '@rollup/plugin-json';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [json()]
};
```
Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
With an accompanying file `src/index.js`, the local `package.json` file would now be importable as seen below:
```js
// src/index.js
import { readFileSync } from 'fs';
const pkg = JSON.parse(readFileSync(new URL('./package.json', import.meta.url), 'utf8'));
console.log(`running version ${pkg.version}`);
```
## Options
### `compact`
Type: `Boolean`<br>
Default: `false`
If `true`, instructs the plugin to ignore `indent` and generates the smallest code.
### `exclude`
Type: `String` | `Array[...String]`<br>
Default: `null`
A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files in the build the plugin should _ignore_. By default no files are ignored.
### `include`
Type: `String` | `Array[...String]`<br>
Default: `null`
A [picomatch pattern](https://github.com/micromatch/picomatch), or array of patterns, which specifies the files in the build the plugin should operate on. By default all files are targeted.
### `includeArbitraryNames`
Type: `Boolean`<br>
Default: `false`
If `true` and `namedExports` is `true`, generates a named export for not a valid identifier properties of the JSON object by leveraging the ["Arbitrary Module Namespace Identifier Names" feature](https://github.com/tc39/ecma262/pull/2154).
### `indent`
Type: `String`<br>
Default: `'\t'`
Specifies the indentation for the generated default export.
### `namedExports`
Type: `Boolean`<br>
Default: `true`
If `true`, instructs the plugin to generate a named export for every property of the JSON object.
### `preferConst`
Type: `Boolean`<br>
Default: `false`
If `true`, instructs the plugin to declare properties as variables, using either `var` or `const`. This pertains to tree-shaking.
## Meta
[CONTRIBUTING](/.github/CONTRIBUTING.md)
[LICENSE (MIT)](/LICENSE)
+43
View File
@@ -0,0 +1,43 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var pluginutils = require('@rollup/pluginutils');
function json(options) {
if ( options === void 0 ) options = {};
var filter = pluginutils.createFilter(options.include, options.exclude);
var indent = 'indent' in options ? options.indent : '\t';
return {
name: 'json',
// eslint-disable-next-line no-shadow
transform: function transform(code, id) {
if (id.slice(-5) !== '.json' || !filter(id)) { return null; }
try {
var parsed = JSON.parse(code);
return {
code: pluginutils.dataToEsm(parsed, {
preferConst: options.preferConst,
compact: options.compact,
namedExports: options.namedExports,
includeArbitraryNames: options.includeArbitraryNames,
indent: indent
}),
map: { mappings: '' }
};
} catch (err) {
var message = 'Could not parse JSON file';
this.error({ message: message, id: id, cause: err });
return null;
}
}
};
}
exports.default = json;
module.exports = Object.assign(exports.default, exports);
//# sourceMappingURL=index.js.map
+38
View File
@@ -0,0 +1,38 @@
import { createFilter, dataToEsm } from '@rollup/pluginutils';
function json(options) {
if ( options === void 0 ) options = {};
var filter = createFilter(options.include, options.exclude);
var indent = 'indent' in options ? options.indent : '\t';
return {
name: 'json',
// eslint-disable-next-line no-shadow
transform: function transform(code, id) {
if (id.slice(-5) !== '.json' || !filter(id)) { return null; }
try {
var parsed = JSON.parse(code);
return {
code: dataToEsm(parsed, {
preferConst: options.preferConst,
compact: options.compact,
namedExports: options.namedExports,
includeArbitraryNames: options.includeArbitraryNames,
indent: indent
}),
map: { mappings: '' }
};
} catch (err) {
var message = 'Could not parse JSON file';
this.error({ message: message, id: id, cause: err });
return null;
}
}
};
}
export { json as default };
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"type":"module"}
+81
View File
@@ -0,0 +1,81 @@
{
"name": "@rollup/plugin-json",
"version": "6.1.0",
"publishConfig": {
"access": "public"
},
"description": "Convert .json files to ES6 modules",
"license": "MIT",
"repository": {
"url": "rollup/plugins",
"directory": "packages/json"
},
"author": "rollup",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/json#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"exports": {
"types": "./types/index.d.ts",
"import": "./dist/es/index.js",
"default": "./dist/cjs/index.js"
},
"engines": {
"node": ">=14.0.0"
},
"files": [
"dist",
"!dist/**/*.map",
"types",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"json",
"es2015",
"npm",
"modules"
],
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
},
"dependencies": {
"@rollup/pluginutils": "^5.1.0"
},
"devDependencies": {
"@rollup/plugin-buble": "^1.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"rollup": "^4.0.0-24",
"source-map-support": "^0.5.21"
},
"types": "./types/index.d.ts",
"ava": {
"workerThreads": false,
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm build && pnpm lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm test -- --verbose && pnpm test:ts",
"prebuild": "del-cli dist",
"prerelease": "pnpm build",
"pretest": "pnpm build",
"release": "pnpm --workspace-root package:release $(pwd)",
"test": "ava",
"test:ts": "tsc types/index.d.ts test/types.ts --noEmit"
}
}
+41
View File
@@ -0,0 +1,41 @@
import type { FilterPattern } from '@rollup/pluginutils';
import type { Plugin } from 'rollup';
export interface RollupJsonOptions {
/**
* All JSON files will be parsed by default,
* but you can also specifically include files
*/
include?: FilterPattern;
/**
* All JSON files will be parsed by default,
* but you can also specifically exclude files
*/
exclude?: FilterPattern;
/**
* For tree-shaking, properties will be declared as variables, using
* either `var` or `const`.
* @default false
*/
preferConst?: boolean;
/**
* Specify indentation for the generated default export
* @default '\t'
*/
indent?: string;
/**
* Ignores indent and generates the smallest code
* @default false
*/
compact?: boolean;
/**
* Generate a named export for every property of the JSON object
* @default true
*/
namedExports?: boolean;
}
/**
* Convert .json files to ES6 modules
*/
export default function json(options?: RollupJsonOptions): Plugin;
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/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.
+296
View File
@@ -0,0 +1,296 @@
[npm]: https://img.shields.io/npm/v/@rollup/plugin-node-resolve
[npm-url]: https://www.npmjs.com/package/@rollup/plugin-node-resolve
[size]: https://packagephobia.now.sh/badge?p=@rollup/plugin-node-resolve
[size-url]: https://packagephobia.now.sh/result?p=@rollup/plugin-node-resolve
[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)
# @rollup/plugin-node-resolve
🍣 A Rollup plugin which locates modules using the [Node resolution algorithm](https://nodejs.org/api/modules.html#modules_all_together), for using third party modules in `node_modules`
## Requirements
This plugin requires an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v2.78.0+.
## Install
Using npm:
```console
npm install @rollup/plugin-node-resolve --save-dev
```
## Usage
Create a `rollup.config.js` [configuration file](https://www.rollupjs.org/guide/en/#configuration-files) and import the plugin:
```js
import { nodeResolve } from '@rollup/plugin-node-resolve';
export default {
input: 'src/index.js',
output: {
dir: 'output',
format: 'cjs'
},
plugins: [nodeResolve()]
};
```
Then call `rollup` either via the [CLI](https://www.rollupjs.org/guide/en/#command-line-reference) or the [API](https://www.rollupjs.org/guide/en/#javascript-api).
## Package entrypoints
This plugin supports the package entrypoints feature from node js, specified in the `exports` or `imports` field of a package. Check the [official documentation](https://nodejs.org/api/packages.html#packages_package_entry_points) for more information on how this works. This is the default behavior. In the abscence of these fields, the fields in `mainFields` will be the ones to be used.
## Options
### `exportConditions`
Type: `Array[...String]`<br>
Default: `[]`
Additional conditions of the package.json exports field to match when resolving modules. By default, this plugin looks for the `['default', 'module', 'import', 'development|production']` conditions when resolving imports. If neither the `development` or `production` conditions are provided it will default to `production` - or `development` if `NODE_ENV` is set to a value other than `production`.
When using `@rollup/plugin-commonjs` v16 or higher, this plugin will use the `['default', 'module', 'require']` conditions when resolving require statements.
Setting this option will add extra conditions on top of the default conditions. See https://nodejs.org/api/packages.html#packages_conditional_exports for more information.
In order to get the [resolution behavior of Node.js](https://nodejs.org/api/packages.html#packages_conditional_exports), set this to `['node']`.
### `browser`
Type: `Boolean`<br>
Default: `false`
If `true`, instructs the plugin to use the browser module resolutions in `package.json` and adds `'browser'` to `exportConditions` if it is not present so browser conditionals in `exports` are applied. If `false`, any browser properties in package files will be ignored. Alternatively, a value of `'browser'` can be added to both the `mainFields` and `exportConditions` options, however this option takes precedence over `mainFields`.
> This option does not work when a package is using [package entrypoints](https://nodejs.org/api/packages.html#packages_package_entry_points)
### `moduleDirectories`
Type: `Array[...String]`<br>
Default: `['node_modules']`
A list of directory names in which to recursively look for modules.
### `modulePaths`
Type: `Array[...String]`<br>
Default: `[]`
A list of absolute paths to additional locations to search for modules. [This is analogous to setting the `NODE_PATH` environment variable for node](https://nodejs.org/api/modules.html#loading-from-the-global-folders).
### `dedupe`
Type: `Array[...String]`<br>
Default: `[]`
An `Array` of modules names, which instructs the plugin to force resolving for the specified modules to the root `node_modules`. Helps to prevent bundling the same package multiple times if package is imported from dependencies.
```js
dedupe: ['my-package', '@namespace/my-package'];
```
This will deduplicate bare imports such as:
```js
import 'my-package';
import '@namespace/my-package';
```
And it will deduplicate deep imports such as:
```js
import 'my-package/foo.js';
import '@namespace/my-package/bar.js';
```
### `extensions`
Type: `Array[...String]`<br>
Default: `['.mjs', '.js', '.json', '.node']`
Specifies the extensions of files that the plugin will operate on.
### `jail`
Type: `String`<br>
Default: `'/'`
Locks the module search within specified path (e.g. chroot). Modules defined outside this path will be ignored by this plugin.
### `mainFields`
Type: `Array[...String]`<br>
Default: `['module', 'main']`<br>
Valid values: `['browser', 'jsnext:main', 'module', 'main']`
Specifies the properties to scan within a `package.json`, used to determine the bundle entry point. The order of property names is significant, as the first-found property is used as the resolved entry point. If the array contains `'browser'`, key/values specified in the `package.json` `browser` property will be used.
### `preferBuiltins`
Type: `Boolean | (module: string) => boolean`<br>
Default: `true` (with warnings if a builtin module is used over a local version. Set to `true` to disable warning.)
If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`, the plugin will look for locally installed modules of the same name.
Alternatively, you may pass in a function that returns a boolean to confirm whether the plugin should prefer built-in modules. e.g.
```js
preferBuiltins: (module) => module !== 'punycode';
```
will not treat `punycode` as a built-in module
### `modulesOnly`
Type: `Boolean`<br>
Default: `false`
If `true`, inspect resolved files to assert that they are ES2015 modules.
### `resolveOnly`
Type: `Array[...String|RegExp] | (module: string) => boolean`<br>
Default: `null`
An `Array` which instructs the plugin to limit module resolution to those whose names match patterns in the array. _Note: Modules not matching any patterns will be marked as external._
Alternatively, you may pass in a function that returns a boolean to confirm whether the module should be included or not.
Examples:
- `resolveOnly: ['batman', /^@batcave\/.*$/]`
- `resolveOnly: module => !module.includes('joker')`
### `rootDir`
Type: `String`<br>
Default: `process.cwd()`
Specifies the root directory from which to resolve modules. Typically used when resolving entry-point imports, and when resolving deduplicated modules. Useful when executing rollup in a package of a mono-repository.
```
// Set the root directory to be the parent folder
rootDir: path.join(process.cwd(), '..')
```
### `ignoreSideEffectsForRoot`
Type: `Boolean`<br>
Default: `false`
If you use the `sideEffects` property in the package.json, by default this is respected for files in the root package. Set to `true` to ignore the `sideEffects` configuration for the root package.
### `allowExportsFolderMapping`
Older Node versions supported exports mappings of folders like
```json
{
"exports": {
"./foo/": "./dist/foo/"
}
}
```
This was deprecated with Node 14 and removed in Node 17, instead it is recommended to use exports patterns like
```json
{
"exports": {
"./foo/*": "./dist/foo/*"
}
}
```
But for backwards compatibility this behavior is still supported by enabling the `allowExportsFolderMapping` (defaults to `true`).
The default value might change in a futur major release.
## Preserving symlinks
This plugin honours the rollup [`preserveSymlinks`](https://rollupjs.org/guide/en/#preservesymlinks) option.
## Using with @rollup/plugin-commonjs
Since most packages in your node_modules folder are probably legacy CommonJS rather than JavaScript modules, you may need to use [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/master/packages/commonjs):
```js
// rollup.config.js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
export default {
input: 'main.js',
output: {
file: 'bundle.js',
format: 'iife',
name: 'MyModule'
},
plugins: [nodeResolve(), commonjs()]
};
```
## Resolving Built-Ins (like `fs`)
By default this plugin will prefer built-ins over local modules, marking them as external.
See [`preferBuiltins`](#preferbuiltins).
To provide stubbed versions of Node built-ins, use a plugin like [rollup-plugin-node-polyfills](https://github.com/ionic-team/rollup-plugin-node-polyfills) and set `preferBuiltins` to `false`. e.g.
```js
import { nodeResolve } from '@rollup/plugin-node-resolve';
import nodePolyfills from 'rollup-plugin-node-polyfills';
export default ({
input: ...,
plugins: [
nodePolyfills(),
nodeResolve({ preferBuiltins: false })
],
external: builtins,
output: ...
})
```
## Resolving Require Statements
According to [NodeJS module resolution](https://nodejs.org/api/packages.html#packages_package_entry_points) `require` statements should resolve using the `require` condition in the package exports field, while es modules should use the `import` condition.
The node resolve plugin uses `import` by default, you can opt into using the `require` semantics by passing an extra option to the resolve function:
```js
this.resolve(importee, importer, {
skipSelf: true,
custom: { 'node-resolve': { isRequire: true } }
});
```
## Resolve Options
After this plugin resolved an import id to its target file in `node_modules`, it will invoke `this.resolve` again with the resolved id. It will pass the following information in the resolve options:
```js
this.resolve(resolved.id, importer, {
custom: {
'node-resolve': {
resolved, // the object with information from node.js resolve
importee // the original import id
}
}
});
```
Your plugin can use the `importee` information to map an original import to its resolved file in `node_modules`, in a plugin hook such as `resolveId`.
The `resolved` object contains the resolved id, which is passed as the first parameter. It also has a property `moduleSideEffects`, which may contain the value from the npm `package.json` field `sideEffects` or `null`.
## Meta
[CONTRIBUTING](/.github/CONTRIBUTING.md)
[LICENSE (MIT)](/LICENSE)
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1
View File
@@ -0,0 +1 @@
{"type":"module"}
+89
View File
@@ -0,0 +1,89 @@
{
"name": "@rollup/plugin-node-resolve",
"version": "16.0.3",
"publishConfig": {
"access": "public"
},
"description": "Locate and bundle third-party dependencies in node_modules",
"license": "MIT",
"repository": {
"url": "rollup/plugins",
"directory": "packages/node-resolve"
},
"author": "Rich Harris <richard.a.harris@gmail.com>",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/node-resolve/#readme",
"bugs": "https://github.com/rollup/plugins/issues",
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"exports": {
"types": "./types/index.d.ts",
"import": "./dist/es/index.js",
"default": "./dist/cjs/index.js"
},
"engines": {
"node": ">=14.0.0"
},
"files": [
"dist",
"!dist/**/*.map",
"types",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"es2015",
"npm",
"modules"
],
"peerDependencies": {
"rollup": "^2.78.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
},
"dependencies": {
"@rollup/pluginutils": "^5.0.1",
"@types/resolve": "1.20.2",
"deepmerge": "^4.2.2",
"is-module": "^1.0.0",
"resolve": "^1.22.1"
},
"devDependencies": {
"@babel/core": "^7.19.1",
"@babel/plugin-transform-typescript": "^7.10.5",
"@rollup/plugin-babel": "^6.0.0",
"@rollup/plugin-commonjs": "^23.0.0",
"@rollup/plugin-json": "^5.0.0",
"es5-ext": "^0.10.62",
"rollup": "^4.0.0-24",
"source-map": "^0.7.4",
"string-capitalize": "^1.0.1"
},
"types": "./types/index.d.ts",
"ava": {
"workerThreads": false,
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm build && pnpm lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm test -- --verbose",
"prebuild": "del-cli dist",
"prerelease": "pnpm build",
"pretest": "pnpm build",
"release": "pnpm --workspace-root package:release $(pwd)",
"test": "pnpm test:ts && ava",
"test:ts": "tsc types/index.d.ts test/types.ts --noEmit"
}
}
+122
View File
@@ -0,0 +1,122 @@
import type { Plugin } from 'rollup';
export const DEFAULTS: {
customResolveOptions: {};
dedupe: [];
extensions: ['.mjs', '.js', '.json', '.node'];
resolveOnly: [];
};
export interface RollupNodeResolveOptions {
/**
* Additional conditions of the package.json exports field to match when resolving modules.
* By default, this plugin looks for the `'default', 'module', 'import']` conditions when resolving imports.
*
* When using `@rollup/plugin-commonjs` v16 or higher, this plugin will use the
* `['default', 'module', 'import']` conditions when resolving require statements.
*
* Setting this option will add extra conditions on top of the default conditions.
* See https://nodejs.org/api/packages.html#packages_conditional_exports for more information.
*/
exportConditions?: string[];
/**
* If `true`, instructs the plugin to use the `"browser"` property in `package.json`
* files to specify alternative files to load for bundling. This is useful when
* bundling for a browser environment. Alternatively, a value of `'browser'` can be
* added to the `mainFields` option. If `false`, any `"browser"` properties in
* package files will be ignored. This option takes precedence over `mainFields`.
* @default false
*/
browser?: boolean;
/**
* A list of directory names in which to recursively look for modules.
* @default ['node_modules']
*/
moduleDirectories?: string[];
/**
* A list of absolute paths to additional locations to search for modules.
* This is analogous to setting the `NODE_PATH` environment variable for node.
* @default []
*/
modulePaths?: string[];
/**
* An `Array` of modules names, which instructs the plugin to force resolving for the
* specified modules to the root `node_modules`. Helps to prevent bundling the same
* package multiple times if package is imported from dependencies.
*/
dedupe?: string[] | ((importee: string) => boolean);
/**
* Specifies the extensions of files that the plugin will operate on.
* @default [ '.mjs', '.js', '.json', '.node' ]
*/
extensions?: readonly string[];
/**
* Locks the module search within specified path (e.g. chroot). Modules defined
* outside this path will be marked as external.
* @default '/'
*/
jail?: string;
/**
* Specifies the properties to scan within a `package.json`, used to determine the
* bundle entry point.
* @default ['module', 'main']
*/
mainFields?: readonly string[];
/**
* If `true`, inspect resolved files to assert that they are ES2015 modules.
* @default false
*/
modulesOnly?: boolean;
/**
* If `true`, the plugin will prefer built-in modules (e.g. `fs`, `path`). If `false`,
* the plugin will look for locally installed modules of the same name.
*
* If a function is provided, it will be called to determine whether to prefer built-ins.
* @default true
*/
preferBuiltins?: boolean | ((module: string) => boolean);
/**
* An `Array` which instructs the plugin to limit module resolution to those whose
* names match patterns in the array.
* @default []
*/
resolveOnly?: ReadonlyArray<string | RegExp> | null | ((module: string) => boolean);
/**
* Specifies the root directory from which to resolve modules. Typically used when
* resolving entry-point imports, and when resolving deduplicated modules.
* @default process.cwd()
*/
rootDir?: string;
/**
* If you use the `sideEffects` property in the package.json, by default this is respected for files in the root package. Set to `true` to ignore the `sideEffects` configuration for the root package.
*
* @default false
*/
ignoreSideEffectsForRoot?: boolean;
/**
* Allow folder mappings in package exports (trailing /)
* This was deprecated in Node 14 and removed with Node 17, see DEP0148.
* So this option might be changed to default to `false` in a future release.
* @default true
*/
allowExportsFolderMapping?: boolean;
}
/**
* Locate modules using the Node resolution algorithm, for using third party modules in node_modules
*/
export function nodeResolve(options?: RollupNodeResolveOptions): Plugin;
export default nodeResolve;
+21
View File
@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2019 RollupJS Plugin Contributors (https://github.com/rollup/plugins/graphs/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.
+313
View File
@@ -0,0 +1,313 @@
[npm]: https://img.shields.io/npm/v/@rollup/pluginutils
[npm-url]: https://www.npmjs.com/package/@rollup/pluginutils
[size]: https://packagephobia.now.sh/badge?p=@rollup/pluginutils
[size-url]: https://packagephobia.now.sh/result?p=@rollup/pluginutils
[![npm][npm]][npm-url]
[![size][size]][size-url]
[![libera manifesto](https://img.shields.io/badge/libera-manifesto-lightgrey.svg)](https://liberamanifesto.com)
# @rollup/pluginutils
A set of utility functions commonly used by 🍣 Rollup plugins.
## Requirements
The plugin utils require an [LTS](https://github.com/nodejs/Release) Node version (v14.0.0+) and Rollup v1.20.0+.
## Install
Using npm:
```console
npm install @rollup/pluginutils --save-dev
```
## Usage
```js
import utils from '@rollup/pluginutils';
//...
```
## API
Available utility functions are listed below:
_Note: Parameter names immediately followed by a `?` indicate that the parameter is optional._
### addExtension
Adds an extension to a module ID if one does not exist.
Parameters: `(filename: String, ext?: String)`<br>
Returns: `String`
```js
import { addExtension } from '@rollup/pluginutils';
export default function myPlugin(options = {}) {
return {
resolveId(code, id) {
// only adds an extension if there isn't one already
id = addExtension(id); // `foo` -> `foo.js`, `foo.js` -> `foo.js`
id = addExtension(id, '.myext'); // `foo` -> `foo.myext`, `foo.js` -> `foo.js`
}
};
}
```
### attachScopes
Attaches `Scope` objects to the relevant nodes of an AST. Each `Scope` object has a `scope.contains(name)` method that returns `true` if a given name is defined in the current scope or a parent scope.
Parameters: `(ast: Node, propertyName?: String)`<br>
Returns: `Object`
See [@rollup/plugin-inject](https://github.com/rollup/plugins/tree/master/packages/inject) or [@rollup/plugin-commonjs](https://github.com/rollup/plugins/tree/master/packages/commonjs) for an example of usage.
```js
import { attachScopes } from '@rollup/pluginutils';
import { walk } from 'estree-walker';
export default function myPlugin(options = {}) {
return {
transform(code) {
const ast = this.parse(code);
let scope = attachScopes(ast, 'scope');
walk(ast, {
enter(node) {
if (node.scope) scope = node.scope;
if (!scope.contains('foo')) {
// `foo` is not defined, so if we encounter it,
// we assume it's a global
}
},
leave(node) {
if (node.scope) scope = scope.parent;
}
});
}
};
}
```
### createFilter
Constructs a filter function which can be used to determine whether or not certain modules should be operated upon.
Parameters: `(include?: <picomatch>, exclude?: <picomatch>, options?: Object)`<br>
Returns: `(id: string | unknown) => boolean`
#### `include` and `exclude`
Type: `String | RegExp | Array[...String|RegExp]`<br>
A valid [`picomatch`](https://github.com/micromatch/picomatch#globbing-features) pattern, or array of patterns. If `options.include` is omitted or has zero length, filter will return `true` by default. Otherwise, an ID must match one or more of the `picomatch` patterns, and must not match any of the `options.exclude` patterns.
Note that `picomatch` patterns are very similar to [`minimatch`](https://github.com/isaacs/minimatch#readme) patterns, and in most use cases, they are interchangeable. If you have more specific pattern matching needs, you can view [this comparison table](https://github.com/micromatch/picomatch#library-comparisons) to learn more about where the libraries differ.
#### `options`
##### `resolve`
Type: `String | Boolean | null`
Optionally resolves the patterns against a directory other than `process.cwd()`. If a `String` is specified, then the value will be used as the base directory. Relative paths will be resolved against `process.cwd()` first. If `false`, then the patterns will not be resolved against any directory. This can be useful if you want to create a filter for virtual module names.
#### Usage
```js
import { createFilter } from '@rollup/pluginutils';
export default function myPlugin(options = {}) {
// assume that the myPlugin accepts options of `options.include` and `options.exclude`
var filter = createFilter(options.include, options.exclude, {
resolve: '/my/base/dir'
});
return {
transform(code, id) {
if (!filter(id)) return;
// proceed with the transformation...
}
};
}
```
### dataToEsm
Transforms objects into tree-shakable ES Module imports.
Parameters: `(data: Object, options: DataToEsmOptions)`<br>
Returns: `String`
#### `data`
Type: `Object`
An object to transform into an ES module.
#### `options`
Type: `DataToEsmOptions`
_Note: Please see the TypeScript definition for complete documentation of these options_
#### Usage
```js
import { dataToEsm } from '@rollup/pluginutils';
const esModuleSource = dataToEsm(
{
custom: 'data',
to: ['treeshake']
},
{
compact: false,
indent: '\t',
preferConst: true,
objectShorthand: true,
namedExports: true,
includeArbitraryNames: false
}
);
/*
Outputs the string ES module source:
export const custom = 'data';
export const to = ['treeshake'];
export default { custom, to };
*/
```
### extractAssignedNames
Extracts the names of all assignment targets based upon specified patterns.
Parameters: `(param: Node)`<br>
Returns: `Array[...String]`
#### `param`
Type: `Node`
An `acorn` AST Node.
#### Usage
```js
import { extractAssignedNames } from '@rollup/pluginutils';
import { walk } from 'estree-walker';
export default function myPlugin(options = {}) {
return {
transform(code) {
const ast = this.parse(code);
walk(ast, {
enter(node) {
if (node.type === 'VariableDeclarator') {
const declaredNames = extractAssignedNames(node.id);
// do something with the declared names
// e.g. for `const {x, y: z} = ...` => declaredNames = ['x', 'z']
}
}
});
}
};
}
```
### exactRegex
Constructs a RegExp that matches the exact string specified. This is useful for plugin hook filters.
Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`
#### Usage
```js
import { exactRegex } from '@rollup/pluginutils';
exactRegex('foobar'); // /^foobar$/
exactRegex(['foo', 'bar']); // /^(?:foo|bar)$/
exactRegex('foo(bar)', 'i'); // /^foo\(bar\)$/i
```
### makeLegalIdentifier
Constructs a bundle-safe identifier from a `String`.
Parameters: `(str: String)`<br>
Returns: `String`
#### Usage
```js
import { makeLegalIdentifier } from '@rollup/pluginutils';
makeLegalIdentifier('foo-bar'); // 'foo_bar'
makeLegalIdentifier('typeof'); // '_typeof'
```
### normalizePath
Converts path separators to forward slash.
Parameters: `(filename: String)`<br>
Returns: `String`
#### Usage
```js
import { normalizePath } from '@rollup/pluginutils';
normalizePath('foo\\bar'); // 'foo/bar'
normalizePath('foo/bar'); // 'foo/bar'
```
### prefixRegex
Constructs a RegExp that matches a value that has the specified prefix. This is useful for plugin hook filters.
Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`
#### Usage
```js
import { prefixRegex } from '@rollup/pluginutils';
prefixRegex('foobar'); // /^foobar/
prefixRegex(['foo', 'bar']); // /^(?:foo|bar)/
prefixRegex('foo(bar)', 'i'); // /^foo\(bar\)/i
```
### suffixRegex
Constructs a RegExp that matches a value that has the specified suffix. This is useful for plugin hook filters.
Parameters: `(str: String | Array[...String], flags?: String)`<br>
Returns: `RegExp`
#### Usage
```js
import { suffixRegex } from '@rollup/pluginutils';
suffixRegex('foobar'); // /foobar$/
suffixRegex(['foo', 'bar']); // /(?:foo|bar)$/
suffixRegex('foo(bar)', 'i'); // /foo\(bar\)$/i
```
## Meta
[CONTRIBUTING](/.github/CONTRIBUTING.md)
[LICENSE (MIT)](/LICENSE)
+407
View File
@@ -0,0 +1,407 @@
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
var path = require('path');
var estreeWalker = require('estree-walker');
var pm = require('picomatch');
const addExtension = function addExtension(filename, ext = '.js') {
let result = `${filename}`;
if (!path.extname(filename))
result += ext;
return result;
};
const extractors = {
ArrayPattern(names, param) {
for (const element of param.elements) {
if (element)
extractors[element.type](names, element);
}
},
AssignmentPattern(names, param) {
extractors[param.left.type](names, param.left);
},
Identifier(names, param) {
names.push(param.name);
},
MemberExpression() { },
ObjectPattern(names, param) {
for (const prop of param.properties) {
// @ts-ignore Typescript reports that this is not a valid type
if (prop.type === 'RestElement') {
extractors.RestElement(names, prop);
}
else {
extractors[prop.value.type](names, prop.value);
}
}
},
RestElement(names, param) {
extractors[param.argument.type](names, param.argument);
}
};
const extractAssignedNames = function extractAssignedNames(param) {
const names = [];
extractors[param.type](names, param);
return names;
};
const blockDeclarations = {
const: true,
let: true
};
class Scope {
constructor(options = {}) {
this.parent = options.parent;
this.isBlockScope = !!options.block;
this.declarations = Object.create(null);
if (options.params) {
options.params.forEach((param) => {
extractAssignedNames(param).forEach((name) => {
this.declarations[name] = true;
});
});
}
}
addDeclaration(node, isBlockDeclaration, isVar) {
if (!isBlockDeclaration && this.isBlockScope) {
// it's a `var` or function node, and this
// is a block scope, so we need to go up
this.parent.addDeclaration(node, isBlockDeclaration, isVar);
}
else if (node.id) {
extractAssignedNames(node.id).forEach((name) => {
this.declarations[name] = true;
});
}
}
contains(name) {
return this.declarations[name] || (this.parent ? this.parent.contains(name) : false);
}
}
const attachScopes = function attachScopes(ast, propertyName = 'scope') {
let scope = new Scope();
estreeWalker.walk(ast, {
enter(n, parent) {
const node = n;
// function foo () {...}
// class Foo {...}
if (/(?:Function|Class)Declaration/.test(node.type)) {
scope.addDeclaration(node, false, false);
}
// var foo = 1
if (node.type === 'VariableDeclaration') {
const { kind } = node;
const isBlockDeclaration = blockDeclarations[kind];
node.declarations.forEach((declaration) => {
scope.addDeclaration(declaration, isBlockDeclaration, true);
});
}
let newScope;
// create new function scope
if (node.type.includes('Function')) {
const func = node;
newScope = new Scope({
parent: scope,
block: false,
params: func.params
});
// named function expressions - the name is considered
// part of the function's scope
if (func.type === 'FunctionExpression' && func.id) {
newScope.addDeclaration(func, false, false);
}
}
// create new for scope
if (/For(?:In|Of)?Statement/.test(node.type)) {
newScope = new Scope({
parent: scope,
block: true
});
}
// create new block scope
if (node.type === 'BlockStatement' && !parent.type.includes('Function')) {
newScope = new Scope({
parent: scope,
block: true
});
}
// catch clause has its own block scope
if (node.type === 'CatchClause') {
newScope = new Scope({
parent: scope,
params: node.param ? [node.param] : [],
block: true
});
}
if (newScope) {
Object.defineProperty(node, propertyName, {
value: newScope,
configurable: true
});
scope = newScope;
}
},
leave(n) {
const node = n;
if (node[propertyName])
scope = scope.parent;
}
});
return scope;
};
// Helper since Typescript can't detect readonly arrays with Array.isArray
function isArray(arg) {
return Array.isArray(arg);
}
function ensureArray(thing) {
if (isArray(thing))
return thing;
if (thing == null)
return [];
return [thing];
}
const normalizePathRegExp = new RegExp(`\\${path.win32.sep}`, 'g');
const normalizePath = function normalizePath(filename) {
return filename.replace(normalizePathRegExp, path.posix.sep);
};
function getMatcherString(id, resolutionBase) {
if (resolutionBase === false || path.isAbsolute(id) || id.startsWith('**')) {
return normalizePath(id);
}
// resolve('') is valid and will default to process.cwd()
const basePath = normalizePath(path.resolve(resolutionBase || ''))
// escape all possible (posix + win) path characters that might interfere with regex
.replace(/[-^$*+?.()|[\]{}]/g, '\\$&');
// Note that we use posix.join because:
// 1. the basePath has been normalized to use /
// 2. the incoming glob (id) matcher, also uses /
// otherwise Node will force backslash (\) on windows
return path.posix.join(basePath, normalizePath(id));
}
const createFilter = function createFilter(include, exclude, options) {
const resolutionBase = options && options.resolve;
const getMatcher = (id) => id instanceof RegExp
? id
: {
test: (what) => {
// this refactor is a tad overly verbose but makes for easy debugging
const pattern = getMatcherString(id, resolutionBase);
const fn = pm(pattern, { dot: true });
const result = fn(what);
return result;
}
};
const includeMatchers = ensureArray(include).map(getMatcher);
const excludeMatchers = ensureArray(exclude).map(getMatcher);
if (!includeMatchers.length && !excludeMatchers.length)
return (id) => typeof id === 'string' && !id.includes('\0');
return function result(id) {
if (typeof id !== 'string')
return false;
if (id.includes('\0'))
return false;
const pathId = normalizePath(id);
for (let i = 0; i < excludeMatchers.length; ++i) {
const matcher = excludeMatchers[i];
if (matcher instanceof RegExp) {
matcher.lastIndex = 0;
}
if (matcher.test(pathId))
return false;
}
for (let i = 0; i < includeMatchers.length; ++i) {
const matcher = includeMatchers[i];
if (matcher instanceof RegExp) {
matcher.lastIndex = 0;
}
if (matcher.test(pathId))
return true;
}
return !includeMatchers.length;
};
};
const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
forbiddenIdentifiers.add('');
const makeLegalIdentifier = function makeLegalIdentifier(str) {
let identifier = str
.replace(/-(\w)/g, (_, letter) => letter.toUpperCase())
.replace(/[^$_a-zA-Z0-9]/g, '_');
if (/\d/.test(identifier[0]) || forbiddenIdentifiers.has(identifier)) {
identifier = `_${identifier}`;
}
return identifier || '_';
};
function stringify(obj) {
return (JSON.stringify(obj) || 'undefined').replace(/[\u2028\u2029]/g, (char) => `\\u${`000${char.charCodeAt(0).toString(16)}`.slice(-4)}`);
}
function serializeArray(arr, indent, baseIndent) {
let output = '[';
const separator = indent ? `\n${baseIndent}${indent}` : '';
for (let i = 0; i < arr.length; i++) {
const key = arr[i];
output += `${i > 0 ? ',' : ''}${separator}${serialize(key, indent, baseIndent + indent)}`;
}
return `${output}${indent ? `\n${baseIndent}` : ''}]`;
}
function serializeObject(obj, indent, baseIndent) {
let output = '{';
const separator = indent ? `\n${baseIndent}${indent}` : '';
const entries = Object.entries(obj);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
const stringKey = makeLegalIdentifier(key) === key ? key : stringify(key);
output += `${i > 0 ? ',' : ''}${separator}${stringKey}:${indent ? ' ' : ''}${serialize(value, indent, baseIndent + indent)}`;
}
return `${output}${indent ? `\n${baseIndent}` : ''}}`;
}
function serialize(obj, indent, baseIndent) {
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj))
return serializeArray(obj, indent, baseIndent);
if (obj instanceof Date)
return `new Date(${obj.getTime()})`;
if (obj instanceof RegExp)
return obj.toString();
return serializeObject(obj, indent, baseIndent);
}
if (typeof obj === 'number') {
if (obj === Infinity)
return 'Infinity';
if (obj === -Infinity)
return '-Infinity';
if (obj === 0)
return 1 / obj === Infinity ? '0' : '-0';
if (obj !== obj)
return 'NaN'; // eslint-disable-line no-self-compare
}
if (typeof obj === 'symbol') {
const key = Symbol.keyFor(obj);
// eslint-disable-next-line no-undefined
if (key !== undefined)
return `Symbol.for(${stringify(key)})`;
}
if (typeof obj === 'bigint')
return `${obj}n`;
return stringify(obj);
}
// isWellFormed exists from Node.js 20
const hasStringIsWellFormed = 'isWellFormed' in String.prototype;
function isWellFormedString(input) {
// @ts-expect-error String::isWellFormed exists from ES2024. tsconfig lib is set to ES6
if (hasStringIsWellFormed)
return input.isWellFormed();
// https://github.com/tc39/proposal-is-usv-string/blob/main/README.md#algorithm
return !/\p{Surrogate}/u.test(input);
}
const dataToEsm = function dataToEsm(data, options = {}) {
var _a, _b;
const t = options.compact ? '' : 'indent' in options ? options.indent : '\t';
const _ = options.compact ? '' : ' ';
const n = options.compact ? '' : '\n';
const declarationType = options.preferConst ? 'const' : 'var';
if (options.namedExports === false ||
typeof data !== 'object' ||
Array.isArray(data) ||
data instanceof Date ||
data instanceof RegExp ||
data === null) {
const code = serialize(data, options.compact ? null : t, '');
const magic = _ || (/^[{[\-\/]/.test(code) ? '' : ' '); // eslint-disable-line no-useless-escape
return `export default${magic}${code};`;
}
let maxUnderbarPrefixLength = 0;
for (const key of Object.keys(data)) {
const underbarPrefixLength = (_b = (_a = /^(_+)/.exec(key)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
if (underbarPrefixLength > maxUnderbarPrefixLength) {
maxUnderbarPrefixLength = underbarPrefixLength;
}
}
const arbitraryNamePrefix = `${'_'.repeat(maxUnderbarPrefixLength + 1)}arbitrary`;
let namedExportCode = '';
const defaultExportRows = [];
const arbitraryNameExportRows = [];
for (const [key, value] of Object.entries(data)) {
if (key === makeLegalIdentifier(key)) {
if (options.objectShorthand)
defaultExportRows.push(key);
else
defaultExportRows.push(`${key}:${_}${key}`);
namedExportCode += `export ${declarationType} ${key}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
}
else {
defaultExportRows.push(`${stringify(key)}:${_}${serialize(value, options.compact ? null : t, '')}`);
if (options.includeArbitraryNames && isWellFormedString(key)) {
const variableName = `${arbitraryNamePrefix}${arbitraryNameExportRows.length}`;
namedExportCode += `${declarationType} ${variableName}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
arbitraryNameExportRows.push(`${variableName} as ${JSON.stringify(key)}`);
}
}
}
const arbitraryExportCode = arbitraryNameExportRows.length > 0
? `export${_}{${n}${t}${arbitraryNameExportRows.join(`,${n}${t}`)}${n}};${n}`
: '';
const defaultExportCode = `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`;
return `${namedExportCode}${arbitraryExportCode}${defaultExportCode}`;
};
function exactRegex(str, flags) {
return new RegExp(`^${combineMultipleStrings(str)}$`, flags);
}
function prefixRegex(str, flags) {
return new RegExp(`^${combineMultipleStrings(str)}`, flags);
}
function suffixRegex(str, flags) {
return new RegExp(`${combineMultipleStrings(str)}$`, flags);
}
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
function escapeRegex(str) {
return str.replace(escapeRegexRE, '\\$&');
}
function combineMultipleStrings(str) {
if (Array.isArray(str)) {
const escapeStr = str.map(escapeRegex).join('|');
if (escapeStr && str.length > 1) {
return `(?:${escapeStr})`;
}
return escapeStr;
}
return escapeRegex(str);
}
// TODO: remove this in next major
var index = {
addExtension,
attachScopes,
createFilter,
dataToEsm,
exactRegex,
extractAssignedNames,
makeLegalIdentifier,
normalizePath,
prefixRegex,
suffixRegex
};
exports.addExtension = addExtension;
exports.attachScopes = attachScopes;
exports.createFilter = createFilter;
exports.dataToEsm = dataToEsm;
exports.default = index;
exports.exactRegex = exactRegex;
exports.extractAssignedNames = extractAssignedNames;
exports.makeLegalIdentifier = makeLegalIdentifier;
exports.normalizePath = normalizePath;
exports.prefixRegex = prefixRegex;
exports.suffixRegex = suffixRegex;
module.exports = Object.assign(exports.default, exports);
//# sourceMappingURL=index.js.map
+392
View File
@@ -0,0 +1,392 @@
import { extname, win32, posix, isAbsolute, resolve } from 'path';
import { walk } from 'estree-walker';
import pm from 'picomatch';
const addExtension = function addExtension(filename, ext = '.js') {
let result = `${filename}`;
if (!extname(filename))
result += ext;
return result;
};
const extractors = {
ArrayPattern(names, param) {
for (const element of param.elements) {
if (element)
extractors[element.type](names, element);
}
},
AssignmentPattern(names, param) {
extractors[param.left.type](names, param.left);
},
Identifier(names, param) {
names.push(param.name);
},
MemberExpression() { },
ObjectPattern(names, param) {
for (const prop of param.properties) {
// @ts-ignore Typescript reports that this is not a valid type
if (prop.type === 'RestElement') {
extractors.RestElement(names, prop);
}
else {
extractors[prop.value.type](names, prop.value);
}
}
},
RestElement(names, param) {
extractors[param.argument.type](names, param.argument);
}
};
const extractAssignedNames = function extractAssignedNames(param) {
const names = [];
extractors[param.type](names, param);
return names;
};
const blockDeclarations = {
const: true,
let: true
};
class Scope {
constructor(options = {}) {
this.parent = options.parent;
this.isBlockScope = !!options.block;
this.declarations = Object.create(null);
if (options.params) {
options.params.forEach((param) => {
extractAssignedNames(param).forEach((name) => {
this.declarations[name] = true;
});
});
}
}
addDeclaration(node, isBlockDeclaration, isVar) {
if (!isBlockDeclaration && this.isBlockScope) {
// it's a `var` or function node, and this
// is a block scope, so we need to go up
this.parent.addDeclaration(node, isBlockDeclaration, isVar);
}
else if (node.id) {
extractAssignedNames(node.id).forEach((name) => {
this.declarations[name] = true;
});
}
}
contains(name) {
return this.declarations[name] || (this.parent ? this.parent.contains(name) : false);
}
}
const attachScopes = function attachScopes(ast, propertyName = 'scope') {
let scope = new Scope();
walk(ast, {
enter(n, parent) {
const node = n;
// function foo () {...}
// class Foo {...}
if (/(?:Function|Class)Declaration/.test(node.type)) {
scope.addDeclaration(node, false, false);
}
// var foo = 1
if (node.type === 'VariableDeclaration') {
const { kind } = node;
const isBlockDeclaration = blockDeclarations[kind];
node.declarations.forEach((declaration) => {
scope.addDeclaration(declaration, isBlockDeclaration, true);
});
}
let newScope;
// create new function scope
if (node.type.includes('Function')) {
const func = node;
newScope = new Scope({
parent: scope,
block: false,
params: func.params
});
// named function expressions - the name is considered
// part of the function's scope
if (func.type === 'FunctionExpression' && func.id) {
newScope.addDeclaration(func, false, false);
}
}
// create new for scope
if (/For(?:In|Of)?Statement/.test(node.type)) {
newScope = new Scope({
parent: scope,
block: true
});
}
// create new block scope
if (node.type === 'BlockStatement' && !parent.type.includes('Function')) {
newScope = new Scope({
parent: scope,
block: true
});
}
// catch clause has its own block scope
if (node.type === 'CatchClause') {
newScope = new Scope({
parent: scope,
params: node.param ? [node.param] : [],
block: true
});
}
if (newScope) {
Object.defineProperty(node, propertyName, {
value: newScope,
configurable: true
});
scope = newScope;
}
},
leave(n) {
const node = n;
if (node[propertyName])
scope = scope.parent;
}
});
return scope;
};
// Helper since Typescript can't detect readonly arrays with Array.isArray
function isArray(arg) {
return Array.isArray(arg);
}
function ensureArray(thing) {
if (isArray(thing))
return thing;
if (thing == null)
return [];
return [thing];
}
const normalizePathRegExp = new RegExp(`\\${win32.sep}`, 'g');
const normalizePath = function normalizePath(filename) {
return filename.replace(normalizePathRegExp, posix.sep);
};
function getMatcherString(id, resolutionBase) {
if (resolutionBase === false || isAbsolute(id) || id.startsWith('**')) {
return normalizePath(id);
}
// resolve('') is valid and will default to process.cwd()
const basePath = normalizePath(resolve(resolutionBase || ''))
// escape all possible (posix + win) path characters that might interfere with regex
.replace(/[-^$*+?.()|[\]{}]/g, '\\$&');
// Note that we use posix.join because:
// 1. the basePath has been normalized to use /
// 2. the incoming glob (id) matcher, also uses /
// otherwise Node will force backslash (\) on windows
return posix.join(basePath, normalizePath(id));
}
const createFilter = function createFilter(include, exclude, options) {
const resolutionBase = options && options.resolve;
const getMatcher = (id) => id instanceof RegExp
? id
: {
test: (what) => {
// this refactor is a tad overly verbose but makes for easy debugging
const pattern = getMatcherString(id, resolutionBase);
const fn = pm(pattern, { dot: true });
const result = fn(what);
return result;
}
};
const includeMatchers = ensureArray(include).map(getMatcher);
const excludeMatchers = ensureArray(exclude).map(getMatcher);
if (!includeMatchers.length && !excludeMatchers.length)
return (id) => typeof id === 'string' && !id.includes('\0');
return function result(id) {
if (typeof id !== 'string')
return false;
if (id.includes('\0'))
return false;
const pathId = normalizePath(id);
for (let i = 0; i < excludeMatchers.length; ++i) {
const matcher = excludeMatchers[i];
if (matcher instanceof RegExp) {
matcher.lastIndex = 0;
}
if (matcher.test(pathId))
return false;
}
for (let i = 0; i < includeMatchers.length; ++i) {
const matcher = includeMatchers[i];
if (matcher instanceof RegExp) {
matcher.lastIndex = 0;
}
if (matcher.test(pathId))
return true;
}
return !includeMatchers.length;
};
};
const reservedWords = 'break case class catch const continue debugger default delete do else export extends finally for function if import in instanceof let new return super switch this throw try typeof var void while with yield enum await implements package protected static interface private public';
const builtins = 'arguments Infinity NaN undefined null true false eval uneval isFinite isNaN parseFloat parseInt decodeURI decodeURIComponent encodeURI encodeURIComponent escape unescape Object Function Boolean Symbol Error EvalError InternalError RangeError ReferenceError SyntaxError TypeError URIError Number Math Date String RegExp Array Int8Array Uint8Array Uint8ClampedArray Int16Array Uint16Array Int32Array Uint32Array Float32Array Float64Array Map Set WeakMap WeakSet SIMD ArrayBuffer DataView JSON Promise Generator GeneratorFunction Reflect Proxy Intl';
const forbiddenIdentifiers = new Set(`${reservedWords} ${builtins}`.split(' '));
forbiddenIdentifiers.add('');
const makeLegalIdentifier = function makeLegalIdentifier(str) {
let identifier = str
.replace(/-(\w)/g, (_, letter) => letter.toUpperCase())
.replace(/[^$_a-zA-Z0-9]/g, '_');
if (/\d/.test(identifier[0]) || forbiddenIdentifiers.has(identifier)) {
identifier = `_${identifier}`;
}
return identifier || '_';
};
function stringify(obj) {
return (JSON.stringify(obj) || 'undefined').replace(/[\u2028\u2029]/g, (char) => `\\u${`000${char.charCodeAt(0).toString(16)}`.slice(-4)}`);
}
function serializeArray(arr, indent, baseIndent) {
let output = '[';
const separator = indent ? `\n${baseIndent}${indent}` : '';
for (let i = 0; i < arr.length; i++) {
const key = arr[i];
output += `${i > 0 ? ',' : ''}${separator}${serialize(key, indent, baseIndent + indent)}`;
}
return `${output}${indent ? `\n${baseIndent}` : ''}]`;
}
function serializeObject(obj, indent, baseIndent) {
let output = '{';
const separator = indent ? `\n${baseIndent}${indent}` : '';
const entries = Object.entries(obj);
for (let i = 0; i < entries.length; i++) {
const [key, value] = entries[i];
const stringKey = makeLegalIdentifier(key) === key ? key : stringify(key);
output += `${i > 0 ? ',' : ''}${separator}${stringKey}:${indent ? ' ' : ''}${serialize(value, indent, baseIndent + indent)}`;
}
return `${output}${indent ? `\n${baseIndent}` : ''}}`;
}
function serialize(obj, indent, baseIndent) {
if (typeof obj === 'object' && obj !== null) {
if (Array.isArray(obj))
return serializeArray(obj, indent, baseIndent);
if (obj instanceof Date)
return `new Date(${obj.getTime()})`;
if (obj instanceof RegExp)
return obj.toString();
return serializeObject(obj, indent, baseIndent);
}
if (typeof obj === 'number') {
if (obj === Infinity)
return 'Infinity';
if (obj === -Infinity)
return '-Infinity';
if (obj === 0)
return 1 / obj === Infinity ? '0' : '-0';
if (obj !== obj)
return 'NaN'; // eslint-disable-line no-self-compare
}
if (typeof obj === 'symbol') {
const key = Symbol.keyFor(obj);
// eslint-disable-next-line no-undefined
if (key !== undefined)
return `Symbol.for(${stringify(key)})`;
}
if (typeof obj === 'bigint')
return `${obj}n`;
return stringify(obj);
}
// isWellFormed exists from Node.js 20
const hasStringIsWellFormed = 'isWellFormed' in String.prototype;
function isWellFormedString(input) {
// @ts-expect-error String::isWellFormed exists from ES2024. tsconfig lib is set to ES6
if (hasStringIsWellFormed)
return input.isWellFormed();
// https://github.com/tc39/proposal-is-usv-string/blob/main/README.md#algorithm
return !/\p{Surrogate}/u.test(input);
}
const dataToEsm = function dataToEsm(data, options = {}) {
var _a, _b;
const t = options.compact ? '' : 'indent' in options ? options.indent : '\t';
const _ = options.compact ? '' : ' ';
const n = options.compact ? '' : '\n';
const declarationType = options.preferConst ? 'const' : 'var';
if (options.namedExports === false ||
typeof data !== 'object' ||
Array.isArray(data) ||
data instanceof Date ||
data instanceof RegExp ||
data === null) {
const code = serialize(data, options.compact ? null : t, '');
const magic = _ || (/^[{[\-\/]/.test(code) ? '' : ' '); // eslint-disable-line no-useless-escape
return `export default${magic}${code};`;
}
let maxUnderbarPrefixLength = 0;
for (const key of Object.keys(data)) {
const underbarPrefixLength = (_b = (_a = /^(_+)/.exec(key)) === null || _a === void 0 ? void 0 : _a[0].length) !== null && _b !== void 0 ? _b : 0;
if (underbarPrefixLength > maxUnderbarPrefixLength) {
maxUnderbarPrefixLength = underbarPrefixLength;
}
}
const arbitraryNamePrefix = `${'_'.repeat(maxUnderbarPrefixLength + 1)}arbitrary`;
let namedExportCode = '';
const defaultExportRows = [];
const arbitraryNameExportRows = [];
for (const [key, value] of Object.entries(data)) {
if (key === makeLegalIdentifier(key)) {
if (options.objectShorthand)
defaultExportRows.push(key);
else
defaultExportRows.push(`${key}:${_}${key}`);
namedExportCode += `export ${declarationType} ${key}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
}
else {
defaultExportRows.push(`${stringify(key)}:${_}${serialize(value, options.compact ? null : t, '')}`);
if (options.includeArbitraryNames && isWellFormedString(key)) {
const variableName = `${arbitraryNamePrefix}${arbitraryNameExportRows.length}`;
namedExportCode += `${declarationType} ${variableName}${_}=${_}${serialize(value, options.compact ? null : t, '')};${n}`;
arbitraryNameExportRows.push(`${variableName} as ${JSON.stringify(key)}`);
}
}
}
const arbitraryExportCode = arbitraryNameExportRows.length > 0
? `export${_}{${n}${t}${arbitraryNameExportRows.join(`,${n}${t}`)}${n}};${n}`
: '';
const defaultExportCode = `export default${_}{${n}${t}${defaultExportRows.join(`,${n}${t}`)}${n}};${n}`;
return `${namedExportCode}${arbitraryExportCode}${defaultExportCode}`;
};
function exactRegex(str, flags) {
return new RegExp(`^${combineMultipleStrings(str)}$`, flags);
}
function prefixRegex(str, flags) {
return new RegExp(`^${combineMultipleStrings(str)}`, flags);
}
function suffixRegex(str, flags) {
return new RegExp(`${combineMultipleStrings(str)}$`, flags);
}
const escapeRegexRE = /[-/\\^$*+?.()|[\]{}]/g;
function escapeRegex(str) {
return str.replace(escapeRegexRE, '\\$&');
}
function combineMultipleStrings(str) {
if (Array.isArray(str)) {
const escapeStr = str.map(escapeRegex).join('|');
if (escapeStr && str.length > 1) {
return `(?:${escapeStr})`;
}
return escapeStr;
}
return escapeRegex(str);
}
// TODO: remove this in next major
var index = {
addExtension,
attachScopes,
createFilter,
dataToEsm,
exactRegex,
extractAssignedNames,
makeLegalIdentifier,
normalizePath,
prefixRegex,
suffixRegex
};
export { addExtension, attachScopes, createFilter, dataToEsm, index as default, exactRegex, extractAssignedNames, makeLegalIdentifier, normalizePath, prefixRegex, suffixRegex };
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"type":"module"}
+99
View File
@@ -0,0 +1,99 @@
{
"name": "@rollup/pluginutils",
"version": "5.3.0",
"publishConfig": {
"access": "public"
},
"description": "A set of utility functions commonly used by Rollup plugins",
"license": "MIT",
"repository": {
"url": "rollup/plugins",
"directory": "packages/pluginutils"
},
"author": "Rich Harris <richard.a.harris@gmail.com>",
"homepage": "https://github.com/rollup/plugins/tree/master/packages/pluginutils#readme",
"bugs": {
"url": "https://github.com/rollup/plugins/issues"
},
"main": "./dist/cjs/index.js",
"module": "./dist/es/index.js",
"type": "commonjs",
"exports": {
"types": "./types/index.d.ts",
"import": "./dist/es/index.js",
"default": "./dist/cjs/index.js"
},
"engines": {
"node": ">=14.0.0"
},
"files": [
"dist",
"!dist/**/*.map",
"types",
"README.md",
"LICENSE"
],
"keywords": [
"rollup",
"plugin",
"utils"
],
"peerDependencies": {
"rollup": "^1.20.0||^2.0.0||^3.0.0||^4.0.0"
},
"peerDependenciesMeta": {
"rollup": {
"optional": true
}
},
"dependencies": {
"@types/estree": "^1.0.0",
"estree-walker": "^2.0.2",
"picomatch": "^4.0.2"
},
"devDependencies": {
"@rollup/plugin-commonjs": "^23.0.0",
"@rollup/plugin-node-resolve": "^15.0.0",
"@rollup/plugin-typescript": "^9.0.1",
"@types/node": "^14.18.30",
"@types/picomatch": "^2.3.0",
"acorn": "^8.8.0",
"rollup": "^4.0.0-24",
"typescript": "^4.8.3"
},
"types": "./types/index.d.ts",
"ava": {
"extensions": [
"ts"
],
"require": [
"ts-node/register"
],
"workerThreads": false,
"files": [
"!**/fixtures/**",
"!**/helpers/**",
"!**/recipes/**",
"!**/types.ts"
]
},
"nyc": {
"extension": [
".js",
".ts"
]
},
"scripts": {
"build": "rollup -c",
"ci:coverage": "nyc pnpm test && nyc report --reporter=text-lcov > coverage.lcov",
"ci:lint": "pnpm build && pnpm lint",
"ci:lint:commits": "commitlint --from=${CIRCLE_BRANCH} --to=${CIRCLE_SHA1}",
"ci:test": "pnpm test -- --verbose",
"prebuild": "del-cli dist",
"prerelease": "pnpm build",
"pretest": "pnpm build --sourcemap",
"release": "pnpm --workspace-root package:release $(pwd)",
"test": "ava",
"test:ts": "tsc --noEmit"
}
}
+125
View File
@@ -0,0 +1,125 @@
import type { BaseNode } from 'estree';
export interface AttachedScope {
parent?: AttachedScope;
isBlockScope: boolean;
declarations: { [key: string]: boolean };
addDeclaration(node: BaseNode, isBlockDeclaration: boolean, isVar: boolean): void;
contains(name: string): boolean;
}
export interface DataToEsmOptions {
compact?: boolean;
/**
* @desc When this option is set, dataToEsm will generate a named export for keys that
* are not a valid identifier, by leveraging the "Arbitrary Module Namespace Identifier
* Names" feature. See: https://github.com/tc39/ecma262/pull/2154
*/
includeArbitraryNames?: boolean;
indent?: string;
namedExports?: boolean;
objectShorthand?: boolean;
preferConst?: boolean;
}
/**
* A valid `picomatch` glob pattern, or array of patterns.
*/
export type FilterPattern = ReadonlyArray<string | RegExp> | string | RegExp | null;
/**
* Adds an extension to a module ID if one does not exist.
*/
export function addExtension(filename: string, ext?: string): string;
/**
* Attaches `Scope` objects to the relevant nodes of an AST.
* Each `Scope` object has a `scope.contains(name)` method that returns `true`
* if a given name is defined in the current scope or a parent scope.
*/
export function attachScopes(ast: BaseNode, propertyName?: string): AttachedScope;
/**
* Constructs a filter function which can be used to determine whether or not
* certain modules should be operated upon.
* @param include If `include` is omitted or has zero length, filter will return `true` by default.
* @param exclude ID must not match any of the `exclude` patterns.
* @param options Optionally resolves the patterns against a directory other than `process.cwd()`.
* If a `string` is specified, then the value will be used as the base directory.
* Relative paths will be resolved against `process.cwd()` first.
* If `false`, then the patterns will not be resolved against any directory.
* This can be useful if you want to create a filter for virtual module names.
*/
export function createFilter(
include?: FilterPattern,
exclude?: FilterPattern,
options?: { resolve?: string | false | null }
): (id: string | unknown) => boolean;
/**
* Transforms objects into tree-shakable ES Module imports.
* @param data An object to transform into an ES module.
*/
export function dataToEsm(data: unknown, options?: DataToEsmOptions): string;
/**
* Constructs a RegExp that matches the exact string specified.
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function exactRegex(str: string | string[], flags?: string): RegExp;
/**
* Extracts the names of all assignment targets based upon specified patterns.
* @param param An `acorn` AST Node.
*/
export function extractAssignedNames(param: BaseNode): string[];
/**
* Constructs a bundle-safe identifier from a `string`.
*/
export function makeLegalIdentifier(str: string): string;
/**
* Converts path separators to forward slash.
*/
export function normalizePath(filename: string): string;
/**
* Constructs a RegExp that matches a value that has the specified prefix.
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function prefixRegex(str: string | string[], flags?: string): RegExp;
/**
* Constructs a RegExp that matches a value that has the specified suffix.
* @param str the string to match.
* @param flags flags for the RegExp.
*/
export function suffixRegex(str: string | string[], flags?: string): RegExp;
export type AddExtension = typeof addExtension;
export type AttachScopes = typeof attachScopes;
export type CreateFilter = typeof createFilter;
export type ExactRegex = typeof exactRegex;
export type ExtractAssignedNames = typeof extractAssignedNames;
export type MakeLegalIdentifier = typeof makeLegalIdentifier;
export type NormalizePath = typeof normalizePath;
export type DataToEsm = typeof dataToEsm;
export type PrefixRegex = typeof prefixRegex;
export type SuffixRegex = typeof suffixRegex;
declare const defaultExport: {
addExtension: AddExtension;
attachScopes: AttachScopes;
createFilter: CreateFilter;
dataToEsm: DataToEsm;
exactRegex: ExactRegex;
extractAssignedNames: ExtractAssignedNames;
makeLegalIdentifier: MakeLegalIdentifier;
normalizePath: NormalizePath;
prefixRegex: PrefixRegex;
suffixRegex: SuffixRegex;
};
export default defaultExport;
+7
View File
@@ -0,0 +1,7 @@
Copyright (c) 2020 [these people](https://github.com/sveltejs/kit/graphs/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.
+15
View File
@@ -0,0 +1,15 @@
# @sveltejs/adapter-node
[Adapter](https://svelte.dev/docs/kit/adapters) for SvelteKit apps that generates a standalone Node server.
## Docs
[Docs](https://svelte.dev/docs/kit/adapter-node)
## Changelog
[The Changelog for this package is available on GitHub](https://github.com/sveltejs/kit/blob/main/packages/adapter-node/CHANGELOG.md).
## License
[MIT](LICENSE)
+12
View File
@@ -0,0 +1,12 @@
import http from 'node:http';
declare global {
namespace App {
export interface Platform {
/**
* The original Node request object (https://nodejs.org/api/http.html#class-httpincomingmessage)
*/
req: http.IncomingMessage;
}
}
}
+94
View File
@@ -0,0 +1,94 @@
import process from 'node:process';
/* global ENV_PREFIX */
const expected = new Set([
'SOCKET_PATH',
'HOST',
'PORT',
'ORIGIN',
'XFF_DEPTH',
'ADDRESS_HEADER',
'PROTOCOL_HEADER',
'HOST_HEADER',
'PORT_HEADER',
'BODY_SIZE_LIMIT',
'SHUTDOWN_TIMEOUT',
'IDLE_TIMEOUT',
'KEEP_ALIVE_TIMEOUT',
'HEADERS_TIMEOUT'
]);
const expected_unprefixed = new Set(['LISTEN_PID', 'LISTEN_FDS']);
if (ENV_PREFIX) {
for (const name in process.env) {
if (name.startsWith(ENV_PREFIX)) {
const unprefixed = name.slice(ENV_PREFIX.length);
if (!expected.has(unprefixed)) {
throw new Error(
`You should change envPrefix (${ENV_PREFIX}) to avoid conflicts with existing environment variables — unexpectedly saw ${name}`
);
}
}
}
}
/**
* @param {string} name
* @param {any} fallback
*/
function env(name, fallback) {
const prefix = expected_unprefixed.has(name) ? '' : ENV_PREFIX;
const prefixed = prefix + name;
return prefixed in process.env ? process.env[prefixed] : fallback;
}
const integer_regexp = /^\d+$/;
/**
* Throw a consistently-structured parsing error for environment variables.
* @param {string} name
* @param {any} value
* @param {string} description
* @returns {never}
*/
function parsing_error(name, value, description) {
throw new Error(
`Invalid value for environment variable ${name}: ${JSON.stringify(value)} (${description})`
);
}
/**
* Check the environment for a timeout value (non-negative integer) in seconds.
* @param {string} name
* @param {number} [fallback]
* @returns {number | undefined}
*/
function timeout_env(name, fallback) {
const raw = env(name, fallback);
if (!raw) {
return fallback;
}
if (!integer_regexp.test(raw)) {
parsing_error(name, raw, 'should be a non-negative integer');
}
const parsed = Number.parseInt(raw, 10);
// We don't technically need to check `Number.isNaN` because the value already passed the regexp test.
// However, just in case there's some new codepath introduced somewhere down the line, it's probably good
// to stick this in here.
if (Number.isNaN(parsed)) {
parsing_error(name, raw, 'should be a non-negative integer');
}
if (parsed < 0) {
parsing_error(name, raw, 'should be a non-negative integer');
}
return parsed;
}
export { env, timeout_env };
File diff suppressed because it is too large Load Diff
+345
View File
@@ -0,0 +1,345 @@
import http from 'node:http';
import process from 'node:process';
import { handler } from 'HANDLER';
import { env, timeout_env } from 'ENV';
import { setImmediate } from 'node:timers';
import * as qs from 'node:querystring';
/**
* @param {string|RegExp} input The route pattern
* @param {boolean} [loose] Allow open-ended matching. Ignored with `RegExp` input.
*/
function parse$1(input, loose) {
if (input instanceof RegExp) return { keys:false, pattern:input };
var c, o, tmp, ext, keys=[], pattern='', arr = input.split('/');
arr[0] || arr.shift();
while (tmp = arr.shift()) {
c = tmp[0];
if (c === '*') {
keys.push(c);
pattern += tmp[1] === '?' ? '(?:/(.*))?' : '/(.*)';
} else if (c === ':') {
o = tmp.indexOf('?', 1);
ext = tmp.indexOf('.', 1);
keys.push( tmp.substring(1, !!~o ? o : !!~ext ? ext : tmp.length) );
pattern += !!~o && !~ext ? '(?:/([^/]+?))?' : '/([^/]+?)';
if (!!~ext) pattern += (!!~o ? '?' : '') + '\\' + tmp.substring(ext);
} else {
pattern += '/' + tmp;
}
}
return {
keys: keys,
pattern: new RegExp('^' + pattern + (loose ? '(?=$|\/)' : '\/?$'), 'i')
};
}
const MAP = {
"": 0,
GET: 1,
HEAD: 2,
PATCH: 3,
OPTIONS: 4,
CONNECT: 5,
DELETE: 6,
TRACE: 7,
POST: 8,
PUT: 9,
};
class Trouter {
constructor() {
this.routes = [];
this.all = this.add.bind(this, '');
this.get = this.add.bind(this, 'GET');
this.head = this.add.bind(this, 'HEAD');
this.patch = this.add.bind(this, 'PATCH');
this.options = this.add.bind(this, 'OPTIONS');
this.connect = this.add.bind(this, 'CONNECT');
this.delete = this.add.bind(this, 'DELETE');
this.trace = this.add.bind(this, 'TRACE');
this.post = this.add.bind(this, 'POST');
this.put = this.add.bind(this, 'PUT');
}
use(route, ...fns) {
let handlers = [].concat.apply([], fns);
let { keys, pattern } = parse$1(route, true);
this.routes.push({ keys, pattern, method: '', handlers, midx: MAP[''] });
return this;
}
add(method, route, ...fns) {
let { keys, pattern } = parse$1(route);
let handlers = [].concat.apply([], fns);
this.routes.push({ keys, pattern, method, handlers, midx: MAP[method] });
return this;
}
find(method, url) {
let midx = MAP[method];
let isHEAD = (midx === 2);
let i=0, j=0, k, tmp, arr=this.routes;
let matches=[], params={}, handlers=[];
for (; i < arr.length; i++) {
tmp = arr[i];
if (tmp.midx === midx || tmp.midx === 0 || (isHEAD && tmp.midx===1) ) {
if (tmp.keys === false) {
matches = tmp.pattern.exec(url);
if (matches === null) continue;
if (matches.groups !== void 0) for (k in matches.groups) params[k]=matches.groups[k];
tmp.handlers.length > 1 ? (handlers=handlers.concat(tmp.handlers)) : handlers.push(tmp.handlers[0]);
} else if (tmp.keys.length > 0) {
matches = tmp.pattern.exec(url);
if (matches === null) continue;
for (j=0; j < tmp.keys.length;) params[tmp.keys[j]]=matches[++j];
tmp.handlers.length > 1 ? (handlers=handlers.concat(tmp.handlers)) : handlers.push(tmp.handlers[0]);
} else if (tmp.pattern.test(url)) {
tmp.handlers.length > 1 ? (handlers=handlers.concat(tmp.handlers)) : handlers.push(tmp.handlers[0]);
}
} // else not a match
}
return { params, handlers };
}
}
/**
* @typedef ParsedURL
* @type {import('.').ParsedURL}
*/
/**
* @typedef Request
* @property {string} url
* @property {ParsedURL} _parsedUrl
*/
/**
* @param {Request} req
* @returns {ParsedURL|void}
*/
function parse(req) {
let raw = req.url;
if (raw == null) return;
let prev = req._parsedUrl;
if (prev && prev.raw === raw) return prev;
let pathname=raw, search='', query;
if (raw.length > 1) {
let idx = raw.indexOf('?', 1);
if (idx !== -1) {
search = raw.substring(idx);
pathname = raw.substring(0, idx);
if (search.length > 1) {
query = qs.parse(search.substring(1));
}
}
}
return req._parsedUrl = { pathname, search, query, raw };
}
function onError(err, req, res) {
let code = typeof err.status === 'number' && err.status;
code = res.statusCode = (code && code >= 100 ? code : 500);
if (typeof err === 'string' || Buffer.isBuffer(err)) res.end(err);
else res.end(err.message || http.STATUS_CODES[code]);
}
const mount = fn => fn instanceof Polka ? fn.attach : fn;
class Polka extends Trouter {
constructor(opts={}) {
super();
this.parse = parse;
this.server = opts.server;
this.handler = this.handler.bind(this);
this.onError = opts.onError || onError; // catch-all handler
this.onNoMatch = opts.onNoMatch || this.onError.bind(null, { status: 404 });
this.attach = (req, res) => setImmediate(this.handler, req, res);
}
use(base, ...fns) {
if (base === '/') {
super.use(base, fns.map(mount));
} else if (typeof base === 'function' || base instanceof Polka) {
super.use('/', [base, ...fns].map(mount));
} else {
super.use(base,
(req, _, next) => {
if (typeof base === 'string') {
let len = base.length;
base.startsWith('/') || len++;
req.url = req.url.substring(len) || '/';
req.path = req.path.substring(len) || '/';
} else {
req.url = req.url.replace(base, '') || '/';
req.path = req.path.replace(base, '') || '/';
}
if (req.url.charAt(0) !== '/') {
req.url = '/' + req.url;
}
next();
},
fns.map(mount),
(req, _, next) => {
req.path = req._parsedUrl.pathname;
req.url = req.path + req._parsedUrl.search;
next();
}
);
}
return this; // chainable
}
listen() {
(this.server = this.server || http.createServer()).on('request', this.attach);
this.server.listen.apply(this.server, arguments);
return this;
}
handler(req, res, next) {
let info = this.parse(req), path = info.pathname;
let obj = this.find(req.method, req.path=path);
req.url = path + info.search;
req.originalUrl = req.originalUrl || req.url;
req.query = info.query || {};
req.search = info.search;
req.params = obj.params;
if (path.length > 1 && path.indexOf('%', 1) !== -1) {
for (let k in req.params) {
try { req.params[k] = decodeURIComponent(req.params[k]); }
catch (e) { /* malform uri segment */ }
}
}
let i=0, arr=obj.handlers.concat(this.onNoMatch), len=arr.length;
let loop = async () => res.finished || (i < len) && arr[i++](req, res, next);
(next = next || (err => err ? this.onError(err, req, res, next) : loop().catch(next)))(); // init
}
}
function polka (opts) {
return new Polka(opts);
}
const path = env('SOCKET_PATH', false);
const host = env('HOST', '0.0.0.0');
const port = env('PORT', !path && '3000');
const shutdown_timeout = parseInt(env('SHUTDOWN_TIMEOUT', '30'));
const idle_timeout = parseInt(env('IDLE_TIMEOUT', '0'));
const listen_pid = parseInt(env('LISTEN_PID', '0'));
const listen_fds = parseInt(env('LISTEN_FDS', '0'));
// https://www.freedesktop.org/software/systemd/man/latest/sd_listen_fds.html
const SD_LISTEN_FDS_START = 3;
if (listen_pid !== 0 && listen_pid !== process.pid) {
throw new Error(`received LISTEN_PID ${listen_pid} but current process id is ${process.pid}`);
}
if (listen_fds > 1) {
throw new Error(
`only one socket is allowed for socket activation, but LISTEN_FDS was set to ${listen_fds}`
);
}
const socket_activation = listen_pid === process.pid && listen_fds === 1;
let requests = 0;
/** @type {NodeJS.Timeout | void} */
let shutdown_timeout_id;
/** @type {NodeJS.Timeout | void} */
let idle_timeout_id;
// Initialize the HTTP server here so that we can set properties before starting to listen.
// Otherwise, polka delays creating the server until listen() is called. Settings these
// properties after the server has started listening could lead to race conditions.
const httpServer = http.createServer();
const keep_alive_timeout = timeout_env('KEEP_ALIVE_TIMEOUT');
if (keep_alive_timeout !== undefined) {
// Convert the keep-alive timeout from seconds to milliseconds (the unit Node.js expects).
httpServer.keepAliveTimeout = keep_alive_timeout * 1000;
}
const headers_timeout = timeout_env('HEADERS_TIMEOUT');
if (headers_timeout !== undefined) {
// Convert the headers timeout from seconds to milliseconds (the unit Node.js expects).
httpServer.headersTimeout = headers_timeout * 1000;
}
const server = polka({ server: httpServer }).use(handler);
if (socket_activation) {
server.listen({ fd: SD_LISTEN_FDS_START }, () => {
console.log(`Listening on file descriptor ${SD_LISTEN_FDS_START}`);
});
} else {
server.listen({ path, host, port }, () => {
console.log(`Listening on ${path || `http://${host}:${port}`}`);
});
}
/** @param {'SIGINT' | 'SIGTERM' | 'IDLE'} reason */
function graceful_shutdown(reason) {
if (shutdown_timeout_id) return;
// If a connection was opened with a keep-alive header close() will wait for the connection to
// time out rather than close it even if it is not handling any requests, so call this first
httpServer.closeIdleConnections();
httpServer.close((error) => {
// occurs if the server is already closed
if (error) return;
if (shutdown_timeout_id) {
clearTimeout(shutdown_timeout_id);
}
if (idle_timeout_id) {
clearTimeout(idle_timeout_id);
}
// @ts-expect-error custom events cannot be typed
process.emit('sveltekit:shutdown', reason);
});
shutdown_timeout_id = setTimeout(() => httpServer.closeAllConnections(), shutdown_timeout * 1000);
}
httpServer.on(
'request',
/** @param {import('node:http').IncomingMessage} req */
(req) => {
requests++;
if (socket_activation && idle_timeout_id) {
idle_timeout_id = clearTimeout(idle_timeout_id);
}
req.on('close', () => {
requests--;
if (shutdown_timeout_id) {
// close connections as soon as they become idle, so they don't accept new requests
httpServer.closeIdleConnections();
}
if (requests === 0 && socket_activation && idle_timeout) {
idle_timeout_id = setTimeout(() => graceful_shutdown('IDLE'), idle_timeout * 1000);
}
});
}
);
process.on('SIGTERM', graceful_shutdown);
process.on('SIGINT', graceful_shutdown);
export { host, path, port, server };
+32
View File
@@ -0,0 +1,32 @@
import buffer from 'node:buffer';
import { webcrypto } from 'node:crypto';
// `buffer.File` was added in Node 18.13.0 while the `File` global was added in Node 20.0.0
const File = /** @type {import('node:buffer') & { File?: File}} */ (buffer).File;
/** @type {Record<string, any>} */
const globals = {
crypto: webcrypto,
File
};
// exported for dev/preview and node environments
/**
* Make various web APIs available as globals:
* - `crypto`
* - `File`
*/
function installPolyfills() {
for (const name in globals) {
if (name in globalThis) continue;
Object.defineProperty(globalThis, name, {
enumerable: true,
configurable: true,
writable: true,
value: globals[name]
});
}
}
installPolyfills();
+15
View File
@@ -0,0 +1,15 @@
import { Adapter } from '@sveltejs/kit';
import './ambient.js';
declare global {
const ENV_PREFIX: string;
const PRECOMPRESS: boolean;
}
interface AdapterOptions {
out?: string;
precompress?: boolean;
envPrefix?: string;
}
export default function plugin(options?: AdapterOptions): Adapter;
+128
View File
@@ -0,0 +1,128 @@
import { readFileSync, writeFileSync } from 'node:fs';
import { fileURLToPath } from 'node:url';
import { rollup } from 'rollup';
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import json from '@rollup/plugin-json';
/**
* @template T
* @template {keyof T} K
* @typedef {Partial<Omit<T, K>> & Required<Pick<T, K>>} PartialExcept
*/
/**
* We use a custom `Builder` type here to support the minimum version of SvelteKit.
* @typedef {PartialExcept<import('@sveltejs/kit').Builder, 'log' | 'rimraf' | 'mkdirp' | 'config' | 'prerendered' | 'routes' | 'createEntries' | 'findServerAssets' | 'generateFallback' | 'generateEnvModule' | 'generateManifest' | 'getBuildDirectory' | 'getClientDirectory' | 'getServerDirectory' | 'getAppPath' | 'writeClient' | 'writePrerendered' | 'writePrerendered' | 'writeServer' | 'copy' | 'compress'>} Builder2_4_0
*/
const files = fileURLToPath(new URL('./files', import.meta.url).href);
/** @type {import('./index.js').default} */
export default function (opts = {}) {
const { out = 'build', precompress = true, envPrefix = '' } = opts;
return {
name: '@sveltejs/adapter-node',
/** @param {Builder2_4_0} builder */
async adapt(builder) {
const tmp = builder.getBuildDirectory('adapter-node');
builder.rimraf(out);
builder.rimraf(tmp);
builder.mkdirp(tmp);
builder.log.minor('Copying assets');
builder.writeClient(`${out}/client${builder.config.kit.paths.base}`);
builder.writePrerendered(`${out}/prerendered${builder.config.kit.paths.base}`);
if (precompress) {
builder.log.minor('Compressing assets');
await Promise.all([
builder.compress(`${out}/client`),
builder.compress(`${out}/prerendered`)
]);
}
builder.log.minor('Building server');
builder.writeServer(tmp);
writeFileSync(
`${tmp}/manifest.js`,
[
`export const manifest = ${builder.generateManifest({ relativePath: './' })};`,
`export const prerendered = new Set(${JSON.stringify(builder.prerendered.paths)});`,
`export const base = ${JSON.stringify(builder.config.kit.paths.base)};`
].join('\n\n')
);
const pkg = JSON.parse(readFileSync('package.json', 'utf8'));
/** @type {Record<string, string>} */
const input = {
index: `${tmp}/index.js`,
manifest: `${tmp}/manifest.js`
};
if (builder.hasServerInstrumentationFile?.()) {
input['instrumentation.server'] = `${tmp}/instrumentation.server.js`;
}
// we bundle the Vite output so that deployments only need
// their production dependencies. Anything in devDependencies
// will get included in the bundled code
const bundle = await rollup({
input,
external: [
// dependencies could have deep exports, so we need a regex
...Object.keys(pkg.dependencies || {}).map((d) => new RegExp(`^${d}(\\/.*)?$`))
],
plugins: [
nodeResolve({
preferBuiltins: true,
exportConditions: ['node']
}),
// @ts-ignore https://github.com/rollup/plugins/issues/1329
commonjs({ strictRequires: true }),
// @ts-ignore https://github.com/rollup/plugins/issues/1329
json()
]
});
await bundle.write({
dir: `${out}/server`,
format: 'esm',
sourcemap: true,
chunkFileNames: 'chunks/[name]-[hash].js'
});
builder.copy(files, out, {
replace: {
ENV: './env.js',
HANDLER: './handler.js',
MANIFEST: './server/manifest.js',
SERVER: './server/index.js',
SHIMS: './shims.js',
ENV_PREFIX: JSON.stringify(envPrefix),
PRECOMPRESS: JSON.stringify(precompress)
}
});
if (builder.hasServerInstrumentationFile?.()) {
builder.instrument?.({
entrypoint: `${out}/index.js`,
instrumentation: `${out}/server/instrumentation.server.js`,
module: {
exports: ['path', 'host', 'port', 'server']
}
});
}
},
supports: {
read: () => true,
instrumentation: () => true
}
};
}
+62
View File
@@ -0,0 +1,62 @@
{
"name": "@sveltejs/adapter-node",
"version": "5.5.3",
"description": "Adapter for SvelteKit apps that generates a standalone Node server",
"keywords": [
"adapter",
"deploy",
"hosting",
"node.js",
"svelte",
"sveltekit"
],
"repository": {
"type": "git",
"url": "git+https://github.com/sveltejs/kit.git",
"directory": "packages/adapter-node"
},
"license": "MIT",
"homepage": "https://svelte.dev/docs/kit/adapter-node",
"type": "module",
"exports": {
".": {
"types": "./index.d.ts",
"import": "./index.js"
},
"./package.json": "./package.json"
},
"types": "index.d.ts",
"files": [
"files",
"index.js",
"index.d.ts",
"ambient.d.ts"
],
"devDependencies": {
"@polka/url": "^1.0.0-next.28",
"@sveltejs/vite-plugin-svelte": "^6.0.0-next.3",
"@types/node": "^18.19.119",
"polka": "^1.0.0-next.28",
"sirv": "^3.0.2",
"typescript": "^5.3.3",
"vitest": "^4.0.0",
"@sveltejs/kit": "^2.51.0"
},
"dependencies": {
"@rollup/plugin-commonjs": "^29.0.0",
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.0",
"rollup": "^4.9.5"
},
"peerDependencies": {
"@sveltejs/kit": "^2.4.0"
},
"scripts": {
"dev": "rollup -cw",
"build": "rollup -c",
"test": "vitest run",
"check": "tsc",
"lint": "prettier --check .",
"format": "pnpm lint --write"
}
}
Generated Vendored Executable
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
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
Generated Vendored Executable
+16
View File
@@ -0,0 +1,16 @@
# Installation
> `npm install --save @types/resolve`
# Summary
This package contains type definitions for resolve (https://github.com/browserify/resolve).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/resolve.
### Additional Details
* Last updated: Thu, 21 Apr 2022 18:01:43 GMT
* Dependencies: none
* Global values: none
# Credits
These definitions were written by [Mario Nebl](https://github.com/marionebl), [Klaus Meinhardt](https://github.com/ajafff), and [Jordan Harband](https://github.com/ljharb).
Generated Vendored Executable
+175
View File
@@ -0,0 +1,175 @@
// Type definitions for resolve 1.20.0
// Project: https://github.com/browserify/resolve
// Definitions by: Mario Nebl <https://github.com/marionebl>
// Klaus Meinhardt <https://github.com/ajafff>
// Jordan Harband <https://github.com/ljharb>
// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped
interface PackageMeta {
name: string;
version: string;
[key: string]: any;
}
interface ToString {
toString(): string;
}
type StringOrToString = string | ToString;
/**
* Callback invoked when resolving asynchronously
*
* @param error
* @param resolved Absolute path to resolved identifier
*/
type resolveCallback = (err: Error | null, resolved?: string, pkg?: PackageMeta) => void;
/**
* Callback invoked when checking if a file or directory exists
*
* @param error
* @param exists If the given file or directory exists
*/
type existsCallback = (err: Error | null, isFile?: boolean) => void;
/**
* Callback invoked when reading a file
*
* @param error
* @param isFile If the given file exists
*/
type readFileCallback = (err: Error | null, file?: StringOrToString) => void;
/**
* Callback invoked when resolving a potential symlink
*
* @param error
* @param resolved Absolute path to the resolved file
*/
type realpathCallback = (err: Error | null, resolved?: string) => void;
/**
* Callback invoked when reading and parsing a package.json file
*
* @param error
* @param resolved Absolute path to the resolved file
*/
type readPackageCallback = (err: Error | null, package?: Record<string, unknown>) => void;
/**
* Asynchronously resolve the module path string id into cb(err, res [, pkg]), where pkg (if defined) is the data from package.json
*
* @param id Identifier to resolve
* @param callback
*/
declare function resolve(id: string, cb: resolveCallback): void;
/**
* Asynchronously resolve the module path string id into cb(err, res [, pkg]), where pkg (if defined) is the data from package.json
*
* @param id Identifier to resolve
* @param options Options to use for resolving, optional.
* @param callback
*/
declare function resolve(id: string, opts: resolve.AsyncOpts, cb: resolveCallback): void;
/**
* Synchronously resolve the module path string id, returning the result and throwing an error when id can't be resolved.
*
* @param id Identifier to resolve
* @param options Options to use for resolving, optional.
*/
declare function resolveSync(id: string, opts?: resolve.SyncOpts): string;
/**
* Return whether a package is in core
*/
declare function resolveIsCore(id: string): boolean | undefined;
// https://github.com/Microsoft/TypeScript/issues/3496#issuecomment-128553540
type JSONValue = string | number | boolean | JSONObject | JSONArray;
interface JSONObject {
[x: string]: JSONValue;
}
interface JSONArray extends Array<JSONValue> { }
declare namespace resolve {
export type PackageJSON = JSONObject;
interface Opts {
/** directory to begin resolving from (defaults to __dirname) */
basedir?: string | undefined;
/** package.json data applicable to the module being loaded */
package?: any;
/** set to false to exclude node core modules (e.g. fs) from the search */
includeCoreModules?: boolean | undefined;
/** array of file extensions to search in order (defaults to ['.js']) */
extensions?: string | ReadonlyArray<string> | undefined;
/** transform the parsed package.json contents before looking at the "main" field */
packageFilter?: ((pkg: PackageJSON, pkgFile: string, dir: string) => PackageJSON) | undefined;
/** transform a path within a package */
pathFilter?: ((pkg: PackageJSON, path: string, relativePath: string) => string) | undefined;
/** require.paths array to use if nothing is found on the normal node_modules recursive walk (probably don't use this) */
paths?: string | ReadonlyArray<string> | undefined;
/** return the list of candidate paths where the packages sources may be found (probably don't use this) */
packageIterator?: ((request: string, start: string, getPackageCandidates: () => string[], opts: Opts) => string[]) | undefined;
/** directory (or directories) in which to recursively look for modules. (default to 'node_modules') */
moduleDirectory?: string | ReadonlyArray<string> | undefined;
/**
* if true, doesn't resolve `basedir` to real path before resolving.
* This is the way Node resolves dependencies when executed with the --preserve-symlinks flag.
*
* Note: this property is currently true by default but it will be changed to false in the next major version because Node's resolution
* algorithm does not preserve symlinks by default.
*/
preserveSymlinks?: boolean | undefined;
}
interface BaseAsyncOpts extends Opts {
/** function to asynchronously test whether a file exists */
isFile?: ((file: string, cb: existsCallback) => void) | undefined;
/** function to asynchronously test whether a directory exists */
isDirectory?: ((directory: string, cb: existsCallback) => void) | undefined;
/** function to asynchronously resolve a potential symlink to its real path */
realpath?: ((file: string, cb: realpathCallback) => void) | undefined;
}
export type AsyncOpts = BaseAsyncOpts & ({
/** how to read files asynchronously (defaults to fs.readFile) */
readFile?: ((file: string, cb: readFileCallback) => void) | undefined;
/** function to asynchronously read and parse a package.json file */
readPackage?: never | undefined;
} | {
/** how to read files asynchronously (defaults to fs.readFile) */
readFile?: never | undefined
/** function to asynchronously read and parse a package.json file */
readPackage?: ((readFile: (file: string, cb: readFileCallback) => void, pkgfile: string, cb: readPackageCallback) => void) | undefined;
});
interface BaseSyncOpts extends Opts {
/** function to synchronously test whether a file exists */
isFile?: ((file: string) => boolean) | undefined;
/** function to synchronously test whether a directory exists */
isDirectory?: ((directory: string) => boolean) | undefined;
/** function to synchronously resolve a potential symlink to its real path */
realpathSync?: ((file: string) => string) | undefined;
}
export type SyncOpts = BaseSyncOpts & ({
/** how to read files synchronously (defaults to fs.readFileSync) */
readFileSync?: ((file: string) => StringOrToString) | undefined;
/** function to synchronously read and parse a package.json file */
readPackageSync?: never | undefined;
} | {
/** how to read files synchronously (defaults to fs.readFileSync) */
readFileSync?: never | undefined;
/** function to synchronously read and parse a package.json file */
readPackageSync?: ((readFileSync: (file: string) => StringOrToString, pkgfile: string) => Record<string, unknown> | undefined) | undefined;
});
export var sync: typeof resolveSync;
export var isCore: typeof resolveIsCore;
}
export = resolve;
Generated Vendored Executable
+35
View File
@@ -0,0 +1,35 @@
{
"name": "@types/resolve",
"version": "1.20.2",
"description": "TypeScript definitions for resolve",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/resolve",
"license": "MIT",
"contributors": [
{
"name": "Mario Nebl",
"url": "https://github.com/marionebl",
"githubUsername": "marionebl"
},
{
"name": "Klaus Meinhardt",
"url": "https://github.com/ajafff",
"githubUsername": "ajafff"
},
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb",
"githubUsername": "ljharb"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/resolve"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "f17c01e45c248ed2430e1f5d8b89310de423f1564ee420b04ea91177066c05f1",
"typeScriptVersion": "3.9"
}
+24
View File
@@ -0,0 +1,24 @@
The MIT License
Copyright (c) 2013 James Halliday (mail@substack.net)
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.
+3
View File
@@ -0,0 +1,3 @@
var commondir = require('../');
var dir = commondir(process.argv.slice(2));
console.log(dir);
+29
View File
@@ -0,0 +1,29 @@
var path = require('path');
module.exports = function (basedir, relfiles) {
if (relfiles) {
var files = relfiles.map(function (r) {
return path.resolve(basedir, r);
});
}
else {
var files = basedir;
}
var res = files.slice(1).reduce(function (ps, file) {
if (!file.match(/^([A-Za-z]:)?\/|\\/)) {
throw new Error('relative path without a basedir');
}
var xs = file.split(/\/+|\\+/);
for (
var i = 0;
ps[i] === xs[i] && i < Math.min(ps.length, xs.length);
i++
);
return ps.slice(0, i);
}, files[0].split(/\/+|\\+/));
// Windows correctly handles paths with forward-slashes
return res.length > 1 ? res.join('/') : '/'
};
+34
View File
@@ -0,0 +1,34 @@
{
"name": "commondir",
"version": "1.0.1",
"description": "compute the closest common parent for file paths",
"main": "index.js",
"dependencies": {},
"devDependencies": {
"tape": "^3.5.0"
},
"scripts": {
"test": "tape test/*.js"
},
"repository": {
"type": "git",
"url": "http://github.com/substack/node-commondir.git"
},
"keywords": [
"common",
"path",
"directory",
"file",
"parent",
"root"
],
"author": {
"name": "James Halliday",
"email": "mail@substack.net",
"url": "http://substack.net"
},
"license": "MIT",
"engine": {
"node": ">=0.4"
}
}
+48
View File
@@ -0,0 +1,48 @@
# commondir
compute the closest common parent directory among an array of directories
# example
``` js
var commondir = require('commondir');
var dir = commondir(process.argv.slice(2))
console.log(dir);
```
output:
```
$ node dir.js /x/y/z /x/y /x/y/w/q
/x/y
$ node ../baz ../../foo/quux ./bizzy
/foo
```
# methods
``` js
var commondir = require('commondir');
```
## commondir(absolutePaths)
Compute the closest common parent directory for an array `absolutePaths`.
## commondir(basedir, relativePaths)
Compute the closest common parent directory for an array `relativePaths` which
will be resolved for each `dir` in `relativePaths` according to:
`path.resolve(basedir, dir)`.
# install
With [npm](https://npmjs.org) do:
```
npm install commondir
```
# license
MIT
+55
View File
@@ -0,0 +1,55 @@
var test = require('tape');
var commondir = require('../');
test('common', function (t) {
t.equal(
commondir([ '/foo', '//foo/bar', '/foo//bar/baz' ]),
'/foo'
);
t.equal(
commondir([ '/a/b/c', '/a/b', '/a/b/c/d/e' ]),
'/a/b'
);
t.equal(
commondir([ '/x/y/z/w', '/xy/z', '/x/y/z' ]),
'/'
);
t.equal(
commondir([ 'X:\\foo', 'X:\\\\foo\\bar', 'X://foo/bar/baz' ]),
'X:/foo'
);
t.equal(
commondir([ 'X:\\a\\b\\c', 'X:\\a\\b', 'X:\\a\\b\\c\\d\\e' ]),
'X:/a/b'
);
t.equal(
commondir([ 'X:\\x\\y\\z\\w', '\\\\xy\\z', '\\x\\y\\z' ]),
'/'
);
t.throws(function () {
commondir([ '/x/y/z/w', 'qrs', '/x/y/z' ]);
});
t.end();
});
test('base', function (t) {
t.equal(
commondir('/foo/bar', [ 'baz', './quux', '../bar/bazzy' ]),
'/foo/bar'
);
t.equal(
commondir('/a/b', [ 'c', '../b/.', '../../a/b/e' ]),
'/a/b'
);
t.equal(
commondir('/a/b/c', [ '..', '../d', '../../a/z/e' ]),
'/a'
);
t.equal(
commondir('/foo/bar', [ 'baz', '.\\quux', '..\\bar\\bazzy' ]),
'/foo/bar'
);
// Tests including X:\ basedirs must wait until path.resolve supports
// Windows-style paths, starting in Node.js v0.5.X
t.end();
});
+92
View File
@@ -0,0 +1,92 @@
# changelog
## 2.0.2
* Internal tidying up (change test runner, convert to JS)
## 2.0.1
* Robustify `this.remove()`, pass current index to walker functions ([#18](https://github.com/Rich-Harris/estree-walker/pull/18))
## 2.0.0
* Add an `asyncWalk` export ([#20](https://github.com/Rich-Harris/estree-walker/pull/20))
* Internal rewrite
## 1.0.1
* Relax node type to `BaseNode` ([#17](https://github.com/Rich-Harris/estree-walker/pull/17))
## 1.0.0
* Don't cache child keys
## 0.9.0
* Add `this.remove()` method
## 0.8.1
* Fix pkg.files
## 0.8.0
* Adopt `estree` types
## 0.7.0
* Add a `this.replace(node)` method
## 0.6.1
* Only traverse nodes that exist and have a type ([#9](https://github.com/Rich-Harris/estree-walker/pull/9))
* Only cache keys for nodes with a type ([#8](https://github.com/Rich-Harris/estree-walker/pull/8))
## 0.6.0
* Fix walker context type
* Update deps, remove unncessary Bublé transformation
## 0.5.2
* Add types to package
## 0.5.1
* Prevent context corruption when `walk()` is called during a walk
## 0.5.0
* Export `childKeys`, for manually fixing in case of malformed ASTs
## 0.4.0
* Add TypeScript typings ([#3](https://github.com/Rich-Harris/estree-walker/pull/3))
## 0.3.1
* Include `pkg.repository` ([#2](https://github.com/Rich-Harris/estree-walker/pull/2))
## 0.3.0
* More predictable ordering
## 0.2.1
* Keep `context` shape
## 0.2.0
* Add ES6 build
## 0.1.3
* npm snafu
## 0.1.2
* Pass current prop and index to `enter`/`leave` callbacks
## 0.1.1
* First release
+7
View File
@@ -0,0 +1,7 @@
Copyright (c) 2015-20 [these people](https://github.com/Rich-Harris/estree-walker/graphs/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.
+48
View File
@@ -0,0 +1,48 @@
# estree-walker
Simple utility for walking an [ESTree](https://github.com/estree/estree)-compliant AST, such as one generated by [acorn](https://github.com/marijnh/acorn).
## Installation
```bash
npm i estree-walker
```
## Usage
```js
var walk = require( 'estree-walker' ).walk;
var acorn = require( 'acorn' );
ast = acorn.parse( sourceCode, options ); // https://github.com/acornjs/acorn
walk( ast, {
enter: function ( node, parent, prop, index ) {
// some code happens
},
leave: function ( node, parent, prop, index ) {
// some code happens
}
});
```
Inside the `enter` function, calling `this.skip()` will prevent the node's children being walked, or the `leave` function (which is optional) being called.
Call `this.replace(new_node)` in either `enter` or `leave` to replace the current node with a new one.
Call `this.remove()` in either `enter` or `leave` to remove the current node.
## Why not use estraverse?
The ESTree spec is evolving to accommodate ES6/7. I've had a couple of experiences where [estraverse](https://github.com/estools/estraverse) was unable to handle an AST generated by recent versions of acorn, because it hard-codes visitor keys.
estree-walker, by contrast, simply enumerates a node's properties to find child nodes (and child lists of nodes), and is therefore resistant to spec changes. It's also much smaller. (The performance, if you're wondering, is basically identical.)
None of which should be taken as criticism of estraverse, which has more features and has been battle-tested in many more situations, and for which I'm very grateful.
## License
MIT
+333
View File
@@ -0,0 +1,333 @@
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef {{
skip: () => void;
remove: () => void;
replace: (node: BaseNode) => void;
}} WalkerContext */
class WalkerBase {
constructor() {
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {BaseNode | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
* @param {BaseNode} node
*/
replace(parent, prop, index, node) {
if (parent) {
if (index !== null) {
parent[prop][index] = node;
} else {
parent[prop] = node;
}
}
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
*/
remove(parent, prop, index) {
if (parent) {
if (index !== null) {
parent[prop].splice(index, 1);
} else {
delete parent[prop];
}
}
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker.js').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => void} SyncHandler */
class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} enter
* @param {SyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {SyncHandler} */
this.enter = enter;
/** @type {SyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {BaseNode}
*/
visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!this.visit(value[i], node, key, i)) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => Promise<void>} AsyncHandler */
class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} enter
* @param {AsyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {AsyncHandler} */
this.enter = enter;
/** @type {AsyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {Promise<BaseNode>}
*/
async visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
await this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!(await this.visit(value[i], node, key, i))) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
await this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
await this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./sync.js').SyncHandler} SyncHandler */
/** @typedef { import('./async.js').AsyncHandler} AsyncHandler */
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {BaseNode}
*/
function walk(ast, { enter, leave }) {
const instance = new SyncWalker(enter, leave);
return instance.visit(ast, null);
}
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<BaseNode>}
*/
async function asyncWalk(ast, { enter, leave }) {
const instance = new AsyncWalker(enter, leave);
return await instance.visit(ast, null);
}
export { asyncWalk, walk };
+1
View File
@@ -0,0 +1 @@
{"type":"module"}
+344
View File
@@ -0,0 +1,344 @@
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.estreeWalker = {}));
}(this, (function (exports) { 'use strict';
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef {{
skip: () => void;
remove: () => void;
replace: (node: BaseNode) => void;
}} WalkerContext */
class WalkerBase {
constructor() {
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {BaseNode | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
* @param {BaseNode} node
*/
replace(parent, prop, index, node) {
if (parent) {
if (index !== null) {
parent[prop][index] = node;
} else {
parent[prop] = node;
}
}
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
*/
remove(parent, prop, index) {
if (parent) {
if (index !== null) {
parent[prop].splice(index, 1);
} else {
delete parent[prop];
}
}
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker.js').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => void} SyncHandler */
class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} enter
* @param {SyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {SyncHandler} */
this.enter = enter;
/** @type {SyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {BaseNode}
*/
visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!this.visit(value[i], node, key, i)) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => Promise<void>} AsyncHandler */
class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} enter
* @param {AsyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {AsyncHandler} */
this.enter = enter;
/** @type {AsyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {Promise<BaseNode>}
*/
async visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
await this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!(await this.visit(value[i], node, key, i))) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
await this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
await this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./sync.js').SyncHandler} SyncHandler */
/** @typedef { import('./async.js').AsyncHandler} AsyncHandler */
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {BaseNode}
*/
function walk(ast, { enter, leave }) {
const instance = new SyncWalker(enter, leave);
return instance.visit(ast, null);
}
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<BaseNode>}
*/
async function asyncWalk(ast, { enter, leave }) {
const instance = new AsyncWalker(enter, leave);
return await instance.visit(ast, null);
}
exports.asyncWalk = asyncWalk;
exports.walk = walk;
Object.defineProperty(exports, '__esModule', { value: true });
})));
+37
View File
@@ -0,0 +1,37 @@
{
"name": "estree-walker",
"description": "Traverse an ESTree-compliant AST",
"version": "2.0.2",
"private": false,
"author": "Rich Harris",
"license": "MIT",
"repository": {
"type": "git",
"url": "https://github.com/Rich-Harris/estree-walker"
},
"type": "commonjs",
"main": "./dist/umd/estree-walker.js",
"module": "./dist/esm/estree-walker.js",
"exports": {
"require": "./dist/umd/estree-walker.js",
"import": "./dist/esm/estree-walker.js"
},
"types": "types/index.d.ts",
"scripts": {
"prepublishOnly": "npm run build && npm test",
"build": "tsc && rollup -c",
"test": "uvu test"
},
"devDependencies": {
"@types/estree": "0.0.42",
"rollup": "^2.10.9",
"typescript": "^3.7.5",
"uvu": "^0.5.1"
},
"files": [
"src",
"dist",
"types",
"README.md"
]
}
+118
View File
@@ -0,0 +1,118 @@
// @ts-check
import { WalkerBase } from './walker.js';
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => Promise<void>} AsyncHandler */
export class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} enter
* @param {AsyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {AsyncHandler} */
this.enter = enter;
/** @type {AsyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {Promise<BaseNode>}
*/
async visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
await this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!(await this.visit(value[i], node, key, i))) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
await this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
await this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
+35
View File
@@ -0,0 +1,35 @@
// @ts-check
import { SyncWalker } from './sync.js';
import { AsyncWalker } from './async.js';
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./sync.js').SyncHandler} SyncHandler */
/** @typedef { import('./async.js').AsyncHandler} AsyncHandler */
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {BaseNode}
*/
export function walk(ast, { enter, leave }) {
const instance = new SyncWalker(enter, leave);
return instance.visit(ast, null);
}
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<BaseNode>}
*/
export async function asyncWalk(ast, { enter, leave }) {
const instance = new AsyncWalker(enter, leave);
return await instance.visit(ast, null);
}
+1
View File
@@ -0,0 +1 @@
{"type": "module"}
+118
View File
@@ -0,0 +1,118 @@
// @ts-check
import { WalkerBase } from './walker.js';
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker.js').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => void} SyncHandler */
export class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} enter
* @param {SyncHandler} leave
*/
constructor(enter, leave) {
super();
/** @type {SyncHandler} */
this.enter = enter;
/** @type {SyncHandler} */
this.leave = leave;
}
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {BaseNode}
*/
visit(node, parent, prop, index) {
if (node) {
if (this.enter) {
const _should_skip = this.should_skip;
const _should_remove = this.should_remove;
const _replacement = this.replacement;
this.should_skip = false;
this.should_remove = false;
this.replacement = null;
this.enter.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const skipped = this.should_skip;
const removed = this.should_remove;
this.should_skip = _should_skip;
this.should_remove = _should_remove;
this.replacement = _replacement;
if (skipped) return node;
if (removed) return null;
}
for (const key in node) {
const value = node[key];
if (typeof value !== "object") {
continue;
} else if (Array.isArray(value)) {
for (let i = 0; i < value.length; i += 1) {
if (value[i] !== null && typeof value[i].type === 'string') {
if (!this.visit(value[i], node, key, i)) {
// removed
i--;
}
}
}
} else if (value !== null && typeof value.type === "string") {
this.visit(value, node, key, null);
}
}
if (this.leave) {
const _replacement = this.replacement;
const _should_remove = this.should_remove;
this.replacement = null;
this.should_remove = false;
this.leave.call(this.context, node, parent, prop, index);
if (this.replacement) {
node = this.replacement;
this.replace(parent, prop, index, node);
}
if (this.should_remove) {
this.remove(parent, prop, index);
}
const removed = this.should_remove;
this.replacement = _replacement;
this.should_remove = _should_remove;
if (removed) return null;
}
}
return node;
}
}
+61
View File
@@ -0,0 +1,61 @@
// @ts-check
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef {{
skip: () => void;
remove: () => void;
replace: (node: BaseNode) => void;
}} WalkerContext */
export class WalkerBase {
constructor() {
/** @type {boolean} */
this.should_skip = false;
/** @type {boolean} */
this.should_remove = false;
/** @type {BaseNode | null} */
this.replacement = null;
/** @type {WalkerContext} */
this.context = {
skip: () => (this.should_skip = true),
remove: () => (this.should_remove = true),
replace: (node) => (this.replacement = node)
};
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
* @param {BaseNode} node
*/
replace(parent, prop, index, node) {
if (parent) {
if (index !== null) {
parent[prop][index] = node;
} else {
parent[prop] = node;
}
}
}
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
*/
remove(parent, prop, index) {
if (parent) {
if (index !== null) {
parent[prop].splice(index, 1);
} else {
delete parent[prop];
}
}
}
}
+53
View File
@@ -0,0 +1,53 @@
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => Promise<void>} AsyncHandler */
export class AsyncWalker extends WalkerBase {
/**
*
* @param {AsyncHandler} enter
* @param {AsyncHandler} leave
*/
constructor(enter: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>, leave: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>);
/** @type {AsyncHandler} */
enter: AsyncHandler;
/** @type {AsyncHandler} */
leave: AsyncHandler;
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {Promise<BaseNode>}
*/
visit(node: import("estree").BaseNode, parent: import("estree").BaseNode, prop?: string, index?: number): Promise<import("estree").BaseNode>;
should_skip: any;
should_remove: any;
replacement: any;
}
export type BaseNode = import("estree").BaseNode;
export type WalkerContext = {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
};
export type AsyncHandler = (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>;
import { WalkerBase } from "./walker.js";
+56
View File
@@ -0,0 +1,56 @@
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./sync.js').SyncHandler} SyncHandler */
/** @typedef { import('./async.js').AsyncHandler} AsyncHandler */
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: SyncHandler
* leave?: SyncHandler
* }} walker
* @returns {BaseNode}
*/
export function walk(ast: import("estree").BaseNode, { enter, leave }: {
enter?: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void;
leave?: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void;
}): import("estree").BaseNode;
/**
*
* @param {BaseNode} ast
* @param {{
* enter?: AsyncHandler
* leave?: AsyncHandler
* }} walker
* @returns {Promise<BaseNode>}
*/
export function asyncWalk(ast: import("estree").BaseNode, { enter, leave }: {
enter?: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>;
leave?: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>;
}): Promise<import("estree").BaseNode>;
export type BaseNode = import("estree").BaseNode;
export type SyncHandler = (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void;
export type AsyncHandler = (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => Promise<void>;
+53
View File
@@ -0,0 +1,53 @@
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef { import('./walker.js').WalkerContext} WalkerContext */
/** @typedef {(
* this: WalkerContext,
* node: BaseNode,
* parent: BaseNode,
* key: string,
* index: number
* ) => void} SyncHandler */
export class SyncWalker extends WalkerBase {
/**
*
* @param {SyncHandler} enter
* @param {SyncHandler} leave
*/
constructor(enter: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void, leave: (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void);
/** @type {SyncHandler} */
enter: SyncHandler;
/** @type {SyncHandler} */
leave: SyncHandler;
/**
*
* @param {BaseNode} node
* @param {BaseNode} parent
* @param {string} [prop]
* @param {number} [index]
* @returns {BaseNode}
*/
visit(node: import("estree").BaseNode, parent: import("estree").BaseNode, prop?: string, index?: number): import("estree").BaseNode;
should_skip: any;
should_remove: any;
replacement: any;
}
export type BaseNode = import("estree").BaseNode;
export type WalkerContext = {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
};
export type SyncHandler = (this: {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
}, node: import("estree").BaseNode, parent: import("estree").BaseNode, key: string, index: number) => void;
import { WalkerBase } from "./walker.js";
+345
View File
@@ -0,0 +1,345 @@
{
"program": {
"fileInfos": {
"../node_modules/typescript/lib/lib.es5.d.ts": {
"version": "fc43680ad3a1a4ec8c7b8d908af1ec9ddff87845346de5f02c735c9171fa98ea",
"signature": "fc43680ad3a1a4ec8c7b8d908af1ec9ddff87845346de5f02c735c9171fa98ea"
},
"../node_modules/typescript/lib/lib.es2015.d.ts": {
"version": "7994d44005046d1413ea31d046577cdda33b8b2470f30281fd9c8b3c99fe2d96",
"signature": "7994d44005046d1413ea31d046577cdda33b8b2470f30281fd9c8b3c99fe2d96"
},
"../node_modules/typescript/lib/lib.es2016.d.ts": {
"version": "5f217838d25704474d9ef93774f04164889169ca31475fe423a9de6758f058d1",
"signature": "5f217838d25704474d9ef93774f04164889169ca31475fe423a9de6758f058d1"
},
"../node_modules/typescript/lib/lib.es2017.d.ts": {
"version": "459097c7bdd88fc5731367e56591e4f465f2c9de81a35427a7bd473165c34743",
"signature": "459097c7bdd88fc5731367e56591e4f465f2c9de81a35427a7bd473165c34743"
},
"../node_modules/typescript/lib/lib.dom.d.ts": {
"version": "d93de5e8a7275cb9d47481410e13b3b1debb997e216490954b5d106e37e086de",
"signature": "d93de5e8a7275cb9d47481410e13b3b1debb997e216490954b5d106e37e086de"
},
"../node_modules/typescript/lib/lib.dom.iterable.d.ts": {
"version": "8329c3401aa8708426c7760f14219170f69a2cb77e4519758cec6f5027270faf",
"signature": "8329c3401aa8708426c7760f14219170f69a2cb77e4519758cec6f5027270faf"
},
"../node_modules/typescript/lib/lib.webworker.importscripts.d.ts": {
"version": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b",
"signature": "fe4e59403e34c7ff747abe4ff6abbc7718229556d7c1a5b93473fb53156c913b"
},
"../node_modules/typescript/lib/lib.scripthost.d.ts": {
"version": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9",
"signature": "b9faa17292f17d2ad75e34fac77dd63a6403af1dba02d39cd0cbb9ffdf3de8b9"
},
"../node_modules/typescript/lib/lib.es2015.core.d.ts": {
"version": "734ddc145e147fbcd55f07d034f50ccff1086f5a880107665ec326fb368876f6",
"signature": "734ddc145e147fbcd55f07d034f50ccff1086f5a880107665ec326fb368876f6"
},
"../node_modules/typescript/lib/lib.es2015.collection.d.ts": {
"version": "4a0862a21f4700de873db3b916f70e41570e2f558da77d2087c9490f5a0615d8",
"signature": "4a0862a21f4700de873db3b916f70e41570e2f558da77d2087c9490f5a0615d8"
},
"../node_modules/typescript/lib/lib.es2015.generator.d.ts": {
"version": "765e0e9c9d74cf4d031ca8b0bdb269a853e7d81eda6354c8510218d03db12122",
"signature": "765e0e9c9d74cf4d031ca8b0bdb269a853e7d81eda6354c8510218d03db12122"
},
"../node_modules/typescript/lib/lib.es2015.iterable.d.ts": {
"version": "285958e7699f1babd76d595830207f18d719662a0c30fac7baca7df7162a9210",
"signature": "285958e7699f1babd76d595830207f18d719662a0c30fac7baca7df7162a9210"
},
"../node_modules/typescript/lib/lib.es2015.promise.d.ts": {
"version": "d4deaafbb18680e3143e8b471acd650ed6f72a408a33137f0a0dd104fbe7f8ca",
"signature": "d4deaafbb18680e3143e8b471acd650ed6f72a408a33137f0a0dd104fbe7f8ca"
},
"../node_modules/typescript/lib/lib.es2015.proxy.d.ts": {
"version": "5e72f949a89717db444e3bd9433468890068bb21a5638d8ab15a1359e05e54fe",
"signature": "5e72f949a89717db444e3bd9433468890068bb21a5638d8ab15a1359e05e54fe"
},
"../node_modules/typescript/lib/lib.es2015.reflect.d.ts": {
"version": "f5b242136ae9bfb1cc99a5971cccc44e99947ae6b5ef6fd8aa54b5ade553b976",
"signature": "f5b242136ae9bfb1cc99a5971cccc44e99947ae6b5ef6fd8aa54b5ade553b976"
},
"../node_modules/typescript/lib/lib.es2015.symbol.d.ts": {
"version": "9ae2860252d6b5f16e2026d8a2c2069db7b2a3295e98b6031d01337b96437230",
"signature": "9ae2860252d6b5f16e2026d8a2c2069db7b2a3295e98b6031d01337b96437230"
},
"../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts": {
"version": "3e0a459888f32b42138d5a39f706ff2d55d500ab1031e0988b5568b0f67c2303",
"signature": "3e0a459888f32b42138d5a39f706ff2d55d500ab1031e0988b5568b0f67c2303"
},
"../node_modules/typescript/lib/lib.es2016.array.include.d.ts": {
"version": "3f96f1e570aedbd97bf818c246727151e873125d0512e4ae904330286c721bc0",
"signature": "3f96f1e570aedbd97bf818c246727151e873125d0512e4ae904330286c721bc0"
},
"../node_modules/typescript/lib/lib.es2017.object.d.ts": {
"version": "c2d60b2e558d44384e4704b00e6b3d154334721a911f094d3133c35f0917b408",
"signature": "c2d60b2e558d44384e4704b00e6b3d154334721a911f094d3133c35f0917b408"
},
"../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts": {
"version": "b8667586a618c5cf64523d4e500ae39e781428abfb28f3de441fc66b56144b6f",
"signature": "b8667586a618c5cf64523d4e500ae39e781428abfb28f3de441fc66b56144b6f"
},
"../node_modules/typescript/lib/lib.es2017.string.d.ts": {
"version": "21df2e0059f14dcb4c3a0e125859f6b6ff01332ee24b0065a741d121250bc71c",
"signature": "21df2e0059f14dcb4c3a0e125859f6b6ff01332ee24b0065a741d121250bc71c"
},
"../node_modules/typescript/lib/lib.es2017.intl.d.ts": {
"version": "c1759cb171c7619af0d2234f2f8fb2a871ee88e956e2ed91bb61778e41f272c6",
"signature": "c1759cb171c7619af0d2234f2f8fb2a871ee88e956e2ed91bb61778e41f272c6"
},
"../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts": {
"version": "28569d59e07d4378cb3d54979c4c60f9f06305c9bb6999ffe6cab758957adc46",
"signature": "28569d59e07d4378cb3d54979c4c60f9f06305c9bb6999ffe6cab758957adc46"
},
"../node_modules/typescript/lib/lib.es2017.full.d.ts": {
"version": "873c09f1c309389742d98b7b67419a8e0a5fa6f10ce59fd5149ecd31a2818594",
"signature": "873c09f1c309389742d98b7b67419a8e0a5fa6f10ce59fd5149ecd31a2818594"
},
"../node_modules/@types/estree/index.d.ts": {
"version": "c2efad8a2f2d7fb931ff15c7959fb45340e74684cd665ddf0cbf9b3977be1644",
"signature": "c2efad8a2f2d7fb931ff15c7959fb45340e74684cd665ddf0cbf9b3977be1644"
},
"../src/walker.js": {
"version": "4cc9d0e334d83a4cebeeac502de37a1aeeb953f6d4145a886d9eecea1f2142a7",
"signature": "075872468ccc19c83b03fd717fc9305b5f8ec09592210cf60279cb13eca2bd70"
},
"../src/async.js": {
"version": "904efd145090ac40c3c98f29cc928332898a62ab642dd5921db2ae249bfe014a",
"signature": "da428f781d6dc6dfd4f4afd0dd5f25a780897dc8b57e5b30462491b7d08f32c0"
},
"../src/sync.js": {
"version": "85bb22b85042f0a3717d8fac2fc8f62af16894652be34d1e08eb3e63785535f5",
"signature": "5b131a727db18c956611a5e33d08217df96d0f2e0f26d98b804d1ec2407e59ae"
},
"../src/index.js": {
"version": "99128f4c6cb79cb1e3abf3f2ba96faedd2b820aab4fd7f743aab0b8d710a73af",
"signature": "c52be5c79280bfcfcf359c084c6f2f70f405b0ad14dde96b6703dbc5ef2261f5"
}
},
"options": {
"allowJs": true,
"target": 4,
"module": 99,
"types": [
"estree"
],
"declaration": true,
"declarationDir": "./",
"emitDeclarationOnly": true,
"outDir": "./",
"newLine": 1,
"noImplicitAny": true,
"noImplicitThis": true,
"incremental": true,
"configFilePath": "../tsconfig.json"
},
"referencedMap": {
"../src/walker.js": [
"../node_modules/@types/estree/index.d.ts"
],
"../src/async.js": [
"../src/walker.js",
"../node_modules/@types/estree/index.d.ts"
],
"../src/sync.js": [
"../src/walker.js",
"../node_modules/@types/estree/index.d.ts"
],
"../src/index.js": [
"../src/sync.js",
"../src/async.js",
"../node_modules/@types/estree/index.d.ts"
]
},
"exportedModulesMap": {
"../src/walker.js": [
"../node_modules/@types/estree/index.d.ts"
],
"../src/async.js": [
"../node_modules/@types/estree/index.d.ts"
],
"../src/sync.js": [
"../node_modules/@types/estree/index.d.ts"
],
"../src/index.js": [
"../node_modules/@types/estree/index.d.ts"
]
},
"semanticDiagnosticsPerFile": [
"../node_modules/typescript/lib/lib.es5.d.ts",
"../node_modules/typescript/lib/lib.es2015.d.ts",
"../node_modules/typescript/lib/lib.es2016.d.ts",
"../node_modules/typescript/lib/lib.es2017.d.ts",
"../node_modules/typescript/lib/lib.dom.d.ts",
"../node_modules/typescript/lib/lib.dom.iterable.d.ts",
"../node_modules/typescript/lib/lib.webworker.importscripts.d.ts",
"../node_modules/typescript/lib/lib.scripthost.d.ts",
"../node_modules/typescript/lib/lib.es2015.core.d.ts",
"../node_modules/typescript/lib/lib.es2015.collection.d.ts",
"../node_modules/typescript/lib/lib.es2015.generator.d.ts",
"../node_modules/typescript/lib/lib.es2015.iterable.d.ts",
"../node_modules/typescript/lib/lib.es2015.promise.d.ts",
"../node_modules/typescript/lib/lib.es2015.proxy.d.ts",
"../node_modules/typescript/lib/lib.es2015.reflect.d.ts",
"../node_modules/typescript/lib/lib.es2015.symbol.d.ts",
"../node_modules/typescript/lib/lib.es2015.symbol.wellknown.d.ts",
"../node_modules/typescript/lib/lib.es2016.array.include.d.ts",
"../node_modules/typescript/lib/lib.es2017.object.d.ts",
"../node_modules/typescript/lib/lib.es2017.sharedmemory.d.ts",
"../node_modules/typescript/lib/lib.es2017.string.d.ts",
"../node_modules/typescript/lib/lib.es2017.intl.d.ts",
"../node_modules/typescript/lib/lib.es2017.typedarrays.d.ts",
"../node_modules/typescript/lib/lib.es2017.full.d.ts",
"../node_modules/@types/estree/index.d.ts",
"../src/walker.js",
[
"../src/async.js",
[
{
"file": "../src/async.js",
"start": 864,
"length": 12,
"messageText": "'_should_skip' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 907,
"length": 14,
"messageText": "'_should_remove' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 954,
"length": 12,
"messageText": "'_replacement' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 991,
"length": 24,
"messageText": "'should_skip' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 1021,
"length": 26,
"messageText": "'should_remove' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 1053,
"length": 23,
"messageText": "'replacement' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/async.js",
"start": 1643,
"length": 9,
"code": 7053,
"category": 1,
"messageText": {
"messageText": "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'BaseNode'.",
"category": 1,
"code": 7053,
"next": [
{
"messageText": "No index signature with a parameter of type 'string' was found on type 'BaseNode'.",
"category": 1,
"code": 7054
}
]
}
}
]
],
[
"../src/sync.js",
[
{
"file": "../src/sync.js",
"start": 837,
"length": 12,
"messageText": "'_should_skip' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 880,
"length": 14,
"messageText": "'_should_remove' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 927,
"length": 12,
"messageText": "'_replacement' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 964,
"length": 24,
"messageText": "'should_skip' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 994,
"length": 26,
"messageText": "'should_remove' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 1026,
"length": 23,
"messageText": "'replacement' implicitly has type 'any' because it does not have a type annotation and is referenced directly or indirectly in its own initializer.",
"category": 1,
"code": 7022
},
{
"file": "../src/sync.js",
"start": 1610,
"length": 9,
"code": 7053,
"category": 1,
"messageText": {
"messageText": "Element implicitly has an 'any' type because expression of type 'string' can't be used to index type 'BaseNode'.",
"category": 1,
"code": 7053,
"next": [
{
"messageText": "No index signature with a parameter of type 'string' was found on type 'BaseNode'.",
"category": 1,
"code": 7054
}
]
}
}
]
],
"../src/index.js"
]
},
"version": "3.7.5"
}
+37
View File
@@ -0,0 +1,37 @@
/** @typedef { import('estree').BaseNode} BaseNode */
/** @typedef {{
skip: () => void;
remove: () => void;
replace: (node: BaseNode) => void;
}} WalkerContext */
export class WalkerBase {
/** @type {boolean} */
should_skip: boolean;
/** @type {boolean} */
should_remove: boolean;
/** @type {BaseNode | null} */
replacement: BaseNode | null;
/** @type {WalkerContext} */
context: WalkerContext;
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
* @param {BaseNode} node
*/
replace(parent: any, prop: string, index: number, node: import("estree").BaseNode): void;
/**
*
* @param {any} parent
* @param {string} prop
* @param {number} index
*/
remove(parent: any, prop: string, index: number): void;
}
export type BaseNode = import("estree").BaseNode;
export type WalkerContext = {
skip: () => void;
remove: () => void;
replace: (node: import("estree").BaseNode) => void;
};
+21
View File
@@ -0,0 +1,21 @@
{
"root": true,
"extends": "@ljharb",
"rules": {
"func-name-matching": 0,
"indent": [2, 4],
"no-new-func": [1],
},
"overrides": [
{
"files": "test/**",
"rules": {
"max-lines-per-function": 0,
"strict": [0]
},
},
],
}
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/function-bind
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
+3
View File
@@ -0,0 +1,3 @@
# Security
Please email [@ljharb](https://github.com/ljharb) or see https://tidelift.com/security if you have a potential security vulnerability to report.
+13
View File
@@ -0,0 +1,13 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"lines": 86,
"statements": 85.93,
"functions": 82.43,
"branches": 76.06,
"exclude": [
"coverage",
"test"
]
}
+136
View File
@@ -0,0 +1,136 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v1.1.2](https://github.com/ljharb/function-bind/compare/v1.1.1...v1.1.2) - 2023-10-12
### Merged
- Point to the correct file [`#16`](https://github.com/ljharb/function-bind/pull/16)
### Commits
- [Tests] migrate tests to Github Actions [`4f8b57c`](https://github.com/ljharb/function-bind/commit/4f8b57c02f2011fe9ae353d5e74e8745f0988af8)
- [Tests] remove `jscs` [`90eb2ed`](https://github.com/ljharb/function-bind/commit/90eb2edbeefd5b76cd6c3a482ea3454db169b31f)
- [meta] update `.gitignore` [`53fcdc3`](https://github.com/ljharb/function-bind/commit/53fcdc371cd66634d6e9b71c836a50f437e89fed)
- [Tests] up to `node` `v11.10`, `v10.15`, `v9.11`, `v8.15`, `v6.16`, `v4.9`; use `nvm install-latest-npm`; run audit script in tests [`1fe8f6e`](https://github.com/ljharb/function-bind/commit/1fe8f6e9aed0dfa8d8b3cdbd00c7f5ea0cd2b36e)
- [meta] add `auto-changelog` [`1921fcb`](https://github.com/ljharb/function-bind/commit/1921fcb5b416b63ffc4acad051b6aad5722f777d)
- [Robustness] remove runtime dependency on all builtins except `.apply` [`f743e61`](https://github.com/ljharb/function-bind/commit/f743e61aa6bb2360358c04d4884c9db853d118b7)
- Docs: enable badges; update wording [`503cb12`](https://github.com/ljharb/function-bind/commit/503cb12d998b5f91822776c73332c7adcd6355dd)
- [readme] update badges [`290c5db`](https://github.com/ljharb/function-bind/commit/290c5dbbbda7264efaeb886552a374b869a4bb48)
- [Tests] switch to nyc for coverage [`ea360ba`](https://github.com/ljharb/function-bind/commit/ea360ba907fc2601ed18d01a3827fa2d3533cdf8)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `tape` [`cae5e9e`](https://github.com/ljharb/function-bind/commit/cae5e9e07a5578dc6df26c03ee22851ce05b943c)
- [meta] add `funding` field; create FUNDING.yml [`c9f4274`](https://github.com/ljharb/function-bind/commit/c9f4274aa80ea3aae9657a3938fdba41a3b04ca6)
- [Tests] fix eslint errors from #15 [`f69aaa2`](https://github.com/ljharb/function-bind/commit/f69aaa2beb2fdab4415bfb885760a699d0b9c964)
- [actions] fix permissions [`99a0cd9`](https://github.com/ljharb/function-bind/commit/99a0cd9f3b5bac223a0d572f081834cd73314be7)
- [meta] use `npmignore` to autogenerate an npmignore file [`f03b524`](https://github.com/ljharb/function-bind/commit/f03b524ca91f75a109a5d062f029122c86ecd1ae)
- [Dev Deps] update `@ljharb/eslintconfig`, `eslint`, `tape` [`7af9300`](https://github.com/ljharb/function-bind/commit/7af930023ae2ce7645489532821e4fbbcd7a2280)
- [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `covert`, `tape` [`64a9127`](https://github.com/ljharb/function-bind/commit/64a9127ab0bd331b93d6572eaf6e9971967fc08c)
- [Tests] use `aud` instead of `npm audit` [`e75069c`](https://github.com/ljharb/function-bind/commit/e75069c50010a8fcce2a9ce2324934c35fdb4386)
- [Dev Deps] update `@ljharb/eslint-config`, `aud`, `tape` [`d03555c`](https://github.com/ljharb/function-bind/commit/d03555ca59dea3b71ce710045e4303b9e2619e28)
- [meta] add `safe-publish-latest` [`9c8f809`](https://github.com/ljharb/function-bind/commit/9c8f8092aed027d7e80c94f517aa892385b64f09)
- [Dev Deps] update `@ljharb/eslint-config`, `tape` [`baf6893`](https://github.com/ljharb/function-bind/commit/baf6893e27f5b59abe88bc1995e6f6ed1e527397)
- [meta] create SECURITY.md [`4db1779`](https://github.com/ljharb/function-bind/commit/4db17799f1f28ae294cb95e0081ca2b591c3911b)
- [Tests] add `npm run audit` [`c8b38ec`](https://github.com/ljharb/function-bind/commit/c8b38ec40ed3f85dabdee40ed4148f1748375bc2)
- Revert "Point to the correct file" [`05cdf0f`](https://github.com/ljharb/function-bind/commit/05cdf0fa205c6a3c5ba40bbedd1dfa9874f915c9)
## [v1.1.1](https://github.com/ljharb/function-bind/compare/v1.1.0...v1.1.1) - 2017-08-28
### Commits
- [Tests] up to `node` `v8`; newer npm breaks on older node; fix scripts [`817f7d2`](https://github.com/ljharb/function-bind/commit/817f7d28470fdbff8ef608d4d565dd4d1430bc5e)
- [Dev Deps] update `eslint`, `jscs`, `tape`, `@ljharb/eslint-config` [`854288b`](https://github.com/ljharb/function-bind/commit/854288b1b6f5c555f89aceb9eff1152510262084)
- [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`83e639f`](https://github.com/ljharb/function-bind/commit/83e639ff74e6cd6921285bccec22c1bcf72311bd)
- Only apps should have lockfiles [`5ed97f5`](https://github.com/ljharb/function-bind/commit/5ed97f51235c17774e0832e122abda0f3229c908)
- Use a SPDX-compliant “license” field. [`5feefea`](https://github.com/ljharb/function-bind/commit/5feefea0dc0193993e83e5df01ded424403a5381)
## [v1.1.0](https://github.com/ljharb/function-bind/compare/v1.0.2...v1.1.0) - 2016-02-14
### Commits
- Update `eslint`, `tape`; use my personal shared `eslint` config [`9c9062a`](https://github.com/ljharb/function-bind/commit/9c9062abbe9dd70b59ea2c3a3c3a81f29b457097)
- Add `npm run eslint` [`dd96c56`](https://github.com/ljharb/function-bind/commit/dd96c56720034a3c1ffee10b8a59a6f7c53e24ad)
- [New] return the native `bind` when available. [`82186e0`](https://github.com/ljharb/function-bind/commit/82186e03d73e580f95ff167e03f3582bed90ed72)
- [Dev Deps] update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`a3dd767`](https://github.com/ljharb/function-bind/commit/a3dd76720c795cb7f4586b0544efabf8aa107b8b)
- Update `eslint` [`3dae2f7`](https://github.com/ljharb/function-bind/commit/3dae2f7423de30a2d20313ddb1edc19660142fe9)
- Update `tape`, `covert`, `jscs` [`a181eee`](https://github.com/ljharb/function-bind/commit/a181eee0cfa24eb229c6e843a971f36e060a2f6a)
- [Tests] up to `node` `v5.6`, `v4.3` [`964929a`](https://github.com/ljharb/function-bind/commit/964929a6a4ddb36fb128de2bcc20af5e4f22e1ed)
- Test up to `io.js` `v2.1` [`2be7310`](https://github.com/ljharb/function-bind/commit/2be7310f2f74886a7124ca925be411117d41d5ea)
- Update `tape`, `jscs`, `eslint`, `@ljharb/eslint-config` [`45f3d68`](https://github.com/ljharb/function-bind/commit/45f3d6865c6ca93726abcef54febe009087af101)
- [Dev Deps] update `tape`, `jscs` [`6e1340d`](https://github.com/ljharb/function-bind/commit/6e1340d94642deaecad3e717825db641af4f8b1f)
- [Tests] up to `io.js` `v3.3`, `node` `v4.1` [`d9bad2b`](https://github.com/ljharb/function-bind/commit/d9bad2b778b1b3a6dd2876087b88b3acf319f8cc)
- Update `eslint` [`935590c`](https://github.com/ljharb/function-bind/commit/935590caa024ab356102e4858e8fc315b2ccc446)
- [Dev Deps] update `jscs`, `eslint`, `@ljharb/eslint-config` [`8c9a1ef`](https://github.com/ljharb/function-bind/commit/8c9a1efd848e5167887aa8501857a0940a480c57)
- Test on `io.js` `v2.2` [`9a3a38c`](https://github.com/ljharb/function-bind/commit/9a3a38c92013aed6e108666e7bd40969b84ac86e)
- Run `travis-ci` tests on `iojs` and `node` v0.12; speed up builds; allow 0.8 failures. [`69afc26`](https://github.com/ljharb/function-bind/commit/69afc2617405b147dd2a8d8ae73ca9e9283f18b4)
- [Dev Deps] Update `tape`, `eslint` [`36c1be0`](https://github.com/ljharb/function-bind/commit/36c1be0ab12b45fe5df6b0fdb01a5d5137fd0115)
- Update `tape`, `jscs` [`98d8303`](https://github.com/ljharb/function-bind/commit/98d8303cd5ca1c6b8f985469f86b0d44d7d45f6e)
- Update `jscs` [`9633a4e`](https://github.com/ljharb/function-bind/commit/9633a4e9fbf82051c240855166e468ba8ba0846f)
- Update `tape`, `jscs` [`c80ef0f`](https://github.com/ljharb/function-bind/commit/c80ef0f46efc9791e76fa50de4414092ac147831)
- Test up to `io.js` `v3.0` [`7e2c853`](https://github.com/ljharb/function-bind/commit/7e2c8537d52ab9cf5a655755561d8917684c0df4)
- Test on `io.js` `v2.4` [`5a199a2`](https://github.com/ljharb/function-bind/commit/5a199a27ba46795ba5eaf0845d07d4b8232895c9)
- Test on `io.js` `v2.3` [`a511b88`](https://github.com/ljharb/function-bind/commit/a511b8896de0bddf3b56862daa416c701f4d0453)
- Fixing a typo from 822b4e1938db02dc9584aa434fd3a45cb20caf43 [`732d6b6`](https://github.com/ljharb/function-bind/commit/732d6b63a9b33b45230e630dbcac7a10855d3266)
- Update `jscs` [`da52a48`](https://github.com/ljharb/function-bind/commit/da52a4886c06d6490f46ae30b15e4163ba08905d)
- Lock covert to v1.0.0. [`d6150fd`](https://github.com/ljharb/function-bind/commit/d6150fda1e6f486718ebdeff823333d9e48e7430)
## [v1.0.2](https://github.com/ljharb/function-bind/compare/v1.0.1...v1.0.2) - 2014-10-04
## [v1.0.1](https://github.com/ljharb/function-bind/compare/v1.0.0...v1.0.1) - 2014-10-03
### Merged
- make CI build faster [`#3`](https://github.com/ljharb/function-bind/pull/3)
### Commits
- Using my standard jscs.json [`d8ee94c`](https://github.com/ljharb/function-bind/commit/d8ee94c993eff0a84cf5744fe6a29627f5cffa1a)
- Adding `npm run lint` [`7571ab7`](https://github.com/ljharb/function-bind/commit/7571ab7dfdbd99b25a1dbb2d232622bd6f4f9c10)
- Using consistent indentation [`e91a1b1`](https://github.com/ljharb/function-bind/commit/e91a1b13a61e99ec1e530e299b55508f74218a95)
- Updating jscs [`7e17892`](https://github.com/ljharb/function-bind/commit/7e1789284bc629bc9c1547a61c9b227bbd8c7a65)
- Using consistent quotes [`c50b57f`](https://github.com/ljharb/function-bind/commit/c50b57fcd1c5ec38320979c837006069ebe02b77)
- Adding keywords [`cb94631`](https://github.com/ljharb/function-bind/commit/cb946314eed35f21186a25fb42fc118772f9ee00)
- Directly export a function expression instead of using a declaration, and relying on hoisting. [`5a33c5f`](https://github.com/ljharb/function-bind/commit/5a33c5f45642de180e0d207110bf7d1843ceb87c)
- Naming npm URL and badge in README; use SVG [`2aef8fc`](https://github.com/ljharb/function-bind/commit/2aef8fcb79d54e63a58ae557c4e60949e05d5e16)
- Naming deps URLs in README [`04228d7`](https://github.com/ljharb/function-bind/commit/04228d766670ee45ca24e98345c1f6a7621065b5)
- Naming travis-ci URLs in README; using SVG [`62c810c`](https://github.com/ljharb/function-bind/commit/62c810c2f54ced956cd4d4ab7b793055addfe36e)
- Make sure functions are invoked correctly (also passing coverage tests) [`2b289b4`](https://github.com/ljharb/function-bind/commit/2b289b4dfbf037ffcfa4dc95eb540f6165e9e43a)
- Removing the strict mode pragmas; they make tests fail. [`1aa701d`](https://github.com/ljharb/function-bind/commit/1aa701d199ddc3782476e8f7eef82679be97b845)
- Adding myself as a contributor [`85fd57b`](https://github.com/ljharb/function-bind/commit/85fd57b0860e5a7af42de9a287f3f265fc6d72fc)
- Adding strict mode pragmas [`915b08e`](https://github.com/ljharb/function-bind/commit/915b08e084c86a722eafe7245e21db74aa21ca4c)
- Adding devDeps URLs to README [`4ccc731`](https://github.com/ljharb/function-bind/commit/4ccc73112c1769859e4ca3076caf4086b3cba2cd)
- Fixing the description. [`a7a472c`](https://github.com/ljharb/function-bind/commit/a7a472cf649af515c635cf560fc478fbe48999c8)
- Using a function expression instead of a function declaration. [`b5d3e4e`](https://github.com/ljharb/function-bind/commit/b5d3e4ea6aaffc63888953eeb1fbc7ff45f1fa14)
- Updating tape [`f086be6`](https://github.com/ljharb/function-bind/commit/f086be6029fb56dde61a258c1340600fa174d1e0)
- Updating jscs [`5f9bdb3`](https://github.com/ljharb/function-bind/commit/5f9bdb375ab13ba48f30852aab94029520c54d71)
- Updating jscs [`9b409ba`](https://github.com/ljharb/function-bind/commit/9b409ba6118e23395a4e5d83ef39152aab9d3bfc)
- Run coverage as part of tests. [`8e1b6d4`](https://github.com/ljharb/function-bind/commit/8e1b6d459f047d1bd4fee814e01247c984c80bd0)
- Run linter as part of tests [`c1ca83f`](https://github.com/ljharb/function-bind/commit/c1ca83f832df94587d09e621beba682fabfaa987)
- Updating covert [`701e837`](https://github.com/ljharb/function-bind/commit/701e83774b57b4d3ef631e1948143f43a72f4bb9)
## [v1.0.0](https://github.com/ljharb/function-bind/compare/v0.2.0...v1.0.0) - 2014-08-09
### Commits
- Make sure old and unstable nodes don't fail Travis [`27adca3`](https://github.com/ljharb/function-bind/commit/27adca34a4ab6ad67b6dfde43942a1b103ce4d75)
- Fixing an issue when the bound function is called as a constructor in ES3. [`e20122d`](https://github.com/ljharb/function-bind/commit/e20122d267d92ce553859b280cbbea5d27c07731)
- Adding `npm run coverage` [`a2e29c4`](https://github.com/ljharb/function-bind/commit/a2e29c4ecaef9e2f6cd1603e868c139073375502)
- Updating tape [`b741168`](https://github.com/ljharb/function-bind/commit/b741168b12b235b1717ff696087645526b69213c)
- Upgrading tape [`63631a0`](https://github.com/ljharb/function-bind/commit/63631a04c7fbe97cc2fa61829cc27246d6986f74)
- Updating tape [`363cb46`](https://github.com/ljharb/function-bind/commit/363cb46dafb23cb3e347729a22f9448051d78464)
## v0.2.0 - 2014-03-23
### Commits
- Updating test coverage to match es5-shim. [`aa94d44`](https://github.com/ljharb/function-bind/commit/aa94d44b8f9d7f69f10e060db7709aa7a694e5d4)
- initial [`942ee07`](https://github.com/ljharb/function-bind/commit/942ee07e94e542d91798137bc4b80b926137e066)
- Setting the bound function's length properly. [`079f46a`](https://github.com/ljharb/function-bind/commit/079f46a2d3515b7c0b308c2c13fceb641f97ca25)
- Ensuring that some older browsers will throw when given a regex. [`36ac55b`](https://github.com/ljharb/function-bind/commit/36ac55b87f460d4330253c92870aa26fbfe8227f)
- Removing npm scripts that don't have dependencies [`9d2be60`](https://github.com/ljharb/function-bind/commit/9d2be600002cb8bc8606f8f3585ad3e05868c750)
- Updating tape [`297a4ac`](https://github.com/ljharb/function-bind/commit/297a4acc5464db381940aafb194d1c88f4e678f3)
- Skipping length tests for now. [`d9891ea`](https://github.com/ljharb/function-bind/commit/d9891ea4d2aaffa69f408339cdd61ff740f70565)
- don't take my tea [`dccd930`](https://github.com/ljharb/function-bind/commit/dccd930bfd60ea10cb178d28c97550c3bc8c1e07)
+20
View File
@@ -0,0 +1,20 @@
Copyright (c) 2013 Raynos.
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.
+46
View File
@@ -0,0 +1,46 @@
# function-bind <sup>[![Version Badge][npm-version-svg]][package-url]</sup>
[![github actions][actions-image]][actions-url]
<!--[![coverage][codecov-image]][codecov-url]-->
[![dependency status][deps-svg]][deps-url]
[![dev dependency status][dev-deps-svg]][dev-deps-url]
[![License][license-image]][license-url]
[![Downloads][downloads-image]][downloads-url]
[![npm badge][npm-badge-png]][package-url]
Implementation of function.prototype.bind
Old versions of phantomjs, Internet Explorer < 9, and node < 0.6 don't support `Function.prototype.bind`.
## Example
```js
Function.prototype.bind = require("function-bind")
```
## Installation
`npm install function-bind`
## Contributors
- Raynos
## MIT Licenced
[package-url]: https://npmjs.org/package/function-bind
[npm-version-svg]: https://versionbadg.es/Raynos/function-bind.svg
[deps-svg]: https://david-dm.org/Raynos/function-bind.svg
[deps-url]: https://david-dm.org/Raynos/function-bind
[dev-deps-svg]: https://david-dm.org/Raynos/function-bind/dev-status.svg
[dev-deps-url]: https://david-dm.org/Raynos/function-bind#info=devDependencies
[npm-badge-png]: https://nodei.co/npm/function-bind.png?downloads=true&stars=true
[license-image]: https://img.shields.io/npm/l/function-bind.svg
[license-url]: LICENSE
[downloads-image]: https://img.shields.io/npm/dm/function-bind.svg
[downloads-url]: https://npm-stat.com/charts.html?package=function-bind
[codecov-image]: https://codecov.io/gh/Raynos/function-bind/branch/main/graphs/badge.svg
[codecov-url]: https://app.codecov.io/gh/Raynos/function-bind/
[actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/Raynos/function-bind
[actions-url]: https://github.com/Raynos/function-bind/actions
+84
View File
@@ -0,0 +1,84 @@
'use strict';
/* eslint no-invalid-this: 1 */
var ERROR_MESSAGE = 'Function.prototype.bind called on incompatible ';
var toStr = Object.prototype.toString;
var max = Math.max;
var funcType = '[object Function]';
var concatty = function concatty(a, b) {
var arr = [];
for (var i = 0; i < a.length; i += 1) {
arr[i] = a[i];
}
for (var j = 0; j < b.length; j += 1) {
arr[j + a.length] = b[j];
}
return arr;
};
var slicy = function slicy(arrLike, offset) {
var arr = [];
for (var i = offset || 0, j = 0; i < arrLike.length; i += 1, j += 1) {
arr[j] = arrLike[i];
}
return arr;
};
var joiny = function (arr, joiner) {
var str = '';
for (var i = 0; i < arr.length; i += 1) {
str += arr[i];
if (i + 1 < arr.length) {
str += joiner;
}
}
return str;
};
module.exports = function bind(that) {
var target = this;
if (typeof target !== 'function' || toStr.apply(target) !== funcType) {
throw new TypeError(ERROR_MESSAGE + target);
}
var args = slicy(arguments, 1);
var bound;
var binder = function () {
if (this instanceof bound) {
var result = target.apply(
this,
concatty(args, arguments)
);
if (Object(result) === result) {
return result;
}
return this;
}
return target.apply(
that,
concatty(args, arguments)
);
};
var boundLength = max(0, target.length - args.length);
var boundArgs = [];
for (var i = 0; i < boundLength; i++) {
boundArgs[i] = '$' + i;
}
bound = Function('binder', 'return function (' + joiny(boundArgs, ',') + '){ return binder.apply(this,arguments); }')(binder);
if (target.prototype) {
var Empty = function Empty() {};
Empty.prototype = target.prototype;
bound.prototype = new Empty();
Empty.prototype = null;
}
return bound;
};
+5
View File
@@ -0,0 +1,5 @@
'use strict';
var implementation = require('./implementation');
module.exports = Function.prototype.bind || implementation;
+87
View File
@@ -0,0 +1,87 @@
{
"name": "function-bind",
"version": "1.1.2",
"description": "Implementation of Function.prototype.bind",
"keywords": [
"function",
"bind",
"shim",
"es5"
],
"author": "Raynos <raynos2@gmail.com>",
"repository": {
"type": "git",
"url": "https://github.com/Raynos/function-bind.git"
},
"funding": {
"url": "https://github.com/sponsors/ljharb"
},
"main": "index",
"homepage": "https://github.com/Raynos/function-bind",
"contributors": [
{
"name": "Raynos"
},
{
"name": "Jordan Harband",
"url": "https://github.com/ljharb"
}
],
"bugs": {
"url": "https://github.com/Raynos/function-bind/issues",
"email": "raynos2@gmail.com"
},
"devDependencies": {
"@ljharb/eslint-config": "^21.1.0",
"aud": "^2.0.3",
"auto-changelog": "^2.4.0",
"eslint": "=8.8.0",
"in-publish": "^2.0.1",
"npmignore": "^0.3.0",
"nyc": "^10.3.2",
"safe-publish-latest": "^2.0.0",
"tape": "^5.7.1"
},
"license": "MIT",
"scripts": {
"prepublishOnly": "safe-publish-latest",
"prepublish": "not-in-publish || npm run prepublishOnly",
"prepack": "npmignore --auto --commentLines=autogenerated",
"pretest": "npm run lint",
"test": "npm run tests-only",
"posttest": "aud --production",
"tests-only": "nyc tape 'test/**/*.js'",
"lint": "eslint --ext=js,mjs .",
"version": "auto-changelog && git add CHANGELOG.md",
"postversion": "auto-changelog && git add CHANGELOG.md && git commit --no-edit --amend && git tag -f \"v$(node -e \"console.log(require('./package.json').version)\")\""
},
"testling": {
"files": "test/index.js",
"browsers": [
"ie/8..latest",
"firefox/16..latest",
"firefox/nightly",
"chrome/22..latest",
"chrome/canary",
"opera/12..latest",
"opera/next",
"safari/5.1..latest",
"ipad/6.0..latest",
"iphone/6.0..latest",
"android-browser/4.2..latest"
]
},
"auto-changelog": {
"output": "CHANGELOG.md",
"template": "keepachangelog",
"unreleased": false,
"commitLimit": false,
"backfillLimit": false,
"hideCredit": true
},
"publishConfig": {
"ignore": [
".github/workflows"
]
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"rules": {
"array-bracket-newline": 0,
"array-element-newline": 0,
"max-statements-per-line": [2, { "max": 2 }],
"no-invalid-this": 0,
"no-magic-numbers": 0,
}
}
+252
View File
@@ -0,0 +1,252 @@
// jscs:disable requireUseStrict
var test = require('tape');
var functionBind = require('../implementation');
var getCurrentContext = function () { return this; };
test('functionBind is a function', function (t) {
t.equal(typeof functionBind, 'function');
t.end();
});
test('non-functions', function (t) {
var nonFunctions = [true, false, [], {}, 42, 'foo', NaN, /a/g];
t.plan(nonFunctions.length);
for (var i = 0; i < nonFunctions.length; ++i) {
try { functionBind.call(nonFunctions[i]); } catch (ex) {
t.ok(ex instanceof TypeError, 'throws when given ' + String(nonFunctions[i]));
}
}
t.end();
});
test('without a context', function (t) {
t.test('binds properly', function (st) {
var args, context;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
})
};
namespace.func(1, 2, 3);
st.deepEqual(args, [1, 2, 3]);
st.equal(context, getCurrentContext.call());
st.end();
});
t.test('binds properly, and still supplies bound arguments', function (st) {
var args, context;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, undefined, 1, 2, 3)
};
namespace.func(4, 5, 6);
st.deepEqual(args, [1, 2, 3, 4, 5, 6]);
st.equal(context, getCurrentContext.call());
st.end();
});
t.test('returns properly', function (st) {
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, null)
};
var context = namespace.func(1, 2, 3);
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
st.end();
});
t.test('returns properly with bound arguments', function (st) {
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, null, 1, 2, 3)
};
var context = namespace.func(4, 5, 6);
st.equal(context, getCurrentContext.call(), 'returned context is namespaced context');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
st.end();
});
t.test('called as a constructor', function (st) {
var thunkify = function (value) {
return function () { return value; };
};
st.test('returns object value', function (sst) {
var expectedReturnValue = [1, 2, 3];
var Constructor = functionBind.call(thunkify(expectedReturnValue), null);
var result = new Constructor();
sst.equal(result, expectedReturnValue);
sst.end();
});
st.test('does not return primitive value', function (sst) {
var Constructor = functionBind.call(thunkify(42), null);
var result = new Constructor();
sst.notEqual(result, 42);
sst.end();
});
st.test('object from bound constructor is instance of original and bound constructor', function (sst) {
var A = function (x) {
this.name = x || 'A';
};
var B = functionBind.call(A, null, 'B');
var result = new B();
sst.ok(result instanceof B, 'result is instance of bound constructor');
sst.ok(result instanceof A, 'result is instance of original constructor');
sst.end();
});
st.end();
});
t.end();
});
test('with a context', function (t) {
t.test('with no bound arguments', function (st) {
var args, context;
var boundContext = {};
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, boundContext)
};
namespace.func(1, 2, 3);
st.equal(context, boundContext, 'binds a context properly');
st.deepEqual(args, [1, 2, 3], 'supplies passed arguments');
st.end();
});
t.test('with bound arguments', function (st) {
var args, context;
var boundContext = {};
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
context = this;
}, boundContext, 1, 2, 3)
};
namespace.func(4, 5, 6);
st.equal(context, boundContext, 'binds a context properly');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'supplies bound and passed arguments');
st.end();
});
t.test('returns properly', function (st) {
var boundContext = {};
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, boundContext)
};
var context = namespace.func(1, 2, 3);
st.equal(context, boundContext, 'returned context is bound context');
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
st.deepEqual(args, [1, 2, 3], 'passed arguments are correct');
st.end();
});
t.test('returns properly with bound arguments', function (st) {
var boundContext = {};
var args;
var namespace = {
func: functionBind.call(function () {
args = Array.prototype.slice.call(arguments);
return this;
}, boundContext, 1, 2, 3)
};
var context = namespace.func(4, 5, 6);
st.equal(context, boundContext, 'returned context is bound context');
st.notEqual(context, getCurrentContext.call(), 'returned context is not lexical context');
st.deepEqual(args, [1, 2, 3, 4, 5, 6], 'passed arguments are correct');
st.end();
});
t.test('passes the correct arguments when called as a constructor', function (st) {
var expected = { name: 'Correct' };
var namespace = {
Func: functionBind.call(function (arg) {
return arg;
}, { name: 'Incorrect' })
};
var returned = new namespace.Func(expected);
st.equal(returned, expected, 'returns the right arg when called as a constructor');
st.end();
});
t.test('has the new instance\'s context when called as a constructor', function (st) {
var actualContext;
var expectedContext = { foo: 'bar' };
var namespace = {
Func: functionBind.call(function () {
actualContext = this;
}, expectedContext)
};
var result = new namespace.Func();
st.equal(result instanceof namespace.Func, true);
st.notEqual(actualContext, expectedContext);
st.end();
});
t.end();
});
test('bound function length', function (t) {
t.test('sets a correct length without thisArg', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; });
st.equal(subject.length, 3);
st.equal(subject(1, 2, 3), 6);
st.end();
});
t.test('sets a correct length with thisArg', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {});
st.equal(subject.length, 3);
st.equal(subject(1, 2, 3), 6);
st.end();
});
t.test('sets a correct length without thisArg and first argument', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1);
st.equal(subject.length, 2);
st.equal(subject(2, 3), 6);
st.end();
});
t.test('sets a correct length with thisArg and first argument', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1);
st.equal(subject.length, 2);
st.equal(subject(2, 3), 6);
st.end();
});
t.test('sets a correct length without thisArg and too many arguments', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, undefined, 1, 2, 3, 4);
st.equal(subject.length, 0);
st.equal(subject(), 6);
st.end();
});
t.test('sets a correct length with thisArg and too many arguments', function (st) {
var subject = functionBind.call(function (a, b, c) { return a + b + c; }, {}, 1, 2, 3, 4);
st.equal(subject.length, 0);
st.equal(subject(), 6);
st.end();
});
});
+5
View File
@@ -0,0 +1,5 @@
{
"root": true,
"extends": "@ljharb",
}
+12
View File
@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: [ljharb]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: npm/hasown
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # Replace with a single custom sponsorship URL
Generated Vendored
+13
View File
@@ -0,0 +1,13 @@
{
"all": true,
"check-coverage": false,
"reporter": ["text-summary", "text", "html", "json"],
"lines": 86,
"statements": 85.93,
"functions": 82.43,
"branches": 76.06,
"exclude": [
"coverage",
"test"
]
}
+40
View File
@@ -0,0 +1,40 @@
# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [v2.0.2](https://github.com/inspect-js/hasOwn/compare/v2.0.1...v2.0.2) - 2024-03-10
### Commits
- [types] use shared config [`68e9d4d`](https://github.com/inspect-js/hasOwn/commit/68e9d4dab6facb4f05f02c6baea94a3f2a4e44b2)
- [actions] remove redundant finisher; use reusable workflow [`241a68e`](https://github.com/inspect-js/hasOwn/commit/241a68e13ea1fe52bec5ba7f74144befc31fae7b)
- [Tests] increase coverage [`4125c0d`](https://github.com/inspect-js/hasOwn/commit/4125c0d6121db56ae30e38346dfb0c000b04f0a7)
- [Tests] skip `npm ls` in old node due to TS [`01b9282`](https://github.com/inspect-js/hasOwn/commit/01b92822f9971dea031eafdd14767df41d61c202)
- [types] improve predicate type [`d340f85`](https://github.com/inspect-js/hasOwn/commit/d340f85ce02e286ef61096cbbb6697081d40a12b)
- [Dev Deps] update `tape` [`70089fc`](https://github.com/inspect-js/hasOwn/commit/70089fcf544e64acc024cbe60f5a9b00acad86de)
- [Tests] use `@arethetypeswrong/cli` [`50b272c`](https://github.com/inspect-js/hasOwn/commit/50b272c829f40d053a3dd91c9796e0ac0b2af084)
## [v2.0.1](https://github.com/inspect-js/hasOwn/compare/v2.0.0...v2.0.1) - 2024-02-10
### Commits
- [types] use a handwritten d.ts file; fix exported type [`012b989`](https://github.com/inspect-js/hasOwn/commit/012b9898ccf91dc441e2ebf594ff70270a5fda58)
- [Dev Deps] update `@types/function-bind`, `@types/mock-property`, `@types/tape`, `aud`, `mock-property`, `npmignore`, `tape`, `typescript` [`977a56f`](https://github.com/inspect-js/hasOwn/commit/977a56f51a1f8b20566f3c471612137894644025)
- [meta] add `sideEffects` flag [`3a60b7b`](https://github.com/inspect-js/hasOwn/commit/3a60b7bf42fccd8c605e5f145a6fcc83b13cb46f)
## [v2.0.0](https://github.com/inspect-js/hasOwn/compare/v1.0.1...v2.0.0) - 2023-10-19
### Commits
- revamped implementation, tests, readme [`72bf8b3`](https://github.com/inspect-js/hasOwn/commit/72bf8b338e77a638f0a290c63ffaed18339c36b4)
- [meta] revamp package.json [`079775f`](https://github.com/inspect-js/hasOwn/commit/079775fb1ec72c1c6334069593617a0be3847458)
- Only apps should have lockfiles [`6640e23`](https://github.com/inspect-js/hasOwn/commit/6640e233d1bb8b65260880f90787637db157d215)
## v1.0.1 - 2023-10-10
### Commits
- Initial commit [`8dbfde6`](https://github.com/inspect-js/hasOwn/commit/8dbfde6e8fb0ebb076fab38d138f2984eb340a62)
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) Jordan Harband and 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.

Some files were not shown because too many files have changed in this diff Show More