zyzz 0.0.28 → 0.0.30
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/binding/wasi/wasi-worker.mjs +186 -0
- package/binding/wasi/zyzz.wasi.cjs +2302 -0
- package/binding/wasi/zyzz.wasm32-wasi.wasm +0 -0
- package/binding/zyzz.linux-x64-gnu.node +0 -0
- package/dist/babel/index.d.ts.map +1 -1
- package/dist/babel/index.js +2 -4
- package/dist/babel/index.js.map +1 -1
- package/dist/babel/internal/Compilation.d.ts +0 -1
- package/dist/babel/internal/Compilation.d.ts.map +1 -1
- package/dist/compiler/Graph.d.ts +14 -11
- package/dist/compiler/Graph.d.ts.map +1 -1
- package/dist/compiler/Graph.js +57 -1442
- package/dist/compiler/Graph.js.map +1 -1
- package/dist/compiler/Native.d.ts +7 -9
- package/dist/compiler/Native.d.ts.map +1 -1
- package/dist/compiler/Native.js +12 -716
- package/dist/compiler/Native.js.map +1 -1
- package/dist/compiler/Source.d.ts +122 -24
- package/dist/compiler/Source.d.ts.map +1 -1
- package/dist/compiler/Source.js +10 -1267
- package/dist/compiler/Source.js.map +1 -1
- package/dist/compiler/Transform.d.ts +4 -3
- package/dist/compiler/Transform.d.ts.map +1 -1
- package/dist/compiler/Transform.js +13 -961
- package/dist/compiler/Transform.js.map +1 -1
- package/dist/compiler/internal/AtRules.d.ts +5 -1
- package/dist/compiler/internal/AtRules.d.ts.map +1 -1
- package/dist/compiler/internal/AtRules.js +12 -106
- package/dist/compiler/internal/AtRules.js.map +1 -1
- package/dist/compiler/internal/Context.d.ts +11 -0
- package/dist/compiler/internal/Context.d.ts.map +1 -0
- package/dist/compiler/internal/Context.js +11 -0
- package/dist/compiler/internal/Context.js.map +1 -0
- package/dist/compiler/internal/Results.d.ts +148 -0
- package/dist/compiler/internal/Results.d.ts.map +1 -0
- package/dist/compiler/internal/Results.js +259 -0
- package/dist/compiler/internal/Results.js.map +1 -0
- package/dist/compiler/internal/Syntax.d.ts +0 -2
- package/dist/compiler/internal/Syntax.d.ts.map +1 -1
- package/dist/compiler/internal/Syntax.js +0 -2
- package/dist/compiler/internal/Syntax.js.map +1 -1
- package/dist/compiler/internal/Wire.d.ts +17 -0
- package/dist/compiler/internal/Wire.d.ts.map +1 -0
- package/dist/compiler/internal/Wire.js +795 -0
- package/dist/compiler/internal/Wire.js.map +1 -0
- package/dist/internal/Addon.d.ts +28 -0
- package/dist/internal/Addon.d.ts.map +1 -0
- package/dist/internal/Addon.js +87 -0
- package/dist/internal/Addon.js.map +1 -0
- package/dist/internal/Literal.d.ts +4 -1
- package/dist/internal/Literal.d.ts.map +1 -1
- package/dist/internal/Literal.js +4 -2
- package/dist/internal/Literal.js.map +1 -1
- package/dist/internal/Token.d.ts +2 -1
- package/dist/internal/Token.d.ts.map +1 -1
- package/dist/internal/Token.js +2 -2
- package/dist/internal/Token.js.map +1 -1
- package/dist/internal/Vlq.d.ts +14 -0
- package/dist/internal/Vlq.d.ts.map +1 -0
- package/dist/internal/Vlq.js +47 -0
- package/dist/internal/Vlq.js.map +1 -0
- package/dist/internal/Wasm.d.ts +22 -0
- package/dist/internal/Wasm.d.ts.map +1 -0
- package/dist/internal/Wasm.js +83 -0
- package/dist/internal/Wasm.js.map +1 -0
- package/dist/metro/Graph.d.ts +0 -1
- package/dist/metro/Graph.d.ts.map +1 -1
- package/dist/metro/transformer.d.ts.map +1 -1
- package/dist/metro/transformer.js +0 -1
- package/dist/metro/transformer.js.map +1 -1
- package/dist/next/internal/Project.d.ts.map +1 -1
- package/dist/next/internal/Project.js +2 -5
- package/dist/next/internal/Project.js.map +1 -1
- package/dist/node/Host.d.ts.map +1 -1
- package/dist/node/Host.js +0 -2
- package/dist/node/Host.js.map +1 -1
- package/dist/node/internal/Contracts.d.ts.map +1 -1
- package/dist/node/internal/Contracts.js +3 -7
- package/dist/node/internal/Contracts.js.map +1 -1
- package/dist/node/internal/Snapshot.d.ts +0 -1
- package/dist/node/internal/Snapshot.d.ts.map +1 -1
- package/dist/node/internal/Snapshot.js +0 -6
- package/dist/node/internal/Snapshot.js.map +1 -1
- package/dist/runtime/Composition.d.ts +2 -3
- package/dist/runtime/Composition.d.ts.map +1 -1
- package/dist/runtime/Composition.js +51 -30
- package/dist/runtime/Composition.js.map +1 -1
- package/dist/runtime/Recipe.d.ts.map +1 -1
- package/dist/runtime/Recipe.js +16 -12
- package/dist/runtime/Recipe.js.map +1 -1
- package/dist/unplugin/index.d.ts.map +1 -1
- package/dist/unplugin/index.js +3 -6
- package/dist/unplugin/index.js.map +1 -1
- package/dist/vite/index.d.ts.map +1 -1
- package/dist/vite/index.js +696 -201
- package/dist/vite/index.js.map +1 -1
- package/dist/web/Css.d.ts +8 -3
- package/dist/web/Css.d.ts.map +1 -1
- package/dist/web/Css.js +5 -721
- package/dist/web/Css.js.map +1 -1
- package/dist/web/internal/Block.d.ts +0 -2
- package/dist/web/internal/Block.d.ts.map +1 -1
- package/dist/web/internal/Block.js +1 -12
- package/dist/web/internal/Block.js.map +1 -1
- package/dist/web/internal/ClassName.d.ts +23 -18
- package/dist/web/internal/ClassName.d.ts.map +1 -1
- package/dist/web/internal/ClassName.js +26 -55
- package/dist/web/internal/ClassName.js.map +1 -1
- package/dist/web/internal/Contributions.d.ts +3 -5
- package/dist/web/internal/Contributions.d.ts.map +1 -1
- package/dist/web/internal/Contributions.js +0 -45
- package/dist/web/internal/Contributions.js.map +1 -1
- package/dist/web/internal/Engine.browser.d.ts +8 -0
- package/dist/web/internal/Engine.browser.d.ts.map +1 -0
- package/dist/web/internal/Engine.browser.js +42 -0
- package/dist/web/internal/Engine.browser.js.map +1 -0
- package/dist/web/internal/Engine.d.ts +9 -0
- package/dist/web/internal/Engine.d.ts.map +1 -0
- package/dist/web/internal/Engine.js +14 -0
- package/dist/web/internal/Engine.js.map +1 -0
- package/dist/web/internal/Themes.d.ts +1 -9
- package/dist/web/internal/Themes.d.ts.map +1 -1
- package/dist/web/internal/Themes.js +3 -221
- package/dist/web/internal/Themes.js.map +1 -1
- package/dist/web/internal/Wasm.generated.d.ts +4 -0
- package/dist/web/internal/Wasm.generated.d.ts.map +1 -0
- package/dist/web/internal/Wasm.generated.js +4 -0
- package/dist/web/internal/Wasm.generated.js.map +1 -0
- package/dist/web/internal/Wire.d.ts +19 -0
- package/dist/web/internal/Wire.d.ts.map +1 -0
- package/dist/web/internal/Wire.js +387 -0
- package/dist/web/internal/Wire.js.map +1 -0
- package/package.json +20 -1
- package/src/babel/index.ts +2 -5
- package/src/babel/internal/Compilation.ts +0 -1
- package/src/compiler/Graph.ts +89 -1930
- package/src/compiler/Native.ts +18 -871
- package/src/compiler/Source.ts +144 -1803
- package/src/compiler/Transform.ts +16 -1315
- package/src/compiler/internal/AtRules.ts +27 -115
- package/src/compiler/internal/Context.ts +11 -0
- package/src/compiler/internal/Results.ts +406 -0
- package/src/compiler/internal/Syntax.ts +0 -3
- package/src/compiler/internal/Wire.ts +1045 -0
- package/src/internal/Addon.ts +118 -0
- package/src/internal/Literal.ts +4 -2
- package/src/internal/Token.ts +2 -2
- package/src/internal/Vlq.ts +59 -0
- package/src/internal/Wasm.ts +111 -0
- package/src/metro/transformer.ts +0 -1
- package/src/next/internal/Project.ts +2 -9
- package/src/node/Host.ts +0 -2
- package/src/node/internal/Contracts.ts +3 -7
- package/src/node/internal/Snapshot.ts +0 -8
- package/src/runtime/Composition.ts +48 -25
- package/src/runtime/Recipe.ts +21 -14
- package/src/unplugin/index.ts +6 -6
- package/src/vite/index.ts +922 -221
- package/src/web/Css.ts +12 -908
- package/src/web/internal/Block.ts +0 -14
- package/src/web/internal/ClassName.ts +52 -85
- package/src/web/internal/Contributions.ts +3 -59
- package/src/web/internal/Engine.browser.ts +51 -0
- package/src/web/internal/Engine.ts +17 -0
- package/src/web/internal/Themes.ts +3 -279
- package/src/web/internal/Wasm.generated.ts +3 -0
- package/src/web/internal/Wire.ts +466 -0
- package/src/web/internal/wasm.d.ts +9 -0
- package/dist/compiler/internal/Applications.d.ts +0 -55
- package/dist/compiler/internal/Applications.d.ts.map +0 -1
- package/dist/compiler/internal/Applications.js +0 -393
- package/dist/compiler/internal/Applications.js.map +0 -1
- package/dist/compiler/internal/ColorProfiles.d.ts +0 -3
- package/dist/compiler/internal/ColorProfiles.d.ts.map +0 -1
- package/dist/compiler/internal/ColorProfiles.js +0 -84
- package/dist/compiler/internal/ColorProfiles.js.map +0 -1
- package/dist/compiler/internal/CompositionBindings.d.ts +0 -16
- package/dist/compiler/internal/CompositionBindings.d.ts.map +0 -1
- package/dist/compiler/internal/CompositionBindings.js +0 -89
- package/dist/compiler/internal/CompositionBindings.js.map +0 -1
- package/dist/compiler/internal/Compositions.d.ts +0 -37
- package/dist/compiler/internal/Compositions.d.ts.map +0 -1
- package/dist/compiler/internal/Compositions.js +0 -494
- package/dist/compiler/internal/Compositions.js.map +0 -1
- package/dist/compiler/internal/Configurations.d.ts +0 -26
- package/dist/compiler/internal/Configurations.d.ts.map +0 -1
- package/dist/compiler/internal/Configurations.js +0 -259
- package/dist/compiler/internal/Configurations.js.map +0 -1
- package/dist/compiler/internal/Contract.d.ts +0 -30
- package/dist/compiler/internal/Contract.d.ts.map +0 -1
- package/dist/compiler/internal/Contract.js +0 -753
- package/dist/compiler/internal/Contract.js.map +0 -1
- package/dist/compiler/internal/Contributions.d.ts +0 -54
- package/dist/compiler/internal/Contributions.d.ts.map +0 -1
- package/dist/compiler/internal/Contributions.js +0 -1151
- package/dist/compiler/internal/Contributions.js.map +0 -1
- package/dist/compiler/internal/Descriptors.d.ts +0 -15
- package/dist/compiler/internal/Descriptors.d.ts.map +0 -1
- package/dist/compiler/internal/Descriptors.js +0 -192
- package/dist/compiler/internal/Descriptors.js.map +0 -1
- package/dist/compiler/internal/Dynamic.d.ts +0 -14
- package/dist/compiler/internal/Dynamic.d.ts.map +0 -1
- package/dist/compiler/internal/Dynamic.js +0 -175
- package/dist/compiler/internal/Dynamic.js.map +0 -1
- package/dist/compiler/internal/Expression.d.ts +0 -19
- package/dist/compiler/internal/Expression.d.ts.map +0 -1
- package/dist/compiler/internal/Expression.js +0 -164
- package/dist/compiler/internal/Expression.js.map +0 -1
- package/dist/compiler/internal/Functions.d.ts +0 -5
- package/dist/compiler/internal/Functions.d.ts.map +0 -1
- package/dist/compiler/internal/Functions.js +0 -191
- package/dist/compiler/internal/Functions.js.map +0 -1
- package/dist/compiler/internal/Keyframes.d.ts +0 -5
- package/dist/compiler/internal/Keyframes.d.ts.map +0 -1
- package/dist/compiler/internal/Keyframes.js +0 -51
- package/dist/compiler/internal/Keyframes.js.map +0 -1
- package/dist/compiler/internal/Names.d.ts +0 -5
- package/dist/compiler/internal/Names.d.ts.map +0 -1
- package/dist/compiler/internal/Names.js +0 -37
- package/dist/compiler/internal/Names.js.map +0 -1
- package/dist/compiler/internal/NativeBindings.d.ts +0 -72
- package/dist/compiler/internal/NativeBindings.d.ts.map +0 -1
- package/dist/compiler/internal/NativeBindings.js +0 -171
- package/dist/compiler/internal/NativeBindings.js.map +0 -1
- package/dist/compiler/internal/NativeMedia.d.ts +0 -14
- package/dist/compiler/internal/NativeMedia.d.ts.map +0 -1
- package/dist/compiler/internal/NativeMedia.js +0 -287
- package/dist/compiler/internal/NativeMedia.js.map +0 -1
- package/dist/compiler/internal/NativeVars.d.ts +0 -28
- package/dist/compiler/internal/NativeVars.d.ts.map +0 -1
- package/dist/compiler/internal/NativeVars.js +0 -160
- package/dist/compiler/internal/NativeVars.js.map +0 -1
- package/dist/compiler/internal/PackedStyles.d.ts +0 -37
- package/dist/compiler/internal/PackedStyles.d.ts.map +0 -1
- package/dist/compiler/internal/PackedStyles.js +0 -344
- package/dist/compiler/internal/PackedStyles.js.map +0 -1
- package/dist/compiler/internal/Properties.d.ts +0 -5
- package/dist/compiler/internal/Properties.d.ts.map +0 -1
- package/dist/compiler/internal/Properties.js +0 -82
- package/dist/compiler/internal/Properties.js.map +0 -1
- package/dist/compiler/internal/RecipeConditions.d.ts +0 -41
- package/dist/compiler/internal/RecipeConditions.d.ts.map +0 -1
- package/dist/compiler/internal/RecipeConditions.js +0 -82
- package/dist/compiler/internal/RecipeConditions.js.map +0 -1
- package/dist/compiler/internal/RecipePayloads.d.ts +0 -31
- package/dist/compiler/internal/RecipePayloads.d.ts.map +0 -1
- package/dist/compiler/internal/RecipePayloads.js +0 -99
- package/dist/compiler/internal/RecipePayloads.js.map +0 -1
- package/dist/compiler/internal/Recipes.d.ts +0 -32
- package/dist/compiler/internal/Recipes.d.ts.map +0 -1
- package/dist/compiler/internal/Recipes.js +0 -339
- package/dist/compiler/internal/Recipes.js.map +0 -1
- package/dist/compiler/internal/Selectors.d.ts +0 -13
- package/dist/compiler/internal/Selectors.d.ts.map +0 -1
- package/dist/compiler/internal/Selectors.js +0 -280
- package/dist/compiler/internal/Selectors.js.map +0 -1
- package/dist/compiler/internal/Static.d.ts +0 -39
- package/dist/compiler/internal/Static.d.ts.map +0 -1
- package/dist/compiler/internal/Static.js +0 -534
- package/dist/compiler/internal/Static.js.map +0 -1
- package/dist/compiler/internal/Themes.d.ts +0 -190
- package/dist/compiler/internal/Themes.d.ts.map +0 -1
- package/dist/compiler/internal/Themes.js +0 -1577
- package/dist/compiler/internal/Themes.js.map +0 -1
- package/dist/compiler/internal/Vars.d.ts +0 -33
- package/dist/compiler/internal/Vars.d.ts.map +0 -1
- package/dist/compiler/internal/Vars.js +0 -387
- package/dist/compiler/internal/Vars.js.map +0 -1
- package/dist/compiler/internal/ViewTransitions.d.ts +0 -3
- package/dist/compiler/internal/ViewTransitions.d.ts.map +0 -1
- package/dist/compiler/internal/ViewTransitions.js +0 -68
- package/dist/compiler/internal/ViewTransitions.js.map +0 -1
- package/dist/internal/Cascade.d.ts +0 -74
- package/dist/internal/Cascade.d.ts.map +0 -1
- package/dist/internal/Cascade.js +0 -210
- package/dist/internal/Cascade.js.map +0 -1
- package/src/compiler/internal/Applications.ts +0 -610
- package/src/compiler/internal/ColorProfiles.ts +0 -93
- package/src/compiler/internal/CompositionBindings.ts +0 -120
- package/src/compiler/internal/Compositions.ts +0 -678
- package/src/compiler/internal/Configurations.ts +0 -349
- package/src/compiler/internal/Contract.ts +0 -1028
- package/src/compiler/internal/Contributions.ts +0 -1561
- package/src/compiler/internal/Descriptors.ts +0 -242
- package/src/compiler/internal/Dynamic.ts +0 -275
- package/src/compiler/internal/Expression.ts +0 -218
- package/src/compiler/internal/Functions.ts +0 -206
- package/src/compiler/internal/Keyframes.ts +0 -62
- package/src/compiler/internal/Names.ts +0 -48
- package/src/compiler/internal/NativeBindings.ts +0 -235
- package/src/compiler/internal/NativeMedia.ts +0 -342
- package/src/compiler/internal/NativeVars.ts +0 -231
- package/src/compiler/internal/PackedStyles.ts +0 -473
- package/src/compiler/internal/Properties.ts +0 -121
- package/src/compiler/internal/RecipeConditions.ts +0 -139
- package/src/compiler/internal/RecipePayloads.ts +0 -132
- package/src/compiler/internal/Recipes.ts +0 -531
- package/src/compiler/internal/Selectors.ts +0 -353
- package/src/compiler/internal/Static.ts +0 -784
- package/src/compiler/internal/Themes.ts +0 -2398
- package/src/compiler/internal/Vars.ts +0 -516
- package/src/compiler/internal/ViewTransitions.ts +0 -82
package/src/compiler/Source.ts
CHANGED
|
@@ -2,49 +2,20 @@
|
|
|
2
2
|
* Extracts literal styles and local themes through lexical source analysis.
|
|
3
3
|
* @module
|
|
4
4
|
*/
|
|
5
|
-
import * as
|
|
6
|
-
import * as
|
|
7
|
-
import type * as Ast from '@oxc-project/types'
|
|
8
|
-
import * as AtRules from './internal/AtRules.js'
|
|
9
|
-
import * as Binding from '../internal/Binding.js'
|
|
10
|
-
import * as Condition from '../internal/Condition.js'
|
|
11
|
-
import type * as Composition from '../runtime/Composition.js'
|
|
12
|
-
import * as Compositions from './internal/Compositions.js'
|
|
13
|
-
import * as Contributions from './internal/Contributions.js'
|
|
14
|
-
import * as Css from '../web/Css.js'
|
|
15
|
-
import * as Dynamic from './internal/Dynamic.js'
|
|
16
|
-
import * as Expression from './internal/Expression.js'
|
|
17
|
-
import * as Selectors from './internal/Selectors.js'
|
|
18
|
-
import type * as Namespace from '../web/internal/Namespace.js'
|
|
19
|
-
import * as Syntax from './internal/Syntax.js'
|
|
20
|
-
import * as RuleReference from '../internal/RuleReference.js'
|
|
21
|
-
import type * as Recipe from '../runtime/Recipe.js'
|
|
5
|
+
import * as Addon from '../internal/Addon.js'
|
|
6
|
+
import type * as Binding from '../internal/Binding.js'
|
|
22
7
|
import type * as StaticRecipe from '../internal/Recipe.js'
|
|
23
|
-
import type * as
|
|
24
|
-
import * as Recipes from './internal/Recipes.js'
|
|
25
|
-
import * as PackedStyles from './internal/PackedStyles.js'
|
|
26
|
-
import * as Scope from './internal/Scope.js'
|
|
8
|
+
import type * as RuleReference from '../internal/RuleReference.js'
|
|
27
9
|
import type * as Shorthands from '../internal/Shorthands.js'
|
|
28
|
-
import * as Static from './internal/Static.js'
|
|
29
|
-
import * as Style from '../Style.js'
|
|
30
10
|
import type * as Theme from '../internal/Theme.js'
|
|
31
|
-
import * as
|
|
32
|
-
import * as
|
|
33
|
-
import * as
|
|
34
|
-
import * as
|
|
35
|
-
import * as
|
|
36
|
-
import
|
|
37
|
-
import * as
|
|
38
|
-
import * as
|
|
39
|
-
import * as Vars from './internal/Vars.js'
|
|
40
|
-
import * as Walker from 'oxc-walker'
|
|
41
|
-
|
|
42
|
-
// JavaScript extraction supplies untyped values. Keep structural checks without
|
|
43
|
-
// asserting that those values already satisfy the TypeScript authoring contract.
|
|
44
|
-
const define = Style.define as unknown as (
|
|
45
|
-
styles: Record<string, unknown>,
|
|
46
|
-
options: Style.define.Options,
|
|
47
|
-
) => Style.Definition
|
|
11
|
+
import type * as Composition from '../runtime/Composition.js'
|
|
12
|
+
import type * as Recipe from '../runtime/Recipe.js'
|
|
13
|
+
import type * as Style from '../Style.js'
|
|
14
|
+
import type * as Vars from '../Vars.js'
|
|
15
|
+
import type * as Css from '../web/Css.js'
|
|
16
|
+
import type { cssFunction } from '../web/cssFunction.js'
|
|
17
|
+
import type * as Namespace from '../web/internal/Namespace.js'
|
|
18
|
+
import * as Wire from './internal/Wire.js'
|
|
48
19
|
|
|
49
20
|
/** A direct definition call available for a later source rewriter. */
|
|
50
21
|
export type Call = {
|
|
@@ -102,8 +73,6 @@ export type Call = {
|
|
|
102
73
|
| undefined
|
|
103
74
|
/** Stable selector identity retained independently of declaration deduplication. */
|
|
104
75
|
readonly identity?: string | undefined
|
|
105
|
-
/** Expanded immutable source data retained for declaration mapping. */
|
|
106
|
-
readonly body?: Ast.ObjectExpression | undefined
|
|
107
76
|
/** Alias targets retained for declaration source locations. */
|
|
108
77
|
readonly shorthands?: Shorthands.Map | undefined
|
|
109
78
|
/** Emitted typography field counts keyed by authored property offsets. */
|
|
@@ -113,7 +82,7 @@ export type Call = {
|
|
|
113
82
|
/** Native HTML attribute output selected by the bound configuration. */
|
|
114
83
|
readonly output?: 'html' | undefined
|
|
115
84
|
/** Typed runtime slots for callback definitions. */
|
|
116
|
-
readonly slots?:
|
|
85
|
+
readonly slots?: Readonly<Record<string, Binding.Reference>> | undefined
|
|
117
86
|
/** Authored scalar input type retained in packed declarations. */
|
|
118
87
|
readonly valuesType?: string | undefined
|
|
119
88
|
/** Exclusive UTF-16 offset of the complete call. */
|
|
@@ -142,1720 +111,135 @@ export type Diagnostic = {
|
|
|
142
111
|
readonly start: number
|
|
143
112
|
}
|
|
144
113
|
|
|
114
|
+
/** A static stylesheet effect call replaced by its compiled data. */
|
|
115
|
+
type ContributionCall = {
|
|
116
|
+
/** Exported binding offset of a named factory result. */
|
|
117
|
+
readonly binding?: number | undefined
|
|
118
|
+
/** Exclusive UTF-16 offset of the complete call. */
|
|
119
|
+
readonly end: number
|
|
120
|
+
/** Whether the factory result is exported. */
|
|
121
|
+
readonly exported?: boolean | undefined
|
|
122
|
+
/** CSS function signature of a `cssFunction` call. */
|
|
123
|
+
readonly function?: ThemeCall['function']
|
|
124
|
+
/** Stylesheet factory that created the effect. */
|
|
125
|
+
readonly kind: string
|
|
126
|
+
/** Authored binding of a named factory result. */
|
|
127
|
+
readonly name?: string | undefined
|
|
128
|
+
/** Inclusive UTF-16 offset of the complete call. */
|
|
129
|
+
readonly start: number
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/** Local bound-authoring initializer replaced while retaining its inferred type. */
|
|
133
|
+
type ThemeAlias = ThemeCall & {
|
|
134
|
+
/** Ordered authoring members replaced in a shared destructuring initializer. */
|
|
135
|
+
readonly bindings?: readonly ('style' | 'variants')[] | undefined
|
|
136
|
+
/** Whether the initializer supplies destructured authoring bindings. */
|
|
137
|
+
readonly destructured: boolean
|
|
138
|
+
/** Retains an immutable theme/configuration alias value with an explicit type. */
|
|
139
|
+
readonly retained?: boolean | undefined
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
/** Theme factory span and generated scope key. */
|
|
143
|
+
type ThemeCall = {
|
|
144
|
+
/** Whether the compiled configuration supplies root controls. */
|
|
145
|
+
readonly appearance?: boolean | undefined
|
|
146
|
+
/** Legacy packed catalog exposes members but lacks callable-selection capability. */
|
|
147
|
+
readonly catalogOnly?: boolean | undefined
|
|
148
|
+
readonly directVariables?: boolean | undefined
|
|
149
|
+
/** Exclusive source offset. */
|
|
150
|
+
readonly end: number
|
|
151
|
+
/** Static CSS function signature shared during extraction and packed serialization. */
|
|
152
|
+
readonly function?:
|
|
153
|
+
| {
|
|
154
|
+
parameters: readonly cssFunction.Parameter[]
|
|
155
|
+
returns: cssFunction.Syntax
|
|
156
|
+
}
|
|
157
|
+
| undefined
|
|
158
|
+
/** Bound root initialization script export. */
|
|
159
|
+
readonly initialization?: boolean | undefined
|
|
160
|
+
/** JSON-encoded member path tuples and their compiled scope keys. */
|
|
161
|
+
readonly members?: Readonly<Record<string, string>> | undefined
|
|
162
|
+
/** Stable module/binding scope key. */
|
|
163
|
+
readonly name: string
|
|
164
|
+
/** Whether native defineConfig retains a typed React Provider. */
|
|
165
|
+
readonly nativeProvider?: boolean | undefined
|
|
166
|
+
/** Validated inline configuration options retained for packed declarations. */
|
|
167
|
+
readonly options?: Readonly<Record<string, unknown>> | undefined
|
|
168
|
+
readonly output?: 'html' | undefined
|
|
169
|
+
/** Whether this bound authoring alias declares recipes. */
|
|
170
|
+
readonly recipe?: boolean | undefined
|
|
171
|
+
/** Named stylesheet identity domain. */
|
|
172
|
+
readonly reference?: RuleReference.Kind | undefined
|
|
173
|
+
/** Bound root controls export. */
|
|
174
|
+
readonly root?: boolean | undefined
|
|
175
|
+
/** Whether the compiled configuration supplies initialization. */
|
|
176
|
+
readonly script?: boolean | undefined
|
|
177
|
+
/** Config helper represented by this linked binding. */
|
|
178
|
+
readonly selection?: boolean | undefined
|
|
179
|
+
/** Inclusive source offset. */
|
|
180
|
+
readonly start: number
|
|
181
|
+
/** Literal token contract retained in rewritten TypeScript type assertions. */
|
|
182
|
+
readonly tokenType: string
|
|
183
|
+
/** Complete authoring type retained for configuration declarations. */
|
|
184
|
+
readonly type?: string | undefined
|
|
185
|
+
readonly variableConfig?: boolean | undefined
|
|
186
|
+
readonly variableMappings?: Vars.Mappings | false | undefined
|
|
187
|
+
/** Canonical defining module for multi-entry variable contracts. */
|
|
188
|
+
readonly variableOwner?: string | undefined
|
|
189
|
+
/** Portable explicit variable references. */
|
|
190
|
+
readonly variables?: Readonly<Record<string, Binding.Reference>> | undefined
|
|
191
|
+
readonly variableSet?: boolean | undefined
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
/** An explicit variable contract replaced by fixed slot data. */
|
|
195
|
+
type VariableCall = {
|
|
196
|
+
/** Exclusive source offset. */
|
|
197
|
+
readonly end: number
|
|
198
|
+
/** Whether the consumer supplied a portable variable identity. */
|
|
199
|
+
readonly explicit?: boolean | undefined
|
|
200
|
+
/** Fixed scalar reference retained in portable metadata. */
|
|
201
|
+
readonly slots: Readonly<Record<string, Binding.Reference>>
|
|
202
|
+
/** Inclusive source offset. */
|
|
203
|
+
readonly start: number
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/** A readonly variable argument consumed by a native React hook. */
|
|
207
|
+
type VarsRead = {
|
|
208
|
+
/** Owning configuration fallback. */
|
|
209
|
+
readonly defaultVars: string
|
|
210
|
+
/** Exclusive source offset. */
|
|
211
|
+
readonly end: number
|
|
212
|
+
/** Stable configuration identity for graph-owned native profiles. */
|
|
213
|
+
readonly owner: string
|
|
214
|
+
/** Inclusive source offset. */
|
|
215
|
+
readonly start: number
|
|
216
|
+
/** A standalone definition that does not select a named catalog entry. */
|
|
217
|
+
readonly unnamed: boolean
|
|
218
|
+
/** Complete compatible variable alternatives. */
|
|
219
|
+
readonly vars: Readonly<Record<string, Theme.Definition>>
|
|
220
|
+
}
|
|
221
|
+
|
|
145
222
|
/**
|
|
146
223
|
* Extracts direct style calls and local Theme definitions imported from zyzz.
|
|
147
|
-
* Parses TypeScript and JSX without reading files, loading config, or
|
|
224
|
+
* Parses TypeScript and JSX in the Rust compiler without reading files, loading config, or
|
|
225
|
+
* evaluating source. The returned calls carry no syntax trees.
|
|
148
226
|
* @param options - Source text and a portable package-relative module identity.
|
|
149
227
|
* @returns Frozen style/theme definitions and rewrite spans. Source text is unchanged.
|
|
150
228
|
* @throws {ExtractError} For syntax errors, unsupported imported references, or invalid literals.
|
|
151
229
|
*/
|
|
152
230
|
export function extract(options: extract.Options): extract.ReturnType {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
node?: Pick<Ast.Node, 'end' | 'start'>,
|
|
163
|
-
) {
|
|
164
|
-
diagnostics.push({
|
|
165
|
-
code,
|
|
166
|
-
end: node?.end ?? 0,
|
|
167
|
-
message,
|
|
168
|
-
source: options.moduleId,
|
|
169
|
-
start: node?.start ?? 0,
|
|
170
|
-
})
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
if (
|
|
174
|
-
!options.moduleId ||
|
|
175
|
-
options.moduleId.includes('\\') ||
|
|
176
|
-
options.moduleId.includes(':') ||
|
|
177
|
-
options.moduleId
|
|
178
|
-
.split('/')
|
|
179
|
-
.some((part) => !part || part === '.' || part === '..')
|
|
180
|
-
) {
|
|
181
|
-
report(
|
|
182
|
-
'invalid_module',
|
|
183
|
-
'Expected a portable package-relative module ID without absolute paths, backslashes, or traversal segments.',
|
|
184
|
-
)
|
|
185
|
-
throw new ExtractError(diagnostics)
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
const namespace = identity(options.moduleId)
|
|
189
|
-
const parsed = options[Themes.context]?.parsed ?? Syntax.parse(options)
|
|
190
|
-
for (const node of parsed.program.body) {
|
|
191
|
-
if (node.type !== 'ImportDeclaration' || node.source.value !== 'zyzz')
|
|
192
|
-
continue
|
|
193
|
-
for (const specifier of node.specifiers) {
|
|
194
|
-
if (specifier.type !== 'ImportSpecifier') continue
|
|
195
|
-
const name =
|
|
196
|
-
specifier.imported.type === 'Identifier'
|
|
197
|
-
? specifier.imported.name
|
|
198
|
-
: specifier.imported.value
|
|
199
|
-
if (name === 'Theme' || name === 'Variables')
|
|
200
|
-
throw new ExtractError([
|
|
201
|
-
{
|
|
202
|
-
code: 'unsupported_syntax',
|
|
203
|
-
message: `Import Vars instead of ${name}.`,
|
|
204
|
-
source: options.moduleId,
|
|
205
|
-
start: specifier.start,
|
|
206
|
-
end: specifier.end,
|
|
207
|
-
},
|
|
208
|
-
])
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (parsed.errors.length) {
|
|
213
|
-
for (const error of parsed.errors) {
|
|
214
|
-
const span = error.labels[0]
|
|
215
|
-
|
|
216
|
-
report('syntax_error', error.message, span)
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
throw new ExtractError(diagnostics)
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const program = parsed.program
|
|
223
|
-
const authoredNames = Names.collect(program)
|
|
224
|
-
const scopeTracker = new Scope.Tracker({ preserveExitedScopes: true })
|
|
225
|
-
|
|
226
|
-
Walker.walk(program, { scopeTracker })
|
|
227
|
-
scopeTracker.freeze()
|
|
228
|
-
|
|
229
|
-
const staticData = Static.create(
|
|
230
|
-
program,
|
|
231
|
-
scopeTracker,
|
|
232
|
-
options[Themes.context]?.constants,
|
|
233
|
-
)
|
|
234
|
-
|
|
235
|
-
const contributions = (() => {
|
|
236
|
-
try {
|
|
237
|
-
return Contributions.scan(
|
|
238
|
-
program,
|
|
239
|
-
scopeTracker,
|
|
240
|
-
namespace,
|
|
241
|
-
options[Themes.context]?.links,
|
|
242
|
-
options[Themes.context]?.factories,
|
|
243
|
-
)
|
|
244
|
-
} catch (error) {
|
|
245
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
246
|
-
|
|
247
|
-
report('unsupported_syntax', error.message, error)
|
|
248
|
-
throw new ExtractError(diagnostics)
|
|
249
|
-
}
|
|
250
|
-
})()
|
|
251
|
-
|
|
252
|
-
const variables = (() => {
|
|
253
|
-
try {
|
|
254
|
-
return Vars.collect(
|
|
255
|
-
program,
|
|
256
|
-
namespace,
|
|
257
|
-
scopeTracker,
|
|
258
|
-
options[Themes.context]?.links,
|
|
259
|
-
options.moduleId,
|
|
260
|
-
)
|
|
261
|
-
} catch (error) {
|
|
262
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
263
|
-
|
|
264
|
-
report('unsupported_syntax', error.message, error)
|
|
265
|
-
throw new ExtractError(diagnostics)
|
|
266
|
-
}
|
|
267
|
-
})()
|
|
268
|
-
|
|
269
|
-
const themes = (() => {
|
|
270
|
-
try {
|
|
271
|
-
return Themes.collect(program, {
|
|
272
|
-
native: options.target === 'native',
|
|
273
|
-
staticBindings: staticData.bindings,
|
|
274
|
-
namespace: `src-${Identity.label(
|
|
275
|
-
options.moduleId
|
|
276
|
-
.split('/')
|
|
277
|
-
.at(-1)!
|
|
278
|
-
.replace(/\.[cm]?[jt]sx?$/, ''),
|
|
279
|
-
)}-${Identity.compact(options.moduleId)}`,
|
|
280
|
-
contributionCalls: new Set(
|
|
281
|
-
contributions.calls.map((call) => call.start),
|
|
282
|
-
),
|
|
283
|
-
linked: options[Themes.context] !== undefined,
|
|
284
|
-
links: options[Themes.context]?.links,
|
|
285
|
-
})
|
|
286
|
-
} catch (error) {
|
|
287
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
288
|
-
|
|
289
|
-
report('unsupported_syntax', error.message, error)
|
|
290
|
-
throw new ExtractError(diagnostics)
|
|
291
|
-
}
|
|
292
|
-
})()
|
|
293
|
-
|
|
294
|
-
const ancestors: Ast.Node[] = []
|
|
295
|
-
const typeAncestors = new Set<Ast.Node>()
|
|
296
|
-
const typeNodes = new Set([
|
|
297
|
-
'TSInterfaceDeclaration',
|
|
298
|
-
'TSTypeAliasDeclaration',
|
|
299
|
-
'TSTypeAnnotation',
|
|
300
|
-
'TSTypeParameterDeclaration',
|
|
301
|
-
'TSTypeParameterInstantiation',
|
|
302
|
-
'TSTypeQuery',
|
|
303
|
-
])
|
|
304
|
-
|
|
305
|
-
Walker.walk(program, {
|
|
306
|
-
enter(node, parent) {
|
|
307
|
-
const declaration = staticData.visitor.enter(node, parent)
|
|
308
|
-
ancestors.push(node)
|
|
309
|
-
if (
|
|
310
|
-
(parent &&
|
|
311
|
-
'typeAnnotation' in parent &&
|
|
312
|
-
parent.typeAnnotation === node) ||
|
|
313
|
-
typeNodes.has(node.type) ||
|
|
314
|
-
(node.type === 'ExportNamedDeclaration' &&
|
|
315
|
-
(node.source !== null || node.exportKind === 'type')) ||
|
|
316
|
-
(node.type === 'ExportSpecifier' && node.exportKind === 'type')
|
|
317
|
-
)
|
|
318
|
-
typeAncestors.add(node)
|
|
319
|
-
|
|
320
|
-
if (
|
|
321
|
-
(node.type !== 'Identifier' && node.type !== 'JSXIdentifier') ||
|
|
322
|
-
!parent ||
|
|
323
|
-
(node.type === 'Identifier'
|
|
324
|
-
? declaration === undefined
|
|
325
|
-
: !Walker.isReferenceIdentifier(node, parent))
|
|
326
|
-
)
|
|
327
|
-
return
|
|
328
|
-
|
|
329
|
-
// Both passes visit identical scopes; skipping type subtrees changes scope IDs.
|
|
330
|
-
if (typeAncestors.size) return
|
|
331
|
-
|
|
332
|
-
const binding =
|
|
333
|
-
node.type === 'Identifier'
|
|
334
|
-
? (declaration ?? null)
|
|
335
|
-
: scopeTracker.getDeclaration(node.name)
|
|
336
|
-
|
|
337
|
-
contributions.read(node, parent, binding)
|
|
338
|
-
|
|
339
|
-
try {
|
|
340
|
-
if (variables.reference(node, parent, ancestors, binding)) return
|
|
341
|
-
} catch (error) {
|
|
342
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
343
|
-
|
|
344
|
-
report('unsupported_syntax', error.message, error)
|
|
345
|
-
|
|
346
|
-
return
|
|
347
|
-
}
|
|
348
|
-
|
|
349
|
-
if (themes)
|
|
350
|
-
try {
|
|
351
|
-
if (
|
|
352
|
-
themes.reference(
|
|
353
|
-
node,
|
|
354
|
-
parent,
|
|
355
|
-
ancestors,
|
|
356
|
-
binding,
|
|
357
|
-
(name) => scopeTracker.getDeclaration(name) ?? null,
|
|
358
|
-
)
|
|
359
|
-
)
|
|
360
|
-
return
|
|
361
|
-
} catch (error) {
|
|
362
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
363
|
-
|
|
364
|
-
report('unsupported_syntax', error.message, error)
|
|
365
|
-
|
|
366
|
-
return
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
if (
|
|
370
|
-
binding?.type !== 'Import' ||
|
|
371
|
-
binding.importNode.source.value !== 'zyzz' ||
|
|
372
|
-
binding.importNode.importKind === 'type'
|
|
373
|
-
)
|
|
374
|
-
return
|
|
375
|
-
|
|
376
|
-
const specifier = binding.node
|
|
377
|
-
|
|
378
|
-
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
379
|
-
if (parent.type === 'MemberExpression' && parent.object === node) {
|
|
380
|
-
const name = (() => {
|
|
381
|
-
if (parent.property.type === 'Identifier' && !parent.computed) {
|
|
382
|
-
return parent.property.name
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
if (parent.property.type === 'Literal') {
|
|
386
|
-
return parent.property.value
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
return undefined
|
|
390
|
-
})()
|
|
391
|
-
|
|
392
|
-
if (
|
|
393
|
-
name === 'Config' ||
|
|
394
|
-
name === 'cx' ||
|
|
395
|
-
name === 'defineConfig' ||
|
|
396
|
-
name === 'defineVars' ||
|
|
397
|
-
name === 'extendVars' ||
|
|
398
|
-
name === 'style' ||
|
|
399
|
-
name === 'Theme' ||
|
|
400
|
-
name === 'Vars' ||
|
|
401
|
-
name === 'variable' ||
|
|
402
|
-
name === 'variants'
|
|
403
|
-
)
|
|
404
|
-
report(
|
|
405
|
-
'unsupported_syntax',
|
|
406
|
-
`Import ${name} by name; namespace authoring calls are not supported yet.`,
|
|
407
|
-
parent,
|
|
408
|
-
)
|
|
409
|
-
}
|
|
410
|
-
|
|
411
|
-
return
|
|
412
|
-
}
|
|
413
|
-
|
|
414
|
-
if (
|
|
415
|
-
specifier.type !== 'ImportSpecifier' ||
|
|
416
|
-
specifier.importKind === 'type' ||
|
|
417
|
-
!['style', 'variants'].includes(
|
|
418
|
-
specifier.imported.type === 'Identifier'
|
|
419
|
-
? specifier.imported.name
|
|
420
|
-
: specifier.imported.value,
|
|
421
|
-
)
|
|
422
|
-
)
|
|
423
|
-
return
|
|
424
|
-
|
|
425
|
-
// Follow only assignment targets; computed keys and default values are reads.
|
|
426
|
-
let target: Ast.Node = node
|
|
427
|
-
let write: Ast.Node | undefined
|
|
428
|
-
|
|
429
|
-
for (let index = ancestors.length - 2; index >= 0; index--) {
|
|
430
|
-
const ancestor = ancestors[index]!
|
|
431
|
-
|
|
432
|
-
if (
|
|
433
|
-
(ancestor.type === 'AssignmentExpression' &&
|
|
434
|
-
ancestor.left === target) ||
|
|
435
|
-
(ancestor.type === 'UpdateExpression' &&
|
|
436
|
-
ancestor.argument === target) ||
|
|
437
|
-
((ancestor.type === 'ForInStatement' ||
|
|
438
|
-
ancestor.type === 'ForOfStatement') &&
|
|
439
|
-
ancestor.left === target)
|
|
440
|
-
) {
|
|
441
|
-
write = ancestor
|
|
442
|
-
break
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
if (
|
|
446
|
-
(ancestor.type === 'Property' && ancestor.value === target) ||
|
|
447
|
-
ancestor.type === 'ObjectPattern' ||
|
|
448
|
-
ancestor.type === 'ArrayPattern' ||
|
|
449
|
-
(ancestor.type === 'RestElement' && ancestor.argument === target) ||
|
|
450
|
-
(ancestor.type === 'AssignmentPattern' && ancestor.left === target)
|
|
451
|
-
)
|
|
452
|
-
target = ancestor
|
|
453
|
-
else break
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
if (write)
|
|
457
|
-
report(
|
|
458
|
-
'unsupported_syntax',
|
|
459
|
-
'Imported style bindings cannot be reassigned.',
|
|
460
|
-
write,
|
|
461
|
-
)
|
|
462
|
-
else if (
|
|
463
|
-
parent.type === 'CallExpression' &&
|
|
464
|
-
parent.callee === node &&
|
|
465
|
-
!parent.optional
|
|
466
|
-
) {
|
|
467
|
-
pending.push(parent)
|
|
468
|
-
if (
|
|
469
|
-
(specifier.imported.type === 'Identifier'
|
|
470
|
-
? specifier.imported.name
|
|
471
|
-
: specifier.imported.value) === 'variants'
|
|
472
|
-
)
|
|
473
|
-
recipes.add(parent.start)
|
|
474
|
-
} else
|
|
475
|
-
report(
|
|
476
|
-
'unsupported_syntax',
|
|
477
|
-
'Use a direct style call; aliases, re-exports, and indirect references are not supported yet.',
|
|
478
|
-
node,
|
|
479
|
-
)
|
|
480
|
-
},
|
|
481
|
-
leave(node) {
|
|
482
|
-
ancestors.pop()
|
|
483
|
-
typeAncestors.delete(node)
|
|
484
|
-
staticData.visitor.leave()
|
|
485
|
-
},
|
|
486
|
-
scopeTracker,
|
|
487
|
-
})
|
|
488
|
-
|
|
489
|
-
Contributions.resolve(contributions)
|
|
490
|
-
|
|
491
|
-
// Imports and reference lists can have a different order from authored calls.
|
|
492
|
-
if (themes)
|
|
493
|
-
for (const entry of themes.styles.values()) {
|
|
494
|
-
pending.push(entry.call)
|
|
495
|
-
if (entry.recipe) recipes.add(entry.call.start)
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
pending.sort((a, b) => a.start - b.start)
|
|
499
|
-
|
|
500
|
-
const staticCalls = new Set([
|
|
501
|
-
...pending.map((call) => call.start),
|
|
502
|
-
...contributions.calls.map((call) => call.start),
|
|
503
|
-
])
|
|
504
|
-
const opaque = new Set(variables.references.keys())
|
|
505
|
-
const normalized = new Map<number, Ast.Node | Error>()
|
|
506
|
-
const selectorKeys = new Set<number>()
|
|
507
|
-
const composed: Ast.Node[] = []
|
|
508
|
-
for (const call of pending) {
|
|
509
|
-
if (!call.arguments[0]) continue
|
|
510
|
-
try {
|
|
511
|
-
const value = staticData.normalize(call.arguments[0], staticCalls, opaque)
|
|
512
|
-
normalized.set(call.start, value)
|
|
513
|
-
if (value.type === 'ArrayExpression')
|
|
514
|
-
for (const element of value.elements) {
|
|
515
|
-
const entry = element && Expression.unwrap(element)
|
|
516
|
-
if (
|
|
517
|
-
entry?.type === 'Identifier' ||
|
|
518
|
-
entry?.type === 'MemberExpression'
|
|
519
|
-
)
|
|
520
|
-
composed.push(entry)
|
|
521
|
-
}
|
|
522
|
-
const body =
|
|
523
|
-
value.type === 'ArrowFunctionExpression'
|
|
524
|
-
? staticData.normalize(value.body, staticCalls, opaque)
|
|
525
|
-
: value
|
|
526
|
-
|
|
527
|
-
Walker.walk(body, {
|
|
528
|
-
enter(node) {
|
|
529
|
-
if (
|
|
530
|
-
node.type !== 'Property' ||
|
|
531
|
-
node.computed ||
|
|
532
|
-
node.value.type !== 'ObjectExpression' ||
|
|
533
|
-
!(
|
|
534
|
-
(node.key.type === 'Identifier' &&
|
|
535
|
-
node.key.name === 'selectors') ||
|
|
536
|
-
(node.key.type === 'Literal' && node.key.value === 'selectors')
|
|
537
|
-
)
|
|
538
|
-
)
|
|
539
|
-
return
|
|
540
|
-
|
|
541
|
-
for (const property of node.value.properties)
|
|
542
|
-
if (property.type === 'Property')
|
|
543
|
-
selectorKeys.add(property.key.start)
|
|
544
|
-
},
|
|
545
|
-
})
|
|
546
|
-
} catch (error) {
|
|
547
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
548
|
-
normalized.set(call.start, error)
|
|
549
|
-
}
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
for (const call of pending) {
|
|
553
|
-
try {
|
|
554
|
-
Identifiers.explicit(call)
|
|
555
|
-
} catch (error) {
|
|
556
|
-
report('unsupported_syntax', (error as Error).message, call)
|
|
557
|
-
}
|
|
558
|
-
}
|
|
559
|
-
if (diagnostics.length) throw new ExtractError(diagnostics)
|
|
560
|
-
|
|
561
|
-
const selectors = (() => {
|
|
562
|
-
try {
|
|
563
|
-
return Selectors.scan(
|
|
564
|
-
program,
|
|
565
|
-
scopeTracker,
|
|
566
|
-
namespace,
|
|
567
|
-
pending,
|
|
568
|
-
options[Themes.context]?.links,
|
|
569
|
-
selectorKeys,
|
|
570
|
-
new Map(
|
|
571
|
-
[...(themes?.styles ?? [])].flatMap(([start, context]) => {
|
|
572
|
-
const id = context.theme[Token.definition].contract[Token.identity]
|
|
573
|
-
return id?.startsWith('id-') ? [[start, id.slice(3)] as const] : []
|
|
574
|
-
}),
|
|
575
|
-
),
|
|
576
|
-
options.moduleId,
|
|
577
|
-
composed,
|
|
578
|
-
)
|
|
579
|
-
} catch (error) {
|
|
580
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
581
|
-
|
|
582
|
-
report('unsupported_syntax', error.message, error)
|
|
583
|
-
throw new ExtractError(diagnostics)
|
|
584
|
-
}
|
|
585
|
-
})()
|
|
586
|
-
|
|
587
|
-
const bodies = new Map<number, Ast.ObjectExpression>()
|
|
588
|
-
const cssNameCounts = new Map<string, number>()
|
|
589
|
-
for (const call of pending) {
|
|
590
|
-
const name = authoredNames.get(call.start)!
|
|
591
|
-
cssNameCounts.set(name, (cssNameCounts.get(name) ?? 0) + 1)
|
|
592
|
-
}
|
|
593
|
-
const cssNameIndices = new Map<string, number>()
|
|
594
|
-
for (const [callIndex, call] of pending.entries()) {
|
|
595
|
-
const explicitId = (() => {
|
|
596
|
-
try {
|
|
597
|
-
return Identifiers.explicit(call)
|
|
598
|
-
} catch (error) {
|
|
599
|
-
report('unsupported_syntax', (error as Error).message, call)
|
|
600
|
-
return undefined
|
|
601
|
-
}
|
|
602
|
-
})()
|
|
603
|
-
const contractIdentity = themes?.styles.get(call.start)?.theme[
|
|
604
|
-
Token.definition
|
|
605
|
-
].contract[Token.identity]
|
|
606
|
-
const cssNamespace = contractIdentity?.startsWith('id-')
|
|
607
|
-
? contractIdentity.slice(3)
|
|
608
|
-
: undefined
|
|
609
|
-
const authoredName = authoredNames.get(call.start)!
|
|
610
|
-
const nameIndex = cssNameIndices.get(authoredName) ?? 0
|
|
611
|
-
cssNameIndices.set(authoredName, nameIndex + 1)
|
|
612
|
-
const cssName =
|
|
613
|
-
explicitId !== undefined
|
|
614
|
-
? Identity.name(explicitId)
|
|
615
|
-
: `${Identity.compact(options.moduleId).slice(-6)}-${
|
|
616
|
-
authoredName === 'style'
|
|
617
|
-
? `style-${callIndex}`
|
|
618
|
-
: cssNameCounts.get(authoredName)! > 1
|
|
619
|
-
? `${authoredName}-${nameIndex}`
|
|
620
|
-
: authoredName
|
|
621
|
-
}`
|
|
622
|
-
const definitionId =
|
|
623
|
-
explicitId === undefined
|
|
624
|
-
? `${cssNamespace ? `${cssNamespace}-` : ''}${cssName}`
|
|
625
|
-
: `id-${cssNamespace ? `${cssNamespace}-` : ''}${Identity.requireId(explicitId, 'style').slice(3)}`
|
|
626
|
-
let argument = call.arguments[0]
|
|
627
|
-
|
|
628
|
-
if (call.arguments.length === 0)
|
|
629
|
-
argument = {
|
|
630
|
-
end: call.end - 1,
|
|
631
|
-
properties: [],
|
|
632
|
-
start: call.end - 1,
|
|
633
|
-
type: 'ObjectExpression',
|
|
634
|
-
}
|
|
635
|
-
|
|
636
|
-
while (
|
|
637
|
-
argument?.type === 'TSAsExpression' ||
|
|
638
|
-
argument?.type === 'TSSatisfiesExpression'
|
|
639
|
-
)
|
|
640
|
-
argument = argument.expression
|
|
641
|
-
|
|
642
|
-
const original = argument
|
|
643
|
-
|
|
644
|
-
try {
|
|
645
|
-
const value = normalized.get(call.start)
|
|
646
|
-
if (value instanceof Error) throw value
|
|
647
|
-
if (value) argument = value as Ast.Expression
|
|
648
|
-
} catch (error) {
|
|
649
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
650
|
-
|
|
651
|
-
report('unsupported_syntax', error.message, error)
|
|
652
|
-
continue
|
|
653
|
-
}
|
|
654
|
-
|
|
655
|
-
const diagnosticCount = diagnostics.length
|
|
656
|
-
|
|
657
|
-
const dynamic = (() => {
|
|
658
|
-
if (!argument) return undefined
|
|
659
|
-
|
|
660
|
-
try {
|
|
661
|
-
return Dynamic.read(argument, definitionId, staticData.type)
|
|
662
|
-
} catch (error) {
|
|
663
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
664
|
-
|
|
665
|
-
report('unsupported_syntax', error.message, error)
|
|
666
|
-
|
|
667
|
-
return undefined
|
|
668
|
-
}
|
|
669
|
-
})()
|
|
670
|
-
if (diagnostics.length !== diagnosticCount) continue
|
|
671
|
-
|
|
672
|
-
let dynamicValues: RecipePayloads.Bindings | undefined = dynamic
|
|
673
|
-
|
|
674
|
-
function resolveDynamic(node: Ast.Node) {
|
|
675
|
-
try {
|
|
676
|
-
return dynamicValues?.resolve(node)
|
|
677
|
-
} catch (error) {
|
|
678
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
679
|
-
|
|
680
|
-
report('unsupported_syntax', error.message, error)
|
|
681
|
-
|
|
682
|
-
return undefined
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
|
|
686
|
-
if (dynamic) {
|
|
687
|
-
try {
|
|
688
|
-
argument = staticData.normalize(
|
|
689
|
-
dynamic.body,
|
|
690
|
-
staticCalls,
|
|
691
|
-
opaque,
|
|
692
|
-
) as Ast.Expression
|
|
693
|
-
} catch (error) {
|
|
694
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
695
|
-
|
|
696
|
-
report('unsupported_syntax', error.message, error)
|
|
697
|
-
continue
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
const entries =
|
|
702
|
-
argument?.type === 'ArrayExpression' &&
|
|
703
|
-
!dynamic &&
|
|
704
|
-
!recipes.has(call.start)
|
|
705
|
-
? argument.elements
|
|
706
|
-
: undefined
|
|
707
|
-
|
|
708
|
-
if (
|
|
709
|
-
call.arguments.length > 2 ||
|
|
710
|
-
(argument?.type !== 'ObjectExpression' && !entries)
|
|
711
|
-
) {
|
|
712
|
-
report(
|
|
713
|
-
'unsupported_syntax',
|
|
714
|
-
'Expected one literal object, typed callback, or array of style definitions and literal objects; spreads are not supported.',
|
|
715
|
-
call,
|
|
716
|
-
)
|
|
717
|
-
continue
|
|
718
|
-
}
|
|
719
|
-
|
|
720
|
-
const before = diagnostics.length
|
|
721
|
-
let recipe: Recipe.Definition | undefined
|
|
722
|
-
let recipeTypes: Call['recipeTypes']
|
|
723
|
-
let staticRecipe: StaticRecipe.Definition<Ast.ObjectExpression> | undefined
|
|
724
|
-
let dynamicRecipe: StaticRecipe.Definition<Ast.ObjectExpression> | undefined
|
|
725
|
-
if (recipes.has(call.start) && argument?.type === 'ObjectExpression') {
|
|
726
|
-
try {
|
|
727
|
-
if (dynamic)
|
|
728
|
-
throw new Themes.InvalidError(
|
|
729
|
-
'Recipes require static top-level objects.',
|
|
730
|
-
original ?? call,
|
|
731
|
-
)
|
|
732
|
-
const expanded = Recipes.expand(argument, {
|
|
733
|
-
identity: definitionId,
|
|
734
|
-
normalize: (node) => staticData.normalize(node, staticCalls, opaque),
|
|
735
|
-
queries: themes?.styles.get(call.start)?.theme[Token.definition]
|
|
736
|
-
.queries,
|
|
737
|
-
resolveType: staticData.type,
|
|
738
|
-
source: options.source,
|
|
739
|
-
})
|
|
740
|
-
argument = expanded.body
|
|
741
|
-
recipe = expanded.recipe
|
|
742
|
-
staticRecipe = expanded.staticRecipe
|
|
743
|
-
dynamicRecipe = expanded.dynamicRecipe
|
|
744
|
-
recipeTypes = expanded.types
|
|
745
|
-
dynamicValues = expanded.bindings
|
|
746
|
-
} catch (error) {
|
|
747
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
748
|
-
report('unsupported_syntax', error.message, error)
|
|
749
|
-
continue
|
|
750
|
-
}
|
|
751
|
-
}
|
|
752
|
-
const name = `style-${namespace}-${call.start}`
|
|
753
|
-
const locations: Style.SourceLocation[] = []
|
|
754
|
-
const typography = new Map<number, number>()
|
|
755
|
-
const typographyQueries = new Map<number, number>()
|
|
756
|
-
const conditionKeys = new Map<string, Ast.Node>()
|
|
757
|
-
|
|
758
|
-
function object(
|
|
759
|
-
argument: Ast.ObjectExpression,
|
|
760
|
-
prefix: readonly string[] = [],
|
|
761
|
-
): Record<string, unknown> {
|
|
762
|
-
const values: Record<string, unknown> = Object.create(null)
|
|
763
|
-
const target = prefix.lastIndexOf('targets')
|
|
764
|
-
if (target !== -1 && prefix.length > 64) {
|
|
765
|
-
report(
|
|
766
|
-
'unsupported_syntax',
|
|
767
|
-
'Target nesting exceeds 64 levels.',
|
|
768
|
-
argument,
|
|
769
|
-
)
|
|
770
|
-
return values
|
|
771
|
-
}
|
|
772
|
-
const depth = prefix.length + 2
|
|
773
|
-
|
|
774
|
-
function localSlot(node: Ast.Node) {
|
|
775
|
-
const slot = resolveDynamic(node)
|
|
776
|
-
|
|
777
|
-
if (
|
|
778
|
-
slot &&
|
|
779
|
-
prefix.some(
|
|
780
|
-
(key) =>
|
|
781
|
-
!Condition.local(key) && !selectors.localConditions.has(key),
|
|
782
|
-
)
|
|
783
|
-
) {
|
|
784
|
-
report(
|
|
785
|
-
'unsupported_syntax',
|
|
786
|
-
'Dynamic values require conditions that select the styled element.',
|
|
787
|
-
node,
|
|
788
|
-
)
|
|
789
|
-
|
|
790
|
-
return undefined
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
return slot
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
const properties: Ast.ObjectExpression['properties'] = []
|
|
797
|
-
for (const entry of argument.properties) {
|
|
798
|
-
const key =
|
|
799
|
-
entry.type === 'Property' && !entry.computed
|
|
800
|
-
? entry.key.type === 'Identifier'
|
|
801
|
-
? entry.key.name
|
|
802
|
-
: entry.key.type === 'Literal'
|
|
803
|
-
? entry.key.value
|
|
804
|
-
: undefined
|
|
805
|
-
: undefined
|
|
806
|
-
if (key !== 'selectors' && key !== 'vars') {
|
|
807
|
-
properties.push(entry)
|
|
808
|
-
continue
|
|
809
|
-
}
|
|
810
|
-
if (
|
|
811
|
-
entry.type !== 'Property' ||
|
|
812
|
-
entry.kind !== 'init' ||
|
|
813
|
-
entry.method ||
|
|
814
|
-
entry.shorthand ||
|
|
815
|
-
entry.value.type !== 'ObjectExpression'
|
|
816
|
-
) {
|
|
817
|
-
report(
|
|
818
|
-
'unsupported_syntax',
|
|
819
|
-
`${key} requires an explicit literal object.`,
|
|
820
|
-
entry,
|
|
821
|
-
)
|
|
822
|
-
continue
|
|
823
|
-
}
|
|
824
|
-
for (const property of entry.value.properties) {
|
|
825
|
-
if (
|
|
826
|
-
property.type !== 'Property' ||
|
|
827
|
-
(key === 'selectors'
|
|
828
|
-
? !selectors.conditions.has(property.key.start)
|
|
829
|
-
: !property.computed ||
|
|
830
|
-
!variables.references.has(property.key.start))
|
|
831
|
-
) {
|
|
832
|
-
report(
|
|
833
|
-
'unsupported_syntax',
|
|
834
|
-
key === 'selectors'
|
|
835
|
-
? 'Selectors require explicit & targets.'
|
|
836
|
-
: 'Variable assignments require declared variable keys.',
|
|
837
|
-
property,
|
|
838
|
-
)
|
|
839
|
-
continue
|
|
840
|
-
}
|
|
841
|
-
properties.push(property)
|
|
842
|
-
}
|
|
843
|
-
}
|
|
844
|
-
|
|
845
|
-
for (const property of properties) {
|
|
846
|
-
if (
|
|
847
|
-
property.type !== 'Property' ||
|
|
848
|
-
property.kind !== 'init' ||
|
|
849
|
-
property.method ||
|
|
850
|
-
(property.computed &&
|
|
851
|
-
!selectors.conditions.has(property.key.start) &&
|
|
852
|
-
!variables.references.has(property.key.start) &&
|
|
853
|
-
!contributions.queryKeys.has(property.key.start)) ||
|
|
854
|
-
property.shorthand ||
|
|
855
|
-
(!selectors.conditions.has(property.key.start) &&
|
|
856
|
-
!variables.references.has(property.key.start) &&
|
|
857
|
-
property.key.type !== 'Identifier' &&
|
|
858
|
-
(property.key.type !== 'Literal' ||
|
|
859
|
-
typeof property.key.value !== 'string'))
|
|
860
|
-
) {
|
|
861
|
-
report(
|
|
862
|
-
'unsupported_syntax',
|
|
863
|
-
(() => {
|
|
864
|
-
const key =
|
|
865
|
-
property.type === 'Property' && property.computed
|
|
866
|
-
? Expression.unwrap(property.key)
|
|
867
|
-
: undefined
|
|
868
|
-
|
|
869
|
-
// Template keys with an & target are selectors outside their group.
|
|
870
|
-
return key?.type === 'TemplateLiteral' &&
|
|
871
|
-
key.quasis.some((quasi) => quasi.value.raw.includes('&'))
|
|
872
|
-
? 'Template selector keys require a selectors object.'
|
|
873
|
-
: 'Only explicit literal properties are supported; spreads, computed keys, shorthand, and methods are not evaluated.'
|
|
874
|
-
})(),
|
|
875
|
-
property,
|
|
876
|
-
)
|
|
877
|
-
continue
|
|
878
|
-
}
|
|
879
|
-
|
|
880
|
-
const key =
|
|
881
|
-
variables.references.get(property.key.start)?.reference.name ??
|
|
882
|
-
selectors.conditions.get(property.key.start) ??
|
|
883
|
-
contributions.queryKeys.get(property.key.start) ??
|
|
884
|
-
(property.key.type === 'Identifier'
|
|
885
|
-
? property.key.name
|
|
886
|
-
: property.key.type === 'Literal'
|
|
887
|
-
? String(property.key.value)
|
|
888
|
-
: '')
|
|
889
|
-
|
|
890
|
-
if (Object.hasOwn(values, key)) {
|
|
891
|
-
report(
|
|
892
|
-
'unsupported_syntax',
|
|
893
|
-
'Duplicate properties are not supported in source definitions yet.',
|
|
894
|
-
property,
|
|
895
|
-
)
|
|
896
|
-
continue
|
|
897
|
-
}
|
|
898
|
-
|
|
899
|
-
if (
|
|
900
|
-
(key === 'targets' || target !== -1) &&
|
|
901
|
-
staticData.absent(property.value)
|
|
902
|
-
)
|
|
903
|
-
continue
|
|
904
|
-
|
|
905
|
-
if (key === 'targets' || prefix.at(-1) === 'targets') {
|
|
906
|
-
const input = Expression.unwrap(property.value)
|
|
907
|
-
if (input.type !== 'ObjectExpression') {
|
|
908
|
-
report(
|
|
909
|
-
'unsupported_syntax',
|
|
910
|
-
'Target branches require static declaration objects.',
|
|
911
|
-
input,
|
|
912
|
-
)
|
|
913
|
-
continue
|
|
914
|
-
}
|
|
915
|
-
values[key] = object(input, [...prefix, key])
|
|
916
|
-
continue
|
|
917
|
-
}
|
|
918
|
-
if (target !== -1 && prefix[target + 1] !== 'web') {
|
|
919
|
-
function nativeValue(input: Ast.Node, depth = 0): unknown {
|
|
920
|
-
const node = Expression.unwrap(input)
|
|
921
|
-
if (depth > 64) {
|
|
922
|
-
report(
|
|
923
|
-
'unsupported_syntax',
|
|
924
|
-
'Native value nesting exceeds 64 levels.',
|
|
925
|
-
node,
|
|
926
|
-
)
|
|
927
|
-
return undefined
|
|
928
|
-
}
|
|
929
|
-
if (node.type === 'ObjectExpression')
|
|
930
|
-
return object(node, [...prefix, key])
|
|
931
|
-
if (node.type === 'ArrayExpression')
|
|
932
|
-
return node.elements.map((entry) => {
|
|
933
|
-
if (!entry || entry.type === 'SpreadElement') {
|
|
934
|
-
report(
|
|
935
|
-
'unsupported_syntax',
|
|
936
|
-
'Native arrays require dense static entries.',
|
|
937
|
-
node,
|
|
938
|
-
)
|
|
939
|
-
return undefined
|
|
940
|
-
}
|
|
941
|
-
return nativeValue(entry, depth + 1)
|
|
942
|
-
})
|
|
943
|
-
if (
|
|
944
|
-
node.type === 'Literal' &&
|
|
945
|
-
(node.value === null ||
|
|
946
|
-
['boolean', 'number', 'string'].includes(typeof node.value))
|
|
947
|
-
)
|
|
948
|
-
return node.value
|
|
949
|
-
if (
|
|
950
|
-
node.type === 'UnaryExpression' &&
|
|
951
|
-
['+', '-'].includes(node.operator) &&
|
|
952
|
-
node.argument.type === 'Literal' &&
|
|
953
|
-
typeof node.argument.value === 'number'
|
|
954
|
-
)
|
|
955
|
-
return (node.operator === '-' ? -1 : 1) * node.argument.value
|
|
956
|
-
if (node.type === 'TemplateLiteral') {
|
|
957
|
-
const value = Expression.template(node)
|
|
958
|
-
if (typeof value === 'string') return value
|
|
959
|
-
}
|
|
960
|
-
report(
|
|
961
|
-
'unsupported_syntax',
|
|
962
|
-
'Native branches require static literal values.',
|
|
963
|
-
node,
|
|
964
|
-
)
|
|
965
|
-
return undefined
|
|
966
|
-
}
|
|
967
|
-
values[key] = nativeValue(property.value)
|
|
968
|
-
continue
|
|
969
|
-
}
|
|
970
|
-
if (Condition.is(key)) {
|
|
971
|
-
conditionKeys.set(
|
|
972
|
-
JSON.stringify([name, ...prefix, key]),
|
|
973
|
-
property.key,
|
|
974
|
-
)
|
|
975
|
-
|
|
976
|
-
const input = Expression.unwrap(property.value)
|
|
977
|
-
|
|
978
|
-
if (input.type !== 'ObjectExpression') {
|
|
979
|
-
report(
|
|
980
|
-
'unsupported_syntax',
|
|
981
|
-
'Conditions require literal declaration objects.',
|
|
982
|
-
input,
|
|
983
|
-
)
|
|
984
|
-
continue
|
|
985
|
-
}
|
|
986
|
-
|
|
987
|
-
locations.push({
|
|
988
|
-
source: options.moduleId,
|
|
989
|
-
start: property.start,
|
|
990
|
-
end: property.end,
|
|
991
|
-
path: [name, ...prefix, key],
|
|
992
|
-
})
|
|
993
|
-
values[key] = object(input, [...prefix, key])
|
|
994
|
-
continue
|
|
995
|
-
}
|
|
996
|
-
|
|
997
|
-
const targets = themes?.styles.get(call.start)?.theme[Token.definition]
|
|
998
|
-
.contract.shorthands?.[key] ?? [key as Style.Declaration['property']]
|
|
999
|
-
|
|
1000
|
-
function value(node: Ast.Node, path: readonly string[]): unknown {
|
|
1001
|
-
const unwrapped = Expression.unwrap(node)
|
|
1002
|
-
const token =
|
|
1003
|
-
variables.references.get(unwrapped.start) ??
|
|
1004
|
-
themes?.tokens.get(unwrapped.start)
|
|
1005
|
-
const reference =
|
|
1006
|
-
localSlot(node) ??
|
|
1007
|
-
(token && token.end === unwrapped.end ? token.reference : undefined)
|
|
1008
|
-
|
|
1009
|
-
if (
|
|
1010
|
-
dynamicValues &&
|
|
1011
|
-
reference &&
|
|
1012
|
-
Object.values(dynamicValues.slots).includes(
|
|
1013
|
-
reference as Binding.Reference,
|
|
1014
|
-
) &&
|
|
1015
|
-
path.length > depth
|
|
1016
|
-
) {
|
|
1017
|
-
report(
|
|
1018
|
-
'unsupported_syntax',
|
|
1019
|
-
'Dynamic fallback entries are not supported.',
|
|
1020
|
-
node,
|
|
1021
|
-
)
|
|
1022
|
-
|
|
1023
|
-
return undefined
|
|
1024
|
-
}
|
|
1025
|
-
|
|
1026
|
-
node = Expression.unwrap(node)
|
|
1027
|
-
|
|
1028
|
-
const animation = contributions.references.get(node.start)
|
|
1029
|
-
if (animation) {
|
|
1030
|
-
const kind = contributions.kinds.get(animation)
|
|
1031
|
-
if (
|
|
1032
|
-
kind &&
|
|
1033
|
-
targets.some((target) => !RuleReference.accepts(kind, target))
|
|
1034
|
-
) {
|
|
1035
|
-
report(
|
|
1036
|
-
'unsupported_syntax',
|
|
1037
|
-
'Named stylesheet reference is incompatible with this property.',
|
|
1038
|
-
node,
|
|
1039
|
-
)
|
|
1040
|
-
return undefined
|
|
1041
|
-
}
|
|
1042
|
-
return animation
|
|
1043
|
-
}
|
|
1044
|
-
|
|
1045
|
-
const template =
|
|
1046
|
-
node.type === 'TemplateLiteral'
|
|
1047
|
-
? Expression.template(node, 0, (expression, prefix) => {
|
|
1048
|
-
const animation = contributions.references.get(
|
|
1049
|
-
Expression.unwrap(expression).start,
|
|
1050
|
-
)
|
|
1051
|
-
if (animation) {
|
|
1052
|
-
const kind = contributions.kinds.get(animation)
|
|
1053
|
-
if (
|
|
1054
|
-
kind &&
|
|
1055
|
-
targets.some(
|
|
1056
|
-
(target) =>
|
|
1057
|
-
!RuleReference.acceptsExpression(
|
|
1058
|
-
kind,
|
|
1059
|
-
target,
|
|
1060
|
-
prefix,
|
|
1061
|
-
),
|
|
1062
|
-
)
|
|
1063
|
-
) {
|
|
1064
|
-
report(
|
|
1065
|
-
'unsupported_syntax',
|
|
1066
|
-
'Named stylesheet reference is incompatible with this property.',
|
|
1067
|
-
expression,
|
|
1068
|
-
)
|
|
1069
|
-
return undefined
|
|
1070
|
-
}
|
|
1071
|
-
return animation
|
|
1072
|
-
}
|
|
1073
|
-
|
|
1074
|
-
const token =
|
|
1075
|
-
variables.references.get(expression.start) ??
|
|
1076
|
-
themes?.tokens.get(expression.start)
|
|
1077
|
-
const slot = localSlot(expression)
|
|
1078
|
-
|
|
1079
|
-
if (slot) {
|
|
1080
|
-
if (path.length > depth) {
|
|
1081
|
-
report(
|
|
1082
|
-
'unsupported_syntax',
|
|
1083
|
-
'Dynamic fallback entries are not supported.',
|
|
1084
|
-
expression,
|
|
1085
|
-
)
|
|
1086
|
-
|
|
1087
|
-
return undefined
|
|
1088
|
-
}
|
|
1089
|
-
|
|
1090
|
-
return slot
|
|
1091
|
-
}
|
|
1092
|
-
|
|
1093
|
-
return token?.end === expression.end
|
|
1094
|
-
? token.reference
|
|
1095
|
-
: undefined
|
|
1096
|
-
})
|
|
1097
|
-
: undefined
|
|
1098
|
-
|
|
1099
|
-
if (Token.isExpression(template)) {
|
|
1100
|
-
for (const part of template.parts) {
|
|
1101
|
-
if (
|
|
1102
|
-
typeof part !== 'string' &&
|
|
1103
|
-
!(Binding.is(part)
|
|
1104
|
-
? (dynamicValues !== undefined &&
|
|
1105
|
-
Object.values(dynamicValues.slots).includes(part)) ||
|
|
1106
|
-
targets.every(
|
|
1107
|
-
(target) =>
|
|
1108
|
-
Binding.accepts(part.type, target) ||
|
|
1109
|
-
(part.type === 'color' &&
|
|
1110
|
-
Expression.acceptsColor(template, target)),
|
|
1111
|
-
)
|
|
1112
|
-
: targets.every(
|
|
1113
|
-
(target) =>
|
|
1114
|
-
Token.acceptsReference(part, target) ||
|
|
1115
|
-
(part.contract.variableSet &&
|
|
1116
|
-
Expression.acceptsVariables(template, target)) ||
|
|
1117
|
-
(part.group === 'color' &&
|
|
1118
|
-
Expression.acceptsColor(template, target)),
|
|
1119
|
-
))
|
|
1120
|
-
) {
|
|
1121
|
-
report(
|
|
1122
|
-
'unsupported_syntax',
|
|
1123
|
-
Binding.is(part)
|
|
1124
|
-
? 'Variable domain is incompatible with this property.'
|
|
1125
|
-
: 'Theme variable domain is incompatible with this property.',
|
|
1126
|
-
node,
|
|
1127
|
-
)
|
|
1128
|
-
|
|
1129
|
-
return undefined
|
|
1130
|
-
}
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
if (
|
|
1135
|
-
reference &&
|
|
1136
|
-
Token.is(reference) &&
|
|
1137
|
-
!targets.every((target) =>
|
|
1138
|
-
Token.acceptsReference(reference, target),
|
|
1139
|
-
) &&
|
|
1140
|
-
!targets.every((target) =>
|
|
1141
|
-
dynamicValues?.accepts(
|
|
1142
|
-
reference as unknown as Binding.Reference,
|
|
1143
|
-
target,
|
|
1144
|
-
),
|
|
1145
|
-
)
|
|
1146
|
-
) {
|
|
1147
|
-
report(
|
|
1148
|
-
'unsupported_syntax',
|
|
1149
|
-
'Theme variable domain is incompatible with this property.',
|
|
1150
|
-
node,
|
|
1151
|
-
)
|
|
1152
|
-
|
|
1153
|
-
return undefined
|
|
1154
|
-
}
|
|
1155
|
-
|
|
1156
|
-
if (
|
|
1157
|
-
reference &&
|
|
1158
|
-
Binding.is(reference) &&
|
|
1159
|
-
!(
|
|
1160
|
-
dynamicValues &&
|
|
1161
|
-
Object.values(dynamicValues.slots).includes(reference) &&
|
|
1162
|
-
reference.type !== 'number'
|
|
1163
|
-
) &&
|
|
1164
|
-
!targets.every(
|
|
1165
|
-
(target) =>
|
|
1166
|
-
Binding.accepts(reference.type, target) ||
|
|
1167
|
-
dynamicValues?.accepts(
|
|
1168
|
-
reference as unknown as Binding.Reference,
|
|
1169
|
-
target,
|
|
1170
|
-
),
|
|
1171
|
-
)
|
|
1172
|
-
) {
|
|
1173
|
-
report(
|
|
1174
|
-
'unsupported_syntax',
|
|
1175
|
-
'Variable domain is incompatible with this property.',
|
|
1176
|
-
node,
|
|
1177
|
-
)
|
|
1178
|
-
|
|
1179
|
-
return undefined
|
|
1180
|
-
}
|
|
1181
|
-
|
|
1182
|
-
let result: unknown
|
|
1183
|
-
|
|
1184
|
-
if (reference) result = reference
|
|
1185
|
-
else if (template !== undefined) result = template
|
|
1186
|
-
else if (
|
|
1187
|
-
node.type === 'Literal' &&
|
|
1188
|
-
(typeof node.value === 'string' || typeof node.value === 'number')
|
|
1189
|
-
)
|
|
1190
|
-
result = node.value
|
|
1191
|
-
else if (
|
|
1192
|
-
node.type === 'UnaryExpression' &&
|
|
1193
|
-
(node.operator === '-' || node.operator === '+') &&
|
|
1194
|
-
node.argument.type === 'Literal' &&
|
|
1195
|
-
typeof node.argument.value === 'number'
|
|
1196
|
-
)
|
|
1197
|
-
result =
|
|
1198
|
-
node.operator === '-' ? -node.argument.value : node.argument.value
|
|
1199
|
-
else if (node.type === 'ArrayExpression' && path.length === depth) {
|
|
1200
|
-
result = node.elements.map((element, index) => {
|
|
1201
|
-
if (!element || element.type === 'SpreadElement') {
|
|
1202
|
-
report(
|
|
1203
|
-
'unsupported_syntax',
|
|
1204
|
-
'Fallback arrays require dense literal entries without spreads.',
|
|
1205
|
-
element ?? node,
|
|
1206
|
-
)
|
|
1207
|
-
|
|
1208
|
-
return undefined
|
|
1209
|
-
}
|
|
1210
|
-
|
|
1211
|
-
return value(element, [...path, String(index)])
|
|
1212
|
-
})
|
|
1213
|
-
} else {
|
|
1214
|
-
report(
|
|
1215
|
-
'unsupported_syntax',
|
|
1216
|
-
'Expected a literal string or number; expressions are not evaluated.',
|
|
1217
|
-
node,
|
|
1218
|
-
)
|
|
1219
|
-
|
|
1220
|
-
return undefined
|
|
1221
|
-
}
|
|
1222
|
-
|
|
1223
|
-
locations.push({
|
|
1224
|
-
end: node.end,
|
|
1225
|
-
path,
|
|
1226
|
-
source: options.moduleId,
|
|
1227
|
-
start: node.start,
|
|
1228
|
-
})
|
|
1229
|
-
|
|
1230
|
-
return result
|
|
1231
|
-
}
|
|
1232
|
-
|
|
1233
|
-
values[key] = value(property.value, [name, ...prefix, key])
|
|
1234
|
-
}
|
|
1235
|
-
|
|
1236
|
-
if (typeof values.typography === 'string') {
|
|
1237
|
-
const theme = themes?.styles.get(call.start)?.theme
|
|
1238
|
-
const mappings = theme?.[Token.definition].contract.shorthands
|
|
1239
|
-
const explicit = new Set(
|
|
1240
|
-
Object.keys(values).flatMap((key) => mappings?.[key] ?? [key]),
|
|
1241
|
-
)
|
|
1242
|
-
const parsed = Value.parse(values.typography, 'fontFamily')
|
|
1243
|
-
const keys = Typography.keys(
|
|
1244
|
-
theme,
|
|
1245
|
-
parsed && !('invalid' in parsed) ? parsed.value : values.typography,
|
|
1246
|
-
explicit,
|
|
1247
|
-
)
|
|
1248
|
-
const queries = keys.filter(Typography.condition).length
|
|
1249
|
-
for (const property of properties) {
|
|
1250
|
-
if (property.type !== 'Property') continue
|
|
1251
|
-
const key =
|
|
1252
|
-
property.key.type === 'Identifier'
|
|
1253
|
-
? property.key.name
|
|
1254
|
-
: property.key.type === 'Literal'
|
|
1255
|
-
? property.key.value
|
|
1256
|
-
: undefined
|
|
1257
|
-
if (key === 'typography') {
|
|
1258
|
-
typography.set(property.start, keys.length - queries)
|
|
1259
|
-
if (queries) typographyQueries.set(property.start, queries)
|
|
1260
|
-
}
|
|
1261
|
-
}
|
|
1262
|
-
}
|
|
1263
|
-
|
|
1264
|
-
return values
|
|
1265
|
-
}
|
|
1266
|
-
|
|
1267
|
-
// Each entry becomes an ordered declaration segment, so later entries win as authored declarations do.
|
|
1268
|
-
function compose(elements: Ast.ArrayExpression['elements']) {
|
|
1269
|
-
const parts: Style.NamedStyle[] = []
|
|
1270
|
-
const properties: Ast.ObjectExpression['properties'] = []
|
|
1271
|
-
|
|
1272
|
-
for (const element of elements) {
|
|
1273
|
-
const entry =
|
|
1274
|
-
element && element.type !== 'SpreadElement'
|
|
1275
|
-
? Expression.unwrap(element)
|
|
1276
|
-
: undefined
|
|
1277
|
-
|
|
1278
|
-
if (entry?.type === 'ObjectExpression') {
|
|
1279
|
-
const values = object(entry)
|
|
1280
|
-
if (diagnostics.length !== before) continue
|
|
1281
|
-
|
|
1282
|
-
parts.push(
|
|
1283
|
-
define(
|
|
1284
|
-
{ [name]: values },
|
|
1285
|
-
{ locations, vars: themes?.styles.get(call.start)?.theme },
|
|
1286
|
-
).styles[0]!,
|
|
1287
|
-
)
|
|
1288
|
-
properties.push(...entry.properties)
|
|
1289
|
-
continue
|
|
1290
|
-
}
|
|
1291
|
-
|
|
1292
|
-
const target = entry && selectors.compositions.get(entry.start)
|
|
1293
|
-
const local =
|
|
1294
|
-
target && 'type' in target
|
|
1295
|
-
? calls.find((value) => value.start === target.start)
|
|
1296
|
-
: undefined
|
|
1297
|
-
const packed = target && !('type' in target) ? target.style : undefined
|
|
1298
|
-
const style = local
|
|
1299
|
-
? styles.find((style) => style.name === local.name)
|
|
1300
|
-
: packed?.style
|
|
1301
|
-
|
|
1302
|
-
if (!style) {
|
|
1303
|
-
report(
|
|
1304
|
-
'unsupported_syntax',
|
|
1305
|
-
'Composition entries require literal objects or previously declared style definitions.',
|
|
1306
|
-
element ?? call,
|
|
1307
|
-
)
|
|
1308
|
-
continue
|
|
1309
|
-
}
|
|
1310
|
-
|
|
1311
|
-
if (
|
|
1312
|
-
local?.recipe ||
|
|
1313
|
-
local?.slots ||
|
|
1314
|
-
packed?.dynamic ||
|
|
1315
|
-
(packed?.staticRecipe &&
|
|
1316
|
-
!(
|
|
1317
|
-
packed.staticRecipe.rules.length === 1 &&
|
|
1318
|
-
packed.staticRecipe.rules[0]!.value.styles.length === 1 &&
|
|
1319
|
-
packed.staticRecipe.rules[0]!.value.styles[0]!.name ===
|
|
1320
|
-
packed.style.name
|
|
1321
|
-
))
|
|
1322
|
-
) {
|
|
1323
|
-
report(
|
|
1324
|
-
'unsupported_syntax',
|
|
1325
|
-
'Composition entries cannot be variants or dynamic styles; apply them with cx.',
|
|
1326
|
-
entry!,
|
|
1327
|
-
)
|
|
1328
|
-
continue
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
// Native tables select variable alternatives from one context per call.
|
|
1332
|
-
if (
|
|
1333
|
-
options.target === 'native' &&
|
|
1334
|
-
!context(
|
|
1335
|
-
local
|
|
1336
|
-
? themes?.nativeContext(local.start, local.end)
|
|
1337
|
-
: packed?.nativeContext,
|
|
1338
|
-
themes?.nativeContext(call.start, call.end),
|
|
1339
|
-
)
|
|
1340
|
-
) {
|
|
1341
|
-
report(
|
|
1342
|
-
'unsupported_syntax',
|
|
1343
|
-
'Native composition entries require the variable catalog of the composing style.',
|
|
1344
|
-
entry!,
|
|
1345
|
-
)
|
|
1346
|
-
continue
|
|
1347
|
-
}
|
|
1348
|
-
|
|
1349
|
-
// The composing configuration decides output for every copied entry.
|
|
1350
|
-
parts.push(
|
|
1351
|
-
Object.fromEntries(
|
|
1352
|
-
Object.entries(style).filter(
|
|
1353
|
-
([key]) => key !== 'composition' && key !== 'cssOutput',
|
|
1354
|
-
),
|
|
1355
|
-
) as Style.NamedStyle,
|
|
1356
|
-
)
|
|
1357
|
-
|
|
1358
|
-
if (local) {
|
|
1359
|
-
properties.push(...(bodies.get(local.start)?.properties ?? []))
|
|
1360
|
-
for (const [start, count] of local.typography ?? [])
|
|
1361
|
-
typography.set(start, count)
|
|
1362
|
-
for (const [start, count] of local.typographyQueries ?? [])
|
|
1363
|
-
typographyQueries.set(start, count)
|
|
1364
|
-
continue
|
|
1365
|
-
}
|
|
1366
|
-
|
|
1367
|
-
// Packed declarations have no authored source here, so they map to the entry.
|
|
1368
|
-
properties.push(
|
|
1369
|
-
...declarations(style).map(
|
|
1370
|
-
(declaration): Ast.ObjectProperty => ({
|
|
1371
|
-
type: 'Property',
|
|
1372
|
-
computed: false,
|
|
1373
|
-
kind: 'init',
|
|
1374
|
-
method: false,
|
|
1375
|
-
shorthand: false,
|
|
1376
|
-
start: entry!.start,
|
|
1377
|
-
end: entry!.end,
|
|
1378
|
-
key: {
|
|
1379
|
-
type: 'Literal',
|
|
1380
|
-
value: declaration.property,
|
|
1381
|
-
raw: JSON.stringify(declaration.property),
|
|
1382
|
-
start: entry!.start,
|
|
1383
|
-
end: entry!.end,
|
|
1384
|
-
},
|
|
1385
|
-
value: {
|
|
1386
|
-
type: 'Literal',
|
|
1387
|
-
value: '',
|
|
1388
|
-
raw: '""',
|
|
1389
|
-
start: entry!.start,
|
|
1390
|
-
end: entry!.end,
|
|
1391
|
-
},
|
|
1392
|
-
}),
|
|
1393
|
-
),
|
|
1394
|
-
)
|
|
1395
|
-
}
|
|
1396
|
-
|
|
1397
|
-
return {
|
|
1398
|
-
body: {
|
|
1399
|
-
type: 'ObjectExpression',
|
|
1400
|
-
start: call.start,
|
|
1401
|
-
end: call.end,
|
|
1402
|
-
properties,
|
|
1403
|
-
} satisfies Ast.ObjectExpression,
|
|
1404
|
-
definition: {
|
|
1405
|
-
styles: [
|
|
1406
|
-
Object.freeze<Style.NamedStyle>({
|
|
1407
|
-
name,
|
|
1408
|
-
declarations: Object.freeze([]),
|
|
1409
|
-
rules: Object.freeze(
|
|
1410
|
-
parts.map((style) => Object.freeze({ style })),
|
|
1411
|
-
),
|
|
1412
|
-
}),
|
|
1413
|
-
],
|
|
1414
|
-
} satisfies Style.Definition as Style.Definition,
|
|
1415
|
-
}
|
|
1416
|
-
}
|
|
1417
|
-
|
|
1418
|
-
const values = entries
|
|
1419
|
-
? undefined
|
|
1420
|
-
: object(argument as Ast.ObjectExpression)
|
|
1421
|
-
if (diagnostics.length !== before) continue
|
|
1422
|
-
|
|
1423
|
-
try {
|
|
1424
|
-
const composite = entries && compose(entries)
|
|
1425
|
-
if (diagnostics.length !== before) continue
|
|
1426
|
-
|
|
1427
|
-
const definition =
|
|
1428
|
-
composite?.definition ??
|
|
1429
|
-
define(
|
|
1430
|
-
{ [name]: values! },
|
|
1431
|
-
{ locations, vars: themes?.styles.get(call.start)?.theme },
|
|
1432
|
-
)
|
|
1433
|
-
|
|
1434
|
-
const body = composite?.body ?? (argument as Ast.ObjectExpression)
|
|
1435
|
-
bodies.set(call.start, body)
|
|
1436
|
-
|
|
1437
|
-
function validate(style: Style.NamedStyle, path: readonly string[]) {
|
|
1438
|
-
for (const declaration of style.declarations) {
|
|
1439
|
-
if (
|
|
1440
|
-
Token.is(declaration.value) &&
|
|
1441
|
-
declaration.value.contract.variableSet &&
|
|
1442
|
-
Literal.rule(declaration.property)?.kind === 'identifier' &&
|
|
1443
|
-
!Expression.acceptsIdentifier(
|
|
1444
|
-
declaration.value,
|
|
1445
|
-
declaration.property,
|
|
1446
|
-
)
|
|
1447
|
-
)
|
|
1448
|
-
report(
|
|
1449
|
-
'invalid_literal',
|
|
1450
|
-
'Variable value is incompatible with this property.',
|
|
1451
|
-
call,
|
|
1452
|
-
)
|
|
1453
|
-
}
|
|
1454
|
-
if (style.targets?.web)
|
|
1455
|
-
validate(style.targets.web, [...path, 'targets', 'web'])
|
|
1456
|
-
for (const rule of style.rules ?? []) {
|
|
1457
|
-
if (rule.condition !== undefined) {
|
|
1458
|
-
const location =
|
|
1459
|
-
conditionKeys.get(JSON.stringify([...path, rule.condition])) ??
|
|
1460
|
-
call
|
|
1461
|
-
|
|
1462
|
-
try {
|
|
1463
|
-
AtRules.transform({
|
|
1464
|
-
filename: options.moduleId,
|
|
1465
|
-
code: Buffer.from(`.z{${rule.condition}{color:red;}}`),
|
|
1466
|
-
errorRecovery: false,
|
|
1467
|
-
})
|
|
1468
|
-
} catch (error) {
|
|
1469
|
-
report(
|
|
1470
|
-
'unsupported_syntax',
|
|
1471
|
-
`Invalid selector or condition: ${(error as Error).message}`,
|
|
1472
|
-
location,
|
|
1473
|
-
)
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
|
|
1477
|
-
validate(
|
|
1478
|
-
rule.style,
|
|
1479
|
-
rule.condition === undefined ? path : [...path, rule.condition],
|
|
1480
|
-
)
|
|
1481
|
-
}
|
|
1482
|
-
}
|
|
1483
|
-
|
|
1484
|
-
for (const style of definition.styles) validate(style, [style.name])
|
|
1485
|
-
|
|
1486
|
-
if (diagnostics.length !== before) continue
|
|
1487
|
-
|
|
1488
|
-
const contract = themes?.styles.get(call.start)?.theme[Token.definition]
|
|
1489
|
-
.contract
|
|
1490
|
-
const composition = contract?.composition
|
|
1491
|
-
const cssOutput = contract?.cssOutput
|
|
1492
|
-
styles.push(
|
|
1493
|
-
...definition.styles.map((style) =>
|
|
1494
|
-
composition || cssOutput
|
|
1495
|
-
? Object.freeze({
|
|
1496
|
-
...style,
|
|
1497
|
-
...(composition ? { composition } : {}),
|
|
1498
|
-
...(cssOutput ? { cssOutput } : {}),
|
|
1499
|
-
})
|
|
1500
|
-
: style,
|
|
1501
|
-
),
|
|
1502
|
-
)
|
|
1503
|
-
|
|
1504
|
-
const shorthands = themes?.styles.get(call.start)?.theme[Token.definition]
|
|
1505
|
-
.contract.shorthands
|
|
1506
|
-
|
|
1507
|
-
const retained = staticRecipe ?? dynamicRecipe
|
|
1508
|
-
const targetRecipe = retained && {
|
|
1509
|
-
...retained,
|
|
1510
|
-
rules: retained.rules.map(({ matches, value }, index) => ({
|
|
1511
|
-
matches,
|
|
1512
|
-
value: define(
|
|
1513
|
-
{ [`${name}-${index}`]: object(value) },
|
|
1514
|
-
{ locations, vars: themes?.styles.get(call.start)?.theme },
|
|
1515
|
-
),
|
|
1516
|
-
})),
|
|
1517
|
-
}
|
|
1518
|
-
calls.push({
|
|
1519
|
-
...(recipe ? { recipe, recipeTypes } : {}),
|
|
1520
|
-
...(staticRecipe
|
|
1521
|
-
? { staticRecipe: targetRecipe }
|
|
1522
|
-
: dynamicRecipe
|
|
1523
|
-
? { dynamicRecipe: targetRecipe }
|
|
1524
|
-
: {}),
|
|
1525
|
-
...(selectors.identities.has(call.start)
|
|
1526
|
-
? { identity: selectors.identities.get(call.start)! }
|
|
1527
|
-
: {}),
|
|
1528
|
-
...(body !== (dynamic?.body ?? original) ? { body } : {}),
|
|
1529
|
-
...(shorthands ? { shorthands } : {}),
|
|
1530
|
-
...(typography.size ? { typography } : {}),
|
|
1531
|
-
...(typographyQueries.size ? { typographyQueries } : {}),
|
|
1532
|
-
...(themes?.styles.get(call.start)?.output
|
|
1533
|
-
? { output: 'html' as const }
|
|
1534
|
-
: {}),
|
|
1535
|
-
...(dynamic
|
|
1536
|
-
? {
|
|
1537
|
-
slots: dynamic.slots,
|
|
1538
|
-
valuesType: options.source.slice(
|
|
1539
|
-
dynamic.type.start,
|
|
1540
|
-
dynamic.type.end,
|
|
1541
|
-
),
|
|
1542
|
-
}
|
|
1543
|
-
: {}),
|
|
1544
|
-
...(options.compiler === false
|
|
1545
|
-
? {
|
|
1546
|
-
portable: (() => {
|
|
1547
|
-
if (explicitId !== undefined) return `z-style-${definitionId}`
|
|
1548
|
-
if (
|
|
1549
|
-
dynamic ||
|
|
1550
|
-
recipe ||
|
|
1551
|
-
entries?.length === 0 ||
|
|
1552
|
-
(!definition.styles[0]!.declarations.length &&
|
|
1553
|
-
!definition.styles[0]!.rules &&
|
|
1554
|
-
!definition.styles[0]!.targets)
|
|
1555
|
-
)
|
|
1556
|
-
return undefined
|
|
1557
|
-
return Identity.style(definition.styles[0]!, cssNamespace)
|
|
1558
|
-
})(),
|
|
1559
|
-
}
|
|
1560
|
-
: {}),
|
|
1561
|
-
cssName,
|
|
1562
|
-
cssNamespace,
|
|
1563
|
-
end: call.end,
|
|
1564
|
-
name,
|
|
1565
|
-
start: call.start,
|
|
1566
|
-
})
|
|
1567
|
-
} catch (error) {
|
|
1568
|
-
if (!(error instanceof Style.InvalidError)) throw error
|
|
1569
|
-
|
|
1570
|
-
for (const diagnostic of error.diagnostics)
|
|
1571
|
-
diagnostics.push({
|
|
1572
|
-
code: 'invalid_literal',
|
|
1573
|
-
end: diagnostic.location?.end ?? call.end,
|
|
1574
|
-
message: diagnostic.message,
|
|
1575
|
-
source: options.moduleId,
|
|
1576
|
-
start: diagnostic.location?.start ?? call.start,
|
|
1577
|
-
})
|
|
1578
|
-
}
|
|
1579
|
-
}
|
|
1580
|
-
|
|
1581
|
-
try {
|
|
1582
|
-
let compositionIndex = 0
|
|
1583
|
-
for (const entry of options.target === 'native'
|
|
1584
|
-
? []
|
|
1585
|
-
: Compositions.collect({
|
|
1586
|
-
calls,
|
|
1587
|
-
identity: namespace,
|
|
1588
|
-
links: options[Themes.context]?.links,
|
|
1589
|
-
program,
|
|
1590
|
-
scopes: themes?.scopeApplications,
|
|
1591
|
-
source: options.source,
|
|
1592
|
-
styles,
|
|
1593
|
-
})) {
|
|
1594
|
-
const authored = authoredNames.get(entry.call.start)
|
|
1595
|
-
const name = authored && authored !== 'style' ? authored : 'composition'
|
|
1596
|
-
const cssName = `${name}-${compositionIndex++}-${entry.call.cssName ?? 'style'}`
|
|
1597
|
-
calls.push(
|
|
1598
|
-
...(entry.cases ?? []).map((value, index) => ({
|
|
1599
|
-
...value.call,
|
|
1600
|
-
cssName: `${cssName}-${index}`,
|
|
1601
|
-
})),
|
|
1602
|
-
{ ...entry.call, cssName },
|
|
1603
|
-
)
|
|
1604
|
-
styles.push(
|
|
1605
|
-
...(entry.cases ?? []).map((entry) => entry.style),
|
|
1606
|
-
entry.style,
|
|
1607
|
-
)
|
|
1608
|
-
}
|
|
1609
|
-
} catch (error) {
|
|
1610
|
-
if (!(error instanceof Themes.InvalidError)) throw error
|
|
1611
|
-
report('unsupported_syntax', error.message, error)
|
|
1612
|
-
}
|
|
1613
|
-
|
|
1614
|
-
if (themes && !diagnostics.length)
|
|
1615
|
-
for (const [start, token] of themes.tokens) {
|
|
1616
|
-
if (
|
|
1617
|
-
!staticData.used.has(start) &&
|
|
1618
|
-
!themes.staticTokens.some((node) => node.start === start) &&
|
|
1619
|
-
![...calls, ...contributions.calls].some(
|
|
1620
|
-
(call) => start >= call.start && token.end <= call.end,
|
|
1621
|
-
)
|
|
1622
|
-
)
|
|
1623
|
-
report(
|
|
1624
|
-
'unsupported_syntax',
|
|
1625
|
-
'Theme references require a compiled style declaration.',
|
|
1626
|
-
{ start, end: token.end },
|
|
1627
|
-
)
|
|
1628
|
-
}
|
|
1629
|
-
|
|
1630
|
-
let contributionData: readonly Css.Contribution[] = []
|
|
1631
|
-
const contributionStarts = [...variables.registrationStarts]
|
|
1632
|
-
|
|
1633
|
-
try {
|
|
1634
|
-
for (const [index, registration] of variables.registrations.entries()) {
|
|
1635
|
-
try {
|
|
1636
|
-
const css = Css.compile({
|
|
1637
|
-
styles: { styles: [] },
|
|
1638
|
-
contributions: [registration],
|
|
1639
|
-
}).css
|
|
1640
|
-
AtRules.transform({
|
|
1641
|
-
filename: options.moduleId,
|
|
1642
|
-
code: new TextEncoder().encode(css),
|
|
1643
|
-
errorRecovery: false,
|
|
1644
|
-
})
|
|
1645
|
-
} catch (error) {
|
|
1646
|
-
throw new Themes.InvalidError(
|
|
1647
|
-
(error as Error).message,
|
|
1648
|
-
variables.registrationLocations[index]!,
|
|
1649
|
-
)
|
|
1650
|
-
}
|
|
1651
|
-
}
|
|
1652
|
-
|
|
1653
|
-
contributionData = [
|
|
1654
|
-
...variables.registrations,
|
|
1655
|
-
...Contributions.extract(
|
|
1656
|
-
contributions,
|
|
1657
|
-
themes?.tokens ?? new Map(),
|
|
1658
|
-
contributionStarts,
|
|
1659
|
-
(node) => staticData.resolve(node, staticCalls),
|
|
1660
|
-
),
|
|
1661
|
-
...(themes?.calls ?? []).flatMap((call) =>
|
|
1662
|
-
call.options?.layers
|
|
1663
|
-
? [
|
|
1664
|
-
{
|
|
1665
|
-
kind: 'layers' as const,
|
|
1666
|
-
names: call.options.layers as readonly string[],
|
|
1667
|
-
},
|
|
1668
|
-
]
|
|
1669
|
-
: [],
|
|
1670
|
-
),
|
|
1671
|
-
]
|
|
1672
|
-
|
|
1673
|
-
if (contributionData.length) {
|
|
1674
|
-
const rendered = Css.compile({
|
|
1675
|
-
styles: { styles: [] },
|
|
1676
|
-
contributions: contributionData,
|
|
1677
|
-
vars: themes?.themes,
|
|
1678
|
-
}).css
|
|
1679
|
-
AtRules.transform({
|
|
1680
|
-
filename: options.moduleId,
|
|
1681
|
-
code: new TextEncoder().encode(rendered),
|
|
1682
|
-
errorRecovery: false,
|
|
1683
|
-
...(!options[Themes.context]
|
|
1684
|
-
? {
|
|
1685
|
-
visitor: {
|
|
1686
|
-
Rule(rule) {
|
|
1687
|
-
if (
|
|
1688
|
-
rule.type === 'import' &&
|
|
1689
|
-
rule.value.url &&
|
|
1690
|
-
!/^(?:\/|[?#]|[a-z][a-z\d+.-]*:)/i.test(rule.value.url)
|
|
1691
|
-
)
|
|
1692
|
-
throw new Error(
|
|
1693
|
-
'Relative contribution assets require Graph.compile and a relocation host.',
|
|
1694
|
-
)
|
|
1695
|
-
},
|
|
1696
|
-
Url(url) {
|
|
1697
|
-
if (
|
|
1698
|
-
url.url &&
|
|
1699
|
-
!/^(?:\/|[?#]|[a-z][a-z\d+.-]*:)/i.test(url.url)
|
|
1700
|
-
)
|
|
1701
|
-
throw new Error(
|
|
1702
|
-
'Relative contribution assets require Graph.compile and a relocation host.',
|
|
1703
|
-
)
|
|
1704
|
-
},
|
|
1705
|
-
},
|
|
1706
|
-
}
|
|
1707
|
-
: {}),
|
|
1708
|
-
})
|
|
1709
|
-
}
|
|
1710
|
-
} catch (error) {
|
|
1711
|
-
report(
|
|
1712
|
-
'unsupported_syntax',
|
|
1713
|
-
(error as Error).message,
|
|
1714
|
-
error instanceof Themes.InvalidError ? error : contributions.calls[0],
|
|
1715
|
-
)
|
|
1716
|
-
}
|
|
1717
|
-
|
|
1718
|
-
for (const token of themes?.staticTokens ?? [])
|
|
1719
|
-
if (!staticData.used.has(Expression.unwrap(token).start))
|
|
1720
|
-
report(
|
|
1721
|
-
'unsupported_syntax',
|
|
1722
|
-
'Token references must be direct property values in bound theme style calls.',
|
|
1723
|
-
token,
|
|
1724
|
-
)
|
|
1725
|
-
|
|
1726
|
-
if (diagnostics.length) throw new ExtractError(diagnostics)
|
|
1727
|
-
|
|
1728
|
-
function exportedStyle(link: Themes.Link): Themes.Link {
|
|
1729
|
-
const call = calls.find((call) => call.identity === link.binding)
|
|
1730
|
-
const style = call && styles.find((style) => style.name === call.name)
|
|
1731
|
-
return {
|
|
1732
|
-
...link,
|
|
1733
|
-
...(call && style
|
|
1734
|
-
? {
|
|
1735
|
-
style: PackedStyles.create(
|
|
1736
|
-
{
|
|
1737
|
-
...call,
|
|
1738
|
-
nativeContext: themes?.nativeContext(call.start, call.end),
|
|
1739
|
-
},
|
|
1740
|
-
style,
|
|
1741
|
-
),
|
|
1742
|
-
}
|
|
1743
|
-
: {}),
|
|
1744
|
-
...(link.members
|
|
1745
|
-
? {
|
|
1746
|
-
members: Object.fromEntries(
|
|
1747
|
-
Object.entries(link.members).map(([name, member]) => [
|
|
1748
|
-
name,
|
|
1749
|
-
exportedStyle(member),
|
|
1750
|
-
]),
|
|
1751
|
-
),
|
|
1752
|
-
}
|
|
1753
|
-
: {}),
|
|
1754
|
-
}
|
|
1755
|
-
}
|
|
1756
|
-
|
|
1757
|
-
const callsByName = new Map(calls.map((call) => [call.name, call]))
|
|
1758
|
-
const definition = {
|
|
1759
|
-
styles: Object.freeze(styles),
|
|
1760
|
-
[ClassName.labels]: Object.freeze(
|
|
1761
|
-
Object.fromEntries(
|
|
1762
|
-
styles.map((style) => {
|
|
1763
|
-
let name = style.name
|
|
1764
|
-
let call = callsByName.get(name)
|
|
1765
|
-
while (!call && name.includes('-')) {
|
|
1766
|
-
name = name.slice(0, name.lastIndexOf('-'))
|
|
1767
|
-
call = callsByName.get(name)
|
|
1768
|
-
}
|
|
1769
|
-
return [
|
|
1770
|
-
style.name,
|
|
1771
|
-
{
|
|
1772
|
-
name: call?.cssName
|
|
1773
|
-
? call.cssName + style.name.slice(call.name.length)
|
|
1774
|
-
: style.name,
|
|
1775
|
-
namespace: call?.cssNamespace,
|
|
1776
|
-
},
|
|
1777
|
-
]
|
|
1778
|
-
}),
|
|
1779
|
-
),
|
|
1780
|
-
),
|
|
1781
|
-
}
|
|
1782
|
-
Object.defineProperty(definition, ClassName.labels, { enumerable: false })
|
|
1783
|
-
const selections =
|
|
1784
|
-
options.target === 'native' ? themes?.selectionUses : themes?.selections
|
|
1785
|
-
|
|
1786
|
-
return Object.freeze({
|
|
1787
|
-
namespaces: contributionData.filter(
|
|
1788
|
-
(value): value is Extract<Css.Contribution, { kind: 'namespace' }> =>
|
|
1789
|
-
value.kind === 'namespace',
|
|
1790
|
-
),
|
|
1791
|
-
...(contributionData.length
|
|
1792
|
-
? { contributions: contributionData, contributionStarts }
|
|
1793
|
-
: {}),
|
|
1794
|
-
...(contributions.calls.length
|
|
1795
|
-
? { contributionCalls: contributions.calls }
|
|
1796
|
-
: {}),
|
|
1797
|
-
...(options[Themes.context]
|
|
1798
|
-
? {
|
|
1799
|
-
themeExports: Object.freeze({
|
|
1800
|
-
...themes?.exports,
|
|
1801
|
-
...Object.fromEntries(
|
|
1802
|
-
Object.entries(selectors.exports).map(([name, link]) => [
|
|
1803
|
-
name,
|
|
1804
|
-
exportedStyle(link),
|
|
1805
|
-
]),
|
|
1806
|
-
),
|
|
1807
|
-
...contributions.exports,
|
|
1808
|
-
...variables.exports,
|
|
1809
|
-
}),
|
|
1810
|
-
}
|
|
1811
|
-
: {}),
|
|
1812
|
-
calls: Object.freeze(
|
|
1813
|
-
calls
|
|
1814
|
-
.sort((a, b) => a.start - b.start)
|
|
1815
|
-
.map((call) => {
|
|
1816
|
-
const nativeContext =
|
|
1817
|
-
options.target === 'native'
|
|
1818
|
-
? themes?.nativeContext(call.start, call.end)
|
|
1819
|
-
: undefined
|
|
1820
|
-
return Object.freeze(
|
|
1821
|
-
nativeContext ? { ...call, nativeContext } : call,
|
|
1822
|
-
)
|
|
1823
|
-
}),
|
|
231
|
+
return Wire.decode(
|
|
232
|
+
Addon.load().call(
|
|
233
|
+
'source.extract',
|
|
234
|
+
JSON.stringify({
|
|
235
|
+
compiler: options.compiler,
|
|
236
|
+
moduleId: options.moduleId,
|
|
237
|
+
source: options.source,
|
|
238
|
+
target: options.target,
|
|
239
|
+
}),
|
|
1824
240
|
),
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
? { variableCalls: Object.freeze(variables.calls) }
|
|
1828
|
-
: {}),
|
|
1829
|
-
themeAliases: Object.freeze(themes?.aliases ?? []),
|
|
1830
|
-
...(themes?.appearances.size
|
|
1831
|
-
? { themeAppearances: Object.freeze([...themes.appearances]) }
|
|
1832
|
-
: {}),
|
|
1833
|
-
...(themes?.scripts.size
|
|
1834
|
-
? { themeScripts: Object.freeze([...themes.scripts]) }
|
|
1835
|
-
: {}),
|
|
1836
|
-
...(selections?.size
|
|
1837
|
-
? { themeSelections: Object.freeze([...selections]) }
|
|
1838
|
-
: {}),
|
|
1839
|
-
themeCalls: Object.freeze(themes?.calls ?? []),
|
|
1840
|
-
...(themes?.staticTokens.length
|
|
1841
|
-
? {
|
|
1842
|
-
staticThemeReferences: Object.freeze(
|
|
1843
|
-
(themes?.staticTokens ?? []).map((node) => ({
|
|
1844
|
-
start: node.start,
|
|
1845
|
-
end: node.end,
|
|
1846
|
-
value: ThemeValues.create().serialize(
|
|
1847
|
-
themes!.tokens.get(node.start)!.reference,
|
|
1848
|
-
),
|
|
1849
|
-
})),
|
|
1850
|
-
),
|
|
1851
|
-
}
|
|
1852
|
-
: {}),
|
|
1853
|
-
themeReferences: Object.freeze(themes?.references ?? []),
|
|
1854
|
-
vars: themes?.themes ?? Object.freeze({}),
|
|
1855
|
-
...(themes?.varsReads.length
|
|
1856
|
-
? { nativeVars: Object.freeze(themes.varsReads) }
|
|
1857
|
-
: {}),
|
|
1858
|
-
})
|
|
241
|
+
{ compiler: options.compiler },
|
|
242
|
+
)
|
|
1859
243
|
}
|
|
1860
244
|
|
|
1861
245
|
/** Input and output of source extraction. */
|
|
@@ -1871,8 +255,6 @@ export declare namespace extract {
|
|
|
1871
255
|
readonly compiler?: boolean | undefined
|
|
1872
256
|
/** Portable identity including package and module path; no filesystem access occurs. */
|
|
1873
257
|
readonly moduleId: string
|
|
1874
|
-
/** Compiler-owned graph context. */
|
|
1875
|
-
readonly [Themes.context]?: Themes.Context | undefined
|
|
1876
258
|
/** Complete module text, parsed as TypeScript with JSX. */
|
|
1877
259
|
readonly source: string
|
|
1878
260
|
}
|
|
@@ -1880,21 +262,21 @@ export declare namespace extract {
|
|
|
1880
262
|
/** Ordered public compiler input and spans for later rewriting. */
|
|
1881
263
|
type ReturnType = {
|
|
1882
264
|
/** Readonly native variable arguments and their complete catalogs. */
|
|
1883
|
-
readonly nativeVars?: readonly
|
|
265
|
+
readonly nativeVars?: readonly VarsRead[] | undefined
|
|
1884
266
|
/** Module-owned namespace bindings retained when contributions are shared. */
|
|
1885
267
|
readonly namespaces?: readonly Namespace.Definition[] | undefined
|
|
1886
268
|
/** Static stylesheet effects and their source replacements. */
|
|
1887
269
|
readonly contributionStarts?: readonly number[] | undefined
|
|
1888
270
|
readonly contributions?: readonly Css.Contribution[] | undefined
|
|
1889
|
-
readonly contributionCalls?: readonly
|
|
271
|
+
readonly contributionCalls?: readonly ContributionCall[] | undefined
|
|
1890
272
|
/** Explicit variable contracts replaced by fixed slot data. */
|
|
1891
|
-
readonly variableCalls?: readonly
|
|
273
|
+
readonly variableCalls?: readonly VariableCall[] | undefined
|
|
1892
274
|
/** Direct calls in source order. */
|
|
1893
275
|
readonly calls: readonly Call[]
|
|
1894
276
|
/** Validated definitions accepted by Css.compile. */
|
|
1895
277
|
readonly styles: Style.Definition
|
|
1896
278
|
/** Local bound-authoring initializers and their retained token types. */
|
|
1897
|
-
readonly themeAliases: readonly
|
|
279
|
+
readonly themeAliases: readonly ThemeAlias[]
|
|
1898
280
|
/** Configuration identities retaining their root controls. */
|
|
1899
281
|
readonly themeAppearances?: readonly string[] | undefined
|
|
1900
282
|
/** Configuration identities retaining their initialization helper. */
|
|
@@ -1902,7 +284,7 @@ export declare namespace extract {
|
|
|
1902
284
|
/** Configuration identities whose theme selector is called, passed, or bound. */
|
|
1903
285
|
readonly themeSelections?: readonly string[] | undefined
|
|
1904
286
|
/** Local factory spans replaced by compiled scope data. */
|
|
1905
|
-
readonly themeCalls: readonly
|
|
287
|
+
readonly themeCalls: readonly ThemeCall[]
|
|
1906
288
|
/** Scope reads replaced by class constants. */
|
|
1907
289
|
readonly staticThemeReferences?:
|
|
1908
290
|
| readonly {
|
|
@@ -1911,9 +293,12 @@ export declare namespace extract {
|
|
|
1911
293
|
readonly value: string
|
|
1912
294
|
}[]
|
|
1913
295
|
| undefined
|
|
1914
|
-
readonly themeReferences: readonly
|
|
1915
|
-
|
|
1916
|
-
|
|
296
|
+
readonly themeReferences: readonly Pick<
|
|
297
|
+
ThemeCall,
|
|
298
|
+
'end' | 'name' | 'start'
|
|
299
|
+
>[]
|
|
300
|
+
/** Resolved authoring exports when extracted as part of a source graph, absent from a direct call. */
|
|
301
|
+
readonly themeExports?: Readonly<Record<string, object>> | undefined
|
|
1917
302
|
/** Stable scope keys and validated local theme definitions. */
|
|
1918
303
|
readonly vars: Readonly<Record<string, Theme.Definition>>
|
|
1919
304
|
}
|
|
@@ -1939,47 +324,3 @@ export class ExtractError extends Error {
|
|
|
1939
324
|
/** Stable namespaced error identifier. */
|
|
1940
325
|
override name = 'Source.ExtractError'
|
|
1941
326
|
}
|
|
1942
|
-
|
|
1943
|
-
/** Accepts an entry context that the composing call selects identically. */
|
|
1944
|
-
function context(
|
|
1945
|
-
entry: Call['nativeContext'],
|
|
1946
|
-
composite: Call['nativeContext'],
|
|
1947
|
-
): boolean {
|
|
1948
|
-
if (!entry || entry === composite) return true
|
|
1949
|
-
if (!composite || entry.defaultVars !== composite.defaultVars) return false
|
|
1950
|
-
|
|
1951
|
-
const names = Object.keys(entry.vars)
|
|
1952
|
-
return (
|
|
1953
|
-
names.length === Object.keys(composite.vars).length &&
|
|
1954
|
-
names.every((name) => {
|
|
1955
|
-
const left = entry.vars[name]?.[Token.definition].contract
|
|
1956
|
-
const right = composite.vars[name]?.[Token.definition].contract
|
|
1957
|
-
return (
|
|
1958
|
-
!!left &&
|
|
1959
|
-
!!right &&
|
|
1960
|
-
(left === right ||
|
|
1961
|
-
(left[Token.identity] !== undefined &&
|
|
1962
|
-
left[Token.identity] === right[Token.identity]))
|
|
1963
|
-
)
|
|
1964
|
-
})
|
|
1965
|
-
)
|
|
1966
|
-
}
|
|
1967
|
-
|
|
1968
|
-
/** Lists declarations in emitted order, through conditions and segments. */
|
|
1969
|
-
function declarations(style: Style.NamedStyle): readonly Style.Declaration[] {
|
|
1970
|
-
return style.rules
|
|
1971
|
-
? style.rules.flatMap((rule) => declarations(rule.style))
|
|
1972
|
-
: style.declarations
|
|
1973
|
-
}
|
|
1974
|
-
|
|
1975
|
-
function identity(value: string): string {
|
|
1976
|
-
let first = 2166136261
|
|
1977
|
-
let second = 2246822507
|
|
1978
|
-
|
|
1979
|
-
for (let index = 0; index < value.length; index++) {
|
|
1980
|
-
first = Math.imul(first ^ value.charCodeAt(index), 16777619)
|
|
1981
|
-
second = Math.imul(second ^ value.charCodeAt(index), 3266489909)
|
|
1982
|
-
}
|
|
1983
|
-
|
|
1984
|
-
return `${(first >>> 0).toString(36)}${(second >>> 0).toString(36)}`
|
|
1985
|
-
}
|