@knighted/module 1.0.0-alpha.9 → 1.0.0-beta.0
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/expressionStatement.d.cts +2 -3
- package/dist/cjs/format.cjs +96 -22
- package/dist/cjs/format.d.cts +3 -4
- 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/memberExpression.d.cts +2 -3
- package/dist/cjs/metaProperty.d.cts +2 -3
- package/dist/cjs/module.cjs +24 -25
- 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 +32 -4
- package/dist/cjs/utils.cjs +218 -0
- package/dist/cjs/utils.d.cts +25 -0
- package/dist/cjs/walk.cjs +75 -0
- package/dist/cjs/walk.d.cts +20 -0
- package/dist/expressionStatement.d.ts +2 -3
- package/dist/format.d.ts +3 -4
- package/dist/format.js +98 -23
- package/dist/formatters/assignmentExpression.d.ts +12 -0
- package/dist/formatters/assignmentExpression.js +30 -0
- package/dist/formatters/expressionStatement.d.ts +2 -3
- package/dist/formatters/expressionStatement.js +36 -55
- package/dist/formatters/identifier.d.ts +11 -4
- package/dist/formatters/identifier.js +31 -31
- package/dist/formatters/memberExpression.d.ts +2 -3
- package/dist/formatters/memberExpression.js +24 -11
- package/dist/formatters/metaProperty.d.ts +2 -3
- package/dist/formatters/metaProperty.js +23 -35
- package/dist/helpers/identifier.d.ts +31 -0
- package/dist/helpers/identifier.js +127 -0
- package/dist/helpers/scope.d.ts +6 -0
- package/dist/helpers/scope.js +7 -0
- package/dist/identifier.d.ts +31 -5
- package/dist/memberExpression.d.ts +2 -3
- package/dist/metaProperty.d.ts +2 -3
- package/dist/module.js +24 -25
- package/dist/parse.d.ts +1 -1
- package/dist/parse.js +3 -14
- package/dist/scope.d.ts +6 -0
- package/dist/types.d.ts +32 -4
- package/dist/utils.d.ts +25 -0
- package/dist/utils.js +209 -0
- package/dist/walk.d.ts +20 -0
- package/dist/walk.js +69 -0
- package/package.json +43 -25
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Node } from 'oxc-parser';
|
|
2
|
+
/**
|
|
3
|
+
* Using visitorKeys instead of oxc Visitor to keep
|
|
4
|
+
* an ancestor-aware enter/leave API with this.skip()
|
|
5
|
+
* without per-node method boilerplate.
|
|
6
|
+
*/
|
|
7
|
+
type AncestorContext = {
|
|
8
|
+
skip: () => void;
|
|
9
|
+
};
|
|
10
|
+
type AncestorVisitor = {
|
|
11
|
+
enter?: (this: AncestorContext, node: Node, ancestors: Node[]) => void | Promise<void>;
|
|
12
|
+
leave?: (this: AncestorContext, node: Node, ancestors: Node[]) => void | Promise<void>;
|
|
13
|
+
};
|
|
14
|
+
type WalkVisitor = {
|
|
15
|
+
enter?: (this: AncestorContext, node: Node, parent: Node | null) => void | Promise<void>;
|
|
16
|
+
leave?: (this: AncestorContext, node: Node, parent: Node | null) => void | Promise<void>;
|
|
17
|
+
};
|
|
18
|
+
declare const ancestorWalk: (node: Node, visitors: AncestorVisitor) => Promise<void>;
|
|
19
|
+
declare const walk: (node: Node, visitors: WalkVisitor) => Promise<void>;
|
|
20
|
+
export { ancestorWalk, walk };
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import type {
|
|
3
|
-
import type { ExpressionStatement } from '@babel/types';
|
|
2
|
+
import type { Node, ExpressionStatement } from 'oxc-parser';
|
|
4
3
|
import type { FormatterOptions } from '../types.js';
|
|
5
|
-
export declare const expressionStatement: (
|
|
4
|
+
export declare const expressionStatement: (node: ExpressionStatement, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
package/dist/format.d.ts
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type { ParseResult } from '@babel/parser';
|
|
3
|
-
import type { File } from '@babel/types';
|
|
1
|
+
import type { ParseResult } from 'oxc-parser';
|
|
4
2
|
import type { FormatterOptions } from './types.js';
|
|
5
3
|
/**
|
|
6
4
|
* Note, there is no specific conversion for `import.meta.main` as it does not exist.
|
|
7
5
|
* @see https://github.com/nodejs/node/issues/49440
|
|
8
6
|
*/
|
|
9
|
-
|
|
7
|
+
declare const format: (src: string, ast: ParseResult, opts: FormatterOptions) => Promise<string>;
|
|
8
|
+
export { format };
|
package/dist/format.js
CHANGED
|
@@ -1,34 +1,109 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import _traverse from '@babel/traverse';
|
|
3
|
-
import { moduleType } from 'node-module-type';
|
|
4
2
|
import { identifier } from './formatters/identifier.js';
|
|
5
3
|
import { metaProperty } from './formatters/metaProperty.js';
|
|
6
4
|
import { memberExpression } from './formatters/memberExpression.js';
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
* Temporary fix until I switch to oxc-parser.
|
|
12
|
-
*/
|
|
13
|
-
const type = moduleType();
|
|
14
|
-
const traverse = typeof _traverse === 'function' || type === 'commonjs' ? _traverse : _traverse.default;
|
|
5
|
+
import { assignmentExpression } from './formatters/assignmentExpression.js';
|
|
6
|
+
import { isValidUrl, exportsRename, collectModuleIdentifiers } from './utils.js';
|
|
7
|
+
import { isIdentifierName } from './helpers/identifier.js';
|
|
8
|
+
import { ancestorWalk } from './walk.js';
|
|
15
9
|
|
|
16
10
|
/**
|
|
17
11
|
* Note, there is no specific conversion for `import.meta.main` as it does not exist.
|
|
18
12
|
* @see https://github.com/nodejs/node/issues/49440
|
|
19
13
|
*/
|
|
20
|
-
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
14
|
+
const format = async (src, ast, opts) => {
|
|
15
|
+
const code = new MagicString(src);
|
|
16
|
+
const exportsMeta = {
|
|
17
|
+
hasExportsBeenReassigned: false,
|
|
18
|
+
defaultExportValue: undefined,
|
|
19
|
+
hasDefaultExportBeenReassigned: false,
|
|
20
|
+
hasDefaultExportBeenAssigned: false
|
|
21
|
+
};
|
|
22
|
+
await collectModuleIdentifiers(ast.program);
|
|
23
|
+
if (opts.target === 'module' && opts.transformSyntax) {
|
|
24
|
+
/**
|
|
25
|
+
* Prepare ESM output by renaming `exports` to `__exports` and seeding an
|
|
26
|
+
* `import.meta.filename` touch so import.meta is present even when the
|
|
27
|
+
* original source never referenced it.
|
|
28
|
+
*/
|
|
29
|
+
code.prepend(`let ${exportsRename} = {};
|
|
30
|
+
void import.meta.filename;
|
|
31
|
+
`);
|
|
32
|
+
}
|
|
33
|
+
await ancestorWalk(ast.program, {
|
|
34
|
+
async enter(node, ancestors) {
|
|
35
|
+
const parent = ancestors[ancestors.length - 2] ?? null;
|
|
36
|
+
if (node.type === 'FunctionDeclaration' || node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
|
|
37
|
+
const skipped = ['__filename', '__dirname'];
|
|
38
|
+
const skippedParams = node.params.filter(param => param.type === 'Identifier' && skipped.includes(param.name));
|
|
39
|
+
const skippedFuncIdentifier = node.id?.type === 'Identifier' && skipped.includes(node.id.name);
|
|
40
|
+
if (skippedParams.length || skippedFuncIdentifier) {
|
|
41
|
+
this.skip();
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Check for assignment to `import.meta.url`.
|
|
47
|
+
*/
|
|
48
|
+
if (node.type === 'AssignmentExpression' && node.left.type === 'MemberExpression' && node.left.object.type === 'MetaProperty' && node.left.property.type === 'Identifier' && node.left.property.name === 'url') {
|
|
49
|
+
if (node.right.type === 'Literal' && typeof node.right.value === 'string') {
|
|
50
|
+
if (!isValidUrl(node.right.value)) {
|
|
51
|
+
const rhs = code.snip(node.right.start, node.right.end).toString();
|
|
52
|
+
const assignment = code.snip(node.start, node.end).toString();
|
|
53
|
+
code.update(node.start, node.end, `/* Invalid assignment: ${rhs} is not a URL. ${assignment} */`);
|
|
54
|
+
this.skip();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Skip module scope CJS globals when they are object properties.
|
|
61
|
+
* Ignoring `exports` here.
|
|
62
|
+
*/
|
|
63
|
+
if (node.type === 'MemberExpression' && node.property.type === 'Identifier' && ['__filename', '__dirname'].includes(node.property.name)) {
|
|
64
|
+
this.skip();
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Check for bare `module.exports` expressions.
|
|
69
|
+
*/
|
|
70
|
+
if (node.type === 'MemberExpression' && node.object.type === 'Identifier' && node.object.name === 'module' && node.property.type === 'Identifier' && node.property.name === 'exports' && parent?.type === 'ExpressionStatement') {
|
|
71
|
+
if (opts.target === 'module') {
|
|
72
|
+
code.update(node.start, node.end, ';');
|
|
73
|
+
// Prevent parsing the `exports` identifier again.
|
|
74
|
+
this.skip();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Format `module.exports` and `exports` assignments.
|
|
80
|
+
*/
|
|
81
|
+
if (node.type === 'AssignmentExpression') {
|
|
82
|
+
await assignmentExpression({
|
|
83
|
+
node,
|
|
84
|
+
parent,
|
|
85
|
+
code,
|
|
86
|
+
opts,
|
|
87
|
+
meta: exportsMeta
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
if (node.type === 'MetaProperty') {
|
|
91
|
+
metaProperty(node, parent, code, opts);
|
|
92
|
+
}
|
|
93
|
+
if (node.type === 'MemberExpression') {
|
|
94
|
+
memberExpression(node, parent, code, opts);
|
|
95
|
+
}
|
|
96
|
+
if (isIdentifierName(node)) {
|
|
97
|
+
identifier({
|
|
98
|
+
node,
|
|
99
|
+
ancestors,
|
|
100
|
+
code,
|
|
101
|
+
opts,
|
|
102
|
+
meta: exportsMeta
|
|
103
|
+
});
|
|
104
|
+
}
|
|
31
105
|
}
|
|
32
106
|
});
|
|
33
|
-
return
|
|
34
|
-
};
|
|
107
|
+
return code.toString();
|
|
108
|
+
};
|
|
109
|
+
export { format };
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import MagicString from 'magic-string';
|
|
2
|
+
import type { Node, AssignmentExpression } from 'oxc-parser';
|
|
3
|
+
import type { FormatterOptions, ExportsMeta } from '../types.js';
|
|
4
|
+
type AssignmentExpressionArg = {
|
|
5
|
+
node: AssignmentExpression;
|
|
6
|
+
parent: Node | null;
|
|
7
|
+
code: MagicString;
|
|
8
|
+
opts: FormatterOptions;
|
|
9
|
+
meta: ExportsMeta;
|
|
10
|
+
};
|
|
11
|
+
export declare const assignmentExpression: ({ node, parent: _parent, code: _code, opts, meta: _meta, }: AssignmentExpressionArg) => Promise<void>;
|
|
12
|
+
export {};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { walk } from '../walk.js';
|
|
2
|
+
export const assignmentExpression = async ({
|
|
3
|
+
node,
|
|
4
|
+
parent: _parent,
|
|
5
|
+
code: _code,
|
|
6
|
+
opts,
|
|
7
|
+
meta: _meta
|
|
8
|
+
}) => {
|
|
9
|
+
if (opts.target === 'module' && opts.transformSyntax) {
|
|
10
|
+
await walk(node, {
|
|
11
|
+
enter(childNode, childParent) {
|
|
12
|
+
if (childNode.type === 'Identifier' && childNode.name === 'exports') {
|
|
13
|
+
if (childParent === node && node.left === childNode) {
|
|
14
|
+
/**
|
|
15
|
+
* The code is reassigning `exports` to something else.
|
|
16
|
+
* Redeclare it with a new variable name using var.
|
|
17
|
+
*/
|
|
18
|
+
//meta.hasExportsBeenReassigned = true
|
|
19
|
+
//console.log('writing exports reassignment')
|
|
20
|
+
//code.update(node.left.start, node.left.end, exportsRename)
|
|
21
|
+
//console.log(code.slice(node.start, node.end))
|
|
22
|
+
//code.update(childNode.start, childNode.end, exportsRename)
|
|
23
|
+
//console.log('reassigning exports', childParent, code.update(node.left.start, node.left.end, exportsRename))
|
|
24
|
+
}
|
|
25
|
+
//console.log('found exports assignment', meta.hasExportsBeenReassigned, expr)
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
};
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import type {
|
|
3
|
-
import type { ExpressionStatement } from '@babel/types';
|
|
2
|
+
import type { Node, ExpressionStatement } from 'oxc-parser';
|
|
4
3
|
import type { FormatterOptions } from '../types.js';
|
|
5
|
-
export declare const expressionStatement: (
|
|
4
|
+
export declare const expressionStatement: (node: ExpressionStatement, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
|
@@ -1,61 +1,42 @@
|
|
|
1
|
-
export const expressionStatement = (
|
|
2
|
-
if (options.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
} = node;
|
|
10
|
-
if (typeof start === 'number' && typeof end === 'number') {
|
|
11
|
-
const isMemberExpressionModuleExports = expression => {
|
|
12
|
-
return expression.object.type === 'Identifier' && expression.object.name === 'module' && expression.property.type === 'Identifier' && expression.property.name === 'exports';
|
|
13
|
-
};
|
|
14
|
-
if (node.expression.type === 'Identifier') {
|
|
15
|
-
const name = node.expression.name;
|
|
1
|
+
export const expressionStatement = (node, parent, src, options) => {
|
|
2
|
+
if (options.target === 'module') {
|
|
3
|
+
if (node.expression.type === 'Identifier') {
|
|
4
|
+
const {
|
|
5
|
+
start,
|
|
6
|
+
end
|
|
7
|
+
} = node;
|
|
8
|
+
const name = node.expression.name;
|
|
16
9
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
src.update(start, end, 'import.meta.filename');
|
|
27
|
-
break;
|
|
28
|
-
case '__dirname':
|
|
29
|
-
src.update(start, end, 'import.meta.dirname');
|
|
30
|
-
break;
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
if (node.expression.type === 'MemberExpression') {
|
|
34
|
-
const {
|
|
35
|
-
expression
|
|
36
|
-
} = node;
|
|
37
|
-
|
|
38
|
-
// Check for `module.exports` without an assignment
|
|
39
|
-
if (isMemberExpressionModuleExports(expression)) {
|
|
40
|
-
/**
|
|
41
|
-
* @TODO: Should this depend on `options.modules` being enabled?
|
|
42
|
-
* Probably not for the same reason `exports` is converted to an empty object (ReferenceError in ESM).
|
|
43
|
-
* This is a standalone reference to `module.exports` without being part of an AssignmentExpression.
|
|
44
|
-
*/
|
|
10
|
+
// CommonJS globals (as bare identifiers)
|
|
11
|
+
switch (name) {
|
|
12
|
+
case 'require':
|
|
13
|
+
src.remove(start, end);
|
|
14
|
+
break;
|
|
15
|
+
case 'module':
|
|
16
|
+
src.update(start, end, 'import.meta');
|
|
17
|
+
break;
|
|
18
|
+
case 'exports':
|
|
45
19
|
src.update(start, end, '{}');
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
node.expression.left.type === 'MemberExpression' &&
|
|
54
|
-
isMemberExpressionModuleExports(node.expression.left)
|
|
55
|
-
) {
|
|
56
|
-
// @TODO support `modules` option.
|
|
20
|
+
break;
|
|
21
|
+
case '__filename':
|
|
22
|
+
src.update(start, end, 'import.meta.filename');
|
|
23
|
+
break;
|
|
24
|
+
case '__dirname':
|
|
25
|
+
src.update(start, end, 'import.meta.dirname');
|
|
26
|
+
break;
|
|
57
27
|
}
|
|
58
|
-
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
if (options.target === 'commonjs') {
|
|
31
|
+
if (node.expression.type === 'Identifier') {
|
|
32
|
+
const {
|
|
33
|
+
start,
|
|
34
|
+
end
|
|
35
|
+
} = node;
|
|
36
|
+
const name = node.expression.name;
|
|
37
|
+
void start;
|
|
38
|
+
void end;
|
|
39
|
+
void name;
|
|
59
40
|
}
|
|
60
41
|
}
|
|
61
42
|
};
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import MagicString from 'magic-string';
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
import type { Node, IdentifierName } from 'oxc-parser';
|
|
3
|
+
import type { FormatterOptions, ExportsMeta } from '../types.js';
|
|
4
|
+
type IdentifierArg = {
|
|
5
|
+
node: IdentifierName;
|
|
6
|
+
ancestors: Node[];
|
|
7
|
+
code: MagicString;
|
|
8
|
+
opts: FormatterOptions;
|
|
9
|
+
meta: ExportsMeta;
|
|
10
|
+
};
|
|
11
|
+
export declare const identifier: ({ node, ancestors, code, opts, meta }: IdentifierArg) => void;
|
|
12
|
+
export {};
|
|
@@ -1,41 +1,41 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import { exportsRename } from '../utils.js';
|
|
2
|
+
import { identifier as ident } from '../helpers/identifier.js';
|
|
3
|
+
export const identifier = ({
|
|
4
|
+
node,
|
|
5
|
+
ancestors,
|
|
6
|
+
code,
|
|
7
|
+
opts,
|
|
8
|
+
meta
|
|
9
|
+
}) => {
|
|
10
|
+
if (opts.target === 'module') {
|
|
6
11
|
const {
|
|
7
12
|
start,
|
|
8
|
-
end
|
|
13
|
+
end,
|
|
14
|
+
name
|
|
9
15
|
} = node;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
16
|
+
switch (name) {
|
|
17
|
+
case '__filename':
|
|
18
|
+
code.update(start, end, 'import.meta.url');
|
|
19
|
+
break;
|
|
20
|
+
case '__dirname':
|
|
21
|
+
code.update(start, end, 'import.meta.dirname');
|
|
22
|
+
break;
|
|
23
|
+
case 'exports':
|
|
24
|
+
{
|
|
25
|
+
const parent = ancestors[ancestors.length - 2];
|
|
26
|
+
if (opts.transformSyntax) {
|
|
27
|
+
if (parent.type === 'AssignmentExpression' && parent.left === node) {
|
|
28
|
+
// The code is reassigning `exports` to something else.
|
|
15
29
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
case 'module':
|
|
19
|
-
{
|
|
20
|
-
if (!isMemberExpression) {
|
|
21
|
-
src.update(start, end, 'import.meta');
|
|
30
|
+
meta.hasExportsBeenReassigned = true;
|
|
31
|
+
code.update(parent.left.start, parent.left.end, exportsRename);
|
|
22
32
|
}
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
case 'exports':
|
|
26
|
-
{
|
|
27
|
-
if (!isMemberExpression) {
|
|
28
|
-
src.update(start, end, '{}');
|
|
33
|
+
if (ident.isModuleScope(ancestors) && !ident.isFunctionExpressionId(ancestors) && !ident.isExportSpecifierAlias(ancestors) && !ident.isClassPropertyKey(ancestors) && !ident.isMethodDefinitionKey(ancestors) && !ident.isMemberKey(ancestors) && !ident.isPropertyKey(ancestors) && !ident.isIife(ancestors)) {
|
|
34
|
+
code.update(start, end, exportsRename);
|
|
29
35
|
}
|
|
30
|
-
break;
|
|
31
36
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
break;
|
|
35
|
-
case '__dirname':
|
|
36
|
-
src.update(start, end, 'import.meta.dirname');
|
|
37
|
-
break;
|
|
38
|
-
}
|
|
37
|
+
}
|
|
38
|
+
break;
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
41
|
};
|
|
@@ -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.js';
|
|
5
|
-
export declare const memberExpression: (
|
|
4
|
+
export declare const memberExpression: (node: MemberExpression, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
1
|
+
import { exportsRename } from '../utils.js';
|
|
2
|
+
export const memberExpression = (node, parent, src, options) => {
|
|
3
|
+
if (options.target === 'module') {
|
|
4
|
+
if (node.object.type === 'Identifier' && node.property.type === 'Identifier' && node.object.name === 'module' && node.property.name === 'exports') {
|
|
5
|
+
src.update(node.start, node.end, exportsRename);
|
|
6
|
+
return;
|
|
7
|
+
}
|
|
8
|
+
if (node.object.type === 'Identifier' && node.property.type === 'Identifier' && node.object.name === 'require') {
|
|
9
|
+
const {
|
|
10
|
+
start,
|
|
11
|
+
end
|
|
12
|
+
} = node;
|
|
11
13
|
const {
|
|
12
14
|
name
|
|
13
15
|
} = node.property;
|
|
@@ -15,7 +17,18 @@ export const memberExpression = (nodePath, src, options) => {
|
|
|
15
17
|
// CommonJS properties of `require`
|
|
16
18
|
switch (name) {
|
|
17
19
|
case 'main':
|
|
18
|
-
|
|
20
|
+
/**
|
|
21
|
+
* Node.js team still quibbling over import.meta.main ¯\_(ツ)_/¯
|
|
22
|
+
* @see https://github.com/nodejs/node/pull/32223
|
|
23
|
+
*/
|
|
24
|
+
if (parent?.type === 'ExpressionStatement') {
|
|
25
|
+
// This is a standalone expression so remove it to not cause run-time errors.
|
|
26
|
+
src.remove(start, end);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Transform require.main === module.
|
|
30
|
+
*/
|
|
31
|
+
if (parent?.type === 'BinaryExpression') {}
|
|
19
32
|
break;
|
|
20
33
|
case 'resolve':
|
|
21
34
|
src.update(start, end, 'import.meta.resolve');
|
|
@@ -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.js';
|
|
5
|
-
export declare const metaProperty: (
|
|
4
|
+
export declare const metaProperty: (node: MetaProperty, parent: Node | null, src: MagicString, options: FormatterOptions) => void;
|
|
@@ -1,42 +1,30 @@
|
|
|
1
|
-
export const metaProperty = (
|
|
2
|
-
if (options.
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
const {
|
|
6
|
-
node
|
|
7
|
-
} = path;
|
|
8
|
-
const {
|
|
9
|
-
start,
|
|
10
|
-
end
|
|
11
|
-
} = node;
|
|
12
|
-
if (node.type === 'MemberExpression' && node.property.type === 'Identifier' && typeof start == 'number' && typeof end === 'number') {
|
|
13
|
-
const name = node.property.name;
|
|
14
|
-
switch (name) {
|
|
15
|
-
case 'url':
|
|
16
|
-
src.update(start, end, 'require("node:url").pathToFileURL(__filename).toString()');
|
|
17
|
-
break;
|
|
18
|
-
case 'filename':
|
|
19
|
-
src.update(start, end, '__filename');
|
|
20
|
-
break;
|
|
21
|
-
case 'dirname':
|
|
22
|
-
src.update(start, end, '__dirname');
|
|
23
|
-
break;
|
|
24
|
-
case 'resolve':
|
|
25
|
-
src.update(start, end, 'require.resolve');
|
|
26
|
-
break;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
} else {
|
|
30
|
-
const {
|
|
31
|
-
node
|
|
32
|
-
} = nodePath;
|
|
1
|
+
export const metaProperty = (node, parent, src, options) => {
|
|
2
|
+
if (options.target === 'commonjs') {
|
|
3
|
+
if (parent?.type !== 'MemberExpression') {
|
|
4
|
+
// This is a bare `import.meta` expression
|
|
33
5
|
const {
|
|
34
6
|
start,
|
|
35
7
|
end
|
|
36
8
|
} = node;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
9
|
+
src.update(start, end, 'module');
|
|
10
|
+
}
|
|
11
|
+
if (parent?.type === 'MemberExpression' && parent.property.type === 'Identifier') {
|
|
12
|
+
switch (parent.property.name) {
|
|
13
|
+
case 'url':
|
|
14
|
+
src.update(parent.start, parent.end, 'require("node:url").pathToFileURL(__filename).href');
|
|
15
|
+
break;
|
|
16
|
+
case 'filename':
|
|
17
|
+
src.update(parent.start, parent.end, '__filename');
|
|
18
|
+
break;
|
|
19
|
+
case 'dirname':
|
|
20
|
+
src.update(parent.start, parent.end, '__dirname');
|
|
21
|
+
break;
|
|
22
|
+
case 'resolve':
|
|
23
|
+
/**
|
|
24
|
+
* Should this be `require('node:url').pathToFileURL(require.resolve(<parsed specifier>)).href`?
|
|
25
|
+
*/
|
|
26
|
+
src.update(parent.start, parent.end, 'require.resolve');
|
|
27
|
+
break;
|
|
40
28
|
}
|
|
41
29
|
}
|
|
42
30
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
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 };
|