@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.
- package/README.md +206 -8
- 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 +7 -1
- package/dist/lib/asset-server.d.ts +29 -6
- package/dist/lib/asset-server.d.ts.map +1 -1
- package/dist/lib/asset-server.js +176 -17
- 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/routes.d.ts.map +1 -1
- package/dist/lib/routes.js +28 -20
- 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 +22 -2
- package/dist/lib/scripts/transform.js +1 -1
- 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 +6 -4
- package/src/assets.ts +1 -0
- package/src/lib/access.ts +8 -1
- package/src/lib/asset-server.ts +273 -28
- 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/routes.ts +36 -33
- package/src/lib/scripts/compiler.ts +43 -5
- package/src/lib/scripts/resolve.ts +35 -3
- package/src/lib/scripts/transform.ts +1 -1
- 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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,WAAW,CAAA;AAS3D,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GACf;IACE,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,CAAA;AAEL,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,MAAM,EAAE,OAAO,CAAA;IACf,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;IAClC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,
|
|
1
|
+
{"version":3,"file":"compiler.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/compiler.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAA;AAEvD,OAAO,KAAK,EAAE,YAAY,EAAgB,MAAM,WAAW,CAAA;AAS3D,KAAK,kBAAkB,GAAG;IACxB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,cAAc,GACf;IACE,KAAK,EAAE,kBAAkB,CAAA;IACzB,IAAI,EAAE,OAAO,CAAA;CACd,GACD;IACE,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,cAAc,CAAA;CACrB,CAAA;AAEL,KAAK,eAAe,GAAG;IACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,oBAAoB,EAAE,MAAM,GAAG,IAAI,CAAA;CACpC,CAAA;AAED,KAAK,oBAAoB,GAAG;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,iBAAiB,EAAE,OAAO,CAAA;IAC1B,gBAAgB,CAAC,CACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KACpC,GACA,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,MAAM,EAAE,OAAO,CAAA;IACf,wBAAwB,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,GAAG,EAAE,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,MAAM,EAAE,CAAA;KAAE,KAAK,IAAI,CAAA;IAC/E,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,oBAAoB,EAAE,UAAU,GAAG,KAAK,CAAA;IACxC,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;IAClC,OAAO,CAAC,EAAE,mBAAmB,CAAA;IAC7B,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;CAChC,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,OAAO,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IAC1C,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;IAC3E,QAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAA;IAC7E,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;CACrF,CAAA;AAKD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,oBAAoB,GAAG,aAAa,CAmOhF;AAkED,wBAAgB,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEzD;AAED,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,kBAAkB,EAC1B,OAAO,EAAE;IACP,YAAY,EAAE,MAAM,CAAA;IACpB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,kBAAkB,EAAE,OAAO,CAAA;IAC3B,MAAM,EAAE,MAAM,CAAA;CACf,GACA,QAAQ,CA6BV"}
|
|
@@ -23,6 +23,7 @@ export function createStyleCompiler(options) {
|
|
|
23
23
|
let emitInFlightByCacheKey = new Map();
|
|
24
24
|
let resolveArgs = {
|
|
25
25
|
isAllowed: resolvedOptions.isAllowed,
|
|
26
|
+
isServedFilePath: resolvedOptions.isServedFilePath,
|
|
26
27
|
isWatchIgnored,
|
|
27
28
|
routes: resolvedOptions.routes,
|
|
28
29
|
};
|
|
@@ -164,6 +165,7 @@ export function createStyleCompiler(options) {
|
|
|
164
165
|
let startedVersion = record.invalidationVersion;
|
|
165
166
|
let resolvedStyle = await getOrCreateResolvedStyle(record);
|
|
166
167
|
let emitResolvedStyleResult = await emitResolvedStyle(resolvedStyle, {
|
|
168
|
+
getServedFileUrl: resolvedOptions.getServedFileUrl,
|
|
167
169
|
getServedUrl,
|
|
168
170
|
sourceMaps: resolvedOptions.sourceMaps,
|
|
169
171
|
});
|
|
@@ -18,6 +18,9 @@ type EmitResult = {
|
|
|
18
18
|
ok: false;
|
|
19
19
|
};
|
|
20
20
|
export declare function emitResolvedStyle(resolvedStyle: ResolvedStyle, options: {
|
|
21
|
+
getServedFileUrl?(identityPath: string, options: {
|
|
22
|
+
transform: readonly string[] | null;
|
|
23
|
+
}): Promise<string>;
|
|
21
24
|
getServedUrl(identityPath: string): Promise<string>;
|
|
22
25
|
sourceMaps?: 'external' | 'inline';
|
|
23
26
|
}): Promise<EmitResult>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/emit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,UAAU,GACX;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,YAAY,CAAA;CACpB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CAAA;AAEL,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE;IACP,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAkCrB"}
|
|
1
|
+
{"version":3,"file":"emit.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/emit.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,cAAc,CAAA;AAEjD,MAAM,MAAM,YAAY,GAAG;IACzB,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;CACb,CAAA;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,IAAI,EAAE,YAAY,CAAA;IAClB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,SAAS,EAAE,YAAY,GAAG,IAAI,CAAA;CAC/B,CAAA;AAED,KAAK,UAAU,GACX;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,YAAY,CAAA;CACpB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CAAA;AAEL,wBAAsB,iBAAiB,CACrC,aAAa,EAAE,aAAa,EAC5B,OAAO,EAAE;IACP,gBAAgB,CAAC,CACf,YAAY,EAAE,MAAM,EACpB,OAAO,EAAE;QACP,SAAS,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;KACpC,GACA,OAAO,CAAC,MAAM,CAAC,CAAA;IAClB,YAAY,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAA;IACnD,UAAU,CAAC,EAAE,UAAU,GAAG,QAAQ,CAAA;CACnC,GACA,OAAO,CAAC,UAAU,CAAC,CAkCrB"}
|
package/dist/lib/styles/emit.js
CHANGED
|
@@ -46,7 +46,11 @@ async function rewriteDependencies(resolvedStyle, options) {
|
|
|
46
46
|
for (let dependency of resolvedStyle.dependencies) {
|
|
47
47
|
let replacement = dependency.kind === 'external'
|
|
48
48
|
? dependency.replacement
|
|
49
|
-
:
|
|
49
|
+
: dependency.kind === 'style'
|
|
50
|
+
? `${await options.getServedUrl(dependency.depPath)}${dependency.suffix}`
|
|
51
|
+
: appendUrlSuffix(await getServedFileUrl(options, resolvedStyle.identityPath, dependency.depPath, {
|
|
52
|
+
transform: dependency.requestTransform,
|
|
53
|
+
}), dependency.suffix);
|
|
50
54
|
let start = resolvedStyle.rawCode.indexOf(dependency.placeholder);
|
|
51
55
|
if (start < 0) {
|
|
52
56
|
throw createAssetServerCompilationError(`Missing dependency placeholder "${dependency.placeholder}" while emitting style ${resolvedStyle.identityPath}.`, {
|
|
@@ -62,6 +66,37 @@ async function rewriteDependencies(resolvedStyle, options) {
|
|
|
62
66
|
: null,
|
|
63
67
|
};
|
|
64
68
|
}
|
|
69
|
+
function appendUrlSuffix(url, suffix) {
|
|
70
|
+
if (!suffix.startsWith('?') || !url.includes('?')) {
|
|
71
|
+
return `${url}${suffix}`;
|
|
72
|
+
}
|
|
73
|
+
return `${url}&${suffix.slice(1)}`;
|
|
74
|
+
}
|
|
75
|
+
async function getServedFileUrl(options, importerPath, identityPath, request) {
|
|
76
|
+
if (!options.getServedFileUrl) {
|
|
77
|
+
throw createAssetServerCompilationError(`Missing file URL resolver for ${identityPath}.`, {
|
|
78
|
+
code: 'EMIT_FAILED',
|
|
79
|
+
});
|
|
80
|
+
}
|
|
81
|
+
try {
|
|
82
|
+
return await options.getServedFileUrl(identityPath, request);
|
|
83
|
+
}
|
|
84
|
+
catch (error) {
|
|
85
|
+
if (request.transform !== null &&
|
|
86
|
+
isAssetServerCompilationError(error) &&
|
|
87
|
+
error.code === 'FILE_TRANSFORM_QUERY_INVALID') {
|
|
88
|
+
console.warn(`Invalid file transform request "${request.transform.join(',')}" in CSS asset ${importerPath} for ${identityPath}: ${error.message}`);
|
|
89
|
+
let href = await options.getServedFileUrl(identityPath, { transform: null });
|
|
90
|
+
let searchParams = new URLSearchParams();
|
|
91
|
+
for (let transform of request.transform) {
|
|
92
|
+
searchParams.append('transform', transform);
|
|
93
|
+
}
|
|
94
|
+
let search = searchParams.toString();
|
|
95
|
+
return search.length > 0 ? `${href}?${search}` : href;
|
|
96
|
+
}
|
|
97
|
+
throw error;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
65
100
|
async function createEmittedAsset(content) {
|
|
66
101
|
return {
|
|
67
102
|
content,
|
|
@@ -10,9 +10,15 @@ type ResolvedDependency = {
|
|
|
10
10
|
replacement: string;
|
|
11
11
|
} | {
|
|
12
12
|
depPath: string;
|
|
13
|
-
kind: '
|
|
13
|
+
kind: 'style';
|
|
14
14
|
placeholder: string;
|
|
15
15
|
suffix: string;
|
|
16
|
+
} | {
|
|
17
|
+
depPath: string;
|
|
18
|
+
kind: 'file';
|
|
19
|
+
placeholder: string;
|
|
20
|
+
requestTransform: readonly string[] | null;
|
|
21
|
+
suffix: string;
|
|
16
22
|
};
|
|
17
23
|
export type ResolvedStyle = {
|
|
18
24
|
dependencies: ResolvedDependency[];
|
|
@@ -27,6 +33,7 @@ export type ResolvedStyle = {
|
|
|
27
33
|
};
|
|
28
34
|
export type ResolveArgs = {
|
|
29
35
|
isAllowed(absolutePath: string): boolean;
|
|
36
|
+
isServedFilePath(filePath: string): boolean;
|
|
30
37
|
isWatchIgnored(filePath: string): boolean;
|
|
31
38
|
routes: CompiledRoutes;
|
|
32
39
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/resolve.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"resolve.d.ts","sourceRoot":"","sources":["../../../src/lib/styles/resolve.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,yBAAyB,CAAA;AAC1E,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAA;AACtE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAClD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAC7C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAA;AAEtD,KAAK,WAAW,GAAG,YAAY,CAAC,gBAAgB,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;AAE9E,KAAK,kBAAkB,GACnB;IACE,IAAI,EAAE,UAAU,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IACnB,WAAW,EAAE,MAAM,CAAA;CACpB,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,OAAO,CAAA;IACb,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;CACf,GACD;IACE,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,IAAI,CAAA;IAC1C,MAAM,EAAE,MAAM,CAAA;CACf,CAAA;AAEL,MAAM,MAAM,aAAa,GAAG;IAC1B,YAAY,EAAE,kBAAkB,EAAE,CAAA;IAClC,IAAI,EAAE,MAAM,EAAE,CAAA;IACd,WAAW,EAAE,MAAM,GAAG,IAAI,CAAA;IAC1B,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,CAAA;IACf,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;IACxB,iBAAiB,EAAE,MAAM,CAAA;IACzB,YAAY,EAAE,MAAM,EAAE,CAAA;CACvB,CAAA;AAED,MAAM,MAAM,WAAW,GAAG;IACxB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAA;IACxC,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IAC3C,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAA;IACzC,MAAM,EAAE,cAAc,CAAA;CACvB,CAAA;AAED,KAAK,aAAa,GAAG;IACnB,QAAQ,EAAE,cAAc,CAAA;CACzB,GAAG,CACA;IACE,EAAE,EAAE,IAAI,CAAA;IACR,KAAK,EAAE,aAAa,CAAA;CACrB,GACD;IACE,KAAK,EAAE,2BAA2B,CAAA;IAClC,EAAE,EAAE,KAAK,CAAA;CACV,CACJ,CAAA;AAQD,wBAAsB,YAAY,CAChC,MAAM,EAAE,WAAW,EACnB,WAAW,EAAE,gBAAgB,EAC7B,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,aAAa,CAAC,CA+DxB;AAED,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,WAAW,GAChB;IACD,YAAY,EAAE,MAAM,CAAA;IACpB,iBAAiB,EAAE,MAAM,CAAA;CAC1B,CA+BA"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'node:fs';
|
|
2
2
|
import * as path from 'node:path';
|
|
3
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
3
4
|
import { createAssetServerCompilationError, isAssetServerCompilationError, } from "../compilation-error.js";
|
|
4
5
|
import { normalizeFilePath } from "../paths.js";
|
|
5
6
|
export async function resolveStyle(record, transformed, args) {
|
|
@@ -9,19 +10,21 @@ export async function resolveStyle(record, transformed, args) {
|
|
|
9
10
|
for (let unresolved of transformed.unresolvedDependencies) {
|
|
10
11
|
let trackedFile = unresolved.type === 'import'
|
|
11
12
|
? getTrackedImportFilePath(unresolved.url, transformed.resolvedPath)
|
|
12
|
-
:
|
|
13
|
+
: getTrackedUrlFilePath(unresolved.url, transformed.resolvedPath);
|
|
13
14
|
if (trackedFile && !args.isWatchIgnored(trackedFile)) {
|
|
14
15
|
trackedFiles.add(trackedFile);
|
|
15
16
|
}
|
|
16
17
|
try {
|
|
17
18
|
let resolved = unresolved.type === 'import'
|
|
18
19
|
? resolveImportDependency(unresolved.url, transformed.resolvedPath, unresolved.placeholder, args)
|
|
19
|
-
: resolveUrlDependency(unresolved.url, unresolved.placeholder);
|
|
20
|
+
: resolveUrlDependency(unresolved.url, transformed.resolvedPath, unresolved.placeholder, args);
|
|
20
21
|
dependencies.push(resolved);
|
|
21
|
-
if (resolved.kind === '
|
|
22
|
+
if (resolved.kind === 'style' || resolved.kind === 'file') {
|
|
22
23
|
if (!args.isWatchIgnored(resolved.depPath)) {
|
|
23
24
|
trackedFiles.add(resolved.depPath);
|
|
24
25
|
}
|
|
26
|
+
}
|
|
27
|
+
if (resolved.kind === 'style') {
|
|
25
28
|
deps.add(resolved.depPath);
|
|
26
29
|
}
|
|
27
30
|
}
|
|
@@ -80,22 +83,16 @@ function resolveImportDependency(url, importerPath, placeholder, args) {
|
|
|
80
83
|
replacement: url,
|
|
81
84
|
};
|
|
82
85
|
}
|
|
83
|
-
let
|
|
84
|
-
if (
|
|
85
|
-
return {
|
|
86
|
-
kind: 'external',
|
|
87
|
-
placeholder,
|
|
88
|
-
replacement: url,
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
if (pathname.startsWith('/')) {
|
|
86
|
+
let parsedUrl = parseRelativeUrl(url, importerPath);
|
|
87
|
+
if (parsedUrl === null) {
|
|
92
88
|
return {
|
|
93
89
|
kind: 'external',
|
|
94
90
|
placeholder,
|
|
95
91
|
replacement: url,
|
|
96
92
|
};
|
|
97
93
|
}
|
|
98
|
-
let
|
|
94
|
+
let { hash, resolvedPath, search } = parsedUrl;
|
|
95
|
+
let resolvedFilePath = resolvedPath;
|
|
99
96
|
let identityPath = resolveExistingFilePath(resolvedFilePath);
|
|
100
97
|
if (!identityPath || !isStyleFilePath(identityPath)) {
|
|
101
98
|
throw createAssetServerCompilationError(`Failed to resolve import "${url}" in ${importerPath}.`, {
|
|
@@ -116,16 +113,60 @@ function resolveImportDependency(url, importerPath, placeholder, args) {
|
|
|
116
113
|
}
|
|
117
114
|
return {
|
|
118
115
|
depPath: identityPath,
|
|
119
|
-
kind: '
|
|
116
|
+
kind: 'style',
|
|
120
117
|
placeholder,
|
|
121
|
-
suffix
|
|
118
|
+
suffix: `${search}${hash}`,
|
|
122
119
|
};
|
|
123
120
|
}
|
|
124
|
-
function resolveUrlDependency(url, placeholder) {
|
|
121
|
+
function resolveUrlDependency(url, importerPath, placeholder, args) {
|
|
122
|
+
if (isExternalUrl(url)) {
|
|
123
|
+
return {
|
|
124
|
+
kind: 'external',
|
|
125
|
+
placeholder,
|
|
126
|
+
replacement: url,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
let parsedUrl = parseRelativeUrl(url, importerPath);
|
|
130
|
+
if (parsedUrl === null) {
|
|
131
|
+
return {
|
|
132
|
+
kind: 'external',
|
|
133
|
+
placeholder,
|
|
134
|
+
replacement: url,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
let { hash, resolvedPath, search } = parsedUrl;
|
|
138
|
+
let resolvedFilePath = resolvedPath;
|
|
139
|
+
let identityPath = resolveExistingFilePath(resolvedFilePath);
|
|
140
|
+
if (!identityPath) {
|
|
141
|
+
throw createAssetServerCompilationError(`Failed to resolve url("${url}") in ${importerPath}.`, {
|
|
142
|
+
code: 'URL_RESOLUTION_FAILED',
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
if (!args.isServedFilePath(identityPath)) {
|
|
146
|
+
throw createAssetServerCompilationError(`URL "${url}" in ${importerPath}, resolved to "${identityPath}", is not a supported file asset. ` +
|
|
147
|
+
`Add the file extension to files.extensions to serve this asset.`, {
|
|
148
|
+
code: 'URL_NOT_SUPPORTED',
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
if (!args.isAllowed(identityPath)) {
|
|
152
|
+
throw createAssetServerCompilationError(`URL "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server allow/deny configuration. ` +
|
|
153
|
+
`Add a matching allow rule for this file path or remove a conflicting deny rule for this file path.`, {
|
|
154
|
+
code: 'URL_NOT_ALLOWED',
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
if (!args.routes.toUrlPathname(identityPath)) {
|
|
158
|
+
throw createAssetServerCompilationError(`URL "${url}" in ${importerPath}, resolved to "${identityPath}", is outside all configured fileMap entries. ` +
|
|
159
|
+
`Add a matching fileMap entry for this file path.`, {
|
|
160
|
+
code: 'URL_OUTSIDE_FILE_MAP',
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
let parsedRequest = parseResolvedFileRequest({ hash, search });
|
|
125
164
|
return {
|
|
126
|
-
|
|
165
|
+
depPath: identityPath,
|
|
166
|
+
kind: 'file',
|
|
127
167
|
placeholder,
|
|
128
|
-
|
|
168
|
+
requestTransform: parsedRequest.transform,
|
|
169
|
+
suffix: parsedRequest.suffix,
|
|
129
170
|
};
|
|
130
171
|
}
|
|
131
172
|
function resolveExistingFilePath(filePath) {
|
|
@@ -138,27 +179,39 @@ function resolveExistingFilePath(filePath) {
|
|
|
138
179
|
throw error;
|
|
139
180
|
}
|
|
140
181
|
}
|
|
141
|
-
function
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
182
|
+
function parseRelativeUrl(url, importerPath) {
|
|
183
|
+
if (url.length === 0 || url.startsWith('?') || url.startsWith('/') || isExternalUrl(url)) {
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
let parsed = new URL(url, pathToFileURL(importerPath));
|
|
187
|
+
return {
|
|
188
|
+
hash: parsed.hash,
|
|
189
|
+
resolvedPath: normalizeFilePath(fileURLToPath(parsed)),
|
|
190
|
+
search: parsed.search,
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
function parseResolvedFileRequest(url) {
|
|
194
|
+
let { hash, search } = url;
|
|
195
|
+
if (search.length === 0) {
|
|
146
196
|
return {
|
|
147
|
-
|
|
148
|
-
|
|
197
|
+
suffix: hash,
|
|
198
|
+
transform: null,
|
|
149
199
|
};
|
|
150
200
|
}
|
|
201
|
+
let searchParams = new URLSearchParams(search.slice(1));
|
|
202
|
+
let transform = searchParams.getAll('transform');
|
|
203
|
+
searchParams.delete('transform');
|
|
204
|
+
let remainingSearch = searchParams.toString();
|
|
151
205
|
return {
|
|
152
|
-
|
|
153
|
-
|
|
206
|
+
suffix: `${remainingSearch.length > 0 ? `?${remainingSearch}` : ''}${hash}`,
|
|
207
|
+
transform: transform.length > 0 ? transform : null,
|
|
154
208
|
};
|
|
155
209
|
}
|
|
156
210
|
function getTrackedImportFilePath(specifier, importerPath) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
return null;
|
|
211
|
+
return parseRelativeUrl(specifier, importerPath)?.resolvedPath ?? null;
|
|
212
|
+
}
|
|
213
|
+
function getTrackedUrlFilePath(url, importerPath) {
|
|
214
|
+
return parseRelativeUrl(url, importerPath)?.resolvedPath ?? null;
|
|
162
215
|
}
|
|
163
216
|
function isStyleFilePath(filePath) {
|
|
164
217
|
return path.extname(filePath).toLowerCase() === '.css';
|
package/dist/lib/watch.d.ts
CHANGED
|
@@ -15,6 +15,8 @@ export type AssetServerWatcher = {
|
|
|
15
15
|
updateWatchedDirectories(delta: {
|
|
16
16
|
add: readonly string[];
|
|
17
17
|
remove: readonly string[];
|
|
18
|
+
}, options?: {
|
|
19
|
+
includeAncestors?: boolean;
|
|
18
20
|
}): void;
|
|
19
21
|
};
|
|
20
22
|
export declare function createAssetServerWatcher(options: AssetServerWatcherOptions): AssetServerWatcher;
|
package/dist/lib/watch.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/lib/watch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAI/B,KAAK,yBAAyB,GAAG;IAC/B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1E,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;AACxD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;AAE/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAAA;IACtC,wBAAwB,
|
|
1
|
+
{"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/lib/watch.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,UAAU,CAAA;AAI/B,KAAK,yBAAyB,GAAG;IAC/B,MAAM,CAAC,EAAE,SAAS,MAAM,EAAE,CAAA;IAC1B,wBAAwB,CAAC,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAA;IAC7D,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAC1E,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,KAAK,qBAAqB,GAAG,KAAK,GAAG,QAAQ,GAAG,QAAQ,CAAA;AACxD,MAAM,MAAM,eAAe,GAAG,UAAU,CAAC,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAA;AAE/D,MAAM,MAAM,kBAAkB,GAAG;IAC/B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;IACtB,iBAAiB,IAAI,SAAS,MAAM,EAAE,CAAA;IACtC,wBAAwB,CACtB,KAAK,EAAE;QAAE,GAAG,EAAE,SAAS,MAAM,EAAE,CAAC;QAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAAA;KAAE,EAC5D,OAAO,CAAC,EAAE;QAAE,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAAE,GACvC,IAAI,CAAA;CACR,CAAA;AAED,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,yBAAyB,GAAG,kBAAkB,CAiE/F"}
|
package/dist/lib/watch.js
CHANGED
|
@@ -7,7 +7,8 @@ export function createAssetServerWatcher(options) {
|
|
|
7
7
|
...resolveChokidarWatchOptions(options),
|
|
8
8
|
});
|
|
9
9
|
options.onChokidarWatcherCreated?.(watcher);
|
|
10
|
-
let
|
|
10
|
+
let watchedResolutionDirectories = new Set();
|
|
11
|
+
let watchedFileDirectories = new Set();
|
|
11
12
|
let watchedTargets = new Set();
|
|
12
13
|
for (let event of ['add', 'change', 'unlink']) {
|
|
13
14
|
watcher.on(event, (filePath) => {
|
|
@@ -24,15 +25,29 @@ export function createAssetServerWatcher(options) {
|
|
|
24
25
|
getWatchedTargets() {
|
|
25
26
|
return [...watchedTargets];
|
|
26
27
|
},
|
|
27
|
-
updateWatchedDirectories(delta) {
|
|
28
|
-
let
|
|
28
|
+
updateWatchedDirectories(delta, updateOptions = {}) {
|
|
29
|
+
let includeAncestors = updateOptions.includeAncestors ?? true;
|
|
30
|
+
let previousDirectories = includeAncestors
|
|
31
|
+
? watchedResolutionDirectories
|
|
32
|
+
: watchedFileDirectories;
|
|
33
|
+
let nextWatchedDirectories = new Set(previousDirectories);
|
|
29
34
|
for (let directory of delta.add) {
|
|
30
35
|
nextWatchedDirectories.add(directory);
|
|
31
36
|
}
|
|
32
37
|
for (let directory of delta.remove) {
|
|
33
38
|
nextWatchedDirectories.delete(directory);
|
|
34
39
|
}
|
|
35
|
-
|
|
40
|
+
if (includeAncestors) {
|
|
41
|
+
watchedResolutionDirectories = nextWatchedDirectories;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
watchedFileDirectories = nextWatchedDirectories;
|
|
45
|
+
}
|
|
46
|
+
let nextTargets = getWatchTargets({
|
|
47
|
+
rootDir: options.rootDir,
|
|
48
|
+
fileDirectories: [...watchedFileDirectories],
|
|
49
|
+
resolutionDirectories: [...watchedResolutionDirectories],
|
|
50
|
+
});
|
|
36
51
|
let targetsToAdd = [...nextTargets].filter((target) => !watchedTargets.has(target));
|
|
37
52
|
let targetsToRemove = [...watchedTargets].filter((target) => !nextTargets.has(target));
|
|
38
53
|
if (targetsToRemove.length > 0) {
|
|
@@ -41,7 +56,6 @@ export function createAssetServerWatcher(options) {
|
|
|
41
56
|
if (targetsToAdd.length > 0) {
|
|
42
57
|
watcher.add(targetsToAdd);
|
|
43
58
|
}
|
|
44
|
-
watchedDirectories = nextWatchedDirectories;
|
|
45
59
|
watchedTargets = nextTargets;
|
|
46
60
|
},
|
|
47
61
|
};
|
|
@@ -58,11 +72,14 @@ function resolveChokidarWatchOptions(options) {
|
|
|
58
72
|
usePolling: options.poll ?? false,
|
|
59
73
|
};
|
|
60
74
|
}
|
|
61
|
-
function
|
|
62
|
-
let normalizedRootDir = normalizeFilePath(rootDir);
|
|
75
|
+
function getWatchTargets(options) {
|
|
76
|
+
let normalizedRootDir = normalizeFilePath(options.rootDir);
|
|
63
77
|
let targets = new Set();
|
|
64
78
|
let configAncestors = new Set();
|
|
65
|
-
for (let directory of
|
|
79
|
+
for (let directory of options.fileDirectories) {
|
|
80
|
+
targets.add(normalizeFilePath(directory).replace(/\/+$/, ''));
|
|
81
|
+
}
|
|
82
|
+
for (let directory of options.resolutionDirectories) {
|
|
66
83
|
let normalizedDirectory = normalizeFilePath(directory).replace(/\/+$/, '');
|
|
67
84
|
targets.add(normalizedDirectory);
|
|
68
85
|
if (!isSameOrDescendantPath(normalizedDirectory, normalizedRootDir))
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@remix-run/assets",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Fetch-based server for compiling browser JS/TS and CSS assets on demand",
|
|
5
5
|
"author": "Michael Jackson <mjijackson@gmail.com>",
|
|
6
6
|
"license": "MIT",
|
|
@@ -38,15 +38,17 @@
|
|
|
38
38
|
"oxc-transform": "^0.121.0",
|
|
39
39
|
"picomatch": "^4.0.4",
|
|
40
40
|
"source-map-js": "^1.2.1",
|
|
41
|
-
"@remix-run/
|
|
42
|
-
"@remix-run/
|
|
41
|
+
"@remix-run/file-storage": "0.13.4",
|
|
42
|
+
"@remix-run/headers": "0.20.0",
|
|
43
|
+
"@remix-run/mime": "0.4.1",
|
|
44
|
+
"@remix-run/route-pattern": "0.21.0"
|
|
43
45
|
},
|
|
44
46
|
"devDependencies": {
|
|
45
47
|
"@types/node": "^24.6.0",
|
|
46
48
|
"@types/picomatch": "^4.0.3",
|
|
47
49
|
"@typescript/native-preview": "7.0.0-dev.20251125.1",
|
|
48
50
|
"@remix-run/assert": "0.2.0",
|
|
49
|
-
"@remix-run/test": "0.
|
|
51
|
+
"@remix-run/test": "0.4.0"
|
|
50
52
|
},
|
|
51
53
|
"keywords": [
|
|
52
54
|
"remix",
|
package/src/assets.ts
CHANGED
package/src/lib/access.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { createFileMatcher } from './file-matcher.ts'
|
|
|
2
2
|
import { isInjectedPackageFilePath } from './injected-packages.ts'
|
|
3
3
|
|
|
4
4
|
type AccessPolicy = {
|
|
5
|
+
isDenied(filePath: string): boolean
|
|
5
6
|
isAllowed(filePath: string): boolean
|
|
6
7
|
}
|
|
7
8
|
|
|
@@ -15,11 +16,17 @@ export function createAccessPolicy(options: {
|
|
|
15
16
|
createFileMatcher(pattern, options.rootDir),
|
|
16
17
|
)
|
|
17
18
|
|
|
19
|
+
function isDenied(filePath: string): boolean {
|
|
20
|
+
if (isInjectedPackageFilePath(filePath)) return false
|
|
21
|
+
return denyMatchers.length > 0 && denyMatchers.some((matcher) => matcher(filePath))
|
|
22
|
+
}
|
|
23
|
+
|
|
18
24
|
return {
|
|
25
|
+
isDenied,
|
|
19
26
|
isAllowed(filePath) {
|
|
20
27
|
if (isInjectedPackageFilePath(filePath)) return true
|
|
21
28
|
if (!allowMatchers.some((matcher) => matcher(filePath))) return false
|
|
22
|
-
if (
|
|
29
|
+
if (isDenied(filePath)) return false
|
|
23
30
|
return true
|
|
24
31
|
},
|
|
25
32
|
}
|