@knighted/module 1.0.0-beta.3 → 1.0.0-beta.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/cjs/format.cjs +6 -0
- package/dist/cjs/scopeNodes.d.cts +2 -0
- package/dist/cjs/utils/identifiers.cjs +6 -3
- package/dist/cjs/utils/lang.cjs +3 -3
- package/dist/cjs/utils/scopeNodes.cjs +7 -0
- package/dist/cjs/utils.cjs +9 -6
- package/dist/format.js +6 -0
- package/dist/scopeNodes.d.ts +2 -0
- package/dist/src/utils/scopeNodes.d.ts +2 -0
- package/dist/utils/identifiers.js +5 -2
- package/dist/utils/lang.js +3 -3
- package/dist/utils/scopeNodes.js +2 -0
- package/dist/utils.js +8 -5
- package/package.json +2 -2
- package/dist/cjs/helpers/scope.cjs +0 -12
- package/dist/cjs/scope.d.cts +0 -6
- package/dist/helpers/scope.js +0 -7
- package/dist/scope.d.ts +0 -6
- package/dist/src/helpers/scope.d.ts +0 -6
package/README.md
CHANGED
|
@@ -22,7 +22,7 @@ By default `@knighted/module` transforms the one-to-one [differences between ES
|
|
|
22
22
|
|
|
23
23
|
## Requirements
|
|
24
24
|
|
|
25
|
-
- Node >=
|
|
25
|
+
- Node >= 22.21.1
|
|
26
26
|
|
|
27
27
|
## Install
|
|
28
28
|
|
|
@@ -133,6 +133,7 @@ Behavior notes (defaults in parentheses)
|
|
|
133
133
|
- `requireSource` (`builtin`): whether `require` comes from Node or `createRequire`.
|
|
134
134
|
- `cjsDefault` (`auto`): bundler-style default interop vs direct `module.exports`.
|
|
135
135
|
- `out`/`inPlace`: write the transformed code to a file; otherwise the function returns the transformed string only.
|
|
136
|
+
- CommonJS → ESM lowering will throw on `with` statements and unshadowed `eval` calls to avoid unsound rewrites.
|
|
136
137
|
|
|
137
138
|
See [docs/esm-to-cjs.md](docs/esm-to-cjs.md) for deeper notes on live bindings, interop helpers, top-level await behavior, and `import.meta.main` handling. For CommonJS to ESM lowering details, read [docs/cjs-to-esm.md](docs/cjs-to-esm.md).
|
|
138
139
|
|
|
@@ -141,3 +142,4 @@ See [docs/esm-to-cjs.md](docs/esm-to-cjs.md) for deeper notes on live bindings,
|
|
|
141
142
|
- Remove `@knighted/specifier` and avoid double parsing.
|
|
142
143
|
- Emit source maps and clearer diagnostics for transform choices.
|
|
143
144
|
- Broaden fixtures covering live-binding and top-level await edge cases across Node versions.
|
|
145
|
+
- Benchmark scope analysis choices: compare `periscopic`, `scope-analyzer`, and `eslint-scope` on fixtures and pick the final adapter.
|
package/dist/cjs/format.cjs
CHANGED
|
@@ -382,6 +382,12 @@ const format = async (src, ast, opts) => {
|
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
}
|
|
385
|
+
if (shouldRaiseEsm && node.type === 'WithStatement') {
|
|
386
|
+
throw new Error('Cannot transform to ESM: with statements are not supported.');
|
|
387
|
+
}
|
|
388
|
+
if (shouldRaiseEsm && node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === 'eval' && !shadowedBindings.has('eval')) {
|
|
389
|
+
throw new Error('Cannot transform to ESM: eval is not supported.');
|
|
390
|
+
}
|
|
385
391
|
if (shouldRaiseEsm && node.type === 'CallExpression' && isRequireCall(node, shadowedBindings)) {
|
|
386
392
|
const isStatic = isStaticRequire(node, shadowedBindings);
|
|
387
393
|
const parent = ancestors[ancestors.length - 2] ?? null;
|
|
@@ -5,8 +5,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.collectScopeIdentifiers = exports.collectModuleIdentifiers = void 0;
|
|
7
7
|
var _walk = require("#walk");
|
|
8
|
-
var _scope = require("#helpers/scope.js");
|
|
9
8
|
var _identifier = require("#helpers/identifier.js");
|
|
9
|
+
var _scopeNodes = require("./scopeNodes.cjs");
|
|
10
10
|
const collectScopeIdentifiers = (node, scopes) => {
|
|
11
11
|
const {
|
|
12
12
|
type
|
|
@@ -152,11 +152,14 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
152
152
|
const isModuleScope = _identifier.identifier.isModuleScope(ancestors);
|
|
153
153
|
const isClassOrFuncDeclaration = _identifier.identifier.isClassOrFuncDeclarationId(ancestors);
|
|
154
154
|
const isVarDeclarationInGlobalScope = _identifier.identifier.isVarDeclarationInGlobalScope(ancestors);
|
|
155
|
+
const parent = ancestors[ancestors.length - 2];
|
|
156
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
157
|
+
const hoistSafe = parent.type === 'FunctionDeclaration' || parent.type === 'VariableDeclarator' && grandParent?.type === 'VariableDeclaration' && grandParent.kind === 'var';
|
|
155
158
|
if (isModuleScope || isClassOrFuncDeclaration || isVarDeclarationInGlobalScope) {
|
|
156
159
|
meta.declare.push(node);
|
|
157
160
|
|
|
158
161
|
// Check for hoisted reads
|
|
159
|
-
if (hoisting && globalReads.has(name)) {
|
|
162
|
+
if (hoisting && hoistSafe && globalReads.has(name)) {
|
|
160
163
|
const reads = globalReads.get(name);
|
|
161
164
|
if (reads) {
|
|
162
165
|
reads.forEach(read => {
|
|
@@ -180,7 +183,7 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
180
183
|
const {
|
|
181
184
|
type
|
|
182
185
|
} = node;
|
|
183
|
-
if (
|
|
186
|
+
if (_scopeNodes.scopeNodes.includes(type)) {
|
|
184
187
|
scopes.pop();
|
|
185
188
|
}
|
|
186
189
|
}
|
package/dist/cjs/utils/lang.cjs
CHANGED
|
@@ -8,11 +8,11 @@ var _nodePath = require("node:path");
|
|
|
8
8
|
// Determine language from filename extension for specifier rewrite.
|
|
9
9
|
|
|
10
10
|
const getLangFromExt = filename => {
|
|
11
|
-
const ext = (0, _nodePath.extname)(filename);
|
|
12
|
-
if (ext
|
|
11
|
+
const ext = (0, _nodePath.extname)(filename).toLowerCase();
|
|
12
|
+
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
|
|
13
13
|
return 'js';
|
|
14
14
|
}
|
|
15
|
-
if (ext
|
|
15
|
+
if (ext === '.ts' || ext === '.mts' || ext === '.cts') {
|
|
16
16
|
return 'ts';
|
|
17
17
|
}
|
|
18
18
|
if (ext === '.tsx') {
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.scopeNodes = void 0;
|
|
7
|
+
const scopeNodes = exports.scopeNodes = ['BlockStatement', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression', 'ClassDeclaration', 'ClassExpression', 'ClassBody', 'StaticBlock'];
|
package/dist/cjs/utils.cjs
CHANGED
|
@@ -6,14 +6,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
6
6
|
exports.requireMainRgx = exports.isValidUrl = exports.getLangFromExt = exports.exportsRename = exports.collectScopeIdentifiers = exports.collectModuleIdentifiers = exports.collectCjsExports = void 0;
|
|
7
7
|
var _nodePath = require("node:path");
|
|
8
8
|
var _walk = require("./walk.cjs");
|
|
9
|
-
var _scope = require("./helpers/scope.cjs");
|
|
10
9
|
var _identifier = require("./helpers/identifier.cjs");
|
|
10
|
+
var _scopeNodes = require("./utils/scopeNodes.cjs");
|
|
11
11
|
const getLangFromExt = filename => {
|
|
12
|
-
const ext = (0, _nodePath.extname)(filename);
|
|
13
|
-
if (ext
|
|
12
|
+
const ext = (0, _nodePath.extname)(filename).toLowerCase();
|
|
13
|
+
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
|
|
14
14
|
return 'js';
|
|
15
15
|
}
|
|
16
|
-
if (ext
|
|
16
|
+
if (ext === '.ts' || ext === '.mts' || ext === '.cts') {
|
|
17
17
|
return 'ts';
|
|
18
18
|
}
|
|
19
19
|
if (ext === '.tsx') {
|
|
@@ -250,11 +250,14 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
250
250
|
const isModuleScope = _identifier.identifier.isModuleScope(ancestors);
|
|
251
251
|
const isClassOrFuncDeclaration = _identifier.identifier.isClassOrFuncDeclarationId(ancestors);
|
|
252
252
|
const isVarDeclarationInGlobalScope = _identifier.identifier.isVarDeclarationInGlobalScope(ancestors);
|
|
253
|
+
const parent = ancestors[ancestors.length - 2];
|
|
254
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
255
|
+
const hoistSafe = parent.type === 'FunctionDeclaration' || parent.type === 'VariableDeclarator' && grandParent?.type === 'VariableDeclaration' && grandParent.kind === 'var';
|
|
253
256
|
if (isModuleScope || isClassOrFuncDeclaration || isVarDeclarationInGlobalScope) {
|
|
254
257
|
meta.declare.push(node);
|
|
255
258
|
|
|
256
259
|
// Check for hoisted reads
|
|
257
|
-
if (hoisting && globalReads.has(name)) {
|
|
260
|
+
if (hoisting && hoistSafe && globalReads.has(name)) {
|
|
258
261
|
const reads = globalReads.get(name);
|
|
259
262
|
if (reads) {
|
|
260
263
|
reads.forEach(read => {
|
|
@@ -278,7 +281,7 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
278
281
|
const {
|
|
279
282
|
type
|
|
280
283
|
} = node;
|
|
281
|
-
if (
|
|
284
|
+
if (_scopeNodes.scopeNodes.includes(type)) {
|
|
282
285
|
scopes.pop();
|
|
283
286
|
}
|
|
284
287
|
}
|
package/dist/format.js
CHANGED
|
@@ -375,6 +375,12 @@ const format = async (src, ast, opts) => {
|
|
|
375
375
|
}
|
|
376
376
|
}
|
|
377
377
|
}
|
|
378
|
+
if (shouldRaiseEsm && node.type === 'WithStatement') {
|
|
379
|
+
throw new Error('Cannot transform to ESM: with statements are not supported.');
|
|
380
|
+
}
|
|
381
|
+
if (shouldRaiseEsm && node.type === 'CallExpression' && node.callee.type === 'Identifier' && node.callee.name === 'eval' && !shadowedBindings.has('eval')) {
|
|
382
|
+
throw new Error('Cannot transform to ESM: eval is not supported.');
|
|
383
|
+
}
|
|
378
384
|
if (shouldRaiseEsm && node.type === 'CallExpression' && isRequireCall(node, shadowedBindings)) {
|
|
379
385
|
const isStatic = isStaticRequire(node, shadowedBindings);
|
|
380
386
|
const parent = ancestors[ancestors.length - 2] ?? null;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ancestorWalk } from '#walk';
|
|
2
|
-
import { scopes as scopeNodes } from '#helpers/scope.js';
|
|
3
2
|
import { identifier } from '#helpers/identifier.js';
|
|
3
|
+
import { scopeNodes } from './scopeNodes.js';
|
|
4
4
|
const collectScopeIdentifiers = (node, scopes) => {
|
|
5
5
|
const {
|
|
6
6
|
type
|
|
@@ -145,11 +145,14 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
145
145
|
const isModuleScope = identifier.isModuleScope(ancestors);
|
|
146
146
|
const isClassOrFuncDeclaration = identifier.isClassOrFuncDeclarationId(ancestors);
|
|
147
147
|
const isVarDeclarationInGlobalScope = identifier.isVarDeclarationInGlobalScope(ancestors);
|
|
148
|
+
const parent = ancestors[ancestors.length - 2];
|
|
149
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
150
|
+
const hoistSafe = parent.type === 'FunctionDeclaration' || parent.type === 'VariableDeclarator' && grandParent?.type === 'VariableDeclaration' && grandParent.kind === 'var';
|
|
148
151
|
if (isModuleScope || isClassOrFuncDeclaration || isVarDeclarationInGlobalScope) {
|
|
149
152
|
meta.declare.push(node);
|
|
150
153
|
|
|
151
154
|
// Check for hoisted reads
|
|
152
|
-
if (hoisting && globalReads.has(name)) {
|
|
155
|
+
if (hoisting && hoistSafe && globalReads.has(name)) {
|
|
153
156
|
const reads = globalReads.get(name);
|
|
154
157
|
if (reads) {
|
|
155
158
|
reads.forEach(read => {
|
package/dist/utils/lang.js
CHANGED
|
@@ -3,11 +3,11 @@ import { extname } from 'node:path';
|
|
|
3
3
|
// Determine language from filename extension for specifier rewrite.
|
|
4
4
|
|
|
5
5
|
const getLangFromExt = filename => {
|
|
6
|
-
const ext = extname(filename);
|
|
7
|
-
if (ext
|
|
6
|
+
const ext = extname(filename).toLowerCase();
|
|
7
|
+
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
|
|
8
8
|
return 'js';
|
|
9
9
|
}
|
|
10
|
-
if (ext
|
|
10
|
+
if (ext === '.ts' || ext === '.mts' || ext === '.cts') {
|
|
11
11
|
return 'ts';
|
|
12
12
|
}
|
|
13
13
|
if (ext === '.tsx') {
|
package/dist/utils.js
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { extname } from 'node:path';
|
|
2
2
|
import { ancestorWalk } from './walk.js';
|
|
3
|
-
import { scopes as scopeNodes } from './helpers/scope.js';
|
|
4
3
|
import { identifier } from './helpers/identifier.js';
|
|
4
|
+
import { scopeNodes } from './utils/scopeNodes.js';
|
|
5
5
|
const getLangFromExt = filename => {
|
|
6
|
-
const ext = extname(filename);
|
|
7
|
-
if (ext
|
|
6
|
+
const ext = extname(filename).toLowerCase();
|
|
7
|
+
if (ext === '.js' || ext === '.mjs' || ext === '.cjs') {
|
|
8
8
|
return 'js';
|
|
9
9
|
}
|
|
10
|
-
if (ext
|
|
10
|
+
if (ext === '.ts' || ext === '.mts' || ext === '.cts') {
|
|
11
11
|
return 'ts';
|
|
12
12
|
}
|
|
13
13
|
if (ext === '.tsx') {
|
|
@@ -240,11 +240,14 @@ const collectModuleIdentifiers = async (ast, hoisting = true) => {
|
|
|
240
240
|
const isModuleScope = identifier.isModuleScope(ancestors);
|
|
241
241
|
const isClassOrFuncDeclaration = identifier.isClassOrFuncDeclarationId(ancestors);
|
|
242
242
|
const isVarDeclarationInGlobalScope = identifier.isVarDeclarationInGlobalScope(ancestors);
|
|
243
|
+
const parent = ancestors[ancestors.length - 2];
|
|
244
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
245
|
+
const hoistSafe = parent.type === 'FunctionDeclaration' || parent.type === 'VariableDeclarator' && grandParent?.type === 'VariableDeclaration' && grandParent.kind === 'var';
|
|
243
246
|
if (isModuleScope || isClassOrFuncDeclaration || isVarDeclarationInGlobalScope) {
|
|
244
247
|
meta.declare.push(node);
|
|
245
248
|
|
|
246
249
|
// Check for hoisted reads
|
|
247
|
-
if (hoisting && globalReads.has(name)) {
|
|
250
|
+
if (hoisting && hoistSafe && globalReads.has(name)) {
|
|
248
251
|
const reads = globalReads.get(name);
|
|
249
252
|
if (reads) {
|
|
250
253
|
reads.forEach(read => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@knighted/module",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.5",
|
|
4
4
|
"description": "Transforms differences between ES modules and CommonJS.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/module.js",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"#formatters/*.js": "./src/formatters/*.js"
|
|
28
28
|
},
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22.21.1"
|
|
31
31
|
},
|
|
32
32
|
"engineStrict": true,
|
|
33
33
|
"scripts": {
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, "__esModule", {
|
|
4
|
-
value: true
|
|
5
|
-
});
|
|
6
|
-
exports.scopes = exports.scope = void 0;
|
|
7
|
-
const scopes = exports.scopes = ['BlockStatement', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression', 'ClassDeclaration', 'ClassExpression', 'ClassBody', 'StaticBlock'];
|
|
8
|
-
const scope = exports.scope = {
|
|
9
|
-
isScope(node) {
|
|
10
|
-
return scopes.includes(node.type);
|
|
11
|
-
}
|
|
12
|
-
};
|
package/dist/cjs/scope.d.cts
DELETED
package/dist/helpers/scope.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
const scopes = ['BlockStatement', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression', 'ClassDeclaration', 'ClassExpression', 'ClassBody', 'StaticBlock'];
|
|
2
|
-
const scope = {
|
|
3
|
-
isScope(node) {
|
|
4
|
-
return scopes.includes(node.type);
|
|
5
|
-
}
|
|
6
|
-
};
|
|
7
|
-
export { scopes, scope };
|
package/dist/scope.d.ts
DELETED