@remix-run/assets 0.0.0 → 0.2.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +325 -2
  3. package/dist/assets.d.ts +3 -0
  4. package/dist/assets.d.ts.map +1 -0
  5. package/dist/assets.js +1 -0
  6. package/dist/lib/access.d.ts +10 -0
  7. package/dist/lib/access.d.ts.map +1 -0
  8. package/dist/lib/access.js +14 -0
  9. package/dist/lib/asset-server.d.ts +139 -0
  10. package/dist/lib/asset-server.d.ts.map +1 -0
  11. package/dist/lib/asset-server.js +338 -0
  12. package/dist/lib/compilation-error.d.ts +33 -0
  13. package/dist/lib/compilation-error.d.ts.map +1 -0
  14. package/dist/lib/compilation-error.js +32 -0
  15. package/dist/lib/file-matcher.d.ts +6 -0
  16. package/dist/lib/file-matcher.d.ts.map +1 -0
  17. package/dist/lib/file-matcher.js +44 -0
  18. package/dist/lib/fingerprint.d.ts +12 -0
  19. package/dist/lib/fingerprint.d.ts.map +1 -0
  20. package/dist/lib/fingerprint.js +49 -0
  21. package/dist/lib/module-store.d.ts +41 -0
  22. package/dist/lib/module-store.d.ts.map +1 -0
  23. package/dist/lib/module-store.js +230 -0
  24. package/dist/lib/paths.d.ts +8 -0
  25. package/dist/lib/paths.d.ts.map +1 -0
  26. package/dist/lib/paths.js +50 -0
  27. package/dist/lib/routes.d.ts +13 -0
  28. package/dist/lib/routes.d.ts.map +1 -0
  29. package/dist/lib/routes.js +94 -0
  30. package/dist/lib/scripts/cjs-check.d.ts +3 -0
  31. package/dist/lib/scripts/cjs-check.d.ts.map +1 -0
  32. package/dist/lib/scripts/cjs-check.js +398 -0
  33. package/dist/lib/scripts/compiler.d.ts +62 -0
  34. package/dist/lib/scripts/compiler.d.ts.map +1 -0
  35. package/dist/lib/scripts/compiler.js +439 -0
  36. package/dist/lib/scripts/emit.d.ts +25 -0
  37. package/dist/lib/scripts/emit.d.ts.map +1 -0
  38. package/dist/lib/scripts/emit.js +63 -0
  39. package/dist/lib/scripts/resolve.d.ts +50 -0
  40. package/dist/lib/scripts/resolve.d.ts.map +1 -0
  41. package/dist/lib/scripts/resolve.js +236 -0
  42. package/dist/lib/scripts/transform.d.ts +64 -0
  43. package/dist/lib/scripts/transform.d.ts.map +1 -0
  44. package/dist/lib/scripts/transform.js +373 -0
  45. package/dist/lib/source-maps.d.ts +4 -0
  46. package/dist/lib/source-maps.d.ts.map +1 -0
  47. package/dist/lib/source-maps.js +62 -0
  48. package/dist/lib/styles/compiler.d.ts +52 -0
  49. package/dist/lib/styles/compiler.d.ts.map +1 -0
  50. package/dist/lib/styles/compiler.js +272 -0
  51. package/dist/lib/styles/emit.d.ts +25 -0
  52. package/dist/lib/styles/emit.d.ts.map +1 -0
  53. package/dist/lib/styles/emit.js +78 -0
  54. package/dist/lib/styles/resolve.d.ts +48 -0
  55. package/dist/lib/styles/resolve.d.ts.map +1 -0
  56. package/dist/lib/styles/resolve.js +188 -0
  57. package/dist/lib/styles/transform.d.ts +47 -0
  58. package/dist/lib/styles/transform.d.ts.map +1 -0
  59. package/dist/lib/styles/transform.js +131 -0
  60. package/dist/lib/target.d.ts +21 -0
  61. package/dist/lib/target.d.ts.map +1 -0
  62. package/dist/lib/target.js +127 -0
  63. package/dist/lib/watch.d.ts +22 -0
  64. package/dist/lib/watch.d.ts.map +1 -0
  65. package/dist/lib/watch.js +96 -0
  66. package/package.json +55 -12
  67. package/src/assets.ts +2 -0
  68. package/src/lib/access.ts +24 -0
  69. package/src/lib/asset-server.ts +537 -0
  70. package/src/lib/compilation-error.ts +61 -0
  71. package/src/lib/file-matcher.ts +63 -0
  72. package/src/lib/fingerprint.ts +65 -0
  73. package/src/lib/module-store.ts +340 -0
  74. package/src/lib/paths.ts +66 -0
  75. package/src/lib/routes.ts +164 -0
  76. package/src/lib/scripts/cjs-check.ts +476 -0
  77. package/src/lib/scripts/compiler.ts +640 -0
  78. package/src/lib/scripts/emit.ts +122 -0
  79. package/src/lib/scripts/resolve.ts +433 -0
  80. package/src/lib/scripts/transform.ts +609 -0
  81. package/src/lib/source-maps.ts +75 -0
  82. package/src/lib/styles/compiler.ts +400 -0
  83. package/src/lib/styles/emit.ts +137 -0
  84. package/src/lib/styles/resolve.ts +316 -0
  85. package/src/lib/styles/transform.ts +226 -0
  86. package/src/lib/target.ts +196 -0
  87. package/src/lib/watch.ts +136 -0
@@ -0,0 +1,476 @@
1
+ import { parseSync, visitorKeys } from 'oxc-parser'
2
+
3
+ const suspiciousCommonJSPattern =
4
+ /\brequire\s*(?:\(|\.|\[)|\bmodule\s*(?:\.\s*exports|\[\s*['"`]exports['"`]\s*\])|\bexports\s*(?:\.|=|\[)/
5
+
6
+ interface AstNode {
7
+ type: string
8
+ [key: string]: unknown
9
+ }
10
+
11
+ interface IdentifierNode extends AstNode {
12
+ name: string
13
+ }
14
+
15
+ type Scope = {
16
+ bindings: Set<string>
17
+ kind: 'block' | 'function' | 'module'
18
+ parent: Scope | null
19
+ }
20
+
21
+ export function mayContainCommonJSModuleGlobals(source: string): boolean {
22
+ return suspiciousCommonJSPattern.test(source)
23
+ }
24
+
25
+ // Detects CommonJS module globals that cannot be served as ES modules.
26
+ export function isCommonJS(source: string): boolean {
27
+ try {
28
+ let result = parseSync('module.js', source, {
29
+ lang: 'js',
30
+ sourceType: 'module',
31
+ })
32
+ if (result.errors.length > 0) {
33
+ return suspiciousCommonJSPattern.test(source)
34
+ }
35
+ return containsCommonJSModuleGlobals(result.program as unknown as AstNode)
36
+ } catch {
37
+ return suspiciousCommonJSPattern.test(source)
38
+ }
39
+ }
40
+
41
+ function containsCommonJSModuleGlobals(program: AstNode): boolean {
42
+ let moduleScope = createScope(null, 'module')
43
+ let nodeScopes = new WeakMap<object, Scope>()
44
+ nodeScopes.set(program, moduleScope)
45
+ collectScopeBindings(program, moduleScope, nodeScopes)
46
+ return walkForCommonJS(program, nodeScopes, moduleScope)
47
+ }
48
+
49
+ function walkForCommonJS(
50
+ node: AstNode,
51
+ nodeScopes: WeakMap<object, Scope>,
52
+ currentScope: Scope,
53
+ parent: AstNode | null = null,
54
+ key?: string,
55
+ ): boolean {
56
+ let nextScope = nodeScopes.get(node) ?? currentScope
57
+
58
+ switch (node.type) {
59
+ case 'ImportDeclaration':
60
+ return false
61
+ case 'VariableDeclarator':
62
+ if (isAstNode(node.init) && walkForCommonJS(node.init, nodeScopes, nextScope, node, 'init')) {
63
+ return true
64
+ }
65
+ return walkPatternForCommonJS(node.id, nodeScopes, nextScope)
66
+ case 'FunctionDeclaration':
67
+ case 'FunctionExpression':
68
+ case 'ArrowFunctionExpression':
69
+ for (let param of getNodeArray(node.params)) {
70
+ if (walkPatternForCommonJS(param, nodeScopes, nextScope)) return true
71
+ }
72
+ return isAstNode(node.body)
73
+ ? walkForCommonJS(node.body, nodeScopes, nextScope, node, 'body')
74
+ : false
75
+ case 'CatchClause':
76
+ if (walkPatternForCommonJS(node.param, nodeScopes, nextScope)) return true
77
+ return isAstNode(node.body)
78
+ ? walkForCommonJS(node.body, nodeScopes, nextScope, node, 'body')
79
+ : false
80
+ case 'Property':
81
+ if (
82
+ node.computed &&
83
+ isAstNode(node.key) &&
84
+ walkForCommonJS(node.key, nodeScopes, nextScope, node, 'key')
85
+ ) {
86
+ return true
87
+ }
88
+ return isAstNode(node.value)
89
+ ? walkForCommonJS(node.value, nodeScopes, nextScope, node, 'value')
90
+ : false
91
+ case 'MemberExpression':
92
+ if (
93
+ isAstNode(node.object) &&
94
+ walkForCommonJS(node.object, nodeScopes, nextScope, node, 'object')
95
+ ) {
96
+ return true
97
+ }
98
+ return (
99
+ !!node.computed &&
100
+ isAstNode(node.property) &&
101
+ walkForCommonJS(node.property, nodeScopes, nextScope, node, 'property')
102
+ )
103
+ case 'ExportSpecifier':
104
+ return isAstNode(node.local)
105
+ ? walkForCommonJS(node.local, nodeScopes, nextScope, node, 'local')
106
+ : false
107
+ case 'Identifier':
108
+ if (!isIdentifier(node) || !isReferenceIdentifier(node, parent, key)) return false
109
+ if (resolveBindingKind(node.name, nextScope) !== null) return false
110
+ return isCommonJSReference(node, parent, key)
111
+ }
112
+
113
+ for (let child of getChildNodes(node)) {
114
+ if (walkForCommonJS(child.node, nodeScopes, nextScope, node, child.key)) {
115
+ return true
116
+ }
117
+ }
118
+
119
+ return false
120
+ }
121
+
122
+ function walkPatternForCommonJS(
123
+ node: unknown,
124
+ nodeScopes: WeakMap<object, Scope>,
125
+ currentScope: Scope,
126
+ ): boolean {
127
+ if (!isAstNode(node)) return false
128
+
129
+ switch (node.type) {
130
+ case 'Identifier':
131
+ return false
132
+ case 'AssignmentPattern':
133
+ return (
134
+ walkPatternForCommonJS(node.left, nodeScopes, currentScope) ||
135
+ (isAstNode(node.right) && walkForCommonJS(node.right, nodeScopes, currentScope))
136
+ )
137
+ case 'RestElement':
138
+ return walkPatternForCommonJS(node.argument, nodeScopes, currentScope)
139
+ case 'ArrayPattern':
140
+ return getNodeArray(node.elements).some((element) =>
141
+ walkPatternForCommonJS(element, nodeScopes, currentScope),
142
+ )
143
+ case 'ObjectPattern':
144
+ return getNodeArray(node.properties).some((property) => {
145
+ if (property.type === 'Property') {
146
+ return (
147
+ (property.computed &&
148
+ isAstNode(property.key) &&
149
+ walkForCommonJS(property.key, nodeScopes, currentScope, property, 'key')) ||
150
+ walkPatternForCommonJS(property.value, nodeScopes, currentScope)
151
+ )
152
+ }
153
+ return walkPatternForCommonJS(property.argument, nodeScopes, currentScope)
154
+ })
155
+ }
156
+
157
+ return false
158
+ }
159
+
160
+ function collectScopeBindings(
161
+ node: AstNode,
162
+ currentScope: Scope,
163
+ nodeScopes: WeakMap<object, Scope>,
164
+ ) {
165
+ switch (node.type) {
166
+ case 'Program':
167
+ forEachChildNode(node, (child) => collectScopeBindings(child, currentScope, nodeScopes))
168
+ return
169
+ case 'ImportDeclaration':
170
+ for (let specifier of getNodeArray(node.specifiers)) {
171
+ if (isAstNode(specifier) && isIdentifier(specifier.local)) {
172
+ currentScope.bindings.add(specifier.local.name)
173
+ }
174
+ }
175
+ return
176
+ case 'VariableDeclaration': {
177
+ let targetScope = node.kind === 'var' ? getFunctionScope(currentScope) : currentScope
178
+ for (let declaration of getNodeArray(node.declarations)) {
179
+ collectPatternBindings(declaration.id, targetScope)
180
+ if (isAstNode(declaration.init)) {
181
+ collectScopeBindings(declaration.init, currentScope, nodeScopes)
182
+ }
183
+ }
184
+ return
185
+ }
186
+ case 'FunctionDeclaration': {
187
+ if (isIdentifier(node.id)) {
188
+ currentScope.bindings.add(node.id.name)
189
+ }
190
+ let functionScope = createScope(currentScope, 'function')
191
+ nodeScopes.set(node, functionScope)
192
+ if (isIdentifier(node.id)) {
193
+ functionScope.bindings.add(node.id.name)
194
+ }
195
+ for (let param of getNodeArray(node.params)) {
196
+ collectPatternBindings(param, functionScope)
197
+ collectPatternScopeBindings(param, functionScope, nodeScopes)
198
+ }
199
+ if (isAstNode(node.body)) {
200
+ collectScopeBindings(node.body, functionScope, nodeScopes)
201
+ }
202
+ return
203
+ }
204
+ case 'FunctionExpression':
205
+ case 'ArrowFunctionExpression': {
206
+ let functionScope = createScope(currentScope, 'function')
207
+ nodeScopes.set(node, functionScope)
208
+ if (node.type === 'FunctionExpression' && isIdentifier(node.id)) {
209
+ functionScope.bindings.add(node.id.name)
210
+ }
211
+ for (let param of getNodeArray(node.params)) {
212
+ collectPatternBindings(param, functionScope)
213
+ collectPatternScopeBindings(param, functionScope, nodeScopes)
214
+ }
215
+ if (isAstNode(node.body)) {
216
+ collectScopeBindings(node.body, functionScope, nodeScopes)
217
+ }
218
+ return
219
+ }
220
+ case 'ClassDeclaration':
221
+ if (isIdentifier(node.id)) {
222
+ currentScope.bindings.add(node.id.name)
223
+ }
224
+ break
225
+ case 'ClassExpression':
226
+ if (isIdentifier(node.id)) {
227
+ let classScope = createScope(currentScope, 'block')
228
+ classScope.bindings.add(node.id.name)
229
+ nodeScopes.set(node, classScope)
230
+ forEachChildNode(node, (child, key) => {
231
+ if (key !== 'id') {
232
+ collectScopeBindings(child, classScope, nodeScopes)
233
+ }
234
+ })
235
+ return
236
+ }
237
+ break
238
+ case 'BlockStatement':
239
+ case 'ForStatement':
240
+ case 'ForInStatement':
241
+ case 'ForOfStatement':
242
+ case 'SwitchStatement': {
243
+ let blockScope = createScope(currentScope, 'block')
244
+ nodeScopes.set(node, blockScope)
245
+ forEachChildNode(node, (child) => collectScopeBindings(child, blockScope, nodeScopes))
246
+ return
247
+ }
248
+ case 'CatchClause': {
249
+ let catchScope = createScope(currentScope, 'block')
250
+ nodeScopes.set(node, catchScope)
251
+ collectPatternBindings(node.param, catchScope)
252
+ collectPatternScopeBindings(node.param, catchScope, nodeScopes)
253
+ if (isAstNode(node.body)) {
254
+ collectScopeBindings(node.body, catchScope, nodeScopes)
255
+ }
256
+ return
257
+ }
258
+ }
259
+
260
+ forEachChildNode(node, (child) => collectScopeBindings(child, currentScope, nodeScopes))
261
+ }
262
+
263
+ function collectPatternBindings(node: unknown, scope: Scope): void {
264
+ if (!isAstNode(node)) return
265
+
266
+ switch (node.type) {
267
+ case 'Identifier':
268
+ if (isIdentifier(node)) {
269
+ scope.bindings.add(node.name)
270
+ }
271
+ return
272
+ case 'RestElement':
273
+ collectPatternBindings(node.argument, scope)
274
+ return
275
+ case 'AssignmentPattern':
276
+ collectPatternBindings(node.left, scope)
277
+ return
278
+ case 'ArrayPattern':
279
+ for (let element of getNodeArray(node.elements)) {
280
+ collectPatternBindings(element, scope)
281
+ }
282
+ return
283
+ case 'ObjectPattern':
284
+ for (let property of getNodeArray(node.properties)) {
285
+ if (property.type === 'Property') {
286
+ collectPatternBindings(property.value, scope)
287
+ } else {
288
+ collectPatternBindings(property.argument, scope)
289
+ }
290
+ }
291
+ return
292
+ }
293
+ }
294
+
295
+ function collectPatternScopeBindings(
296
+ node: unknown,
297
+ currentScope: Scope,
298
+ nodeScopes: WeakMap<object, Scope>,
299
+ ): void {
300
+ if (!isAstNode(node)) return
301
+
302
+ switch (node.type) {
303
+ case 'AssignmentPattern':
304
+ collectPatternScopeBindings(node.left, currentScope, nodeScopes)
305
+ if (isAstNode(node.right)) {
306
+ collectScopeBindings(node.right, currentScope, nodeScopes)
307
+ }
308
+ return
309
+ case 'ArrayPattern':
310
+ for (let element of getNodeArray(node.elements)) {
311
+ collectPatternScopeBindings(element, currentScope, nodeScopes)
312
+ }
313
+ return
314
+ case 'ObjectPattern':
315
+ for (let property of getNodeArray(node.properties)) {
316
+ if (property.type === 'Property') {
317
+ if (property.computed && isAstNode(property.key)) {
318
+ collectScopeBindings(property.key, currentScope, nodeScopes)
319
+ }
320
+ collectPatternScopeBindings(property.value, currentScope, nodeScopes)
321
+ } else {
322
+ collectPatternScopeBindings(property.argument, currentScope, nodeScopes)
323
+ }
324
+ }
325
+ return
326
+ case 'RestElement':
327
+ collectPatternScopeBindings(node.argument, currentScope, nodeScopes)
328
+ return
329
+ }
330
+ }
331
+
332
+ function isCommonJSReference(node: IdentifierNode, parent: AstNode | null, key?: string): boolean {
333
+ if (parent === null) return false
334
+
335
+ if (node.name === 'require') {
336
+ return (
337
+ (parent.type === 'CallExpression' && key === 'callee') ||
338
+ (parent.type === 'MemberExpression' && key === 'object')
339
+ )
340
+ }
341
+
342
+ if (node.name === 'exports') {
343
+ return (
344
+ (parent.type === 'AssignmentExpression' && key === 'left') ||
345
+ (parent.type === 'MemberExpression' && key === 'object')
346
+ )
347
+ }
348
+
349
+ return (
350
+ node.name === 'module' &&
351
+ parent.type === 'MemberExpression' &&
352
+ key === 'object' &&
353
+ isMemberPropertyNamed(parent.property, 'exports')
354
+ )
355
+ }
356
+
357
+ function resolveBindingKind(name: string, currentScope: Scope): 'local' | null {
358
+ let scope: Scope | null = currentScope
359
+ while (scope !== null) {
360
+ if (scope.bindings.has(name)) return 'local'
361
+ scope = scope.parent
362
+ }
363
+ return null
364
+ }
365
+
366
+ function createScope(parent: Scope | null, kind: Scope['kind']): Scope {
367
+ return {
368
+ bindings: new Set(),
369
+ kind,
370
+ parent,
371
+ }
372
+ }
373
+
374
+ function getFunctionScope(scope: Scope): Scope {
375
+ let current = scope
376
+ while (current.kind === 'block' && current.parent !== null) {
377
+ current = current.parent
378
+ }
379
+ return current
380
+ }
381
+
382
+ function isReferenceIdentifier(
383
+ node: IdentifierNode,
384
+ parent: AstNode | null,
385
+ key?: string,
386
+ ): boolean {
387
+ if (parent === null) return false
388
+ if (parent.type === 'ClassDeclaration' || parent.type === 'ClassExpression') {
389
+ return key !== 'id'
390
+ }
391
+ if (parent.type === 'Property' && key === 'key' && !parent.computed) {
392
+ return false
393
+ }
394
+ if (
395
+ (parent.type === 'PropertyDefinition' || parent.type === 'MethodDefinition') &&
396
+ key === 'key' &&
397
+ !parent.computed
398
+ ) {
399
+ return false
400
+ }
401
+ if (parent.type === 'MemberExpression' && key === 'property' && !parent.computed) {
402
+ return false
403
+ }
404
+ if (parent.type === 'MetaProperty') return false
405
+ if (
406
+ (parent.type === 'LabeledStatement' ||
407
+ parent.type === 'BreakStatement' ||
408
+ parent.type === 'ContinueStatement') &&
409
+ key === 'label'
410
+ ) {
411
+ return false
412
+ }
413
+ if (parent.type === 'ExportSpecifier' && key === 'exported') return false
414
+ return true
415
+ }
416
+
417
+ function getChildNodes(node: AstNode): Array<{ key: string; node: AstNode }> {
418
+ let children: Array<{ key: string; node: AstNode }> = []
419
+ forEachChildNode(node, (child, key) => {
420
+ children.push({ key, node: child })
421
+ })
422
+ return children
423
+ }
424
+
425
+ function forEachChildNode(node: AstNode, callback: (child: AstNode, key: string) => void): void {
426
+ for (let key of visitorKeys[node.type] ?? []) {
427
+ let value = node[key]
428
+ if (Array.isArray(value)) {
429
+ for (let child of value) {
430
+ if (isAstNode(child)) {
431
+ callback(child, key)
432
+ }
433
+ }
434
+ continue
435
+ }
436
+ if (isAstNode(value)) {
437
+ callback(value, key)
438
+ }
439
+ }
440
+ }
441
+
442
+ function getNodeArray(value: unknown): AstNode[] {
443
+ return Array.isArray(value) ? value.filter(isAstNode) : []
444
+ }
445
+
446
+ function isMemberPropertyNamed(node: unknown, name: string): boolean {
447
+ if (isIdentifier(node)) return node.name === name
448
+ return isStaticStringValue(node, name)
449
+ }
450
+
451
+ function isStaticStringValue(node: unknown, value: string): boolean {
452
+ if (!isAstNode(node)) return false
453
+
454
+ if (node.type === 'Literal') return node.value === value
455
+
456
+ return (
457
+ node.type === 'TemplateLiteral' &&
458
+ Array.isArray(node.expressions) &&
459
+ node.expressions.length === 0 &&
460
+ Array.isArray(node.quasis) &&
461
+ node.quasis.length === 1 &&
462
+ isAstNode(node.quasis[0]) &&
463
+ !!node.quasis[0].value &&
464
+ typeof node.quasis[0].value === 'object' &&
465
+ 'raw' in node.quasis[0].value &&
466
+ node.quasis[0].value.raw === value
467
+ )
468
+ }
469
+
470
+ function isAstNode(node: unknown): node is AstNode {
471
+ return !!node && typeof node === 'object' && 'type' in node && typeof node.type === 'string'
472
+ }
473
+
474
+ function isIdentifier(node: unknown): node is IdentifierNode {
475
+ return isAstNode(node) && node.type === 'Identifier' && typeof node.name === 'string'
476
+ }