@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.
- package/README.md +241 -28
- package/dist/assets.d.ts +1 -0
- package/dist/assets.d.ts.map +1 -1
- package/dist/assets.js +1 -0
- package/dist/lib/access.d.ts +1 -0
- package/dist/lib/access.d.ts.map +1 -1
- package/dist/lib/access.js +10 -1
- package/dist/lib/asset-server.d.ts +33 -7
- package/dist/lib/asset-server.d.ts.map +1 -1
- package/dist/lib/asset-server.js +195 -23
- package/dist/lib/compilation-error.d.ts +1 -1
- package/dist/lib/compilation-error.d.ts.map +1 -1
- package/dist/lib/files/compiler.d.ts +71 -0
- package/dist/lib/files/compiler.d.ts.map +1 -0
- package/dist/lib/files/compiler.js +552 -0
- package/dist/lib/files/config.d.ts +101 -0
- package/dist/lib/files/config.d.ts.map +1 -0
- package/dist/lib/files/config.js +219 -0
- package/dist/lib/files/store.d.ts +31 -0
- package/dist/lib/files/store.d.ts.map +1 -0
- package/dist/lib/files/store.js +63 -0
- package/dist/lib/fingerprint.d.ts +3 -3
- package/dist/lib/fingerprint.d.ts.map +1 -1
- package/dist/lib/fingerprint.js +5 -5
- package/dist/lib/injected-packages.d.ts +11 -0
- package/dist/lib/injected-packages.d.ts.map +1 -0
- package/dist/lib/injected-packages.js +86 -0
- package/dist/lib/paths.d.ts +1 -0
- package/dist/lib/paths.d.ts.map +1 -1
- package/dist/lib/paths.js +12 -0
- package/dist/lib/routes.d.ts +5 -7
- package/dist/lib/routes.d.ts.map +1 -1
- package/dist/lib/routes.js +41 -36
- package/dist/lib/scripts/compiler.d.ts +1 -0
- package/dist/lib/scripts/compiler.d.ts.map +1 -1
- package/dist/lib/scripts/compiler.js +30 -5
- package/dist/lib/scripts/resolve.d.ts.map +1 -1
- package/dist/lib/scripts/resolve.js +57 -10
- package/dist/lib/scripts/transform.d.ts.map +1 -1
- package/dist/lib/scripts/transform.js +79 -3
- package/dist/lib/styles/compiler.d.ts +4 -0
- package/dist/lib/styles/compiler.d.ts.map +1 -1
- package/dist/lib/styles/compiler.js +2 -0
- package/dist/lib/styles/emit.d.ts +3 -0
- package/dist/lib/styles/emit.d.ts.map +1 -1
- package/dist/lib/styles/emit.js +36 -1
- package/dist/lib/styles/resolve.d.ts +8 -1
- package/dist/lib/styles/resolve.d.ts.map +1 -1
- package/dist/lib/styles/resolve.js +85 -32
- package/dist/lib/watch.d.ts +2 -0
- package/dist/lib/watch.d.ts.map +1 -1
- package/dist/lib/watch.js +25 -8
- package/package.json +11 -5
- package/src/assets.ts +1 -0
- package/src/lib/access.ts +10 -1
- package/src/lib/asset-server.ts +297 -34
- package/src/lib/compilation-error.ts +9 -0
- package/src/lib/files/compiler.ts +885 -0
- package/src/lib/files/config.ts +479 -0
- package/src/lib/files/store.ts +109 -0
- package/src/lib/fingerprint.ts +8 -7
- package/src/lib/injected-packages.ts +117 -0
- package/src/lib/paths.ts +28 -0
- package/src/lib/routes.ts +67 -55
- package/src/lib/scripts/compiler.ts +43 -5
- package/src/lib/scripts/resolve.ts +89 -11
- package/src/lib/scripts/transform.ts +105 -3
- package/src/lib/styles/compiler.ts +9 -0
- package/src/lib/styles/emit.ts +75 -1
- package/src/lib/styles/resolve.ts +132 -35
- package/src/lib/watch.ts +34 -12
package/dist/lib/asset-server.js
CHANGED
|
@@ -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 {
|
|
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
|
-
* '/
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
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
|
-
|
|
284
|
-
|
|
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;
|
|
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":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAA;AAU1D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,wBAAwB,EAAE,gCAAgC,EAAE,MAAM,aAAa,CAAA;AAU7F,KAAK,WAAW,GAAG;IACjB,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,IAAI,EAAE,MAAM,CAAA;IACZ,SAAS,EAAE,MAAM,CAAA;IACjB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAID,KAAK,iBAAiB,GAAG,WAAW,CAAA;AAEpC,KAAK,aAAa,GACd;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,GACD;IACE,IAAI,EAAE,iBAAiB,CAAA;IACvB,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAEL,KAAK,cAAc,GAAG;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;IACnC,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,kBAAkB,GAAG;IACxB,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,mBAAmB,GAAG;IACzB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,KAAK,CAAC,EAAE,WAAW,CAAA;IACnB,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,EAAE,SAAS;QACzB,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;QAC9B,IAAI,CAAC,EAAE,MAAM,CAAA;QACb,SAAS,CACP,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE;YACP,SAAS,EAAE,MAAM,CAAA;YACjB,QAAQ,EAAE,MAAM,CAAA;SACjB,GAEC,MAAM,GACN,UAAU,GACV,wBAAwB,GACxB,IAAI,GACJ,OAAO,CAAC,MAAM,GAAG,UAAU,GAAG,wBAAwB,GAAG,IAAI,CAAC,CAAA;KACnE,EAAE,CAAA;IACH,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,oBAAoB,EAAE,MAAM,CAAA;IAC5B,UAAU,EAAE,gCAAgC,CAAA;IAC5C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,aAAa,CAAC,CAAA;IAC1E,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACvE,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IACpF,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,sBAAsB,CAAC,cAAc,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;CAChE,CAAA;AAED,KAAK,WAAW,GAAG;IACjB,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IAC/B,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,YAAY,GAAG;IAClB,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CAAA;AAkBD,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,mBAAmB,GAAG,YAAY,CAma7E;AAED,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,YAAY,CAkC1F;AAED,wBAAgB,qBAAqB,CACnC,MAAM,EAAE,iBAAiB,EACzB,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CAYV;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,GAAG,OAAO,CAE3F"}
|