zyzz 0.0.5 → 0.0.7
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 +26 -1
- package/dist/Style.d.ts +3 -3
- package/dist/Style.d.ts.map +1 -1
- package/dist/Style.js +12 -1
- package/dist/Style.js.map +1 -1
- package/dist/babel/index.d.ts +2 -0
- package/dist/babel/index.d.ts.map +1 -1
- package/dist/babel/index.js +10 -1
- package/dist/babel/index.js.map +1 -1
- package/dist/compiler/Graph.d.ts +2 -0
- package/dist/compiler/Graph.d.ts.map +1 -1
- package/dist/compiler/Graph.js +19 -1
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +5 -2
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/internal/Contributions.d.ts +1 -1
- package/dist/compiler/internal/Contributions.d.ts.map +1 -1
- package/dist/compiler/internal/Contributions.js +5 -3
- package/dist/compiler/internal/Contributions.js.map +1 -1
- package/dist/compiler/internal/Static.d.ts.map +1 -1
- package/dist/compiler/internal/Static.js +2 -0
- package/dist/compiler/internal/Static.js.map +1 -1
- package/dist/internal/Authoring.d.ts.map +1 -1
- package/dist/internal/Authoring.js +14 -0
- package/dist/internal/Authoring.js.map +1 -1
- package/dist/internal/Binding.d.ts +7 -0
- package/dist/internal/Binding.d.ts.map +1 -1
- package/dist/internal/Binding.js.map +1 -1
- package/dist/internal/Configuration.d.ts +1 -1
- package/dist/internal/Configuration.d.ts.map +1 -1
- package/dist/internal/Configuration.js +7 -6
- package/dist/internal/Configuration.js.map +1 -1
- package/dist/internal/Theme.d.ts +1 -1
- package/dist/internal/Theme.d.ts.map +1 -1
- package/dist/internal/Theme.js.map +1 -1
- package/dist/internal/Token.d.ts +3 -1
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +28 -3
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/Value.d.ts +22 -0
- package/dist/internal/Value.d.ts.map +1 -1
- package/dist/internal/Value.js +76 -9
- package/dist/internal/Value.js.map +1 -1
- package/dist/next/index.d.ts +8 -3
- package/dist/next/index.d.ts.map +1 -1
- package/dist/next/index.js +21 -10
- package/dist/next/index.js.map +1 -1
- package/dist/next/internal/Project.d.ts +28 -0
- package/dist/next/internal/Project.d.ts.map +1 -0
- package/dist/next/internal/Project.js +249 -0
- package/dist/next/internal/Project.js.map +1 -0
- package/dist/next/loader.d.ts +3 -5
- package/dist/next/loader.d.ts.map +1 -1
- package/dist/next/loader.js +14 -144
- package/dist/next/loader.js.map +1 -1
- package/dist/node/Reset.d.ts +3 -0
- package/dist/node/Reset.d.ts.map +1 -0
- package/dist/node/Reset.js +7 -0
- package/dist/node/Reset.js.map +1 -0
- package/dist/unplugin/index.d.ts +2 -0
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +2 -0
- package/dist/unplugin/index.js.map +1 -1
- package/dist/variants.d.ts +1 -1
- package/dist/variants.d.ts.map +1 -1
- package/dist/variants.js.map +1 -1
- package/dist/vite/index.d.ts +2 -0
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +38 -9
- package/dist/vite/index.js.map +1 -1
- package/package.json +1 -1
- package/src/Style.ts +42 -8
- package/src/babel/index.ts +23 -1
- package/src/compiler/Graph.ts +22 -0
- package/src/compiler/Source.ts +5 -1
- package/src/compiler/internal/Contributions.ts +5 -2
- package/src/compiler/internal/Static.ts +1 -0
- package/src/internal/Authoring.ts +21 -0
- package/src/internal/Binding.ts +30 -0
- package/src/internal/Configuration.ts +19 -13
- package/src/internal/Theme.ts +5 -1
- package/src/internal/Token.ts +34 -3
- package/src/internal/Value.ts +180 -10
- package/src/next/index.ts +34 -12
- package/src/next/internal/Project.ts +337 -0
- package/src/next/loader.ts +28 -190
- package/src/node/Reset.ts +7 -0
- package/src/unplugin/index.ts +4 -0
- package/src/variants.ts +1 -0
- package/src/vite/index.ts +43 -14
package/src/next/loader.ts
CHANGED
|
@@ -1,31 +1,23 @@
|
|
|
1
1
|
/** Loads a physical source graph through Next.js resolution and emits cache-owned CSS. @module */
|
|
2
|
+
import * as AtRules from '../compiler/internal/AtRules.js'
|
|
2
3
|
import * as Crypto from 'node:crypto'
|
|
3
4
|
import * as Fs from 'node:fs/promises'
|
|
4
5
|
import * as Path from 'node:path'
|
|
5
|
-
import * as
|
|
6
|
-
import * as Graph from '../compiler/Graph.js'
|
|
7
|
-
import * as AtRules from '../compiler/internal/AtRules.js'
|
|
8
|
-
import * as Contract from '../compiler/internal/Contract.js'
|
|
6
|
+
import * as Project from './internal/Project.js'
|
|
9
7
|
|
|
10
|
-
type Context = {
|
|
11
|
-
addContextDependency(directory: string): void
|
|
12
|
-
addDependency(file: string): void
|
|
8
|
+
type Context = Project.Context & {
|
|
13
9
|
async(): (error: Error | null, code?: string, map?: object) => void
|
|
14
10
|
getOptions(): {
|
|
15
11
|
bundler: string
|
|
16
12
|
mode: 'shared' | 'source' | 'style'
|
|
13
|
+
reset?: boolean | undefined
|
|
17
14
|
root: string
|
|
18
15
|
}
|
|
19
|
-
getResolve(
|
|
20
|
-
options: object,
|
|
21
|
-
): (
|
|
22
|
-
directory: string,
|
|
23
|
-
specifier: string,
|
|
24
|
-
callback: (error: Error | null, file?: string | false) => void,
|
|
25
|
-
) => void
|
|
26
|
-
resourcePath: string
|
|
27
16
|
}
|
|
28
17
|
|
|
18
|
+
// Next owns loader worker lifetimes. Each project retains only its latest graph in that worker.
|
|
19
|
+
const projects = new Map<string, ReturnType<typeof Project.create>>()
|
|
20
|
+
|
|
29
21
|
/** Loader-runner boundary used by Webpack and Turbopack. */
|
|
30
22
|
export default function loader(this: Context, source: string): void {
|
|
31
23
|
const callback = this.async()
|
|
@@ -40,14 +32,6 @@ async function compile(context: Context, source: string) {
|
|
|
40
32
|
const options = context.getOptions()
|
|
41
33
|
const root = options.root
|
|
42
34
|
const directory = Path.resolve(root, '.zyzz', 'next')
|
|
43
|
-
const modules: Record<string, string> = Object.create(null)
|
|
44
|
-
const imports: Record<string, Record<string, string | null>> = Object.create(
|
|
45
|
-
null,
|
|
46
|
-
)
|
|
47
|
-
const contracts: Record<string, string> = Object.create(null)
|
|
48
|
-
const resolve = context.getResolve({})
|
|
49
|
-
const id = (file: string) =>
|
|
50
|
-
`app/${Path.relative(root, file).split(Path.sep).join('/')}`
|
|
51
35
|
const eligible = (file: string) =>
|
|
52
36
|
/\.[cm]?[jt]sx?$/.test(file) &&
|
|
53
37
|
!/\.(?:d|test|test-d|bench|bench-d)\.[cm]?[jt]sx?$/.test(file) &&
|
|
@@ -58,142 +42,31 @@ async function compile(context: Context, source: string) {
|
|
|
58
42
|
part === '..' || part === 'node_modules' || part.startsWith('.'),
|
|
59
43
|
)
|
|
60
44
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
const name = id(file)
|
|
66
|
-
if (Object.hasOwn(modules, name)) return
|
|
67
|
-
|
|
68
|
-
context.addDependency(file)
|
|
69
|
-
modules[name] = text ?? (await Fs.readFile(file, 'utf8'))
|
|
70
|
-
const links: Record<string, string | null> = Object.create(null)
|
|
71
|
-
imports[name] = links
|
|
72
|
-
const parsed = Parser.parseSync(file, modules[name]!, {
|
|
73
|
-
sourceType: 'module',
|
|
74
|
-
})
|
|
75
|
-
|
|
76
|
-
for (const node of parsed.program.body) {
|
|
77
|
-
if (
|
|
78
|
-
(node.type !== 'ImportDeclaration' &&
|
|
79
|
-
node.type !== 'ExportNamedDeclaration' &&
|
|
80
|
-
node.type !== 'ExportAllDeclaration') ||
|
|
81
|
-
!node.source
|
|
82
|
-
)
|
|
83
|
-
continue
|
|
84
|
-
if (
|
|
85
|
-
node.type === 'ImportDeclaration'
|
|
86
|
-
? node.importKind === 'type'
|
|
87
|
-
: node.exportKind === 'type'
|
|
88
|
-
)
|
|
89
|
-
continue
|
|
90
|
-
|
|
91
|
-
const specifier = node.source.value
|
|
92
|
-
links[specifier] = null
|
|
93
|
-
// Next owns this virtual module, which has no physical stylesheet contract.
|
|
94
|
-
if (specifier === 'next/root-params') continue
|
|
95
|
-
if (
|
|
96
|
-
specifier === 'zyzz' ||
|
|
97
|
-
(specifier.startsWith('zyzz/') && specifier !== 'zyzz/default') ||
|
|
98
|
-
specifier.startsWith('node:')
|
|
99
|
-
)
|
|
100
|
-
continue
|
|
101
|
-
|
|
102
|
-
const resolved = await new Promise<string | false | undefined>(
|
|
103
|
-
(accept, reject) => {
|
|
104
|
-
resolve(Path.dirname(file), specifier, (error, value) =>
|
|
105
|
-
error ? reject(error) : accept(value),
|
|
106
|
-
)
|
|
107
|
-
},
|
|
108
|
-
)
|
|
109
|
-
if (!resolved || !/\.[cm]?[jt]sx?$/.test(resolved)) continue
|
|
110
|
-
if (eligible(resolved)) {
|
|
111
|
-
links[specifier] = id(resolved)
|
|
112
|
-
await visit(resolved)
|
|
113
|
-
continue
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const sidecar = `${resolved}.zyzz.json`
|
|
117
|
-
try {
|
|
118
|
-
contracts[resolved] = await Fs.readFile(sidecar, 'utf8')
|
|
119
|
-
context.addDependency(sidecar)
|
|
120
|
-
links[specifier] = resolved
|
|
121
|
-
} catch (error) {
|
|
122
|
-
if ((error as NodeJS.ErrnoException).code !== 'ENOENT') throw error
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
async function discover(directory: string): Promise<void> {
|
|
128
|
-
const items = await Fs.readdir(directory, { withFileTypes: true })
|
|
129
|
-
|
|
130
|
-
// Recursive tracking of a package root follows every installed dependency.
|
|
131
|
-
// A dependency symlink back to an ancestor, as a package linked from its
|
|
132
|
-
// own repository, is rejected as a loop, so such a root is tracked through
|
|
133
|
-
// its files and subdirectories instead.
|
|
134
|
-
if (
|
|
135
|
-
!items.some((item) => item.name === 'node_modules') ||
|
|
136
|
-
!(await loops(directory))
|
|
45
|
+
// Next.js hoists instrumentation CSS out of route stylesheets without loading it.
|
|
46
|
+
if (
|
|
47
|
+
/^(?:src\/)?instrumentation-client\.[cm]?[jt]s$/.test(
|
|
48
|
+
Path.relative(root, context.resourcePath).split(Path.sep).join('/'),
|
|
137
49
|
)
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
for (const item of items) {
|
|
141
|
-
if (
|
|
142
|
-
item.name.startsWith('.') ||
|
|
143
|
-
[
|
|
144
|
-
'node_modules',
|
|
145
|
-
'dist',
|
|
146
|
-
'build',
|
|
147
|
-
'coverage',
|
|
148
|
-
'test',
|
|
149
|
-
'tests',
|
|
150
|
-
'__tests__',
|
|
151
|
-
].includes(item.name)
|
|
152
|
-
)
|
|
153
|
-
continue
|
|
154
|
-
const file = Path.join(directory, item.name)
|
|
155
|
-
if (item.isDirectory()) await discover(file)
|
|
156
|
-
else if (item.isFile() && eligible(file)) await visit(file)
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
if (options.mode !== 'shared') await visit(context.resourcePath, source)
|
|
161
|
-
await discover(root)
|
|
162
|
-
const loaded = new Set<string>()
|
|
163
|
-
async function dependencies(file: string): Promise<void> {
|
|
164
|
-
if (loaded.has(file)) return
|
|
165
|
-
loaded.add(file)
|
|
50
|
+
)
|
|
51
|
+
return { code: source, map: undefined }
|
|
166
52
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
let owner = file
|
|
170
|
-
for (const specifier of section.dependency ?? []) {
|
|
171
|
-
const target = await new Promise<string | false | undefined>(
|
|
172
|
-
(accept, reject) => {
|
|
173
|
-
resolve(Path.dirname(owner), specifier, (error, value) =>
|
|
174
|
-
error ? reject(error) : accept(value),
|
|
175
|
-
)
|
|
176
|
-
},
|
|
177
|
-
)
|
|
178
|
-
if (!target || !Path.isAbsolute(target))
|
|
179
|
-
throw new Error('Unable to resolve packed stylesheet dependency.')
|
|
53
|
+
if (options.mode !== 'shared' && !eligible(context.resourcePath))
|
|
54
|
+
return { code: source, map: undefined }
|
|
180
55
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
context.addDependency(sidecar)
|
|
187
|
-
}
|
|
188
|
-
await dependencies(target)
|
|
189
|
-
owner = target
|
|
190
|
-
}
|
|
191
|
-
}
|
|
56
|
+
const key = JSON.stringify([root, options.bundler, options.reset ?? false])
|
|
57
|
+
let project = projects.get(key)
|
|
58
|
+
if (!project) {
|
|
59
|
+
project = Project.create(options)
|
|
60
|
+
projects.set(key, project)
|
|
192
61
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
62
|
+
const graph = await project.compile(
|
|
63
|
+
context,
|
|
64
|
+
options.mode === 'shared' ? undefined : source,
|
|
65
|
+
)
|
|
66
|
+
const output =
|
|
67
|
+
graph.modules[
|
|
68
|
+
`app/${Path.relative(root, context.resourcePath).split(Path.sep).join('/')}`
|
|
69
|
+
]
|
|
197
70
|
|
|
198
71
|
const assets = new Map<string, string>()
|
|
199
72
|
for (const [placeholder, target] of Object.entries(
|
|
@@ -346,38 +219,3 @@ async function compile(context: Context, source: string) {
|
|
|
346
219
|
|
|
347
220
|
return { code: `${output.code}\n${requests.join('\n')}`, map }
|
|
348
221
|
}
|
|
349
|
-
|
|
350
|
-
/** Whether an installed dependency links back to the directory or one of its ancestors. */
|
|
351
|
-
async function loops(directory: string): Promise<boolean> {
|
|
352
|
-
const installed = Path.join(directory, 'node_modules')
|
|
353
|
-
const entries = await Fs.readdir(installed, { withFileTypes: true }).catch(
|
|
354
|
-
() => [],
|
|
355
|
-
)
|
|
356
|
-
const candidates = (
|
|
357
|
-
await Promise.all(
|
|
358
|
-
entries.map(async (entry) => {
|
|
359
|
-
if (!entry.name.startsWith('@'))
|
|
360
|
-
return [Path.join(installed, entry.name)]
|
|
361
|
-
|
|
362
|
-
const scoped = Path.join(installed, entry.name)
|
|
363
|
-
|
|
364
|
-
return (await Fs.readdir(scoped).catch(() => [])).map((name) =>
|
|
365
|
-
Path.join(scoped, name),
|
|
366
|
-
)
|
|
367
|
-
}),
|
|
368
|
-
)
|
|
369
|
-
).flat()
|
|
370
|
-
|
|
371
|
-
for (const candidate of candidates) {
|
|
372
|
-
const stat = await Fs.lstat(candidate).catch(() => undefined)
|
|
373
|
-
if (!stat?.isSymbolicLink()) continue
|
|
374
|
-
|
|
375
|
-
const target = await Fs.realpath(candidate).catch(() => undefined)
|
|
376
|
-
if (target === undefined) continue
|
|
377
|
-
|
|
378
|
-
const relative = Path.relative(target, directory)
|
|
379
|
-
if (!relative.startsWith('..') && !Path.isAbsolute(relative)) return true
|
|
380
|
-
}
|
|
381
|
-
|
|
382
|
-
return false
|
|
383
|
-
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/** Loads the canonical reset stylesheet for web bundler adapters. @module */
|
|
2
|
+
import * as Fs from 'node:fs'
|
|
3
|
+
|
|
4
|
+
/** Reads the packaged stylesheet without adding a dependency on browser CSS loaders. */
|
|
5
|
+
export function read(): string {
|
|
6
|
+
return Fs.readFileSync(new URL('../reset.css', import.meta.url), 'utf8')
|
|
7
|
+
}
|
package/src/unplugin/index.ts
CHANGED
|
@@ -3,6 +3,7 @@ import * as Mapping from '@jridgewell/gen-mapping'
|
|
|
3
3
|
import * as Crypto from 'node:crypto'
|
|
4
4
|
import * as Fs from 'node:fs/promises'
|
|
5
5
|
import * as Path from 'node:path'
|
|
6
|
+
import * as Reset from '../node/Reset.js'
|
|
6
7
|
import * as Parser from 'oxc-parser'
|
|
7
8
|
import { createUnplugin } from 'unplugin'
|
|
8
9
|
import type { UnpluginBuildContext } from 'unplugin'
|
|
@@ -16,6 +17,8 @@ import * as Vite from '../vite/index.js'
|
|
|
16
17
|
export type Options = {
|
|
17
18
|
/** Rewrite authoring calls. Defaults to true. */
|
|
18
19
|
readonly compiler?: boolean | undefined
|
|
20
|
+
/** Include the CSS reset. Defaults to false. */
|
|
21
|
+
readonly reset?: boolean | undefined
|
|
19
22
|
/** Source directory scanned for modules and global contributions. Defaults to the working directory. */
|
|
20
23
|
readonly root?: string | undefined
|
|
21
24
|
}
|
|
@@ -280,6 +283,7 @@ const portable = createUnplugin<Options | undefined, false>(
|
|
|
280
283
|
|
|
281
284
|
const result = compiler.compile({
|
|
282
285
|
compiler: options.compiler,
|
|
286
|
+
reset: options.reset ? Reset.read() : undefined,
|
|
283
287
|
contracts,
|
|
284
288
|
imports,
|
|
285
289
|
modules,
|
package/src/variants.ts
CHANGED
|
@@ -51,6 +51,7 @@ type CheckedChoice<
|
|
|
51
51
|
values: values,
|
|
52
52
|
) => CheckedStyles<body, tokens, layers, mappings> &
|
|
53
53
|
Binding.Checked<body> &
|
|
54
|
+
Binding.TokenSlots<body, values, tokens, mappings> &
|
|
54
55
|
(string extends keyof values
|
|
55
56
|
? never
|
|
56
57
|
: values extends Record<string, string | number> &
|
package/src/vite/index.ts
CHANGED
|
@@ -10,6 +10,7 @@ import * as Lightning from 'lightningcss'
|
|
|
10
10
|
import * as Crypto from 'node:crypto'
|
|
11
11
|
import * as Fs from 'node:fs/promises'
|
|
12
12
|
import * as Path from 'node:path'
|
|
13
|
+
import * as Reset from '../node/Reset.js'
|
|
13
14
|
import { isBuiltin } from 'node:module'
|
|
14
15
|
import * as Parser from 'oxc-parser'
|
|
15
16
|
import * as Walker from 'oxc-walker'
|
|
@@ -34,6 +35,8 @@ export function zyzz(options: zyzz.Options = {}): Plugin {
|
|
|
34
35
|
options.native.units && Object.freeze({ ...options.native.units }),
|
|
35
36
|
})
|
|
36
37
|
: undefined
|
|
38
|
+
if (native && options.reset)
|
|
39
|
+
throw new Error('The CSS reset is only supported by web builds.')
|
|
37
40
|
if (native && options.compiler === false)
|
|
38
41
|
throw new Error('Native builds require source compilation.')
|
|
39
42
|
|
|
@@ -640,6 +643,7 @@ export function zyzz(options: zyzz.Options = {}): Plugin {
|
|
|
640
643
|
|
|
641
644
|
const result = entry.compiler.compile({
|
|
642
645
|
compiler: options.compiler,
|
|
646
|
+
reset: options.reset ? Reset.read() : undefined,
|
|
643
647
|
native,
|
|
644
648
|
contracts,
|
|
645
649
|
development: entry.environment.mode !== 'build',
|
|
@@ -762,17 +766,39 @@ export function zyzz(options: zyzz.Options = {}): Plugin {
|
|
|
762
766
|
for (const [key, target] of Object.entries(result.sharedAssets ?? {})) {
|
|
763
767
|
const raw = target.split(/[?#]/)[0]!
|
|
764
768
|
|
|
765
|
-
const file = await Fs.realpath(
|
|
766
|
-
target.startsWith('app/')
|
|
767
|
-
? Path.join(root, decodeURIComponent(raw.slice(4)))
|
|
768
|
-
: Path.isAbsolute(raw)
|
|
769
|
-
? decodeURIComponent(raw)
|
|
770
|
-
: (() => {
|
|
771
|
-
throw new Error('Asset path escapes the Vite graph.')
|
|
772
|
-
})(),
|
|
773
|
-
)
|
|
774
|
-
|
|
775
769
|
const identity = result.sharedAssetOwners?.[key]
|
|
770
|
+
const path = target.startsWith('app/')
|
|
771
|
+
? Path.join(root, decodeURIComponent(raw.slice(4)))
|
|
772
|
+
: Path.isAbsolute(raw)
|
|
773
|
+
? decodeURIComponent(raw)
|
|
774
|
+
: undefined
|
|
775
|
+
if (!path) throw new Error('Asset path escapes the Vite graph.')
|
|
776
|
+
|
|
777
|
+
const asset = await (async () => {
|
|
778
|
+
try {
|
|
779
|
+
return { file: await Fs.realpath(path), package: false }
|
|
780
|
+
} catch (error) {
|
|
781
|
+
if (
|
|
782
|
+
(error as NodeJS.ErrnoException).code !== 'ENOENT' ||
|
|
783
|
+
!identity?.startsWith('app/')
|
|
784
|
+
)
|
|
785
|
+
throw error
|
|
786
|
+
|
|
787
|
+
const importer = Path.join(root, identity.slice(4))
|
|
788
|
+
const specifier = Path.relative(Path.dirname(importer), path)
|
|
789
|
+
.split(Path.sep)
|
|
790
|
+
.join('/')
|
|
791
|
+
if (specifier.startsWith('.') || Path.isAbsolute(specifier))
|
|
792
|
+
throw error
|
|
793
|
+
const resolved = await host.resolve(specifier, importer)
|
|
794
|
+
if (!resolved || resolved.external) throw error
|
|
795
|
+
return {
|
|
796
|
+
file: await Fs.realpath(resolved.id.split('?')[0]!),
|
|
797
|
+
package: true,
|
|
798
|
+
}
|
|
799
|
+
}
|
|
800
|
+
})()
|
|
801
|
+
const file = asset.file
|
|
776
802
|
|
|
777
803
|
const owner = identity?.startsWith('app/')
|
|
778
804
|
? appRoot
|
|
@@ -782,9 +808,10 @@ export function zyzz(options: zyzz.Options = {}): Plugin {
|
|
|
782
808
|
|
|
783
809
|
const relative = owner ? Path.relative(owner, file) : '..'
|
|
784
810
|
if (
|
|
785
|
-
|
|
786
|
-
relative
|
|
787
|
-
|
|
811
|
+
!asset.package &&
|
|
812
|
+
(relative === '..' ||
|
|
813
|
+
relative.startsWith(`..${Path.sep}`) ||
|
|
814
|
+
Path.isAbsolute(relative))
|
|
788
815
|
)
|
|
789
816
|
throw new Error('Asset path escapes its owning package.')
|
|
790
817
|
|
|
@@ -793,7 +820,7 @@ export function zyzz(options: zyzz.Options = {}): Plugin {
|
|
|
793
820
|
|
|
794
821
|
let url: string
|
|
795
822
|
|
|
796
|
-
if (/[?#%]/.test(file)) {
|
|
823
|
+
if (asset.package || /[?#%]/.test(file)) {
|
|
797
824
|
if (entry.environment.mode === 'build') {
|
|
798
825
|
url = await host.asset(file)
|
|
799
826
|
|
|
@@ -1465,6 +1492,8 @@ export declare namespace zyzz {
|
|
|
1465
1492
|
readonly compiler?: boolean | undefined
|
|
1466
1493
|
/** Native context captured at creation. Disables CSS delivery and initialization scripts. */
|
|
1467
1494
|
readonly native?: Graph.compile.Options['native']
|
|
1495
|
+
/** Include the CSS reset. Defaults to false. */
|
|
1496
|
+
readonly reset?: boolean | undefined
|
|
1468
1497
|
/**
|
|
1469
1498
|
* Inline each configuration's `script()` at the start of index.html's head.
|
|
1470
1499
|
* False skips injection for documents that inline the script themselves.
|