@knighted/module 1.0.0-alpha.9 → 1.0.0-beta.1
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 +28 -16
- package/dist/assignmentExpression.d.ts +12 -0
- package/dist/cjs/assignmentExpression.d.cts +12 -0
- package/dist/cjs/exports.d.cts +6 -0
- package/dist/cjs/expressionStatement.d.cts +2 -3
- package/dist/cjs/format.cjs +133 -26
- package/dist/cjs/format.d.cts +6 -6
- package/dist/cjs/formatters/assignmentExpression.cjs +37 -0
- package/dist/cjs/formatters/expressionStatement.cjs +36 -55
- package/dist/cjs/formatters/identifier.cjs +31 -31
- package/dist/cjs/formatters/memberExpression.cjs +24 -11
- package/dist/cjs/formatters/metaProperty.cjs +23 -35
- package/dist/cjs/helpers/identifier.cjs +132 -0
- package/dist/cjs/helpers/scope.cjs +12 -0
- package/dist/cjs/identifier.d.cts +31 -5
- package/dist/cjs/identifiers.d.cts +19 -0
- package/dist/cjs/lang.d.cts +4 -0
- package/dist/cjs/memberExpression.d.cts +2 -3
- package/dist/cjs/metaProperty.d.cts +2 -3
- package/dist/cjs/module.cjs +26 -27
- package/dist/cjs/parse.cjs +3 -14
- package/dist/cjs/parse.d.cts +1 -1
- package/dist/cjs/scope.d.cts +6 -0
- package/dist/cjs/types.d.cts +40 -4
- package/dist/cjs/url.d.cts +2 -0
- package/dist/cjs/utils/exports.cjs +227 -0
- package/dist/cjs/utils/identifiers.cjs +190 -0
- package/dist/cjs/utils/lang.cjs +25 -0
- package/dist/cjs/utils/url.cjs +16 -0
- package/dist/cjs/utils.cjs +288 -0
- package/dist/cjs/utils.d.cts +26 -0
- package/dist/cjs/walk.cjs +75 -0
- package/dist/cjs/walk.d.cts +20 -0
- package/dist/exports.d.ts +6 -0
- package/dist/expressionStatement.d.ts +2 -3
- package/dist/format.d.ts +6 -6
- package/dist/format.js +135 -27
- package/dist/formatters/assignmentExpression.js +30 -0
- package/dist/formatters/expressionStatement.js +36 -55
- package/dist/formatters/identifier.js +31 -31
- package/dist/formatters/memberExpression.js +24 -11
- package/dist/formatters/metaProperty.js +23 -35
- package/dist/helpers/identifier.js +127 -0
- package/dist/helpers/scope.js +7 -0
- package/dist/identifier.d.ts +31 -5
- package/dist/identifiers.d.ts +19 -0
- package/dist/lang.d.ts +4 -0
- package/dist/memberExpression.d.ts +2 -3
- package/dist/metaProperty.d.ts +2 -3
- package/dist/module.js +26 -27
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +3 -14
- package/dist/scope.d.ts +6 -0
- package/dist/src/format.d.ts +9 -0
- package/dist/src/formatters/assignmentExpression.d.ts +12 -0
- package/dist/src/formatters/expressionStatement.d.ts +4 -0
- package/dist/src/formatters/identifier.d.ts +12 -0
- package/dist/src/formatters/memberExpression.d.ts +4 -0
- package/dist/src/formatters/metaProperty.d.ts +4 -0
- package/dist/src/helpers/identifier.d.ts +31 -0
- package/dist/src/helpers/scope.d.ts +6 -0
- package/dist/src/module.d.ts +3 -0
- package/dist/src/parse.d.ts +2 -0
- package/dist/src/types.d.ts +43 -0
- package/dist/src/utils/exports.d.ts +6 -0
- package/dist/src/utils/identifiers.d.ts +19 -0
- package/dist/src/utils/lang.d.ts +4 -0
- package/dist/src/utils/url.d.ts +2 -0
- package/dist/src/utils.d.ts +26 -0
- package/dist/src/walk.d.ts +20 -0
- package/dist/types.d.ts +40 -4
- package/dist/url.d.ts +2 -0
- package/dist/utils/exports.js +221 -0
- package/dist/utils/identifiers.js +183 -0
- package/dist/utils/lang.js +20 -0
- package/dist/utils/url.js +10 -0
- package/dist/utils.d.ts +26 -0
- package/dist/utils.js +278 -0
- package/dist/walk.d.ts +20 -0
- package/dist/walk.js +69 -0
- package/package.json +43 -25
- package/dist/formatters/expressionStatement.d.ts +0 -5
- package/dist/formatters/identifier.d.ts +0 -5
- package/dist/formatters/memberExpression.d.ts +0 -5
- package/dist/formatters/metaProperty.d.ts +0 -5
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.isIdentifierName = exports.identifier = void 0;
|
|
7
|
+
var _periscopic = require("periscopic");
|
|
8
|
+
/**
|
|
9
|
+
* Focus exclusively on IdentifierName type as it has the name property,
|
|
10
|
+
* which is what the identifer utilities are interested in.
|
|
11
|
+
*
|
|
12
|
+
* Explicitly ignore the TSThisParameter type as it is not a valid identifier name.
|
|
13
|
+
*/
|
|
14
|
+
const isIdentifierName = node => {
|
|
15
|
+
return node.type === 'Identifier' && typeof node.name === 'string' && node.name !== 'this';
|
|
16
|
+
};
|
|
17
|
+
exports.isIdentifierName = isIdentifierName;
|
|
18
|
+
const scopeCache = new WeakMap();
|
|
19
|
+
const getScopeContext = program => {
|
|
20
|
+
const cached = scopeCache.get(program);
|
|
21
|
+
if (cached) {
|
|
22
|
+
return cached;
|
|
23
|
+
}
|
|
24
|
+
const {
|
|
25
|
+
scope
|
|
26
|
+
} = (0, _periscopic.analyze)(program);
|
|
27
|
+
const context = {
|
|
28
|
+
scope
|
|
29
|
+
};
|
|
30
|
+
scopeCache.set(program, context);
|
|
31
|
+
return context;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* All methods receive the full set of ancestors, which
|
|
36
|
+
* specifically includes the node itself as the last element.
|
|
37
|
+
* The second to last element is the parent node, and so on.
|
|
38
|
+
* The first element is the root node.
|
|
39
|
+
*/
|
|
40
|
+
const identifier = exports.identifier = {
|
|
41
|
+
isNamed: node => {
|
|
42
|
+
return isIdentifierName(node);
|
|
43
|
+
},
|
|
44
|
+
isMetaProperty(ancestors) {
|
|
45
|
+
const parent = ancestors[ancestors.length - 2];
|
|
46
|
+
return parent.type === 'MetaProperty' || parent.type === 'MemberExpression' && parent.object.type === 'MetaProperty';
|
|
47
|
+
},
|
|
48
|
+
isModuleScope(ancestors, includeImports = false) {
|
|
49
|
+
const node = ancestors[ancestors.length - 1];
|
|
50
|
+
const parent = ancestors[ancestors.length - 2];
|
|
51
|
+
const program = ancestors[0];
|
|
52
|
+
if (!identifier.isNamed(node) || identifier.isMetaProperty(ancestors) || parent.type === 'LabeledStatement' || parent.type === 'BreakStatement' || parent.type === 'ContinueStatement') {
|
|
53
|
+
return false;
|
|
54
|
+
}
|
|
55
|
+
if (parent.type === 'ImportSpecifier' || parent.type === 'ImportDefaultSpecifier' || parent.type === 'ImportNamespaceSpecifier') {
|
|
56
|
+
return includeImports && parent.local.name === node.name;
|
|
57
|
+
}
|
|
58
|
+
if (parent.type === 'Property' && parent.key === node && !parent.computed) {
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
if (parent.type === 'MemberExpression' && parent.property === node && !parent.computed) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const {
|
|
65
|
+
scope: rootScope
|
|
66
|
+
} = getScopeContext(program);
|
|
67
|
+
const owner = rootScope.find_owner(node.name);
|
|
68
|
+
if (!owner) {
|
|
69
|
+
return node.name === 'exports';
|
|
70
|
+
}
|
|
71
|
+
return owner === rootScope;
|
|
72
|
+
},
|
|
73
|
+
isMemberExpressionRoot(ancestors) {
|
|
74
|
+
const node = ancestors[ancestors.length - 1];
|
|
75
|
+
const parent = ancestors[ancestors.length - 2];
|
|
76
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
77
|
+
return parent.type === 'MemberExpression' && parent.object === node && grandParent.type !== 'MemberExpression';
|
|
78
|
+
},
|
|
79
|
+
isDeclaration(ancestors) {
|
|
80
|
+
const node = ancestors[ancestors.length - 1];
|
|
81
|
+
const parent = ancestors[ancestors.length - 2];
|
|
82
|
+
return (parent.type === 'VariableDeclarator' || parent.type === 'FunctionDeclaration' || parent.type === 'ClassDeclaration') && parent.id === node;
|
|
83
|
+
},
|
|
84
|
+
isClassOrFuncDeclarationId(ancestors) {
|
|
85
|
+
const node = ancestors[ancestors.length - 1];
|
|
86
|
+
const parent = ancestors[ancestors.length - 2];
|
|
87
|
+
return (parent.type === 'ClassDeclaration' || parent.type === 'FunctionDeclaration') && parent.id === node && ancestors.length <= 3;
|
|
88
|
+
},
|
|
89
|
+
isVarDeclarationInGlobalScope(ancestors) {
|
|
90
|
+
const node = ancestors[ancestors.length - 1];
|
|
91
|
+
const parent = ancestors[ancestors.length - 2];
|
|
92
|
+
const grandParent = ancestors[ancestors.length - 3];
|
|
93
|
+
const varBoundScopes = ['ClassDeclaration', 'ClassExpression', 'FunctionDeclaration', 'FunctionExpression', 'ArrowFunctionExpression'];
|
|
94
|
+
return parent.type === 'VariableDeclarator' && parent.id === node && grandParent.type === 'VariableDeclaration' && grandParent.kind === 'var' && ancestors.every(ancestor => {
|
|
95
|
+
return !varBoundScopes.includes(ancestor.type);
|
|
96
|
+
});
|
|
97
|
+
},
|
|
98
|
+
isIife(ancestors) {
|
|
99
|
+
const parent = ancestors[ancestors.length - 2];
|
|
100
|
+
return parent.type === 'FunctionExpression' && ancestors.some(ancestor => ancestor.type === 'ParenthesizedExpression');
|
|
101
|
+
},
|
|
102
|
+
isFunctionExpressionId(ancestors) {
|
|
103
|
+
const node = ancestors[ancestors.length - 1];
|
|
104
|
+
const parent = ancestors[ancestors.length - 2];
|
|
105
|
+
return parent.type === 'FunctionExpression' && parent.id === node;
|
|
106
|
+
},
|
|
107
|
+
isExportSpecifierAlias(ancestors) {
|
|
108
|
+
const node = ancestors[ancestors.length - 1];
|
|
109
|
+
const parent = ancestors[ancestors.length - 2];
|
|
110
|
+
return parent.type === 'ExportSpecifier' && parent.exported === node;
|
|
111
|
+
},
|
|
112
|
+
isClassPropertyKey(ancestors) {
|
|
113
|
+
const node = ancestors[ancestors.length - 1];
|
|
114
|
+
const parent = ancestors[ancestors.length - 2];
|
|
115
|
+
return parent.type === 'PropertyDefinition' && parent.key === node;
|
|
116
|
+
},
|
|
117
|
+
isMethodDefinitionKey(ancestors) {
|
|
118
|
+
const node = ancestors[ancestors.length - 1];
|
|
119
|
+
const parent = ancestors[ancestors.length - 2];
|
|
120
|
+
return parent.type === 'MethodDefinition' && parent.key === node;
|
|
121
|
+
},
|
|
122
|
+
isMemberKey(ancestors) {
|
|
123
|
+
const node = ancestors[ancestors.length - 1];
|
|
124
|
+
const parent = ancestors[ancestors.length - 2];
|
|
125
|
+
return parent.type === 'MemberExpression' && parent.property === node;
|
|
126
|
+
},
|
|
127
|
+
isPropertyKey(ancestors) {
|
|
128
|
+
const node = ancestors[ancestors.length - 1];
|
|
129
|
+
const parent = ancestors[ancestors.length - 2];
|
|
130
|
+
return parent.type === 'Property' && parent.key === node;
|
|
131
|
+
}
|
|
132
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
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
|
+
};
|
|
@@ -1,5 +1,31 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { Node, IdentifierName } from 'oxc-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Focus exclusively on IdentifierName type as it has the name property,
|
|
4
|
+
* which is what the identifer utilities are interested in.
|
|
5
|
+
*
|
|
6
|
+
* Explicitly ignore the TSThisParameter type as it is not a valid identifier name.
|
|
7
|
+
*/
|
|
8
|
+
declare const isIdentifierName: (node: Node) => node is IdentifierName;
|
|
9
|
+
/**
|
|
10
|
+
* All methods receive the full set of ancestors, which
|
|
11
|
+
* specifically includes the node itself as the last element.
|
|
12
|
+
* The second to last element is the parent node, and so on.
|
|
13
|
+
* The first element is the root node.
|
|
14
|
+
*/
|
|
15
|
+
declare const identifier: {
|
|
16
|
+
isNamed: (node: Node) => node is IdentifierName;
|
|
17
|
+
isMetaProperty(ancestors: Node[]): boolean;
|
|
18
|
+
isModuleScope(ancestors: Node[], includeImports?: boolean): boolean;
|
|
19
|
+
isMemberExpressionRoot(ancestors: Node[]): boolean;
|
|
20
|
+
isDeclaration(ancestors: Node[]): boolean;
|
|
21
|
+
isClassOrFuncDeclarationId(ancestors: Node[]): boolean;
|
|
22
|
+
isVarDeclarationInGlobalScope(ancestors: Node[]): boolean;
|
|
23
|
+
isIife(ancestors: Node[]): boolean;
|
|
24
|
+
isFunctionExpressionId(ancestors: Node[]): boolean;
|
|
25
|
+
isExportSpecifierAlias(ancestors: Node[]): boolean;
|
|
26
|
+
isClassPropertyKey(ancestors: Node[]): boolean;
|
|
27
|
+
isMethodDefinitionKey(ancestors: Node[]): boolean;
|
|
28
|
+
isMemberKey(ancestors: Node[]): boolean;
|
|
29
|
+
isPropertyKey(ancestors: Node[]): boolean;
|
|
30
|
+
};
|
|
31
|
+
export { identifier, isIdentifierName };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { Node } from 'oxc-parser';
|
|
2
|
+
import type { IdentMeta, Scope } from '../types.cjs';
|
|
3
|
+
declare const collectScopeIdentifiers: (node: Node, scopes: Scope[]) => void;
|
|
4
|
+
/**
|
|
5
|
+
* Collects all module scope identifiers in the AST.
|
|
6
|
+
*
|
|
7
|
+
* Ignores identifiers that are in functions or classes.
|
|
8
|
+
* Ignores new scopes for StaticBlock nodes (can only reference static class members).
|
|
9
|
+
*
|
|
10
|
+
* Special case handling for these which create their own scopes,
|
|
11
|
+
* but are also valid module scope identifiers:
|
|
12
|
+
* - ClassDeclaration
|
|
13
|
+
* - FunctionDeclaration
|
|
14
|
+
*
|
|
15
|
+
* Special case handling for var inside BlockStatement
|
|
16
|
+
* which are also valid module scope identifiers.
|
|
17
|
+
*/
|
|
18
|
+
declare const collectModuleIdentifiers: (ast: Node, hoisting?: boolean) => Promise<Map<string, IdentMeta>>;
|
|
19
|
+
export { collectScopeIdentifiers, collectModuleIdentifiers };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import type {
|
|
3
|
-
import type { MemberExpression } from '@babel/types';
|
|
2
|
+
import type { MemberExpression, Node } from 'oxc-parser';
|
|
4
3
|
import type { FormatterOptions } from '../types.cjs';
|
|
5
|
-
export declare const memberExpression: (
|
|
4
|
+
export declare const memberExpression: (node: MemberExpression, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import type {
|
|
3
|
-
import type { MetaProperty } from '@babel/types';
|
|
2
|
+
import type { Node, MetaProperty } from 'oxc-parser';
|
|
4
3
|
import type { FormatterOptions } from '../types.cjs';
|
|
5
|
-
export declare const metaProperty: (
|
|
4
|
+
export declare const metaProperty: (node: MetaProperty, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
package/dist/cjs/module.cjs
CHANGED
|
@@ -7,28 +7,22 @@ exports.transform = void 0;
|
|
|
7
7
|
var _nodePath = require("node:path");
|
|
8
8
|
var _promises = require("node:fs/promises");
|
|
9
9
|
var _specifier = require("@knighted/specifier");
|
|
10
|
-
var _parse = require("
|
|
11
|
-
var _format = require("
|
|
10
|
+
var _parse = require("#parse");
|
|
11
|
+
var _format = require("#format");
|
|
12
|
+
var _lang = require("#utils/lang.js");
|
|
12
13
|
const defaultOptions = {
|
|
13
|
-
|
|
14
|
+
target: 'commonjs',
|
|
15
|
+
sourceType: 'auto',
|
|
16
|
+
transformSyntax: true,
|
|
17
|
+
liveBindings: 'strict',
|
|
18
|
+
rewriteSpecifier: undefined,
|
|
19
|
+
dirFilename: 'inject',
|
|
20
|
+
importMeta: 'shim',
|
|
21
|
+
requireSource: 'builtin',
|
|
22
|
+
cjsDefault: 'auto',
|
|
23
|
+
topLevelAwait: 'error',
|
|
14
24
|
out: undefined,
|
|
15
|
-
|
|
16
|
-
specifier: undefined
|
|
17
|
-
};
|
|
18
|
-
const getLangFromExt = filename => {
|
|
19
|
-
const ext = (0, _nodePath.extname)(filename);
|
|
20
|
-
if (/\.js$/.test(ext)) {
|
|
21
|
-
return 'js';
|
|
22
|
-
}
|
|
23
|
-
if (/\.ts$/.test(ext)) {
|
|
24
|
-
return 'ts';
|
|
25
|
-
}
|
|
26
|
-
if (ext === '.tsx') {
|
|
27
|
-
return 'tsx';
|
|
28
|
-
}
|
|
29
|
-
if (ext === '.jsx') {
|
|
30
|
-
return 'jsx';
|
|
31
|
-
}
|
|
25
|
+
inPlace: false
|
|
32
26
|
};
|
|
33
27
|
const transform = async (filename, options = defaultOptions) => {
|
|
34
28
|
const opts = {
|
|
@@ -37,24 +31,29 @@ const transform = async (filename, options = defaultOptions) => {
|
|
|
37
31
|
};
|
|
38
32
|
const file = (0, _nodePath.resolve)(filename);
|
|
39
33
|
const code = (await (0, _promises.readFile)(file)).toString();
|
|
40
|
-
const ast = (0, _parse.parse)(code);
|
|
41
|
-
let source = (0, _format.format)(code, ast, opts)
|
|
42
|
-
if (
|
|
43
|
-
const code = await _specifier.specifier.updateSrc(source, getLangFromExt(filename), ({
|
|
34
|
+
const ast = (0, _parse.parse)(filename, code);
|
|
35
|
+
let source = await (0, _format.format)(code, ast, opts);
|
|
36
|
+
if (opts.rewriteSpecifier) {
|
|
37
|
+
const code = await _specifier.specifier.updateSrc(source, (0, _lang.getLangFromExt)(filename), ({
|
|
44
38
|
value
|
|
45
39
|
}) => {
|
|
40
|
+
if (typeof opts.rewriteSpecifier === 'function') {
|
|
41
|
+
return opts.rewriteSpecifier(value) ?? undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
46
44
|
// Collapse any BinaryExpression or NewExpression to test for a relative specifier
|
|
47
45
|
const collapsed = value.replace(/['"`+)\s]|new String\(/g, '');
|
|
48
46
|
const relative = /^(?:\.|\.\.)\//;
|
|
49
47
|
if (relative.test(collapsed)) {
|
|
50
48
|
// $2 is for any closing quotation/parens around BE or NE
|
|
51
|
-
return value.replace(/(.+)\.(?:m|c)?(?:j|t)s([)'"
|
|
49
|
+
return value.replace(/(.+)\.(?:m|c)?(?:j|t)s([)'"]*)?$/, `$1${opts.rewriteSpecifier}$2`);
|
|
52
50
|
}
|
|
53
51
|
});
|
|
54
52
|
source = code;
|
|
55
53
|
}
|
|
56
|
-
|
|
57
|
-
|
|
54
|
+
const outputPath = opts.inPlace ? file : opts.out ? (0, _nodePath.resolve)(opts.out) : undefined;
|
|
55
|
+
if (outputPath) {
|
|
56
|
+
await (0, _promises.writeFile)(outputPath, source);
|
|
58
57
|
}
|
|
59
58
|
return source;
|
|
60
59
|
};
|
package/dist/cjs/parse.cjs
CHANGED
|
@@ -4,19 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.parse = void 0;
|
|
7
|
-
var
|
|
8
|
-
const parse = (
|
|
9
|
-
|
|
10
|
-
sourceType: 'module',
|
|
11
|
-
allowAwaitOutsideFunction: true,
|
|
12
|
-
allowReturnOutsideFunction: true,
|
|
13
|
-
allowImportExportEverywhere: true,
|
|
14
|
-
plugins: ['jsx', ['importAttributes', {
|
|
15
|
-
deprecatedAssertSyntax: true
|
|
16
|
-
}], ['typescript', {
|
|
17
|
-
dts
|
|
18
|
-
}]]
|
|
19
|
-
});
|
|
20
|
-
return ast;
|
|
7
|
+
var _oxcParser = require("oxc-parser");
|
|
8
|
+
const parse = (filename, code) => {
|
|
9
|
+
return (0, _oxcParser.parseSync)(filename, code);
|
|
21
10
|
};
|
|
22
11
|
exports.parse = parse;
|
package/dist/cjs/parse.d.cts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const parse: (
|
|
1
|
+
declare const parse: (filename: string, code: string) => import("oxc-parser").ParseResult;
|
|
2
2
|
export { parse };
|
package/dist/cjs/types.d.cts
CHANGED
|
@@ -1,7 +1,43 @@
|
|
|
1
|
+
import type { Node, Span, IdentifierName, IdentifierReference, BindingIdentifier, LabelIdentifier, TSIndexSignatureName } from 'oxc-parser';
|
|
2
|
+
export type RewriteSpecifier = '.js' | '.mjs' | '.cjs' | '.ts' | '.mts' | '.cts' | ((value: string) => string | null | undefined);
|
|
1
3
|
export type ModuleOptions = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
4
|
+
target: 'module' | 'commonjs';
|
|
5
|
+
sourceType?: 'auto' | 'module' | 'commonjs';
|
|
6
|
+
transformSyntax?: boolean;
|
|
7
|
+
liveBindings?: 'strict' | 'loose' | 'off';
|
|
8
|
+
rewriteSpecifier?: RewriteSpecifier;
|
|
9
|
+
dirFilename?: 'inject' | 'preserve' | 'error';
|
|
10
|
+
importMeta?: 'preserve' | 'shim' | 'error';
|
|
11
|
+
requireSource?: 'builtin' | 'create-require';
|
|
12
|
+
cjsDefault?: 'module-exports' | 'auto' | 'none';
|
|
13
|
+
topLevelAwait?: 'error' | 'wrap' | 'preserve';
|
|
5
14
|
out?: string;
|
|
15
|
+
inPlace?: boolean;
|
|
6
16
|
};
|
|
7
|
-
export type
|
|
17
|
+
export type SpannedNode = Node & Span;
|
|
18
|
+
export type ExportsMeta = {
|
|
19
|
+
hasExportsBeenReassigned: boolean;
|
|
20
|
+
hasDefaultExportBeenReassigned: boolean;
|
|
21
|
+
hasDefaultExportBeenAssigned: boolean;
|
|
22
|
+
defaultExportValue: unknown;
|
|
23
|
+
};
|
|
24
|
+
export type CjsExport = {
|
|
25
|
+
key: string;
|
|
26
|
+
writes: SpannedNode[];
|
|
27
|
+
fromIdentifier?: string;
|
|
28
|
+
via: Set<'exports' | 'module.exports'>;
|
|
29
|
+
reassignments: SpannedNode[];
|
|
30
|
+
hasGetter?: boolean;
|
|
31
|
+
};
|
|
32
|
+
export type IdentMeta = {
|
|
33
|
+
declare: SpannedNode[];
|
|
34
|
+
read: SpannedNode[];
|
|
35
|
+
};
|
|
36
|
+
export type Scope = {
|
|
37
|
+
type: string;
|
|
38
|
+
name: string;
|
|
39
|
+
node: Node;
|
|
40
|
+
idents: Set<string>;
|
|
41
|
+
};
|
|
42
|
+
export type FormatterOptions = Omit<ModuleOptions, 'out' | 'inPlace'>;
|
|
43
|
+
export type Identifier = IdentifierName | IdentifierReference | BindingIdentifier | LabelIdentifier | TSIndexSignatureName;
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.requireMainRgx = exports.exportsRename = exports.collectCjsExports = void 0;
|
|
7
|
+
var _walk = require("#walk");
|
|
8
|
+
const exportsRename = exports.exportsRename = '__exports';
|
|
9
|
+
const requireMainRgx = exports.requireMainRgx = /(require\.main\s*===\s*module|module\s*===\s*require\.main)/g;
|
|
10
|
+
const literalPropName = (prop, literals) => {
|
|
11
|
+
if (prop.type === 'Identifier') return literals?.get(prop.name)?.toString() ?? prop.name;
|
|
12
|
+
if (prop.type === 'Literal' && (typeof prop.value === 'string' || typeof prop.value === 'number')) {
|
|
13
|
+
return String(prop.value);
|
|
14
|
+
}
|
|
15
|
+
if (prop.type === 'TemplateLiteral' && prop.expressions.length === 0 && prop.quasis.length === 1) {
|
|
16
|
+
return prop.quasis[0].value.cooked ?? prop.quasis[0].value.raw;
|
|
17
|
+
}
|
|
18
|
+
return null;
|
|
19
|
+
};
|
|
20
|
+
const resolveExportTarget = (node, aliases, literals) => {
|
|
21
|
+
if (node.type === 'Identifier' && node.name === 'exports') {
|
|
22
|
+
return {
|
|
23
|
+
key: 'default',
|
|
24
|
+
via: 'exports'
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'module' && node.property.type === 'Identifier' && node.property.name === 'exports') {
|
|
28
|
+
return {
|
|
29
|
+
key: 'default',
|
|
30
|
+
via: 'module.exports'
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (node.type !== 'MemberExpression') return null;
|
|
34
|
+
const base = node.object;
|
|
35
|
+
const prop = node.property;
|
|
36
|
+
const key = literalPropName(prop, literals);
|
|
37
|
+
if (!key) return null;
|
|
38
|
+
const baseVia = resolveBase(base, aliases);
|
|
39
|
+
if (!baseVia) return null;
|
|
40
|
+
if (baseVia === 'module.exports' && key === 'exports') {
|
|
41
|
+
return {
|
|
42
|
+
key: 'default',
|
|
43
|
+
via: 'module.exports'
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
return {
|
|
47
|
+
key,
|
|
48
|
+
via: baseVia
|
|
49
|
+
};
|
|
50
|
+
};
|
|
51
|
+
const resolveBase = (node, aliases) => {
|
|
52
|
+
if (node.type === 'Identifier') {
|
|
53
|
+
if (node.name === 'exports') return 'exports';
|
|
54
|
+
const alias = aliases.get(node.name);
|
|
55
|
+
if (alias) return alias;
|
|
56
|
+
}
|
|
57
|
+
if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'module' && node.property.type === 'Identifier' && node.property.name === 'exports') {
|
|
58
|
+
return 'module.exports';
|
|
59
|
+
}
|
|
60
|
+
return null;
|
|
61
|
+
};
|
|
62
|
+
const collectCjsExports = async ast => {
|
|
63
|
+
const exportsMap = new Map();
|
|
64
|
+
const localToExport = new Map();
|
|
65
|
+
const aliases = new Map();
|
|
66
|
+
const literals = new Map();
|
|
67
|
+
const addExport = (ref, node, rhs, options) => {
|
|
68
|
+
const entry = exportsMap.get(ref.key) ?? {
|
|
69
|
+
key: ref.key,
|
|
70
|
+
writes: [],
|
|
71
|
+
via: new Set(),
|
|
72
|
+
reassignments: []
|
|
73
|
+
};
|
|
74
|
+
entry.via.add(ref.via);
|
|
75
|
+
entry.writes.push(node);
|
|
76
|
+
if (options?.hasGetter) {
|
|
77
|
+
entry.hasGetter = true;
|
|
78
|
+
}
|
|
79
|
+
if (rhs) {
|
|
80
|
+
entry.fromIdentifier ??= rhs.name;
|
|
81
|
+
const set = localToExport.get(rhs.name) ?? new Set();
|
|
82
|
+
set.add(ref.key);
|
|
83
|
+
localToExport.set(rhs.name, set);
|
|
84
|
+
}
|
|
85
|
+
exportsMap.set(ref.key, entry);
|
|
86
|
+
};
|
|
87
|
+
await (0, _walk.ancestorWalk)(ast, {
|
|
88
|
+
enter(node) {
|
|
89
|
+
if (node.type === 'VariableDeclarator' && node.id.type === 'Identifier' && node.init) {
|
|
90
|
+
const via = resolveBase(node.init, aliases);
|
|
91
|
+
if (via) {
|
|
92
|
+
aliases.set(node.id.name, via);
|
|
93
|
+
}
|
|
94
|
+
if (node.init.type === 'Literal' && (typeof node.init.value === 'string' || typeof node.init.value === 'number')) {
|
|
95
|
+
literals.set(node.id.name, node.init.value);
|
|
96
|
+
}
|
|
97
|
+
if (node.init.type === 'TemplateLiteral' && node.init.expressions.length === 0 && node.init.quasis.length === 1) {
|
|
98
|
+
const cooked = node.init.quasis[0].value.cooked ?? node.init.quasis[0].value.raw;
|
|
99
|
+
literals.set(node.id.name, cooked);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
if (node.type === 'AssignmentExpression') {
|
|
103
|
+
const target = resolveExportTarget(node.left, aliases, literals);
|
|
104
|
+
if (target) {
|
|
105
|
+
const rhsIdent = node.right.type === 'Identifier' ? node.right : undefined;
|
|
106
|
+
addExport(target, node, rhsIdent);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
if (node.left.type === 'Identifier') {
|
|
110
|
+
const keys = localToExport.get(node.left.name);
|
|
111
|
+
if (keys) {
|
|
112
|
+
keys.forEach(key => {
|
|
113
|
+
const entry = exportsMap.get(key);
|
|
114
|
+
if (entry) {
|
|
115
|
+
entry.reassignments.push(node);
|
|
116
|
+
exportsMap.set(key, entry);
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (node.left.type === 'ObjectPattern') {
|
|
122
|
+
for (const prop of node.left.properties) {
|
|
123
|
+
if (prop.type === 'Property' && prop.value.type === 'MemberExpression') {
|
|
124
|
+
const ref = resolveExportTarget(prop.value, aliases, literals);
|
|
125
|
+
if (ref) {
|
|
126
|
+
addExport(ref, node);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
if (node.type === 'CallExpression') {
|
|
133
|
+
const callee = node.callee;
|
|
134
|
+
|
|
135
|
+
// Object.assign(exports, { foo: bar })
|
|
136
|
+
if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.object.name === 'Object' && callee.property.type === 'Identifier' && callee.property.name === 'assign' && node.arguments.length >= 2) {
|
|
137
|
+
const targetArg = node.arguments[0];
|
|
138
|
+
const ref = resolveBase(targetArg, aliases);
|
|
139
|
+
if (!ref) return;
|
|
140
|
+
for (let i = 1; i < node.arguments.length; i++) {
|
|
141
|
+
const arg = node.arguments[i];
|
|
142
|
+
if (arg.type === 'ObjectExpression') {
|
|
143
|
+
for (const prop of arg.properties) {
|
|
144
|
+
if (prop.type !== 'Property') continue;
|
|
145
|
+
const keyName = literalPropName(prop.key, literals);
|
|
146
|
+
if (!keyName) continue;
|
|
147
|
+
let rhsIdent;
|
|
148
|
+
if (prop.value.type === 'Identifier') {
|
|
149
|
+
rhsIdent = prop.value;
|
|
150
|
+
}
|
|
151
|
+
addExport({
|
|
152
|
+
key: keyName,
|
|
153
|
+
via: ref
|
|
154
|
+
}, node, rhsIdent);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Object.defineProperty(exports, 'foo', { value, get, set })
|
|
161
|
+
if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.object.name === 'Object' && callee.property.type === 'Identifier' && callee.property.name === 'defineProperty' && node.arguments.length >= 3) {
|
|
162
|
+
const target = resolveBase(node.arguments[0], aliases);
|
|
163
|
+
if (!target) return;
|
|
164
|
+
const keyName = literalPropName(node.arguments[1], literals);
|
|
165
|
+
if (!keyName) return;
|
|
166
|
+
const desc = node.arguments[2];
|
|
167
|
+
if (desc.type !== 'ObjectExpression') return;
|
|
168
|
+
let rhsIdent;
|
|
169
|
+
let hasGetter = false;
|
|
170
|
+
for (const prop of desc.properties) {
|
|
171
|
+
if (prop.type !== 'Property') continue;
|
|
172
|
+
if (prop.key.type !== 'Identifier') continue;
|
|
173
|
+
if (prop.key.name === 'value' && prop.value.type === 'Identifier') {
|
|
174
|
+
rhsIdent = prop.value;
|
|
175
|
+
}
|
|
176
|
+
if (prop.key.name === 'get' && prop.value.type === 'Identifier') {
|
|
177
|
+
hasGetter = true;
|
|
178
|
+
}
|
|
179
|
+
if (prop.key.name === 'set' && prop.value.type === 'Identifier') {
|
|
180
|
+
// Setter-only doesn’t create a readable export; ignore beyond marking write
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
addExport({
|
|
184
|
+
key: keyName,
|
|
185
|
+
via: target
|
|
186
|
+
}, node, rhsIdent, {
|
|
187
|
+
hasGetter
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// Object.defineProperties(exports, { foo: { value: ... }, bar: { get: ... } })
|
|
192
|
+
if (callee.type === 'MemberExpression' && callee.object.type === 'Identifier' && callee.object.name === 'Object' && callee.property.type === 'Identifier' && callee.property.name === 'defineProperties' && node.arguments.length >= 2) {
|
|
193
|
+
const target = resolveBase(node.arguments[0], aliases);
|
|
194
|
+
if (!target) return;
|
|
195
|
+
const descMap = node.arguments[1];
|
|
196
|
+
if (descMap.type !== 'ObjectExpression') return;
|
|
197
|
+
for (const prop of descMap.properties) {
|
|
198
|
+
if (prop.type !== 'Property') continue;
|
|
199
|
+
const keyName = literalPropName(prop.key, literals);
|
|
200
|
+
if (!keyName) continue;
|
|
201
|
+
if (prop.value.type !== 'ObjectExpression') continue;
|
|
202
|
+
let rhsIdent;
|
|
203
|
+
let hasGetter = false;
|
|
204
|
+
for (const descProp of prop.value.properties) {
|
|
205
|
+
if (descProp.type !== 'Property') continue;
|
|
206
|
+
if (descProp.key.type !== 'Identifier') continue;
|
|
207
|
+
if (descProp.key.name === 'value' && descProp.value.type === 'Identifier') {
|
|
208
|
+
rhsIdent = descProp.value;
|
|
209
|
+
}
|
|
210
|
+
if (descProp.key.name === 'get' && descProp.value.type === 'Identifier') {
|
|
211
|
+
hasGetter = true;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
addExport({
|
|
215
|
+
key: keyName,
|
|
216
|
+
via: target
|
|
217
|
+
}, node, rhsIdent, {
|
|
218
|
+
hasGetter
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
});
|
|
225
|
+
return exportsMap;
|
|
226
|
+
};
|
|
227
|
+
exports.collectCjsExports = collectCjsExports;
|