@remix-run/assets 0.2.0 → 0.4.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 (71) hide show
  1. package/README.md +241 -28
  2. package/dist/assets.d.ts +1 -0
  3. package/dist/assets.d.ts.map +1 -1
  4. package/dist/assets.js +1 -0
  5. package/dist/lib/access.d.ts +1 -0
  6. package/dist/lib/access.d.ts.map +1 -1
  7. package/dist/lib/access.js +10 -1
  8. package/dist/lib/asset-server.d.ts +33 -7
  9. package/dist/lib/asset-server.d.ts.map +1 -1
  10. package/dist/lib/asset-server.js +195 -23
  11. package/dist/lib/compilation-error.d.ts +1 -1
  12. package/dist/lib/compilation-error.d.ts.map +1 -1
  13. package/dist/lib/files/compiler.d.ts +71 -0
  14. package/dist/lib/files/compiler.d.ts.map +1 -0
  15. package/dist/lib/files/compiler.js +552 -0
  16. package/dist/lib/files/config.d.ts +101 -0
  17. package/dist/lib/files/config.d.ts.map +1 -0
  18. package/dist/lib/files/config.js +219 -0
  19. package/dist/lib/files/store.d.ts +31 -0
  20. package/dist/lib/files/store.d.ts.map +1 -0
  21. package/dist/lib/files/store.js +63 -0
  22. package/dist/lib/fingerprint.d.ts +3 -3
  23. package/dist/lib/fingerprint.d.ts.map +1 -1
  24. package/dist/lib/fingerprint.js +5 -5
  25. package/dist/lib/injected-packages.d.ts +11 -0
  26. package/dist/lib/injected-packages.d.ts.map +1 -0
  27. package/dist/lib/injected-packages.js +86 -0
  28. package/dist/lib/paths.d.ts +1 -0
  29. package/dist/lib/paths.d.ts.map +1 -1
  30. package/dist/lib/paths.js +12 -0
  31. package/dist/lib/routes.d.ts +5 -7
  32. package/dist/lib/routes.d.ts.map +1 -1
  33. package/dist/lib/routes.js +41 -36
  34. package/dist/lib/scripts/compiler.d.ts +1 -0
  35. package/dist/lib/scripts/compiler.d.ts.map +1 -1
  36. package/dist/lib/scripts/compiler.js +30 -5
  37. package/dist/lib/scripts/resolve.d.ts.map +1 -1
  38. package/dist/lib/scripts/resolve.js +57 -10
  39. package/dist/lib/scripts/transform.d.ts.map +1 -1
  40. package/dist/lib/scripts/transform.js +79 -3
  41. package/dist/lib/styles/compiler.d.ts +4 -0
  42. package/dist/lib/styles/compiler.d.ts.map +1 -1
  43. package/dist/lib/styles/compiler.js +2 -0
  44. package/dist/lib/styles/emit.d.ts +3 -0
  45. package/dist/lib/styles/emit.d.ts.map +1 -1
  46. package/dist/lib/styles/emit.js +36 -1
  47. package/dist/lib/styles/resolve.d.ts +8 -1
  48. package/dist/lib/styles/resolve.d.ts.map +1 -1
  49. package/dist/lib/styles/resolve.js +85 -32
  50. package/dist/lib/watch.d.ts +2 -0
  51. package/dist/lib/watch.d.ts.map +1 -1
  52. package/dist/lib/watch.js +25 -8
  53. package/package.json +11 -5
  54. package/src/assets.ts +1 -0
  55. package/src/lib/access.ts +10 -1
  56. package/src/lib/asset-server.ts +297 -34
  57. package/src/lib/compilation-error.ts +9 -0
  58. package/src/lib/files/compiler.ts +885 -0
  59. package/src/lib/files/config.ts +479 -0
  60. package/src/lib/files/store.ts +109 -0
  61. package/src/lib/fingerprint.ts +8 -7
  62. package/src/lib/injected-packages.ts +117 -0
  63. package/src/lib/paths.ts +28 -0
  64. package/src/lib/routes.ts +67 -55
  65. package/src/lib/scripts/compiler.ts +43 -5
  66. package/src/lib/scripts/resolve.ts +89 -11
  67. package/src/lib/scripts/transform.ts +105 -3
  68. package/src/lib/styles/compiler.ts +9 -0
  69. package/src/lib/styles/emit.ts +75 -1
  70. package/src/lib/styles/resolve.ts +132 -35
  71. package/src/lib/watch.ts +34 -12
@@ -1,9 +1,12 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs';
3
3
  import { createAccessPolicy } from "./access.js";
4
- import { isAssetServerCompilationError } from "./compilation-error.js";
4
+ import { createAssetServerCompilationError, isAssetServerCompilationError, } from "./compilation-error.js";
5
+ import { createFileCompiler, createResponseForFile } from "./files/compiler.js";
6
+ import { normalizeFilesOptions, serializeAssetTransformInvocations } from "./files/config.js";
5
7
  import { getFingerprintRequestCacheControl, parseFingerprintSuffix } from "./fingerprint.js";
6
- import { normalizeFilePath } from "./paths.js";
8
+ import { getInjectedPackageRouteConfigs } from "./injected-packages.js";
9
+ import { normalizeFilePath, normalizePathname } from "./paths.js";
7
10
  import { compileRoutes } from "./routes.js";
8
11
  import { createResponseForScript, createScriptCompiler } from "./scripts/compiler.js";
9
12
  import { supportedScriptExtensions } from "./scripts/resolve.js";
@@ -31,8 +34,9 @@ export function getInternalWatchTargets(assetServer) {
31
34
  * @example
32
35
  * ```ts
33
36
  * let assetServer = createAssetServer({
37
+ * basePath: '/assets',
34
38
  * fileMap: {
35
- * '/assets/app/*path': 'app/*path',
39
+ * '/app/*path': 'app/*path',
36
40
  * },
37
41
  * allow: ['app/**'],
38
42
  * })
@@ -49,12 +53,14 @@ export function createAssetServer(options) {
49
53
  });
50
54
  let watcher = null;
51
55
  let chokidarWatcher = null;
56
+ let fileCompiler = null;
52
57
  let scriptCompiler = createScriptCompiler({
53
58
  buildId: resolvedOptions.buildId,
54
59
  define: resolvedOptions.define,
55
60
  external: resolvedOptions.external,
56
61
  fingerprintAssets: resolvedOptions.fingerprintAssets,
57
62
  isAllowed: accessPolicy.isAllowed,
63
+ isDenied: accessPolicy.isDenied,
58
64
  minify: resolvedOptions.minify,
59
65
  onWatchDirectoriesChange: (delta) => {
60
66
  if (!watcher)
@@ -72,12 +78,26 @@ export function createAssetServer(options) {
72
78
  let styleCompiler = createStyleCompiler({
73
79
  buildId: resolvedOptions.buildId,
74
80
  fingerprintAssets: resolvedOptions.fingerprintAssets,
81
+ getServedFileUrl: (identityPath, options) => {
82
+ if (!fileCompiler) {
83
+ throw createAssetServerCompilationError(`File type is not supported: ${identityPath}`, {
84
+ code: 'FILE_NOT_SUPPORTED',
85
+ });
86
+ }
87
+ if (options.transform !== null) {
88
+ fileCompiler.validateTransformQuery(options.transform);
89
+ }
90
+ return fileCompiler.getHref(identityPath, { transform: options.transform });
91
+ },
75
92
  isAllowed: accessPolicy.isAllowed,
93
+ isServedFilePath(filePath) {
94
+ return fileCompiler?.isServedFilePath(filePath) ?? false;
95
+ },
76
96
  minify: resolvedOptions.minify,
77
97
  onWatchDirectoriesChange: (delta) => {
78
98
  if (!watcher)
79
99
  return;
80
- watcher.updateWatchedDirectories(delta);
100
+ watcher.updateWatchedDirectories(delta, { includeAncestors: false });
81
101
  },
82
102
  rootDir: resolvedOptions.rootDir,
83
103
  routes: resolvedOptions.routes,
@@ -86,6 +106,20 @@ export function createAssetServer(options) {
86
106
  targets: resolvedOptions.stylesTarget,
87
107
  watchIgnore: resolvedOptions.watchOptions?.ignore,
88
108
  });
109
+ if (resolvedOptions.files.extensions.length > 0) {
110
+ fileCompiler = createFileCompiler({
111
+ buildId: resolvedOptions.buildId,
112
+ cache: resolvedOptions.files.cache,
113
+ extensions: resolvedOptions.files.extensions,
114
+ fingerprintAssets: resolvedOptions.fingerprintAssets,
115
+ globalTransforms: resolvedOptions.files.globalTransforms,
116
+ isAllowed: accessPolicy.isAllowed,
117
+ maxRequestTransforms: resolvedOptions.files.maxRequestTransforms,
118
+ transforms: resolvedOptions.files.transforms,
119
+ rootDir: resolvedOptions.rootDir,
120
+ routes: resolvedOptions.routes,
121
+ });
122
+ }
89
123
  if (resolvedOptions.watchOptions) {
90
124
  watcher = createAssetServerWatcher({
91
125
  ...resolvedOptions.watchOptions,
@@ -110,6 +144,7 @@ export function createAssetServer(options) {
110
144
  let normalizedFilePath = normalizeFilePath(filePath);
111
145
  await scriptCompiler.handleFileEvent(normalizedFilePath, event);
112
146
  await styleCompiler.handleFileEvent(normalizedFilePath, event);
147
+ await fileCompiler?.handleFileEvent(normalizedFilePath, event);
113
148
  }
114
149
  catch (error) {
115
150
  console.error(`There was an error invalidating the asset server cache: ${error}`);
@@ -119,7 +154,9 @@ export function createAssetServer(options) {
119
154
  async fetch(request) {
120
155
  if (request.method !== 'GET' && request.method !== 'HEAD')
121
156
  return null;
122
- let parsedRequestPathname = parseAssetRequestPathname(new URL(request.url).pathname, {
157
+ let requestUrl = new URL(request.url);
158
+ let requestedTransform = normalizeRequestedTransformQuery(requestUrl.searchParams);
159
+ let parsedRequestPathname = parseAssetRequestPathname(requestUrl.pathname, {
123
160
  fingerprintAssets: resolvedOptions.fingerprintAssets,
124
161
  routes: resolvedOptions.routes,
125
162
  });
@@ -128,6 +165,9 @@ export function createAssetServer(options) {
128
165
  try {
129
166
  let ifNoneMatch = request.headers.get('If-None-Match');
130
167
  if (isStyleFilePath(parsedRequestPathname.filePath)) {
168
+ if (requestedTransform !== null) {
169
+ return badRequest('Asset request transforms are only supported for configured file assets');
170
+ }
131
171
  let styleResult = await styleCompiler.getStyle(parsedRequestPathname.filePath, {
132
172
  ifNoneMatch,
133
173
  isSourceMapRequest: parsedRequestPathname.isSourceMapRequest,
@@ -152,7 +192,36 @@ export function createAssetServer(options) {
152
192
  });
153
193
  }
154
194
  if (!isScriptFilePath(parsedRequestPathname.filePath)) {
155
- return null;
195
+ if (!fileCompiler?.isServedFilePath(parsedRequestPathname.filePath)) {
196
+ return null;
197
+ }
198
+ if (parsedRequestPathname.isSourceMapRequest) {
199
+ return null;
200
+ }
201
+ let fileResult = await fileCompiler.getFile(parsedRequestPathname.filePath, {
202
+ ifNoneMatch,
203
+ requestedFingerprint: parsedRequestPathname.requestedFingerprint,
204
+ transform: requestedTransform,
205
+ });
206
+ if (fileResult.type === 'not-modified') {
207
+ return new Response(null, {
208
+ status: 304,
209
+ headers: { ETag: fileResult.etag },
210
+ });
211
+ }
212
+ if (parsedRequestPathname.requestedFingerprint !== null) {
213
+ if (fileResult.file.fingerprint !== parsedRequestPathname.requestedFingerprint) {
214
+ return null;
215
+ }
216
+ }
217
+ return createResponseForFile(fileResult.file, {
218
+ cacheControl: parsedRequestPathname.cacheControl,
219
+ ifNoneMatch,
220
+ method: request.method,
221
+ });
222
+ }
223
+ if (requestedTransform !== null) {
224
+ return badRequest('Asset request transforms are only supported for configured file assets');
156
225
  }
157
226
  let scriptResult = await scriptCompiler.getScript(parsedRequestPathname.filePath, {
158
227
  ifNoneMatch,
@@ -185,42 +254,92 @@ export function createAssetServer(options) {
185
254
  (error.code === 'FILE_NOT_FOUND' || error.code === 'FILE_NOT_ALLOWED')) {
186
255
  return null;
187
256
  }
257
+ if (isAssetServerCompilationError(error) && error.code === 'FILE_TRANSFORM_QUERY_INVALID') {
258
+ return new Response(error.message, {
259
+ status: 400,
260
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
261
+ });
262
+ }
188
263
  return responseForError(error);
189
264
  }
190
265
  },
191
- async getHref(filePath) {
192
- if (isStyleFilePath(filePath)) {
266
+ async getHref(filePath, hrefOptions) {
267
+ let transform = getHrefTransform(hrefOptions, resolvedOptions.files);
268
+ let typeCheckFilePath = stripFilePathUrlSuffix(filePath);
269
+ if (isStyleFilePath(typeCheckFilePath)) {
270
+ if (transform !== null) {
271
+ throw new TypeError('assetServer.getHref() only supports transforms for configured file assets');
272
+ }
193
273
  return styleCompiler.getHref(filePath);
194
274
  }
275
+ if (fileCompiler?.isServedFilePath(typeCheckFilePath)) {
276
+ return fileCompiler.getHref(filePath, {
277
+ transform,
278
+ });
279
+ }
280
+ if (!isScriptFilePath(typeCheckFilePath)) {
281
+ throw createAssetServerCompilationError(`File type is not supported: ${filePath}`, {
282
+ code: 'FILE_NOT_SUPPORTED',
283
+ });
284
+ }
285
+ if (transform !== null) {
286
+ throw new TypeError('assetServer.getHref() only supports transforms for configured file assets');
287
+ }
195
288
  return scriptCompiler.getHref(filePath);
196
289
  },
197
290
  async getPreloads(filePath) {
198
291
  let filePaths = Array.isArray(filePath) ? filePath : [filePath];
292
+ let fileAssetFiles = [];
199
293
  let styleFiles = [];
200
294
  let scriptFiles = [];
295
+ let groupedAssetTypes = [];
201
296
  for (let nextFilePath of filePaths) {
202
- if (isStyleFilePath(nextFilePath)) {
297
+ let typeCheckFilePath = stripFilePathUrlSuffix(nextFilePath);
298
+ if (isStyleFilePath(typeCheckFilePath)) {
299
+ if (!groupedAssetTypes.includes('style')) {
300
+ groupedAssetTypes.push('style');
301
+ }
203
302
  styleFiles.push(nextFilePath);
204
303
  continue;
205
304
  }
305
+ if (fileCompiler?.isServedFilePath(typeCheckFilePath)) {
306
+ if (!groupedAssetTypes.includes('file')) {
307
+ groupedAssetTypes.push('file');
308
+ }
309
+ fileAssetFiles.push(nextFilePath);
310
+ continue;
311
+ }
312
+ if (!groupedAssetTypes.includes('script')) {
313
+ groupedAssetTypes.push('script');
314
+ }
206
315
  scriptFiles.push(nextFilePath);
207
316
  }
208
- if (styleFiles.length === 0 && scriptFiles.length === 0) {
317
+ if (styleFiles.length === 0 && scriptFiles.length === 0 && fileAssetFiles.length === 0) {
209
318
  return [];
210
319
  }
211
- if (styleFiles.length === 0) {
320
+ if (styleFiles.length === 0 && fileAssetFiles.length === 0) {
212
321
  return flattenPreloadLayers(await scriptCompiler.getPreloadLayers(filePath));
213
322
  }
214
- if (scriptFiles.length === 0) {
323
+ if (scriptFiles.length === 0 && fileAssetFiles.length === 0) {
215
324
  return flattenPreloadLayers(await styleCompiler.getPreloadLayers(filePath));
216
325
  }
217
- // Mixed asset type preloads need to be merged, so we merge in order of first asset type seen
218
- let scriptPreloadLayersPromise = scriptCompiler.getPreloadLayers(scriptFiles);
219
- let stylePreloadLayersPromise = styleCompiler.getPreloadLayers(styleFiles);
220
- let preloadLayerGroups = isStyleFilePath(filePaths[0])
221
- ? [stylePreloadLayersPromise, scriptPreloadLayersPromise]
222
- : [scriptPreloadLayersPromise, stylePreloadLayersPromise];
223
- return mergePreloadLayers(await Promise.all(preloadLayerGroups));
326
+ if (scriptFiles.length === 0 && styleFiles.length === 0) {
327
+ return flattenPreloadLayers(await getFilePreloadLayers(fileCompiler, fileAssetFiles));
328
+ }
329
+ // Mixed asset type preloads need to be merged, so we merge in order of first asset type seen.
330
+ let preloadLayerGroupPromises = groupedAssetTypes.flatMap((assetType) => {
331
+ switch (assetType) {
332
+ case 'script':
333
+ return scriptFiles.length > 0 ? [scriptCompiler.getPreloadLayers(scriptFiles)] : [];
334
+ case 'style':
335
+ return styleFiles.length > 0 ? [styleCompiler.getPreloadLayers(styleFiles)] : [];
336
+ case 'file':
337
+ return fileAssetFiles.length > 0
338
+ ? [getFilePreloadLayers(fileCompiler, fileAssetFiles)]
339
+ : [];
340
+ }
341
+ });
342
+ return mergePreloadLayers(await Promise.all(preloadLayerGroupPromises));
224
343
  },
225
344
  async close() {
226
345
  await watcher?.close();
@@ -234,12 +353,31 @@ export function createAssetServer(options) {
234
353
  }
235
354
  return assetServer;
236
355
  }
356
+ function getHrefTransform(options, files) {
357
+ if (!options)
358
+ return null;
359
+ let transform = options.transform;
360
+ if (transform.length === 0) {
361
+ return null;
362
+ }
363
+ return serializeAssetTransformInvocations(transform, files.transforms, files.maxRequestTransforms);
364
+ }
365
+ function normalizeRequestedTransformQuery(searchParams) {
366
+ let transforms = searchParams.getAll('transform');
367
+ return transforms.length > 0 ? transforms : null;
368
+ }
237
369
  function internalServerError() {
238
370
  return new Response('Internal Server Error', {
239
371
  status: 500,
240
372
  headers: { 'Content-Type': 'text/plain; charset=utf-8' },
241
373
  });
242
374
  }
375
+ function badRequest(message) {
376
+ return new Response(message, {
377
+ status: 400,
378
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
379
+ });
380
+ }
243
381
  function mergePreloadLayers(preloadLayersByRoot) {
244
382
  let urls = [];
245
383
  let seen = new Set();
@@ -259,11 +397,27 @@ function mergePreloadLayers(preloadLayersByRoot) {
259
397
  function flattenPreloadLayers(preloadLayers) {
260
398
  return preloadLayers.flatMap((layer) => layer);
261
399
  }
400
+ async function getFilePreloadLayers(fileCompiler, filePaths) {
401
+ if (filePaths.length === 0) {
402
+ return [];
403
+ }
404
+ if (!fileCompiler) {
405
+ throw createAssetServerCompilationError('File type is not supported', {
406
+ code: 'FILE_NOT_SUPPORTED',
407
+ });
408
+ }
409
+ return [
410
+ await Promise.all(filePaths.map((filePath) => fileCompiler.getHref(filePath, {
411
+ transform: null,
412
+ }))),
413
+ ];
414
+ }
262
415
  function defaultErrorHandler(error) {
263
416
  console.error(error);
264
417
  }
265
418
  function resolveAssetServerOptions(options) {
266
419
  let rootDir = normalizeFilePath(fs.realpathSync(path.resolve(options.rootDir ?? process.cwd())));
420
+ let basePath = normalizeBasePath(options.basePath);
267
421
  let scriptOptions = options.scripts ?? {};
268
422
  let fingerprintOptions = normalizeFingerprintOptions({
269
423
  fingerprint: options.fingerprint,
@@ -271,18 +425,23 @@ function resolveAssetServerOptions(options) {
271
425
  });
272
426
  return {
273
427
  allow: options.allow,
428
+ basePath,
274
429
  buildId: fingerprintOptions.buildId,
275
430
  define: scriptOptions.define,
276
431
  deny: options.deny,
277
432
  external: scriptOptions.external ?? [],
433
+ files: normalizeFilesOptions(options.files),
278
434
  fingerprintAssets: fingerprintOptions.enabled,
279
435
  minify: options.minify ?? false,
280
436
  onError: options.onError ?? defaultErrorHandler,
281
437
  rootDir,
282
- routes: compileRoutes({
283
- fileMap: options.fileMap,
284
- rootDir,
285
- }),
438
+ routes: compileRoutes(basePath, [
439
+ {
440
+ fileMap: options.fileMap,
441
+ rootDir,
442
+ },
443
+ ...getInjectedPackageRouteConfigs(),
444
+ ]),
286
445
  sourceMapSourcePaths: options.sourceMapSourcePaths ?? 'url',
287
446
  sourceMaps: options.sourceMaps,
288
447
  scriptsTarget: resolveScriptTarget(options.target),
@@ -290,6 +449,12 @@ function resolveAssetServerOptions(options) {
290
449
  watchOptions: normalizeWatchOptions(options.watch),
291
450
  };
292
451
  }
452
+ function normalizeBasePath(basePath) {
453
+ if (typeof basePath !== 'string') {
454
+ throw new TypeError('basePath must be a string');
455
+ }
456
+ return normalizePathname(basePath || '/').replace(/\/+$/, '') || '/';
457
+ }
293
458
  function normalizeFingerprintOptions(options) {
294
459
  if (!options.fingerprint) {
295
460
  return {
@@ -336,3 +501,10 @@ function parseAssetRequestPathname(pathname, options) {
336
501
  function isScriptFilePath(filePath) {
337
502
  return scriptExtensionSet.has(path.extname(filePath).toLowerCase());
338
503
  }
504
+ function stripFilePathUrlSuffix(filePath) {
505
+ if (filePath.startsWith('file://')) {
506
+ return new URL(filePath).pathname;
507
+ }
508
+ let queryIndex = filePath.indexOf('?');
509
+ return queryIndex === -1 ? filePath : filePath.slice(0, queryIndex);
510
+ }
@@ -1,4 +1,4 @@
1
- type AssetServerCompilationErrorCode = 'FILE_NOT_FOUND' | 'FILE_NOT_ALLOWED' | 'FILE_OUTSIDE_FILE_MAP' | 'COMMONJS_NOT_SUPPORTED' | 'TRANSFORM_FAILED' | 'EMIT_FAILED' | 'IMPORT_RESOLUTION_FAILED' | 'IMPORT_NOT_SUPPORTED' | 'IMPORT_NOT_ALLOWED' | 'IMPORT_OUTSIDE_FILE_MAP';
1
+ type AssetServerCompilationErrorCode = 'FILE_NOT_FOUND' | 'FILE_NOT_ALLOWED' | 'FILE_NOT_SUPPORTED' | 'FILE_OUTSIDE_FILE_MAP' | 'FILE_TRANSFORM_QUERY_INVALID' | 'FILE_TRANSFORM_NOT_SUPPORTED' | 'FILE_TRANSFORM_RESULT_INVALID' | 'FILE_TRANSFORM_FAILED' | 'COMMONJS_NOT_SUPPORTED' | 'TRANSFORM_FAILED' | 'EMIT_FAILED' | 'IMPORT_RESOLUTION_FAILED' | 'IMPORT_NOT_SUPPORTED' | 'IMPORT_NOT_ALLOWED' | 'IMPORT_OUTSIDE_FILE_MAP' | 'URL_RESOLUTION_FAILED' | 'URL_NOT_SUPPORTED' | 'URL_NOT_ALLOWED' | 'URL_OUTSIDE_FILE_MAP';
2
2
  /**
3
3
  * Internal error used by the request-time asset compilation pipeline.
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"compilation-error.d.ts","sourceRoot":"","sources":["../../src/lib/compilation-error.ts"],"names":[],"mappings":"AAAA,KAAK,+BAA+B,GAChC,gBAAgB,GAChB,kBAAkB,GAClB,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,aAAa,GACb,0BAA0B,GAC1B,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,CAAA;AAE7B;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,IAAI,EAAE,+BAA+B,CAAA;IAErC,YACE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,+BAA+B,CAAA;KACtC,EAKF;CACF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,2BAA2B,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,+BAA+B,CAAA;CACtC,GACA,2BAA2B,CAE7B"}
1
+ {"version":3,"file":"compilation-error.d.ts","sourceRoot":"","sources":["../../src/lib/compilation-error.ts"],"names":[],"mappings":"AAAA,KAAK,+BAA+B,GAChC,gBAAgB,GAChB,kBAAkB,GAClB,oBAAoB,GACpB,uBAAuB,GACvB,8BAA8B,GAC9B,8BAA8B,GAC9B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,aAAa,GACb,0BAA0B,GAC1B,sBAAsB,GACtB,oBAAoB,GACpB,yBAAyB,GACzB,uBAAuB,GACvB,mBAAmB,GACnB,iBAAiB,GACjB,sBAAsB,CAAA;AAE1B;;GAEG;AACH,qBAAa,2BAA4B,SAAQ,KAAK;IACpD,IAAI,EAAE,+BAA+B,CAAA;IAErC,YACE,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;QACP,KAAK,CAAC,EAAE,OAAO,CAAA;QACf,IAAI,EAAE,+BAA+B,CAAA;KACtC,EAKF;CACF;AAED;;;;;GAKG;AACH,wBAAgB,6BAA6B,CAC3C,KAAK,EAAE,OAAO,GACb,KAAK,IAAI,2BAA2B,CAEtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,MAAM,EACf,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,IAAI,EAAE,+BAA+B,CAAA;CACtC,GACA,2BAA2B,CAE7B"}
@@ -0,0 +1,71 @@
1
+ import type { FileStorage } from '@remix-run/file-storage';
2
+ import type { CompiledRoutes } from '../routes.ts';
3
+ import type { AssetFileTransformResult, ResolvedAssetRequestTransformMap } from './config.ts';
4
+ type EmittedFile = {
5
+ body: Uint8Array;
6
+ contentType: string;
7
+ etag: string;
8
+ extension: string;
9
+ fingerprint: string | null;
10
+ };
11
+ type FileCompileResult = EmittedFile;
12
+ type FileGetResult = {
13
+ etag: string;
14
+ type: 'not-modified';
15
+ } | {
16
+ file: FileCompileResult;
17
+ type: 'file';
18
+ };
19
+ type FileGetOptions = {
20
+ ifNoneMatch: string | null;
21
+ requestedFingerprint: string | null;
22
+ transform: readonly string[] | null;
23
+ };
24
+ type FileGetHrefOptions = {
25
+ transform: readonly string[] | null;
26
+ };
27
+ type FileCompilerOptions = {
28
+ buildId?: string;
29
+ cache?: FileStorage;
30
+ extensions: readonly string[];
31
+ fingerprintAssets: boolean;
32
+ globalTransforms: readonly {
33
+ extensions?: readonly string[];
34
+ name?: string;
35
+ transform(bytes: Uint8Array, context: {
36
+ extension: string;
37
+ filePath: string;
38
+ }): string | Uint8Array | AssetFileTransformResult | null | Promise<string | Uint8Array | AssetFileTransformResult | null>;
39
+ }[];
40
+ isAllowed(absolutePath: string): boolean;
41
+ maxRequestTransforms: number;
42
+ transforms: ResolvedAssetRequestTransformMap;
43
+ rootDir: string;
44
+ routes: CompiledRoutes;
45
+ };
46
+ export type FileCompiler = {
47
+ getFile(filePath: string, options: FileGetOptions): Promise<FileGetResult>;
48
+ getHref(filePath: string, options: FileGetHrefOptions): Promise<string>;
49
+ handleFileEvent(filePath: string, event: 'add' | 'change' | 'unlink'): Promise<void>;
50
+ isServedFilePath(filePath: string): boolean;
51
+ validateTransformQuery(transformQuery: readonly string[]): void;
52
+ };
53
+ type ResolveArgs = {
54
+ extensions: ReadonlySet<string>;
55
+ isAllowed(absolutePath: string): boolean;
56
+ routes: CompiledRoutes;
57
+ };
58
+ type ResolvedFile = {
59
+ identityPath: string;
60
+ stableUrlPathname: string;
61
+ };
62
+ export declare function createFileCompiler(options: FileCompilerOptions): FileCompiler;
63
+ export declare function resolveServedFileOrThrow(filePath: string, args: ResolveArgs): ResolvedFile;
64
+ export declare function createResponseForFile(result: FileCompileResult, options: {
65
+ cacheControl: string;
66
+ ifNoneMatch: string | null;
67
+ method: string;
68
+ }): Response;
69
+ export declare function isServedFilePath(filePath: string, extensions: ReadonlySet<string>): boolean;
70
+ export {};
71
+ //# sourceMappingURL=compiler.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/files/compiler.ts"],"names":[],"mappings":"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"}