@remix-run/assets 0.5.0 → 0.6.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 (40) hide show
  1. package/README.md +85 -92
  2. package/dist/assets.d.ts +2 -0
  3. package/dist/assets.d.ts.map +1 -1
  4. package/dist/lib/access.d.ts +29 -2
  5. package/dist/lib/access.d.ts.map +1 -1
  6. package/dist/lib/access.js +52 -26
  7. package/dist/lib/asset-server.d.ts +21 -7
  8. package/dist/lib/asset-server.d.ts.map +1 -1
  9. package/dist/lib/asset-server.js +30 -15
  10. package/dist/lib/compilation-error.d.ts +1 -1
  11. package/dist/lib/compilation-error.d.ts.map +1 -1
  12. package/dist/lib/files/compiler.js +2 -2
  13. package/dist/lib/injected-packages.d.ts +3 -2
  14. package/dist/lib/injected-packages.d.ts.map +1 -1
  15. package/dist/lib/injected-packages.js +11 -8
  16. package/dist/lib/inspection.d.ts +39 -0
  17. package/dist/lib/inspection.d.ts.map +1 -0
  18. package/dist/lib/inspection.js +160 -0
  19. package/dist/lib/routes.d.ts +11 -3
  20. package/dist/lib/routes.d.ts.map +1 -1
  21. package/dist/lib/routes.js +124 -80
  22. package/dist/lib/scripts/compiler.js +2 -2
  23. package/dist/lib/scripts/resolve.js +9 -9
  24. package/dist/lib/scripts/transform.js +2 -2
  25. package/dist/lib/styles/resolve.js +8 -8
  26. package/dist/lib/styles/transform.js +2 -2
  27. package/package.json +5 -6
  28. package/src/assets.ts +2 -0
  29. package/src/lib/access.ts +83 -30
  30. package/src/lib/asset-server.ts +50 -22
  31. package/src/lib/compilation-error.ts +3 -3
  32. package/src/lib/files/compiler.ts +2 -2
  33. package/src/lib/injected-packages.ts +16 -10
  34. package/src/lib/inspection.ts +229 -0
  35. package/src/lib/routes.ts +158 -126
  36. package/src/lib/scripts/compiler.ts +2 -2
  37. package/src/lib/scripts/resolve.ts +9 -9
  38. package/src/lib/scripts/transform.ts +2 -2
  39. package/src/lib/styles/resolve.ts +8 -8
  40. package/src/lib/styles/transform.ts +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"asset-server.d.ts","sourceRoot":"","sources":["../../src/lib/asset-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"asset-server.d.ts","sourceRoot":"","sources":["../../src/lib/asset-server.ts"],"names":[],"mappings":"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"}
@@ -6,7 +6,7 @@ import { createFileCompiler, createResponseForFile } from './files/compiler.js';
6
6
  import { normalizeFilesOptions, serializeAssetTransformInvocations } from './files/config.js';
7
7
  import { getFingerprintRequestCacheControl, parseFingerprintSuffix } from './fingerprint.js';
8
8
  import { createHmrClientSource } from './hmr.js';
9
- import { getInjectedPackageRouteConfigs } from './injected-packages.js';
9
+ import { getInjectedPackageMountConfigs } from './injected-packages.js';
10
10
  import { normalizeFilePath, normalizePathname } from './paths.js';
11
11
  import { compileRoutes } from './routes.js';
12
12
  import { createResponseForScript, createScriptCompiler } from './scripts/compiler.js';
@@ -14,7 +14,12 @@ import { supportedScriptExtensions } from './scripts/resolve.js';
14
14
  import { createResponseForStyle, createStyleCompiler, isStyleFilePath } from './styles/compiler.js';
15
15
  import { resolveScriptTarget, resolveStyleTarget } from './target.js';
16
16
  import { createAssetServerWatcher } from './watch.js';
17
+ import { createAssetInspector } from './inspection.js';
17
18
  const scriptExtensionSet = new Set(supportedScriptExtensions);
19
+ const defaultMounts = {
20
+ app: 'app',
21
+ npm: 'node_modules',
22
+ };
18
23
  const chokidarWatcherByAssetServer = new WeakMap();
19
24
  const watcherByAssetServer = new WeakMap();
20
25
  export function getInternalChokidarWatcher(assetServer) {
@@ -27,7 +32,7 @@ export function getInternalWatchTargets(assetServer) {
27
32
  * Create an asset server instance
28
33
  *
29
34
  * Compiles TypeScript/JavaScript scripts and CSS styles on demand with optional
30
- * source-based URL fingerprinting, caching, and configurable file mapping.
35
+ * source-based URL fingerprinting, caching, and configurable directory mounts.
31
36
  *
32
37
  * @param options Server configuration
33
38
  * @returns A {@link AssetServer} with `fetch()`, `getHref()`, and `getPreloads()` methods
@@ -36,9 +41,6 @@ export function getInternalWatchTargets(assetServer) {
36
41
  * ```ts
37
42
  * let assetServer = createAssetServer({
38
43
  * basePath: '/assets',
39
- * fileMap: {
40
- * '/app/*path': 'app/*path',
41
- * },
42
44
  * allowFiles: ['app/routes.ts', 'app/**\/public/**'],
43
45
  * allowPackages: ['remix'],
44
46
  * denyFiles: ['app/**\/*.test.*'],
@@ -54,10 +56,17 @@ export function createAssetServer(options) {
54
56
  allowPackages: resolvedOptions.allowPackages,
55
57
  denyFiles: resolvedOptions.denyFiles,
56
58
  packageSearchRoots: hasPackages(resolvedOptions.allowPackages)
57
- ? getPackageSearchRoots(options.fileMap, resolvedOptions.rootDir)
59
+ ? getPackageSearchRoots(resolvedOptions.mounts, resolvedOptions.rootDir)
58
60
  : undefined,
59
61
  rootDir: resolvedOptions.rootDir,
60
62
  });
63
+ let assetInspector = createAssetInspector({
64
+ accessPolicy,
65
+ allowFiles: resolvedOptions.allowFiles,
66
+ fileExtensions: resolvedOptions.files.extensions,
67
+ rootDir: resolvedOptions.rootDir,
68
+ routes: resolvedOptions.routes,
69
+ });
61
70
  let watcher = null;
62
71
  let chokidarWatcher = null;
63
72
  let fileCompiler = null;
@@ -239,6 +248,12 @@ export function createAssetServer(options) {
239
248
  });
240
249
  }
241
250
  let assetServer = {
251
+ getAssetDetails(input) {
252
+ return assetInspector.getAssetDetails(input);
253
+ },
254
+ getAssets() {
255
+ return assetInspector.getAssets();
256
+ },
242
257
  async fetch(request) {
243
258
  if (request.method !== 'GET' && request.method !== 'HEAD')
244
259
  return null;
@@ -594,9 +609,13 @@ function resolveAssetServerOptions(options) {
594
609
  });
595
610
  let watchOptions = normalizeWatchOptions(options.watch);
596
611
  let hmrFactory = normalizeHmrFactory(options.hmr);
612
+ let mounts = options.mounts ?? defaultMounts;
597
613
  if (hmrFactory && watchOptions === null) {
598
614
  throw new TypeError('hmr requires watch mode');
599
615
  }
616
+ if (Object.keys(mounts).length === 0) {
617
+ throw new TypeError('mounts must include at least one entry');
618
+ }
600
619
  return {
601
620
  allowFiles: options.allowFiles,
602
621
  allowPackages: options.allowPackages,
@@ -609,15 +628,16 @@ function resolveAssetServerOptions(options) {
609
628
  fingerprintAssets: fingerprintOptions.enabled,
610
629
  hmr: hmrFactory,
611
630
  minify: options.minify ?? false,
631
+ mounts,
612
632
  loaders: scriptOptions.loaders ?? [],
613
633
  onError: options.onError ?? defaultErrorHandler,
614
634
  rootDir,
615
635
  routes: compileRoutes(basePath, [
616
636
  {
617
- fileMap: options.fileMap,
637
+ mounts,
618
638
  rootDir,
619
639
  },
620
- ...getInjectedPackageRouteConfigs(),
640
+ ...getInjectedPackageMountConfigs(),
621
641
  ]),
622
642
  sourceMapSourcePaths: options.sourceMapSourcePaths ?? 'url',
623
643
  sourceMaps: options.sourceMaps,
@@ -709,13 +729,8 @@ function normalizeWatchOptions(options) {
709
729
  function hasPackages(packages) {
710
730
  return packages !== undefined && packages.length > 0;
711
731
  }
712
- function getPackageSearchRoots(fileMap, rootDir) {
713
- return Object.values(fileMap).map((filePattern) => path.resolve(rootDir, getStaticFilePatternPrefix(filePattern)));
714
- }
715
- function getStaticFilePatternPrefix(filePattern) {
716
- let firstDynamicIndex = filePattern.search(/[*:]/);
717
- let staticPrefix = firstDynamicIndex === -1 ? filePattern : filePattern.slice(0, firstDynamicIndex);
718
- return staticPrefix.replace(/[/\\]*$/, '');
732
+ function getPackageSearchRoots(mounts, rootDir) {
733
+ return Object.values(mounts).map((fileRoot) => path.resolve(rootDir, fileRoot));
719
734
  }
720
735
  function parseAssetRequestPathname(pathname, options) {
721
736
  let isSourceMapRequest = pathname.endsWith('.map');
@@ -1,4 +1,4 @@
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' | 'LOADER_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';
1
+ type AssetServerCompilationErrorCode = 'FILE_NOT_FOUND' | 'FILE_NOT_ALLOWED' | 'FILE_NOT_SUPPORTED' | 'FILE_OUTSIDE_MOUNTS' | 'FILE_TRANSFORM_QUERY_INVALID' | 'FILE_TRANSFORM_NOT_SUPPORTED' | 'FILE_TRANSFORM_RESULT_INVALID' | 'FILE_TRANSFORM_FAILED' | 'COMMONJS_NOT_SUPPORTED' | 'TRANSFORM_FAILED' | 'LOADER_FAILED' | 'EMIT_FAILED' | 'IMPORT_RESOLUTION_FAILED' | 'IMPORT_NOT_SUPPORTED' | 'IMPORT_NOT_ALLOWED' | 'IMPORT_OUTSIDE_MOUNTS' | 'URL_RESOLUTION_FAILED' | 'URL_NOT_SUPPORTED' | 'URL_NOT_ALLOWED' | 'URL_OUTSIDE_MOUNTS';
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,oBAAoB,GACpB,uBAAuB,GACvB,8BAA8B,GAC9B,8BAA8B,GAC9B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,eAAe,GACf,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"}
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,qBAAqB,GACrB,8BAA8B,GAC9B,8BAA8B,GAC9B,+BAA+B,GAC/B,uBAAuB,GACvB,wBAAwB,GACxB,kBAAkB,GAClB,eAAe,GACf,aAAa,GACb,0BAA0B,GAC1B,sBAAsB,GACtB,oBAAoB,GACpB,uBAAuB,GACvB,uBAAuB,GACvB,mBAAmB,GACnB,iBAAiB,GACjB,oBAAoB,CAAA;AAExB;;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"}
@@ -334,8 +334,8 @@ export function resolveServedFileOrThrow(filePath, args) {
334
334
  }
335
335
  let stableUrlPathname = args.routes.toUrlPathname(identityPath);
336
336
  if (!stableUrlPathname) {
337
- throw createAssetServerCompilationError(`File ${identityPath} is outside all configured fileMap entries.`, {
338
- code: 'FILE_OUTSIDE_FILE_MAP',
337
+ throw createAssetServerCompilationError(`File ${identityPath} is outside all configured mounts.`, {
338
+ code: 'FILE_OUTSIDE_MOUNTS',
339
339
  });
340
340
  }
341
341
  return {
@@ -1,8 +1,9 @@
1
1
  export declare function isInjectedPackageFilePath(filePath: string): boolean;
2
- export declare function getInjectedPackageRouteConfigs(): {
3
- fileMap: Record<string, string>;
2
+ export declare function getInjectedPackageMountConfigs(): {
3
+ mounts: Record<string, string>;
4
4
  rootDir: string;
5
5
  }[];
6
+ export declare function getInjectedPackageRoots(): readonly string[];
6
7
  export declare function getInjectedPackageNameForSpecifier(specifier: string): string | null;
7
8
  export declare function mayContainInjectedPackageSpecifier(sourceText: string): boolean;
8
9
  export declare function maskAuthoredInjectedPackageSpecifier(specifier: string): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"injected-packages.d.ts","sourceRoot":"","sources":["../../src/lib/injected-packages.ts"],"names":[],"mappings":"AAiBA,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAWnE;AAED,wBAAgB,8BAA8B,IAAI;IAChD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,OAAO,EAAE,MAAM,CAAA;CAChB,EAAE,CAYF;AAED,wBAAgB,kCAAkC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcnF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,wBAAgB,oCAAoC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASrF;AAED,wBAAgB,uCAAuC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYxF;AAWD,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD"}
1
+ {"version":3,"file":"injected-packages.d.ts","sourceRoot":"","sources":["../../src/lib/injected-packages.ts"],"names":[],"mappings":"AAiBA,wBAAgB,yBAAyB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAWnE;AAED,wBAAgB,8BAA8B,IAAI;IAChD,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9B,OAAO,EAAE,MAAM,CAAA;CAChB,EAAE,CAYF;AAED,wBAAgB,uBAAuB,IAAI,SAAS,MAAM,EAAE,CAI3D;AAED,wBAAgB,kCAAkC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAcnF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAE9E;AAED,wBAAgB,oCAAoC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CASrF;AAED,wBAAgB,uCAAuC,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAYxF;AAWD,wBAAgB,8BAA8B,IAAI,MAAM,CAEvD"}
@@ -16,18 +16,21 @@ export function isInjectedPackageFilePath(filePath) {
16
16
  }
17
17
  return false;
18
18
  }
19
- export function getInjectedPackageRouteConfigs() {
19
+ export function getInjectedPackageMountConfigs() {
20
20
  return injectedPackageNames.map((packageName) => {
21
21
  let { packageRoot } = getResolvedInjectedPackage(packageName);
22
- let { filePattern, routeRoot } = getInjectedPackageRoute(packageRoot, packageName);
22
+ let { fileRoot, routeRoot } = getInjectedPackageRoute(packageRoot, packageName);
23
23
  return {
24
- fileMap: {
25
- [getInjectedPackageRoutePattern(packageName)]: filePattern,
24
+ mounts: {
25
+ [getInjectedPackageMountPath(packageName)]: fileRoot,
26
26
  },
27
27
  rootDir: routeRoot,
28
28
  };
29
29
  });
30
30
  }
31
+ export function getInjectedPackageRoots() {
32
+ return injectedPackageNames.map((packageName) => getResolvedInjectedPackage(packageName).packageRoot);
33
+ }
31
34
  export function getInjectedPackageNameForSpecifier(specifier) {
32
35
  for (let injectedSpecifier of generatedInjectedPackageSpecifiers) {
33
36
  if (specifier === injectedSpecifier) {
@@ -88,13 +91,13 @@ function getResolvedInjectedPackage(packageName) {
88
91
  resolvedInjectedPackages.set(packageName, resolvedInjectedPackage);
89
92
  return resolvedInjectedPackage;
90
93
  }
91
- function getInjectedPackageRoutePattern(packageName) {
92
- return `${injectedPackagesBasePath}/${packageName}/*path`;
94
+ function getInjectedPackageMountPath(packageName) {
95
+ return `${injectedPackagesBasePath}/${packageName}`;
93
96
  }
94
97
  function getInjectedPackageRoute(packageRoot, packageName) {
95
98
  if (!packageRoot.endsWith(`/${packageName}`)) {
96
99
  return {
97
- filePattern: `${packageRoot.slice(getFilePathDirectory(packageRoot).length + 1)}/*path`,
100
+ fileRoot: packageRoot.slice(getFilePathDirectory(packageRoot).length + 1),
98
101
  routeRoot: getFilePathDirectory(packageRoot),
99
102
  };
100
103
  }
@@ -103,7 +106,7 @@ function getInjectedPackageRoute(packageRoot, packageName) {
103
106
  routeRoot = getFilePathDirectory(routeRoot);
104
107
  }
105
108
  return {
106
- filePattern: `${packageName}/*path`,
109
+ fileRoot: packageName,
107
110
  routeRoot,
108
111
  };
109
112
  }
@@ -0,0 +1,39 @@
1
+ import type { AccessPolicy, AssetAccessDetails } from './access.ts';
2
+ import type { CompiledRoutes } from './routes.ts';
3
+ /** How the asset server handles an inspected file. */
4
+ export type AssetKind = 'file' | 'script' | 'style' | 'unsupported';
5
+ /** Browser-reachability result for an inspected asset. */
6
+ export type AssetStatus = 'denied' | 'missing' | 'not-allowed' | 'reachable' | 'unmapped' | 'unsupported';
7
+ /** Diagnostic information about a configured asset URL or file path. */
8
+ export interface AssetDetails {
9
+ /** Access-control decision and the rules responsible for it. */
10
+ access?: AssetAccessDetails;
11
+ /** Absolute mapped file path. */
12
+ filePath?: string;
13
+ /** Configured filesystem mount root that matched the asset. */
14
+ fileRoot?: string;
15
+ /** Browser-reachability result. */
16
+ status: AssetStatus;
17
+ /** How the asset server handles the file. */
18
+ type?: AssetKind;
19
+ /** Stable public URL pathname for the asset. */
20
+ url?: string;
21
+ /** Public mount root that matched the asset. */
22
+ urlRoot?: string;
23
+ }
24
+ interface AssetInspectorOptions {
25
+ accessPolicy: AccessPolicy;
26
+ allowFiles: readonly string[];
27
+ fileExtensions: readonly string[];
28
+ rootDir: string;
29
+ routes: CompiledRoutes;
30
+ }
31
+ export interface AssetInspector {
32
+ /** Returns diagnostic information for a public URL or file path. */
33
+ getAssetDetails(input: string): Promise<AssetDetails>;
34
+ /** Returns every file currently reachable through the configured asset server. */
35
+ getAssets(): Promise<AssetDetails[]>;
36
+ }
37
+ export declare function createAssetInspector(options: AssetInspectorOptions): AssetInspector;
38
+ export {};
39
+ //# sourceMappingURL=inspection.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inspection.d.ts","sourceRoot":"","sources":["../../src/lib/inspection.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAInE,OAAO,KAAK,EAAmB,cAAc,EAAE,MAAM,aAAa,CAAA;AAOlE,sDAAsD;AACtD,MAAM,MAAM,SAAS,GAAG,MAAM,GAAG,QAAQ,GAAG,OAAO,GAAG,aAAa,CAAA;AAEnE,0DAA0D;AAC1D,MAAM,MAAM,WAAW,GACnB,QAAQ,GACR,SAAS,GACT,aAAa,GACb,WAAW,GACX,UAAU,GACV,aAAa,CAAA;AAEjB,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,gEAAgE;IAChE,MAAM,CAAC,EAAE,kBAAkB,CAAA;IAC3B,iCAAiC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,+DAA+D;IAC/D,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,mCAAmC;IACnC,MAAM,EAAE,WAAW,CAAA;IACnB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,SAAS,CAAA;IAChB,gDAAgD;IAChD,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,gDAAgD;IAChD,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAED,UAAU,qBAAqB;IAC7B,YAAY,EAAE,YAAY,CAAA;IAC1B,UAAU,EAAE,SAAS,MAAM,EAAE,CAAA;IAC7B,cAAc,EAAE,SAAS,MAAM,EAAE,CAAA;IACjC,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,oEAAoE;IACpE,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACrD,kFAAkF;IAClF,SAAS,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC,CAAA;CACrC;AAED,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,qBAAqB,GAAG,cAAc,CA4BnF"}
@@ -0,0 +1,160 @@
1
+ import * as fs from 'node:fs';
2
+ import * as fsPromises from 'node:fs/promises';
3
+ import * as path from 'node:path';
4
+ import { fileURLToPath } from 'node:url';
5
+ import { parseFingerprintSuffix } from './fingerprint.js';
6
+ import { getInjectedPackageRoots } from './injected-packages.js';
7
+ import { isAbsoluteFilePath, normalizeFilePath, resolveFilePath } from './paths.js';
8
+ import { supportedScriptExtensions } from './scripts/resolve.js';
9
+ import { isStyleFilePath } from './styles/compiler.js';
10
+ const scriptExtensions = new Set(supportedScriptExtensions);
11
+ const globSyntaxPattern = /[*?[\]{}()!+@]/;
12
+ export function createAssetInspector(options) {
13
+ let fileExtensions = new Set(options.fileExtensions.map((extension) => extension.toLowerCase()));
14
+ return {
15
+ async getAssetDetails(input) {
16
+ let routeMatch = await resolveInput(input, options);
17
+ if (routeMatch === null)
18
+ return { status: 'unmapped' };
19
+ return inspectRouteMatch(routeMatch, options, fileExtensions);
20
+ },
21
+ async getAssets() {
22
+ let filePaths = await discoverFilePaths(options);
23
+ let assets = [];
24
+ for (let filePath of filePaths) {
25
+ let routeMatch = options.routes.matchFilePath(filePath);
26
+ if (routeMatch === null)
27
+ continue;
28
+ let details = await inspectRouteMatch(routeMatch, options, fileExtensions);
29
+ if (details.status === 'reachable')
30
+ assets.push(details);
31
+ }
32
+ assets.sort((left, right) => {
33
+ let urlOrder = (left.url ?? '').localeCompare(right.url ?? '');
34
+ return urlOrder === 0 ? (left.filePath ?? '').localeCompare(right.filePath ?? '') : urlOrder;
35
+ });
36
+ return assets;
37
+ },
38
+ };
39
+ }
40
+ async function resolveInput(input, options) {
41
+ if (input.startsWith('file://')) {
42
+ return options.routes.matchFilePath(fileURLToPath(input));
43
+ }
44
+ if (/^[A-Za-z][A-Za-z\d+.-]*:\/\//.test(input)) {
45
+ let pathname = parseFingerprintSuffix(new URL(input).pathname).pathname;
46
+ return options.routes.matchUrlPathname(pathname);
47
+ }
48
+ let filePath = resolveFilePath(options.rootDir, input);
49
+ if (!input.startsWith('/') || isAbsoluteFilePath(input)) {
50
+ if (await pathExists(filePath))
51
+ return options.routes.matchFilePath(filePath);
52
+ if (!input.startsWith('/'))
53
+ return options.routes.matchFilePath(filePath);
54
+ }
55
+ let pathname = parseFingerprintSuffix(new URL(input, 'http://remix.run').pathname).pathname;
56
+ return options.routes.matchUrlPathname(pathname);
57
+ }
58
+ async function inspectRouteMatch(routeMatch, options, fileExtensions) {
59
+ let exists = await pathExists(routeMatch.filePath);
60
+ let identityPath = exists ? fs.realpathSync(routeMatch.filePath) : routeMatch.filePath;
61
+ let normalizedIdentityPath = normalizeFilePath(identityPath);
62
+ let access = options.accessPolicy.inspect(normalizedIdentityPath);
63
+ let type = getAssetKind(routeMatch.filePath, fileExtensions);
64
+ let details = {
65
+ access,
66
+ filePath: routeMatch.filePath,
67
+ fileRoot: routeMatch.fileRoot,
68
+ type,
69
+ url: routeMatch.urlPathname,
70
+ urlRoot: routeMatch.urlRoot,
71
+ };
72
+ if (!exists)
73
+ return { ...details, status: 'missing' };
74
+ if (!access.allowed) {
75
+ return { ...details, status: access.deniedBy === undefined ? 'not-allowed' : 'denied' };
76
+ }
77
+ if (type === 'unsupported')
78
+ return { ...details, status: 'unsupported' };
79
+ return { ...details, status: 'reachable' };
80
+ }
81
+ function getAssetKind(filePath, fileExtensions) {
82
+ let extension = path.extname(filePath).toLowerCase();
83
+ if (scriptExtensions.has(extension))
84
+ return 'script';
85
+ if (isStyleFilePath(filePath))
86
+ return 'style';
87
+ if (fileExtensions.has(extension))
88
+ return 'file';
89
+ return 'unsupported';
90
+ }
91
+ async function discoverFilePaths(options) {
92
+ let roots = new Set();
93
+ for (let pattern of options.allowFiles) {
94
+ roots.add(resolveDiscoveryRoot(options.rootDir, pattern));
95
+ }
96
+ for (let packageRoot of options.accessPolicy.getAllowedPackageRoots()) {
97
+ roots.add(packageRoot);
98
+ }
99
+ for (let packageRoot of getInjectedPackageRoots()) {
100
+ roots.add(packageRoot);
101
+ }
102
+ let filePaths = new Set();
103
+ for (let root of roots) {
104
+ await collectFiles(root, filePaths);
105
+ }
106
+ return [...filePaths];
107
+ }
108
+ function resolveDiscoveryRoot(rootDir, pattern) {
109
+ let dynamicIndex = pattern.search(globSyntaxPattern);
110
+ if (dynamicIndex === -1)
111
+ return resolveFilePath(rootDir, pattern);
112
+ let rawStaticPrefix = pattern.slice(0, dynamicIndex);
113
+ let staticPrefix = rawStaticPrefix.replace(/[/\\]+$/, '');
114
+ if (staticPrefix.length === 0)
115
+ return rootDir;
116
+ return resolveFilePath(rootDir, /[/\\]$/.test(rawStaticPrefix) ? staticPrefix : path.dirname(staticPrefix));
117
+ }
118
+ async function collectFiles(root, filePaths) {
119
+ let stat;
120
+ try {
121
+ stat = await fsPromises.stat(root);
122
+ }
123
+ catch (error) {
124
+ if (isPathNotFoundError(error))
125
+ return;
126
+ throw error;
127
+ }
128
+ if (stat.isFile()) {
129
+ filePaths.add(normalizeFilePath(root));
130
+ return;
131
+ }
132
+ if (!stat.isDirectory())
133
+ return;
134
+ let entries = await fsPromises.readdir(root, { withFileTypes: true });
135
+ for (let entry of entries) {
136
+ let entryPath = path.join(root, entry.name);
137
+ if (entry.isDirectory()) {
138
+ await collectFiles(entryPath, filePaths);
139
+ }
140
+ else if (entry.isFile()) {
141
+ filePaths.add(normalizeFilePath(entryPath));
142
+ }
143
+ }
144
+ }
145
+ async function pathExists(filePath) {
146
+ try {
147
+ await fsPromises.access(filePath);
148
+ return true;
149
+ }
150
+ catch (error) {
151
+ if (isPathNotFoundError(error))
152
+ return false;
153
+ throw error;
154
+ }
155
+ }
156
+ function isPathNotFoundError(error) {
157
+ return (error instanceof Error &&
158
+ 'code' in error &&
159
+ (error.code === 'ENOENT' || error.code === 'ENOTDIR'));
160
+ }
@@ -1,11 +1,19 @@
1
- interface RouteConfig {
2
- fileMap: Readonly<Record<string, string>>;
1
+ interface MountConfig {
2
+ mounts: Readonly<Record<string, string>>;
3
3
  rootDir: string;
4
4
  }
5
5
  export interface CompiledRoutes {
6
6
  resolveUrlPathname(pathname: string): string | null;
7
+ matchUrlPathname(pathname: string): AssetRouteMatch | null;
7
8
  toUrlPathname(filePath: string): string | null;
9
+ matchFilePath(filePath: string): AssetRouteMatch | null;
8
10
  }
9
- export declare function compileRoutes(basePath: string, routeConfigs: readonly RouteConfig[]): CompiledRoutes;
11
+ export interface AssetRouteMatch {
12
+ filePath: string;
13
+ fileRoot: string;
14
+ urlPathname: string;
15
+ urlRoot: string;
16
+ }
17
+ export declare function compileRoutes(basePath: string, mountConfigs: readonly MountConfig[]): CompiledRoutes;
10
18
  export {};
11
19
  //# sourceMappingURL=routes.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/lib/routes.ts"],"names":[],"mappings":"AAqBA,UAAU,WAAW;IACnB,OAAO,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACzC,OAAO,EAAE,MAAM,CAAA;CAChB;AAUD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;CAC/C;AAYD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,cAAc,CAgDhB"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/lib/routes.ts"],"names":[],"mappings":"AASA,UAAU,WAAW;IACnB,MAAM,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;CAChB;AASD,MAAM,WAAW,cAAc;IAC7B,kBAAkB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IACnD,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAA;IAC1D,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAA;IAC9C,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAAA;CACxD;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,MAAM,CAAA;IAChB,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,OAAO,EAAE,MAAM,CAAA;CAChB;AAED,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,YAAY,EAAE,SAAS,WAAW,EAAE,GACnC,cAAc,CA8DhB"}