@remix-run/assets 0.3.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 (61) hide show
  1. package/README.md +206 -8
  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 +7 -1
  8. package/dist/lib/asset-server.d.ts +29 -6
  9. package/dist/lib/asset-server.d.ts.map +1 -1
  10. package/dist/lib/asset-server.js +176 -17
  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/routes.d.ts.map +1 -1
  26. package/dist/lib/routes.js +28 -20
  27. package/dist/lib/scripts/compiler.d.ts +1 -0
  28. package/dist/lib/scripts/compiler.d.ts.map +1 -1
  29. package/dist/lib/scripts/compiler.js +30 -5
  30. package/dist/lib/scripts/resolve.d.ts.map +1 -1
  31. package/dist/lib/scripts/resolve.js +22 -2
  32. package/dist/lib/scripts/transform.js +1 -1
  33. package/dist/lib/styles/compiler.d.ts +4 -0
  34. package/dist/lib/styles/compiler.d.ts.map +1 -1
  35. package/dist/lib/styles/compiler.js +2 -0
  36. package/dist/lib/styles/emit.d.ts +3 -0
  37. package/dist/lib/styles/emit.d.ts.map +1 -1
  38. package/dist/lib/styles/emit.js +36 -1
  39. package/dist/lib/styles/resolve.d.ts +8 -1
  40. package/dist/lib/styles/resolve.d.ts.map +1 -1
  41. package/dist/lib/styles/resolve.js +85 -32
  42. package/dist/lib/watch.d.ts +2 -0
  43. package/dist/lib/watch.d.ts.map +1 -1
  44. package/dist/lib/watch.js +25 -8
  45. package/package.json +6 -4
  46. package/src/assets.ts +1 -0
  47. package/src/lib/access.ts +8 -1
  48. package/src/lib/asset-server.ts +273 -28
  49. package/src/lib/compilation-error.ts +9 -0
  50. package/src/lib/files/compiler.ts +885 -0
  51. package/src/lib/files/config.ts +479 -0
  52. package/src/lib/files/store.ts +109 -0
  53. package/src/lib/fingerprint.ts +8 -7
  54. package/src/lib/routes.ts +36 -33
  55. package/src/lib/scripts/compiler.ts +43 -5
  56. package/src/lib/scripts/resolve.ts +35 -3
  57. package/src/lib/scripts/transform.ts +1 -1
  58. package/src/lib/styles/compiler.ts +9 -0
  59. package/src/lib/styles/emit.ts +75 -1
  60. package/src/lib/styles/resolve.ts +132 -35
  61. package/src/lib/watch.ts +34 -12
@@ -1,7 +1,9 @@
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
8
  import { getInjectedPackageRouteConfigs } from "./injected-packages.js";
7
9
  import { normalizeFilePath, normalizePathname } from "./paths.js";
@@ -51,12 +53,14 @@ export function createAssetServer(options) {
51
53
  });
52
54
  let watcher = null;
53
55
  let chokidarWatcher = null;
56
+ let fileCompiler = null;
54
57
  let scriptCompiler = createScriptCompiler({
55
58
  buildId: resolvedOptions.buildId,
56
59
  define: resolvedOptions.define,
57
60
  external: resolvedOptions.external,
58
61
  fingerprintAssets: resolvedOptions.fingerprintAssets,
59
62
  isAllowed: accessPolicy.isAllowed,
63
+ isDenied: accessPolicy.isDenied,
60
64
  minify: resolvedOptions.minify,
61
65
  onWatchDirectoriesChange: (delta) => {
62
66
  if (!watcher)
@@ -74,12 +78,26 @@ export function createAssetServer(options) {
74
78
  let styleCompiler = createStyleCompiler({
75
79
  buildId: resolvedOptions.buildId,
76
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
+ },
77
92
  isAllowed: accessPolicy.isAllowed,
93
+ isServedFilePath(filePath) {
94
+ return fileCompiler?.isServedFilePath(filePath) ?? false;
95
+ },
78
96
  minify: resolvedOptions.minify,
79
97
  onWatchDirectoriesChange: (delta) => {
80
98
  if (!watcher)
81
99
  return;
82
- watcher.updateWatchedDirectories(delta);
100
+ watcher.updateWatchedDirectories(delta, { includeAncestors: false });
83
101
  },
84
102
  rootDir: resolvedOptions.rootDir,
85
103
  routes: resolvedOptions.routes,
@@ -88,6 +106,20 @@ export function createAssetServer(options) {
88
106
  targets: resolvedOptions.stylesTarget,
89
107
  watchIgnore: resolvedOptions.watchOptions?.ignore,
90
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
+ }
91
123
  if (resolvedOptions.watchOptions) {
92
124
  watcher = createAssetServerWatcher({
93
125
  ...resolvedOptions.watchOptions,
@@ -112,6 +144,7 @@ export function createAssetServer(options) {
112
144
  let normalizedFilePath = normalizeFilePath(filePath);
113
145
  await scriptCompiler.handleFileEvent(normalizedFilePath, event);
114
146
  await styleCompiler.handleFileEvent(normalizedFilePath, event);
147
+ await fileCompiler?.handleFileEvent(normalizedFilePath, event);
115
148
  }
116
149
  catch (error) {
117
150
  console.error(`There was an error invalidating the asset server cache: ${error}`);
@@ -121,7 +154,9 @@ export function createAssetServer(options) {
121
154
  async fetch(request) {
122
155
  if (request.method !== 'GET' && request.method !== 'HEAD')
123
156
  return null;
124
- 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, {
125
160
  fingerprintAssets: resolvedOptions.fingerprintAssets,
126
161
  routes: resolvedOptions.routes,
127
162
  });
@@ -130,6 +165,9 @@ export function createAssetServer(options) {
130
165
  try {
131
166
  let ifNoneMatch = request.headers.get('If-None-Match');
132
167
  if (isStyleFilePath(parsedRequestPathname.filePath)) {
168
+ if (requestedTransform !== null) {
169
+ return badRequest('Asset request transforms are only supported for configured file assets');
170
+ }
133
171
  let styleResult = await styleCompiler.getStyle(parsedRequestPathname.filePath, {
134
172
  ifNoneMatch,
135
173
  isSourceMapRequest: parsedRequestPathname.isSourceMapRequest,
@@ -154,7 +192,36 @@ export function createAssetServer(options) {
154
192
  });
155
193
  }
156
194
  if (!isScriptFilePath(parsedRequestPathname.filePath)) {
157
- 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');
158
225
  }
159
226
  let scriptResult = await scriptCompiler.getScript(parsedRequestPathname.filePath, {
160
227
  ifNoneMatch,
@@ -187,42 +254,92 @@ export function createAssetServer(options) {
187
254
  (error.code === 'FILE_NOT_FOUND' || error.code === 'FILE_NOT_ALLOWED')) {
188
255
  return null;
189
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
+ }
190
263
  return responseForError(error);
191
264
  }
192
265
  },
193
- async getHref(filePath) {
194
- 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
+ }
195
273
  return styleCompiler.getHref(filePath);
196
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
+ }
197
288
  return scriptCompiler.getHref(filePath);
198
289
  },
199
290
  async getPreloads(filePath) {
200
291
  let filePaths = Array.isArray(filePath) ? filePath : [filePath];
292
+ let fileAssetFiles = [];
201
293
  let styleFiles = [];
202
294
  let scriptFiles = [];
295
+ let groupedAssetTypes = [];
203
296
  for (let nextFilePath of filePaths) {
204
- if (isStyleFilePath(nextFilePath)) {
297
+ let typeCheckFilePath = stripFilePathUrlSuffix(nextFilePath);
298
+ if (isStyleFilePath(typeCheckFilePath)) {
299
+ if (!groupedAssetTypes.includes('style')) {
300
+ groupedAssetTypes.push('style');
301
+ }
205
302
  styleFiles.push(nextFilePath);
206
303
  continue;
207
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
+ }
208
315
  scriptFiles.push(nextFilePath);
209
316
  }
210
- if (styleFiles.length === 0 && scriptFiles.length === 0) {
317
+ if (styleFiles.length === 0 && scriptFiles.length === 0 && fileAssetFiles.length === 0) {
211
318
  return [];
212
319
  }
213
- if (styleFiles.length === 0) {
320
+ if (styleFiles.length === 0 && fileAssetFiles.length === 0) {
214
321
  return flattenPreloadLayers(await scriptCompiler.getPreloadLayers(filePath));
215
322
  }
216
- if (scriptFiles.length === 0) {
323
+ if (scriptFiles.length === 0 && fileAssetFiles.length === 0) {
217
324
  return flattenPreloadLayers(await styleCompiler.getPreloadLayers(filePath));
218
325
  }
219
- // Mixed asset type preloads need to be merged, so we merge in order of first asset type seen
220
- let scriptPreloadLayersPromise = scriptCompiler.getPreloadLayers(scriptFiles);
221
- let stylePreloadLayersPromise = styleCompiler.getPreloadLayers(styleFiles);
222
- let preloadLayerGroups = isStyleFilePath(filePaths[0])
223
- ? [stylePreloadLayersPromise, scriptPreloadLayersPromise]
224
- : [scriptPreloadLayersPromise, stylePreloadLayersPromise];
225
- 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));
226
343
  },
227
344
  async close() {
228
345
  await watcher?.close();
@@ -236,12 +353,31 @@ export function createAssetServer(options) {
236
353
  }
237
354
  return assetServer;
238
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
+ }
239
369
  function internalServerError() {
240
370
  return new Response('Internal Server Error', {
241
371
  status: 500,
242
372
  headers: { 'Content-Type': 'text/plain; charset=utf-8' },
243
373
  });
244
374
  }
375
+ function badRequest(message) {
376
+ return new Response(message, {
377
+ status: 400,
378
+ headers: { 'Content-Type': 'text/plain; charset=utf-8' },
379
+ });
380
+ }
245
381
  function mergePreloadLayers(preloadLayersByRoot) {
246
382
  let urls = [];
247
383
  let seen = new Set();
@@ -261,6 +397,21 @@ function mergePreloadLayers(preloadLayersByRoot) {
261
397
  function flattenPreloadLayers(preloadLayers) {
262
398
  return preloadLayers.flatMap((layer) => layer);
263
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
+ }
264
415
  function defaultErrorHandler(error) {
265
416
  console.error(error);
266
417
  }
@@ -279,6 +430,7 @@ function resolveAssetServerOptions(options) {
279
430
  define: scriptOptions.define,
280
431
  deny: options.deny,
281
432
  external: scriptOptions.external ?? [],
433
+ files: normalizeFilesOptions(options.files),
282
434
  fingerprintAssets: fingerprintOptions.enabled,
283
435
  minify: options.minify ?? false,
284
436
  onError: options.onError ?? defaultErrorHandler,
@@ -349,3 +501,10 @@ function parseAssetRequestPathname(pathname, options) {
349
501
  function isScriptFilePath(filePath) {
350
502
  return scriptExtensionSet.has(path.extname(filePath).toLowerCase());
351
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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"}