@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
|
@@ -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",
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
"./package.json": "./package.json"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@oxc-project/runtime": "^0.121.0",
|
|
29
30
|
"chokidar": "^5.0.0",
|
|
30
31
|
"es-module-lexer": "^2.0.0",
|
|
31
32
|
"get-tsconfig": "^4.13.6",
|
|
@@ -37,13 +38,17 @@
|
|
|
37
38
|
"oxc-transform": "^0.121.0",
|
|
38
39
|
"picomatch": "^4.0.4",
|
|
39
40
|
"source-map-js": "^1.2.1",
|
|
40
|
-
"@remix-run/
|
|
41
|
-
"@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"
|
|
42
45
|
},
|
|
43
46
|
"devDependencies": {
|
|
44
47
|
"@types/node": "^24.6.0",
|
|
45
48
|
"@types/picomatch": "^4.0.3",
|
|
46
|
-
"@typescript/native-preview": "7.0.0-dev.20251125.1"
|
|
49
|
+
"@typescript/native-preview": "7.0.0-dev.20251125.1",
|
|
50
|
+
"@remix-run/assert": "0.2.0",
|
|
51
|
+
"@remix-run/test": "0.4.0"
|
|
47
52
|
},
|
|
48
53
|
"keywords": [
|
|
49
54
|
"remix",
|
|
@@ -58,7 +63,8 @@
|
|
|
58
63
|
"bench": "pnpm --dir ./bench run bench",
|
|
59
64
|
"build": "tsgo -p tsconfig.build.json",
|
|
60
65
|
"clean": "git clean -fdX",
|
|
61
|
-
"test": "
|
|
66
|
+
"test": "remix-test",
|
|
67
|
+
"test:bun": "bun x --bun remix-test",
|
|
62
68
|
"typecheck": "tsgo --noEmit"
|
|
63
69
|
}
|
|
64
70
|
}
|
package/src/assets.ts
CHANGED
package/src/lib/access.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createFileMatcher } from './file-matcher.ts'
|
|
2
|
+
import { isInjectedPackageFilePath } from './injected-packages.ts'
|
|
2
3
|
|
|
3
4
|
type AccessPolicy = {
|
|
5
|
+
isDenied(filePath: string): boolean
|
|
4
6
|
isAllowed(filePath: string): boolean
|
|
5
7
|
}
|
|
6
8
|
|
|
@@ -14,10 +16,17 @@ export function createAccessPolicy(options: {
|
|
|
14
16
|
createFileMatcher(pattern, options.rootDir),
|
|
15
17
|
)
|
|
16
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
|
+
|
|
17
24
|
return {
|
|
25
|
+
isDenied,
|
|
18
26
|
isAllowed(filePath) {
|
|
27
|
+
if (isInjectedPackageFilePath(filePath)) return true
|
|
19
28
|
if (!allowMatchers.some((matcher) => matcher(filePath))) return false
|
|
20
|
-
if (
|
|
29
|
+
if (isDenied(filePath)) return false
|
|
21
30
|
return true
|
|
22
31
|
},
|
|
23
32
|
}
|