@remix-run/assets 0.0.0 → 0.2.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/LICENSE +21 -0
- package/README.md +325 -2
- package/dist/assets.d.ts +3 -0
- package/dist/assets.d.ts.map +1 -0
- package/dist/assets.js +1 -0
- package/dist/lib/access.d.ts +10 -0
- package/dist/lib/access.d.ts.map +1 -0
- package/dist/lib/access.js +14 -0
- package/dist/lib/asset-server.d.ts +139 -0
- package/dist/lib/asset-server.d.ts.map +1 -0
- package/dist/lib/asset-server.js +338 -0
- package/dist/lib/compilation-error.d.ts +33 -0
- package/dist/lib/compilation-error.d.ts.map +1 -0
- package/dist/lib/compilation-error.js +32 -0
- package/dist/lib/file-matcher.d.ts +6 -0
- package/dist/lib/file-matcher.d.ts.map +1 -0
- package/dist/lib/file-matcher.js +44 -0
- package/dist/lib/fingerprint.d.ts +12 -0
- package/dist/lib/fingerprint.d.ts.map +1 -0
- package/dist/lib/fingerprint.js +49 -0
- package/dist/lib/module-store.d.ts +41 -0
- package/dist/lib/module-store.d.ts.map +1 -0
- package/dist/lib/module-store.js +230 -0
- package/dist/lib/paths.d.ts +8 -0
- package/dist/lib/paths.d.ts.map +1 -0
- package/dist/lib/paths.js +50 -0
- package/dist/lib/routes.d.ts +13 -0
- package/dist/lib/routes.d.ts.map +1 -0
- package/dist/lib/routes.js +94 -0
- package/dist/lib/scripts/cjs-check.d.ts +3 -0
- package/dist/lib/scripts/cjs-check.d.ts.map +1 -0
- package/dist/lib/scripts/cjs-check.js +398 -0
- package/dist/lib/scripts/compiler.d.ts +62 -0
- package/dist/lib/scripts/compiler.d.ts.map +1 -0
- package/dist/lib/scripts/compiler.js +439 -0
- package/dist/lib/scripts/emit.d.ts +25 -0
- package/dist/lib/scripts/emit.d.ts.map +1 -0
- package/dist/lib/scripts/emit.js +63 -0
- package/dist/lib/scripts/resolve.d.ts +50 -0
- package/dist/lib/scripts/resolve.d.ts.map +1 -0
- package/dist/lib/scripts/resolve.js +236 -0
- package/dist/lib/scripts/transform.d.ts +64 -0
- package/dist/lib/scripts/transform.d.ts.map +1 -0
- package/dist/lib/scripts/transform.js +373 -0
- package/dist/lib/source-maps.d.ts +4 -0
- package/dist/lib/source-maps.d.ts.map +1 -0
- package/dist/lib/source-maps.js +62 -0
- package/dist/lib/styles/compiler.d.ts +52 -0
- package/dist/lib/styles/compiler.d.ts.map +1 -0
- package/dist/lib/styles/compiler.js +272 -0
- package/dist/lib/styles/emit.d.ts +25 -0
- package/dist/lib/styles/emit.d.ts.map +1 -0
- package/dist/lib/styles/emit.js +78 -0
- package/dist/lib/styles/resolve.d.ts +48 -0
- package/dist/lib/styles/resolve.d.ts.map +1 -0
- package/dist/lib/styles/resolve.js +188 -0
- package/dist/lib/styles/transform.d.ts +47 -0
- package/dist/lib/styles/transform.d.ts.map +1 -0
- package/dist/lib/styles/transform.js +131 -0
- package/dist/lib/target.d.ts +21 -0
- package/dist/lib/target.d.ts.map +1 -0
- package/dist/lib/target.js +127 -0
- package/dist/lib/watch.d.ts +22 -0
- package/dist/lib/watch.d.ts.map +1 -0
- package/dist/lib/watch.js +96 -0
- package/package.json +55 -12
- package/src/assets.ts +2 -0
- package/src/lib/access.ts +24 -0
- package/src/lib/asset-server.ts +537 -0
- package/src/lib/compilation-error.ts +61 -0
- package/src/lib/file-matcher.ts +63 -0
- package/src/lib/fingerprint.ts +65 -0
- package/src/lib/module-store.ts +340 -0
- package/src/lib/paths.ts +66 -0
- package/src/lib/routes.ts +164 -0
- package/src/lib/scripts/cjs-check.ts +476 -0
- package/src/lib/scripts/compiler.ts +640 -0
- package/src/lib/scripts/emit.ts +122 -0
- package/src/lib/scripts/resolve.ts +433 -0
- package/src/lib/scripts/transform.ts +609 -0
- package/src/lib/source-maps.ts +75 -0
- package/src/lib/styles/compiler.ts +400 -0
- package/src/lib/styles/emit.ts +137 -0
- package/src/lib/styles/resolve.ts +316 -0
- package/src/lib/styles/transform.ts +226 -0
- package/src/lib/target.ts +196 -0
- package/src/lib/watch.ts +136 -0
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
import * as fs from 'node:fs'
|
|
2
|
+
import * as path from 'node:path'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createAssetServerCompilationError,
|
|
6
|
+
isAssetServerCompilationError,
|
|
7
|
+
} from '../compilation-error.ts'
|
|
8
|
+
import { normalizeFilePath } from '../paths.ts'
|
|
9
|
+
import type { AssetServerCompilationError } from '../compilation-error.ts'
|
|
10
|
+
import type { ModuleRecord, ModuleTracking } from '../module-store.ts'
|
|
11
|
+
import type { CompiledRoutes } from '../routes.ts'
|
|
12
|
+
import type { EmittedStyle } from './emit.ts'
|
|
13
|
+
import type { TransformedStyle } from './transform.ts'
|
|
14
|
+
|
|
15
|
+
type StyleRecord = ModuleRecord<TransformedStyle, ResolvedStyle, EmittedStyle>
|
|
16
|
+
|
|
17
|
+
type ResolvedDependency =
|
|
18
|
+
| {
|
|
19
|
+
kind: 'external'
|
|
20
|
+
placeholder: string
|
|
21
|
+
replacement: string
|
|
22
|
+
}
|
|
23
|
+
| {
|
|
24
|
+
depPath: string
|
|
25
|
+
kind: 'local'
|
|
26
|
+
placeholder: string
|
|
27
|
+
suffix: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export type ResolvedStyle = {
|
|
31
|
+
dependencies: ResolvedDependency[]
|
|
32
|
+
deps: string[]
|
|
33
|
+
fingerprint: string | null
|
|
34
|
+
identityPath: string
|
|
35
|
+
rawCode: string
|
|
36
|
+
resolvedPath: string
|
|
37
|
+
sourceMap: string | null
|
|
38
|
+
stableUrlPathname: string
|
|
39
|
+
trackedFiles: string[]
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export type ResolveArgs = {
|
|
43
|
+
isAllowed(absolutePath: string): boolean
|
|
44
|
+
isWatchIgnored(filePath: string): boolean
|
|
45
|
+
routes: CompiledRoutes
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
type ResolveResult = {
|
|
49
|
+
tracking: ModuleTracking
|
|
50
|
+
} & (
|
|
51
|
+
| {
|
|
52
|
+
ok: true
|
|
53
|
+
value: ResolvedStyle
|
|
54
|
+
}
|
|
55
|
+
| {
|
|
56
|
+
error: AssetServerCompilationError
|
|
57
|
+
ok: false
|
|
58
|
+
}
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
export async function resolveStyle(
|
|
62
|
+
record: StyleRecord,
|
|
63
|
+
transformed: TransformedStyle,
|
|
64
|
+
args: ResolveArgs,
|
|
65
|
+
): Promise<ResolveResult> {
|
|
66
|
+
let trackedFiles = new Set(transformed.trackedFiles)
|
|
67
|
+
let dependencies: ResolvedDependency[] = []
|
|
68
|
+
let deps = new Set<string>()
|
|
69
|
+
|
|
70
|
+
for (let unresolved of transformed.unresolvedDependencies) {
|
|
71
|
+
let trackedFile =
|
|
72
|
+
unresolved.type === 'import'
|
|
73
|
+
? getTrackedImportFilePath(unresolved.url, transformed.resolvedPath)
|
|
74
|
+
: null
|
|
75
|
+
if (trackedFile && !args.isWatchIgnored(trackedFile)) {
|
|
76
|
+
trackedFiles.add(trackedFile)
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
try {
|
|
80
|
+
let resolved =
|
|
81
|
+
unresolved.type === 'import'
|
|
82
|
+
? resolveImportDependency(
|
|
83
|
+
unresolved.url,
|
|
84
|
+
transformed.resolvedPath,
|
|
85
|
+
unresolved.placeholder,
|
|
86
|
+
args,
|
|
87
|
+
)
|
|
88
|
+
: resolveUrlDependency(unresolved.url, unresolved.placeholder)
|
|
89
|
+
|
|
90
|
+
dependencies.push(resolved)
|
|
91
|
+
|
|
92
|
+
if (resolved.kind === 'local') {
|
|
93
|
+
if (!args.isWatchIgnored(resolved.depPath)) {
|
|
94
|
+
trackedFiles.add(resolved.depPath)
|
|
95
|
+
}
|
|
96
|
+
deps.add(resolved.depPath)
|
|
97
|
+
}
|
|
98
|
+
} catch (error) {
|
|
99
|
+
return failResolve(error, trackedFiles, transformed.resolvedPath)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
return {
|
|
104
|
+
ok: true,
|
|
105
|
+
tracking: {
|
|
106
|
+
trackedFiles: [...trackedFiles],
|
|
107
|
+
},
|
|
108
|
+
value: {
|
|
109
|
+
dependencies,
|
|
110
|
+
deps: [...deps],
|
|
111
|
+
fingerprint: transformed.fingerprint,
|
|
112
|
+
identityPath: record.identityPath,
|
|
113
|
+
rawCode: transformed.rawCode,
|
|
114
|
+
resolvedPath: transformed.resolvedPath,
|
|
115
|
+
sourceMap: transformed.sourceMap,
|
|
116
|
+
stableUrlPathname: transformed.stableUrlPathname,
|
|
117
|
+
trackedFiles: [...trackedFiles],
|
|
118
|
+
},
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function resolveServedStyleOrThrow(
|
|
123
|
+
filePath: string,
|
|
124
|
+
args: ResolveArgs,
|
|
125
|
+
): {
|
|
126
|
+
identityPath: string
|
|
127
|
+
stableUrlPathname: string
|
|
128
|
+
} {
|
|
129
|
+
let identityPath = resolveExistingFilePath(filePath)
|
|
130
|
+
if (!identityPath) {
|
|
131
|
+
throw createAssetServerCompilationError(`File not found: ${filePath}`, {
|
|
132
|
+
code: 'FILE_NOT_FOUND',
|
|
133
|
+
})
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
if (!isStyleFilePath(identityPath)) {
|
|
137
|
+
throw createAssetServerCompilationError(`File not found: ${identityPath}`, {
|
|
138
|
+
code: 'FILE_NOT_FOUND',
|
|
139
|
+
})
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if (!args.isAllowed(identityPath)) {
|
|
143
|
+
throw createAssetServerCompilationError(`File is not allowed: ${identityPath}`, {
|
|
144
|
+
code: 'FILE_NOT_ALLOWED',
|
|
145
|
+
})
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
let stableUrlPathname = args.routes.toUrlPathname(identityPath)
|
|
149
|
+
if (!stableUrlPathname) {
|
|
150
|
+
throw createAssetServerCompilationError(
|
|
151
|
+
`File ${identityPath} is outside all configured fileMap entries.`,
|
|
152
|
+
{
|
|
153
|
+
code: 'FILE_OUTSIDE_FILE_MAP',
|
|
154
|
+
},
|
|
155
|
+
)
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
return { identityPath, stableUrlPathname }
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
function resolveImportDependency(
|
|
162
|
+
url: string,
|
|
163
|
+
importerPath: string,
|
|
164
|
+
placeholder: string,
|
|
165
|
+
args: ResolveArgs,
|
|
166
|
+
): ResolvedDependency {
|
|
167
|
+
if (isExternalUrl(url)) {
|
|
168
|
+
return {
|
|
169
|
+
kind: 'external',
|
|
170
|
+
placeholder,
|
|
171
|
+
replacement: url,
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
let { pathname, suffix } = splitUrlSuffix(url)
|
|
176
|
+
if (pathname.length === 0 || pathname === '#') {
|
|
177
|
+
return {
|
|
178
|
+
kind: 'external',
|
|
179
|
+
placeholder,
|
|
180
|
+
replacement: url,
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
if (pathname.startsWith('/')) {
|
|
185
|
+
return {
|
|
186
|
+
kind: 'external',
|
|
187
|
+
placeholder,
|
|
188
|
+
replacement: url,
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
let resolvedFilePath = normalizeFilePath(path.resolve(path.dirname(importerPath), pathname))
|
|
193
|
+
let identityPath = resolveExistingFilePath(resolvedFilePath)
|
|
194
|
+
if (!identityPath || !isStyleFilePath(identityPath)) {
|
|
195
|
+
throw createAssetServerCompilationError(
|
|
196
|
+
`Failed to resolve import "${url}" in ${importerPath}.`,
|
|
197
|
+
{
|
|
198
|
+
code: 'IMPORT_RESOLUTION_FAILED',
|
|
199
|
+
},
|
|
200
|
+
)
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
if (!args.isAllowed(identityPath)) {
|
|
204
|
+
throw createAssetServerCompilationError(
|
|
205
|
+
`Import "${url}" in ${importerPath}, resolved to "${identityPath}", is not allowed by the asset server allow/deny configuration. ` +
|
|
206
|
+
`Add a matching allow rule for this file path, remove a conflicting deny rule for this file path, or mark this import as external.`,
|
|
207
|
+
{
|
|
208
|
+
code: 'IMPORT_NOT_ALLOWED',
|
|
209
|
+
},
|
|
210
|
+
)
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
if (!args.routes.toUrlPathname(identityPath)) {
|
|
214
|
+
throw createAssetServerCompilationError(
|
|
215
|
+
`Import "${url}" in ${importerPath}, resolved to "${identityPath}", is outside all configured fileMap entries. ` +
|
|
216
|
+
`Add a matching fileMap entry for this file path, or mark this import as external.`,
|
|
217
|
+
{
|
|
218
|
+
code: 'IMPORT_OUTSIDE_FILE_MAP',
|
|
219
|
+
},
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
depPath: identityPath,
|
|
225
|
+
kind: 'local',
|
|
226
|
+
placeholder,
|
|
227
|
+
suffix,
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
function resolveUrlDependency(url: string, placeholder: string): ResolvedDependency {
|
|
232
|
+
return {
|
|
233
|
+
kind: 'external',
|
|
234
|
+
placeholder,
|
|
235
|
+
replacement: url,
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
function resolveExistingFilePath(filePath: string): string | null {
|
|
240
|
+
try {
|
|
241
|
+
return normalizeFilePath(fs.realpathSync(filePath))
|
|
242
|
+
} catch (error) {
|
|
243
|
+
if (isNoEntityError(error)) return null
|
|
244
|
+
throw error
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
function splitUrlSuffix(url: string): {
|
|
249
|
+
pathname: string
|
|
250
|
+
suffix: string
|
|
251
|
+
} {
|
|
252
|
+
let queryIndex = url.indexOf('?')
|
|
253
|
+
let hashIndex = url.indexOf('#')
|
|
254
|
+
let endIndex = [queryIndex, hashIndex].filter((index) => index >= 0).sort((a, b) => a - b)[0]
|
|
255
|
+
|
|
256
|
+
if (endIndex == null) {
|
|
257
|
+
return {
|
|
258
|
+
pathname: url,
|
|
259
|
+
suffix: '',
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
return {
|
|
264
|
+
pathname: url.slice(0, endIndex),
|
|
265
|
+
suffix: url.slice(endIndex),
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
function getTrackedImportFilePath(specifier: string, importerPath: string): string | null {
|
|
270
|
+
let { pathname } = splitUrlSuffix(specifier)
|
|
271
|
+
if (pathname.startsWith('./') || pathname.startsWith('../')) {
|
|
272
|
+
return normalizeFilePath(path.resolve(path.dirname(importerPath), pathname))
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
return null
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
function isStyleFilePath(filePath: string): boolean {
|
|
279
|
+
return path.extname(filePath).toLowerCase() === '.css'
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
function isExternalUrl(url: string): boolean {
|
|
283
|
+
return url.startsWith('#') || url.startsWith('//') || /^[A-Za-z][A-Za-z\d+.-]*:/.test(url)
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
function isNoEntityError(error: unknown): error is NodeJS.ErrnoException & { code: 'ENOENT' } {
|
|
287
|
+
return (
|
|
288
|
+
error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT'
|
|
289
|
+
)
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
function toResolveError(error: unknown, importerPath: string): AssetServerCompilationError {
|
|
293
|
+
if (isAssetServerCompilationError(error)) return error
|
|
294
|
+
|
|
295
|
+
return createAssetServerCompilationError(
|
|
296
|
+
`Failed to resolve imports in ${importerPath}. ${error instanceof Error ? error.message : String(error)}`,
|
|
297
|
+
{
|
|
298
|
+
cause: error,
|
|
299
|
+
code: 'IMPORT_RESOLUTION_FAILED',
|
|
300
|
+
},
|
|
301
|
+
)
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
function failResolve(
|
|
305
|
+
error: unknown,
|
|
306
|
+
trackedFiles: ReadonlySet<string>,
|
|
307
|
+
importerPath: string,
|
|
308
|
+
): ResolveResult {
|
|
309
|
+
return {
|
|
310
|
+
ok: false,
|
|
311
|
+
error: toResolveError(error, importerPath),
|
|
312
|
+
tracking: {
|
|
313
|
+
trackedFiles: [...trackedFiles],
|
|
314
|
+
},
|
|
315
|
+
}
|
|
316
|
+
}
|
|
@@ -0,0 +1,226 @@
|
|
|
1
|
+
import * as fs from 'node:fs/promises'
|
|
2
|
+
import { transform } from 'lightningcss'
|
|
3
|
+
|
|
4
|
+
import {
|
|
5
|
+
createAssetServerCompilationError,
|
|
6
|
+
isAssetServerCompilationError,
|
|
7
|
+
} from '../compilation-error.ts'
|
|
8
|
+
import { generateFingerprint } from '../fingerprint.ts'
|
|
9
|
+
import type { ModuleTracking } from '../module-store.ts'
|
|
10
|
+
import { rewriteSourceMapSources, stringifySourceMap } from '../source-maps.ts'
|
|
11
|
+
import type { AssetServerCompilationError } from '../compilation-error.ts'
|
|
12
|
+
import type { CompiledRoutes } from '../routes.ts'
|
|
13
|
+
import type { ResolvedStyleTarget } from '../target.ts'
|
|
14
|
+
|
|
15
|
+
type TransformedStyleDependency =
|
|
16
|
+
| {
|
|
17
|
+
placeholder: string
|
|
18
|
+
type: 'import'
|
|
19
|
+
url: string
|
|
20
|
+
}
|
|
21
|
+
| {
|
|
22
|
+
placeholder: string
|
|
23
|
+
type: 'url'
|
|
24
|
+
url: string
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type TransformedStyle = {
|
|
28
|
+
fingerprint: string | null
|
|
29
|
+
identityPath: string
|
|
30
|
+
rawCode: string
|
|
31
|
+
resolvedPath: string
|
|
32
|
+
sourceMap: string | null
|
|
33
|
+
stableUrlPathname: string
|
|
34
|
+
trackedFiles: string[]
|
|
35
|
+
unresolvedDependencies: TransformedStyleDependency[]
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type TransformResult = {
|
|
39
|
+
tracking: ModuleTracking
|
|
40
|
+
} & (
|
|
41
|
+
| {
|
|
42
|
+
ok: true
|
|
43
|
+
value: TransformedStyle
|
|
44
|
+
}
|
|
45
|
+
| {
|
|
46
|
+
error: AssetServerCompilationError
|
|
47
|
+
ok: false
|
|
48
|
+
}
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
export type TransformArgs = {
|
|
52
|
+
buildId: string | null
|
|
53
|
+
isWatchIgnored(filePath: string): boolean
|
|
54
|
+
minify: boolean
|
|
55
|
+
routes: CompiledRoutes
|
|
56
|
+
sourceMaps: 'external' | 'inline' | null
|
|
57
|
+
sourceMapSourcePaths: 'absolute' | 'url'
|
|
58
|
+
targets: ResolvedStyleTarget | null
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
type TransformRecord = {
|
|
62
|
+
identityPath: string
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export async function transformStyle(
|
|
66
|
+
record: TransformRecord,
|
|
67
|
+
args: TransformArgs,
|
|
68
|
+
): Promise<TransformResult> {
|
|
69
|
+
let resolvedPath = record.identityPath
|
|
70
|
+
let trackedFiles = args.isWatchIgnored(resolvedPath) ? [] : [resolvedPath]
|
|
71
|
+
let rawBytes: Uint8Array
|
|
72
|
+
|
|
73
|
+
try {
|
|
74
|
+
rawBytes = new Uint8Array(await fs.readFile(resolvedPath))
|
|
75
|
+
} catch (error) {
|
|
76
|
+
if (isNoEntityError(error)) {
|
|
77
|
+
return {
|
|
78
|
+
ok: false,
|
|
79
|
+
error: createAssetServerCompilationError(`File not found: ${resolvedPath}`, {
|
|
80
|
+
cause: error,
|
|
81
|
+
code: 'FILE_NOT_FOUND',
|
|
82
|
+
}),
|
|
83
|
+
tracking: {
|
|
84
|
+
trackedFiles,
|
|
85
|
+
},
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return {
|
|
90
|
+
ok: false,
|
|
91
|
+
error: toTransformFailedError(error, resolvedPath),
|
|
92
|
+
tracking: {
|
|
93
|
+
trackedFiles,
|
|
94
|
+
},
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
try {
|
|
99
|
+
let stableUrlPathname = args.routes.toUrlPathname(record.identityPath)
|
|
100
|
+
if (!stableUrlPathname) {
|
|
101
|
+
throw createAssetServerCompilationError(
|
|
102
|
+
`File ${record.identityPath} is outside all configured fileMap entries.`,
|
|
103
|
+
{
|
|
104
|
+
code: 'FILE_OUTSIDE_FILE_MAP',
|
|
105
|
+
},
|
|
106
|
+
)
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let transformResult = runLightningTransform(resolvedPath, rawBytes, {
|
|
110
|
+
minify: args.minify,
|
|
111
|
+
sourceMap: args.sourceMaps != null,
|
|
112
|
+
targets: args.targets,
|
|
113
|
+
})
|
|
114
|
+
let sourceText = Buffer.from(rawBytes).toString('utf8')
|
|
115
|
+
let sourceMap = stringifySourceMap(transformResult.map)
|
|
116
|
+
sourceMap = sourceMap
|
|
117
|
+
? rewriteSourceMapSources(
|
|
118
|
+
sourceMap,
|
|
119
|
+
resolvedPath,
|
|
120
|
+
stableUrlPathname,
|
|
121
|
+
args.sourceMapSourcePaths,
|
|
122
|
+
sourceText,
|
|
123
|
+
)
|
|
124
|
+
: null
|
|
125
|
+
|
|
126
|
+
let unresolvedDependencies: TransformedStyleDependency[] = []
|
|
127
|
+
for (let dependency of transformResult.dependencies ?? []) {
|
|
128
|
+
if (dependency.type === 'import') {
|
|
129
|
+
unresolvedDependencies.push({
|
|
130
|
+
placeholder: dependency.placeholder,
|
|
131
|
+
type: 'import',
|
|
132
|
+
url: dependency.url,
|
|
133
|
+
})
|
|
134
|
+
continue
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (dependency.type === 'url') {
|
|
138
|
+
unresolvedDependencies.push({
|
|
139
|
+
placeholder: dependency.placeholder,
|
|
140
|
+
type: 'url',
|
|
141
|
+
url: dependency.url,
|
|
142
|
+
})
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return {
|
|
147
|
+
ok: true,
|
|
148
|
+
tracking: {
|
|
149
|
+
trackedFiles,
|
|
150
|
+
},
|
|
151
|
+
value: {
|
|
152
|
+
fingerprint:
|
|
153
|
+
args.buildId === null
|
|
154
|
+
? null
|
|
155
|
+
: await generateFingerprint({
|
|
156
|
+
buildId: args.buildId,
|
|
157
|
+
content: sourceText,
|
|
158
|
+
}),
|
|
159
|
+
identityPath: record.identityPath,
|
|
160
|
+
rawCode: Buffer.from(transformResult.code).toString('utf8'),
|
|
161
|
+
resolvedPath,
|
|
162
|
+
sourceMap,
|
|
163
|
+
stableUrlPathname,
|
|
164
|
+
trackedFiles,
|
|
165
|
+
unresolvedDependencies,
|
|
166
|
+
},
|
|
167
|
+
}
|
|
168
|
+
} catch (error) {
|
|
169
|
+
return {
|
|
170
|
+
ok: false,
|
|
171
|
+
error: toTransformFailedError(error, resolvedPath),
|
|
172
|
+
tracking: {
|
|
173
|
+
trackedFiles,
|
|
174
|
+
},
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
function runLightningTransform(
|
|
180
|
+
identityPath: string,
|
|
181
|
+
code: Uint8Array,
|
|
182
|
+
options: {
|
|
183
|
+
minify: boolean
|
|
184
|
+
sourceMap: boolean
|
|
185
|
+
targets: ResolvedStyleTarget | null
|
|
186
|
+
},
|
|
187
|
+
) {
|
|
188
|
+
try {
|
|
189
|
+
return transform({
|
|
190
|
+
analyzeDependencies: {
|
|
191
|
+
preserveImports: true,
|
|
192
|
+
},
|
|
193
|
+
code,
|
|
194
|
+
filename: identityPath,
|
|
195
|
+
minify: options.minify,
|
|
196
|
+
sourceMap: options.sourceMap,
|
|
197
|
+
targets: options.targets ?? undefined,
|
|
198
|
+
})
|
|
199
|
+
} catch (error) {
|
|
200
|
+
throw createAssetServerCompilationError(
|
|
201
|
+
`Failed to transform style ${identityPath}. ${error instanceof Error ? error.message : String(error)}`,
|
|
202
|
+
{
|
|
203
|
+
cause: error,
|
|
204
|
+
code: 'TRANSFORM_FAILED',
|
|
205
|
+
},
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
function toTransformFailedError(error: unknown, resolvedPath: string): AssetServerCompilationError {
|
|
211
|
+
if (isAssetServerCompilationError(error)) return error
|
|
212
|
+
|
|
213
|
+
return createAssetServerCompilationError(
|
|
214
|
+
`Failed to transform style ${resolvedPath}. ${error instanceof Error ? error.message : String(error)}`,
|
|
215
|
+
{
|
|
216
|
+
cause: error,
|
|
217
|
+
code: 'TRANSFORM_FAILED',
|
|
218
|
+
},
|
|
219
|
+
)
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
function isNoEntityError(error: unknown): error is NodeJS.ErrnoException & { code: 'ENOENT' } {
|
|
223
|
+
return (
|
|
224
|
+
error instanceof Error && 'code' in error && (error as NodeJS.ErrnoException).code === 'ENOENT'
|
|
225
|
+
)
|
|
226
|
+
}
|