@knighted/module 1.0.0 → 1.1.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.
Files changed (51) hide show
  1. package/README.md +4 -6
  2. package/dist/ast.d.ts +39 -0
  3. package/dist/cjs/ast.d.cts +39 -0
  4. package/dist/cjs/exports.d.cts +4 -1
  5. package/dist/cjs/format.cjs +70 -30
  6. package/dist/cjs/formatters/assignmentExpression.cjs +1 -1
  7. package/dist/cjs/formatters/identifier.cjs +2 -2
  8. package/dist/cjs/formatters/memberExpression.cjs +1 -1
  9. package/dist/cjs/helpers/ast.cjs +29 -0
  10. package/dist/cjs/helpers/identifier.cjs +5 -3
  11. package/dist/cjs/module.cjs +5 -4
  12. package/dist/cjs/specifier.cjs +1 -1
  13. package/dist/cjs/types.d.cts +2 -0
  14. package/dist/cjs/utils/exports.cjs +1 -1
  15. package/dist/cjs/utils/identifiers.cjs +2 -2
  16. package/dist/exports.d.ts +4 -1
  17. package/dist/format.js +70 -30
  18. package/dist/formatters/assignmentExpression.js +1 -1
  19. package/dist/formatters/identifier.js +2 -2
  20. package/dist/formatters/memberExpression.js +1 -1
  21. package/dist/helpers/ast.d.ts +39 -0
  22. package/dist/helpers/ast.js +18 -0
  23. package/dist/helpers/identifier.js +5 -4
  24. package/dist/module.js +6 -5
  25. package/dist/specifier.js +1 -1
  26. package/dist/types.d.ts +2 -0
  27. package/dist/{src/utils → utils}/exports.d.ts +4 -1
  28. package/dist/utils/exports.js +1 -1
  29. package/dist/utils/identifiers.js +2 -2
  30. package/package.json +9 -11
  31. package/dist/cjs/utils.cjs +0 -274
  32. package/dist/cjs/utils.d.cts +0 -23
  33. package/dist/src/format.d.ts +0 -9
  34. package/dist/src/module.d.ts +0 -3
  35. package/dist/src/parse.d.ts +0 -2
  36. package/dist/src/specifier.d.ts +0 -16
  37. package/dist/src/types.d.ts +0 -91
  38. package/dist/src/utils.d.ts +0 -23
  39. package/dist/src/walk.d.ts +0 -20
  40. package/dist/utils.d.ts +0 -23
  41. package/dist/utils.js +0 -265
  42. /package/dist/{src/formatters → formatters}/assignmentExpression.d.ts +0 -0
  43. /package/dist/{src/formatters → formatters}/expressionStatement.d.ts +0 -0
  44. /package/dist/{src/formatters → formatters}/identifier.d.ts +0 -0
  45. /package/dist/{src/formatters → formatters}/memberExpression.d.ts +0 -0
  46. /package/dist/{src/formatters → formatters}/metaProperty.d.ts +0 -0
  47. /package/dist/{src/helpers → helpers}/identifier.d.ts +0 -0
  48. /package/dist/{src/utils → utils}/identifiers.d.ts +0 -0
  49. /package/dist/{src/utils → utils}/lang.d.ts +0 -0
  50. /package/dist/{src/utils → utils}/scopeNodes.d.ts +0 -0
  51. /package/dist/{src/utils → utils}/url.d.ts +0 -0
package/dist/utils.js DELETED
@@ -1,265 +0,0 @@
1
- import { ancestorWalk } from './walk.js';
2
- import { identifier } from './helpers/identifier.js';
3
- import { scopeNodes } from './utils/scopeNodes.js';
4
- const isValidUrl = url => {
5
- try {
6
- new URL(url);
7
- return true;
8
- } catch {
9
- return false;
10
- }
11
- };
12
- const exportsRename = '__exports';
13
- const requireMainRgx = /(require\.main\s*===\s*module|module\s*===\s*require\.main)/g;
14
- const resolveExportTarget = node => {
15
- if (node.type !== 'MemberExpression') return null;
16
- const base = node.object;
17
- const prop = node.property;
18
- if (prop.type !== 'Identifier') return null;
19
- if (base.type === 'Identifier' && base.name === 'exports') {
20
- return {
21
- key: prop.name,
22
- via: 'exports'
23
- };
24
- }
25
- if (base.type === 'MemberExpression' && base.object.type === 'Identifier' && base.object.name === 'module' && base.property.type === 'Identifier' && base.property.name === 'exports') {
26
- return {
27
- key: prop.name,
28
- via: 'module.exports'
29
- };
30
- }
31
- if (base.type === 'Identifier' && base.name === 'module' && prop.type === 'Identifier' && prop.name === 'exports') {
32
- return {
33
- key: 'default',
34
- via: 'module.exports'
35
- };
36
- }
37
- return null;
38
- };
39
- const collectCjsExports = async ast => {
40
- const exportsMap = new Map();
41
- const localToExport = new Map();
42
- await ancestorWalk(ast, {
43
- enter(node) {
44
- if (node.type === 'AssignmentExpression') {
45
- const target = resolveExportTarget(node.left);
46
- if (target) {
47
- const entry = exportsMap.get(target.key) ?? {
48
- key: target.key,
49
- writes: [],
50
- via: new Set(),
51
- reassignments: []
52
- };
53
- entry.via.add(target.via);
54
- entry.writes.push(node);
55
- if (node.right.type === 'Identifier') {
56
- entry.fromIdentifier ??= node.right.name;
57
- if (entry.fromIdentifier) {
58
- const set = localToExport.get(entry.fromIdentifier) ?? new Set();
59
- set.add(target.key);
60
- localToExport.set(entry.fromIdentifier, set);
61
- }
62
- }
63
- exportsMap.set(target.key, entry);
64
- return;
65
- }
66
- if (node.left.type === 'Identifier') {
67
- const keys = localToExport.get(node.left.name);
68
- if (keys) {
69
- keys.forEach(key => {
70
- const entry = exportsMap.get(key);
71
- if (entry) {
72
- entry.reassignments.push(node);
73
- exportsMap.set(key, entry);
74
- }
75
- });
76
- }
77
- }
78
- }
79
- }
80
- });
81
- return exportsMap;
82
- };
83
- const collectScopeIdentifiers = (node, scopes) => {
84
- const {
85
- type
86
- } = node;
87
- switch (type) {
88
- case 'BlockStatement':
89
- case 'ClassBody':
90
- scopes.push({
91
- node,
92
- type: 'Block',
93
- name: type,
94
- idents: new Set()
95
- });
96
- break;
97
- case 'FunctionDeclaration':
98
- case 'FunctionExpression':
99
- case 'ArrowFunctionExpression':
100
- {
101
- const name = node.id ? node.id.name : 'anonymous';
102
- const scope = {
103
- node,
104
- name,
105
- type: 'Function',
106
- idents: new Set()
107
- };
108
- node.params.map(param => {
109
- if (param.type === 'TSParameterProperty') {
110
- return param.parameter;
111
- }
112
- if (param.type === 'RestElement') {
113
- return param.argument;
114
- }
115
- if (param.type === 'AssignmentPattern') {
116
- return param.left;
117
- }
118
- return param;
119
- }).filter(identifier.isNamed).forEach(param => {
120
- scope.idents.add(param.name);
121
- });
122
-
123
- /**
124
- * If a FunctionExpression has an id, it is a named function expression.
125
- * The function expression name shadows the module scope identifier, so
126
- * we don't want to count reads of module identifers that have the same name.
127
- * They also do not cause a SyntaxError if the function expression name is
128
- * the same as a module scope identifier.
129
- *
130
- * TODO: Is this necessary for FunctionDeclaration?
131
- */
132
- if (node.type === 'FunctionExpression' && node.id) {
133
- scope.idents.add(node.id.name);
134
- }
135
-
136
- // First add the function to any previous scopes
137
- if (scopes.length > 0) {
138
- scopes[scopes.length - 1].idents.add(name);
139
- }
140
-
141
- // Then add the function scope to the scopes stack
142
- scopes.push(scope);
143
- }
144
- break;
145
- case 'ClassDeclaration':
146
- {
147
- const className = node.id ? node.id.name : 'anonymous';
148
-
149
- // First add the class to any previous scopes
150
- if (scopes.length > 0) {
151
- scopes[scopes.length - 1].idents.add(className);
152
- }
153
-
154
- // Then add the class to the scopes stack
155
- scopes.push({
156
- node,
157
- name: className,
158
- type: 'Class',
159
- idents: new Set()
160
- });
161
- }
162
- break;
163
- case 'ClassExpression':
164
- {}
165
- break;
166
- case 'VariableDeclaration':
167
- if (scopes.length > 0) {
168
- const scope = scopes[scopes.length - 1];
169
- node.declarations.forEach(decl => {
170
- if (decl.type === 'VariableDeclarator' && decl.id.type === 'Identifier') {
171
- scope.idents.add(decl.id.name);
172
- }
173
- });
174
- }
175
- break;
176
- }
177
- };
178
-
179
- /**
180
- * Collects all module scope identifiers in the AST.
181
- *
182
- * Ignores identifiers that are in functions or classes.
183
- * Ignores new scopes for StaticBlock nodes (can only reference static class members).
184
- *
185
- * Special case handling for these which create their own scopes,
186
- * but are also valid module scope identifiers:
187
- * - ClassDeclaration
188
- * - FunctionDeclaration
189
- *
190
- * Special case handling for var inside BlockStatement
191
- * which are also valid module scope identifiers.
192
- */
193
- const collectModuleIdentifiers = async (ast, hoisting = true) => {
194
- const identifiers = new Map();
195
- const globalReads = new Map();
196
- const scopes = [];
197
- await ancestorWalk(ast, {
198
- enter(node, ancestors) {
199
- const {
200
- type
201
- } = node;
202
- collectScopeIdentifiers(node, scopes);
203
-
204
- // Add module scope identifiers to the registry map
205
-
206
- if (type === 'Identifier') {
207
- const {
208
- name
209
- } = node;
210
- const meta = identifiers.get(name) ?? {
211
- declare: [],
212
- read: []
213
- };
214
- const isDeclaration = identifier.isDeclaration(ancestors);
215
- const inScope = scopes.some(scope => scope.idents.has(name) || scope.name === name);
216
- if (hoisting && !identifier.isDeclaration(ancestors) && !identifier.isFunctionExpressionId(ancestors) && !identifier.isExportSpecifierAlias(ancestors) && !identifier.isClassPropertyKey(ancestors) && !identifier.isMethodDefinitionKey(ancestors) && !identifier.isMemberKey(ancestors) && !identifier.isPropertyKey(ancestors) && !identifier.isIife(ancestors) && !inScope) {
217
- if (globalReads.has(name)) {
218
- globalReads.get(name)?.push(node);
219
- } else {
220
- globalReads.set(name, [node]);
221
- }
222
- }
223
- if (isDeclaration) {
224
- const isModuleScope = identifier.isModuleScope(ancestors);
225
- const isClassOrFuncDeclaration = identifier.isClassOrFuncDeclarationId(ancestors);
226
- const isVarDeclarationInGlobalScope = identifier.isVarDeclarationInGlobalScope(ancestors);
227
- const parent = ancestors[ancestors.length - 2];
228
- const grandParent = ancestors[ancestors.length - 3];
229
- const hoistSafe = parent.type === 'FunctionDeclaration' || parent.type === 'VariableDeclarator' && grandParent?.type === 'VariableDeclaration' && grandParent.kind === 'var';
230
- if (isModuleScope || isClassOrFuncDeclaration || isVarDeclarationInGlobalScope) {
231
- meta.declare.push(node);
232
-
233
- // Check for hoisted reads
234
- if (hoisting && hoistSafe && globalReads.has(name)) {
235
- const reads = globalReads.get(name);
236
- if (reads) {
237
- reads.forEach(read => {
238
- if (!meta.read.includes(read)) {
239
- meta.read.push(read);
240
- }
241
- });
242
- }
243
- }
244
- identifiers.set(name, meta);
245
- }
246
- } else {
247
- if (identifiers.has(name) && !inScope && !identifier.isIife(ancestors) && !identifier.isFunctionExpressionId(ancestors) && !identifier.isExportSpecifierAlias(ancestors) && !identifier.isClassPropertyKey(ancestors) && !identifier.isMethodDefinitionKey(ancestors) && !identifier.isMemberKey(ancestors) && !identifier.isPropertyKey(ancestors)) {
248
- // Closure is referencing module scope identifier
249
- meta.read.push(node);
250
- }
251
- }
252
- }
253
- },
254
- leave(node) {
255
- const {
256
- type
257
- } = node;
258
- if (scopeNodes.includes(type)) {
259
- scopes.pop();
260
- }
261
- }
262
- });
263
- return identifiers;
264
- };
265
- export { isValidUrl, collectScopeIdentifiers, collectModuleIdentifiers, collectCjsExports, exportsRename, requireMainRgx };
File without changes
File without changes
File without changes
File without changes
File without changes