@yahoo/uds-create-config 5.26.0 → 5.27.1
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/dist/configs/react-native-system.d.ts +22 -4
- package/dist/configs/system.js +2 -0
- package/dist/entities/native/NativeToken.d.ts +22 -4
- package/dist/entities/native/NativeToken.js +2 -1
- package/dist/entities/system/LinkedSystem.js +3 -2
- package/dist/entities/system/Token.d.ts +22 -4
- package/dist/entities/system/Token.js +4 -3
- package/dist/framework/Config.d.ts +11 -4
- package/dist/framework/Config.js +94 -10
- package/dist/framework/config-ops.d.ts +1 -1
- package/dist/framework/config-ops.js +25 -4
- package/dist/framework/defineSubEntity.d.ts +7 -0
- package/dist/framework/defineSubEntity.js +9 -0
- package/dist/framework/schema-version.d.ts +1 -1
- package/dist/framework/schema-version.js +5 -5
- package/dist/framework/source-integrity.js +4 -1
- package/dist/framework/utils/deprecated.d.ts +18 -0
- package/dist/framework/utils/deprecated.js +12 -0
- package/dist/migrations/20261013164300_token_overrides_list.d.ts +7 -0
- package/dist/migrations/20261013164300_token_overrides_list.js +10 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +2 -2
|
@@ -69,10 +69,19 @@ declare const ReactNativeSystemDefinition: ConfigClass<{
|
|
|
69
69
|
tokens: EntityClass<_$zod.ZodObject<Omit<{
|
|
70
70
|
value: _$zod.ZodType<string | number | Ref | ComposedValue, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
71
71
|
type: _$zod.ZodOptional<_$zod.ZodString>;
|
|
72
|
-
overrides: _$zod.ZodOptional<
|
|
72
|
+
overrides: _$zod.ZodOptional<_$zod.ZodUnion<readonly [_$zod.ZodPipe<_$zod.ZodArray<_$zod.ZodObject<{
|
|
73
73
|
on: _$zod.ZodType<OverrideCondition, unknown, _$zod_v4_core0.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
74
74
|
value: _$zod.ZodType<string | number | Ref | ComposedValue, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
75
|
-
}, _$zod_v4_core0.$strip
|
|
75
|
+
}, _$zod_v4_core0.$strip>>, _$zod.ZodTransform<Record<string, {
|
|
76
|
+
on: OverrideCondition;
|
|
77
|
+
value: string | number | Ref | ComposedValue;
|
|
78
|
+
}>, {
|
|
79
|
+
on: OverrideCondition;
|
|
80
|
+
value: string | number | Ref | ComposedValue;
|
|
81
|
+
}[]>>, SubEntityClass<_$zod.ZodObject<{
|
|
82
|
+
on: _$zod.ZodType<OverrideCondition, unknown, _$zod_v4_core0.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
83
|
+
value: _$zod.ZodType<string | number | Ref | ComposedValue, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
84
|
+
}, _$zod_v4_core0.$strip>>]>>;
|
|
76
85
|
utility: _$zod.ZodOptional<_$zod.ZodBoolean>;
|
|
77
86
|
property: _$zod.ZodOptional<_$zod.ZodObject<{
|
|
78
87
|
syntax: _$zod.ZodOptional<_$zod.ZodString>;
|
|
@@ -81,10 +90,19 @@ declare const ReactNativeSystemDefinition: ConfigClass<{
|
|
|
81
90
|
cssVariable: _$zod.ZodOptional<_$zod.ZodUnion<readonly [_$zod.ZodString, _$zod.ZodLiteral<false>]>>;
|
|
82
91
|
}, "value" | "property" | "overrides" | "cssVariable"> & {
|
|
83
92
|
value: _$zod.ZodType<string | number | boolean | Ref | DerivedColor, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
84
|
-
overrides: _$zod.ZodOptional<
|
|
93
|
+
overrides: _$zod.ZodOptional<_$zod.ZodUnion<readonly [_$zod.ZodPipe<_$zod.ZodArray<_$zod.ZodObject<{
|
|
94
|
+
on: _$zod.ZodType<OverrideCondition, unknown, _$zod_v4_core0.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
95
|
+
value: _$zod.ZodType<string | number | boolean | Ref | DerivedColor, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
96
|
+
}, _$zod_v4_core0.$strip>>, _$zod.ZodTransform<Record<string, {
|
|
97
|
+
on: OverrideCondition;
|
|
98
|
+
value: string | number | boolean | Ref | DerivedColor;
|
|
99
|
+
}>, {
|
|
100
|
+
on: OverrideCondition;
|
|
101
|
+
value: string | number | boolean | Ref | DerivedColor;
|
|
102
|
+
}[]>>, SubEntityClass<_$zod.ZodObject<{
|
|
85
103
|
on: _$zod.ZodType<OverrideCondition, unknown, _$zod_v4_core0.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
86
104
|
value: _$zod.ZodType<string | number | boolean | Ref | DerivedColor, unknown, _$zod_v4_core0.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
87
|
-
}, _$zod_v4_core0.$strip
|
|
105
|
+
}, _$zod_v4_core0.$strip>>]>>;
|
|
88
106
|
}, _$zod_v4_core0.$strip>, _$zod.ZodObject<Omit<{
|
|
89
107
|
cssPrefix: _$zod.ZodOptional<_$zod.ZodString>;
|
|
90
108
|
cssVariables: _$zod.ZodOptional<_$zod.ZodBoolean>;
|
package/dist/configs/system.js
CHANGED
|
@@ -67,6 +67,7 @@ import { cssMotionStrictMigration } from "../migrations/20261009181635_css_motio
|
|
|
67
67
|
import { linkOverrideRefMigration } from "../migrations/20261009193004_link_override_ref.js";
|
|
68
68
|
import { linkedComponentModulesMigration } from "../migrations/20261012200606_linked_component_modules.js";
|
|
69
69
|
import { componentStatesMigration } from "../migrations/20261013154037_component_states.js";
|
|
70
|
+
import { tokenOverridesListMigration } from "../migrations/20261013164300_token_overrides_list.js";
|
|
70
71
|
const System = defineConfig({
|
|
71
72
|
name: WEB_CONFIG_NAME,
|
|
72
73
|
description: "A design system: the values, primitives and compositions an app is built from. A ref is written `{ \"__ref\": \"<kind>:<path>\" }`, so a token is `{ \"__ref\": \"token:<group>/<name>\" }` and a token group is `{ \"__ref\": \"token:<group>\" }`. Build it in this order. Tokens first, in groups by purpose (colors, spacing, radii, type sizes), since everything else names them. Then style properties, each with `values` holding one ref to the token group whose members it accepts (`{ \"__ref\": \"token:color\" }`), so a prop takes token names rather than raw CSS; add a string keyword only for a value no token holds. A style rule's bag holds a prop's values (`\"padding\": \"4\"`, `\"bg\": \"brand\"`), never raw CSS. Then a few primitive components, one layer each, whose props are style properties (a box for layout and surface, a text for type, a pressable for interaction). Then every other component composed from those primitives: its layers name a primitive or an element, its anatomy places them (a node renders a layer, a tag or `Slot` where a slot prop's content lands; `children` is the edge list; `visible` is `{ \"$state\": \"<prop>\" }`; a prop shown in a nested layer is a `forward` route, and `$state` never sits in a node's props), and its style rules set style-property values per layer, keyed by prop values when a variant changes them. Modes (a dark mode is `{ type: \"selector\", value: \".dark\" }`) change token values through a token's `overrides`, so a component never restyles for a mode; modifiers (hover, focus, disabled) name a state, and a style rule applies under one as a `_hover` block inside a layer bag. Composites bundle style values that recur. Last, register canvas roles: the canvas draws with them, one entity per tool (`frame` for the layout primitive, `text` for the text primitive, `image`) whose entries name the components that tool inserts, and a tool whose role is unregistered is disabled. Give each component a `preview` entry under `*` so it shows content, and never write a CSS property name where a style-property name belongs.",
|
|
@@ -145,5 +146,6 @@ if (!registeredSchemaMigrations().has(20261009181635)) registerSchemaMigrations(
|
|
|
145
146
|
if (!registeredSchemaMigrations().has(20261009193004)) registerSchemaMigrations(linkOverrideRefMigration);
|
|
146
147
|
if (!registeredSchemaMigrations().has(20261012200606)) registerSchemaMigrations(linkedComponentModulesMigration);
|
|
147
148
|
if (!registeredSchemaMigrations().has(20261013154037)) registerSchemaMigrations(componentStatesMigration);
|
|
149
|
+
if (!registeredSchemaMigrations().has(20261013164300)) registerSchemaMigrations(tokenOverridesListMigration);
|
|
148
150
|
//#endregion
|
|
149
151
|
export { System };
|
|
@@ -12,10 +12,19 @@ declare const nativeTokenValue: z.ZodType<number | boolean | string | Ref$1 | De
|
|
|
12
12
|
declare const NativeToken: EntityClass<z.ZodObject<Omit<{
|
|
13
13
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
14
14
|
type: z.ZodOptional<z.ZodString>;
|
|
15
|
-
overrides: z.ZodOptional<
|
|
15
|
+
overrides: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodArray<z.ZodObject<{
|
|
16
16
|
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
17
17
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
18
|
-
}, z.core.$strip
|
|
18
|
+
}, z.core.$strip>>, z.ZodTransform<Record<string, {
|
|
19
|
+
on: OverrideCondition;
|
|
20
|
+
value: string | number | Ref | ComposedValue;
|
|
21
|
+
}>, {
|
|
22
|
+
on: OverrideCondition;
|
|
23
|
+
value: string | number | Ref | ComposedValue;
|
|
24
|
+
}[]>>, SubEntityClass<z.ZodObject<{
|
|
25
|
+
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
26
|
+
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
27
|
+
}, z.core.$strip>>]>>;
|
|
19
28
|
utility: z.ZodOptional<z.ZodBoolean>;
|
|
20
29
|
property: z.ZodOptional<z.ZodObject<{
|
|
21
30
|
syntax: z.ZodOptional<z.ZodString>;
|
|
@@ -24,10 +33,19 @@ declare const NativeToken: EntityClass<z.ZodObject<Omit<{
|
|
|
24
33
|
cssVariable: z.ZodOptional<z.ZodUnion<readonly [z.ZodString, z.ZodLiteral<false>]>>;
|
|
25
34
|
}, "value" | "property" | "overrides" | "cssVariable"> & {
|
|
26
35
|
value: z.ZodType<string | number | boolean | Ref | DerivedColor, unknown, z.core.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
27
|
-
overrides: z.ZodOptional<
|
|
36
|
+
overrides: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodArray<z.ZodObject<{
|
|
37
|
+
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
38
|
+
value: z.ZodType<string | number | boolean | Ref | DerivedColor, unknown, z.core.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
39
|
+
}, z.core.$strip>>, z.ZodTransform<Record<string, {
|
|
40
|
+
on: OverrideCondition;
|
|
41
|
+
value: string | number | boolean | Ref | DerivedColor;
|
|
42
|
+
}>, {
|
|
43
|
+
on: OverrideCondition;
|
|
44
|
+
value: string | number | boolean | Ref | DerivedColor;
|
|
45
|
+
}[]>>, SubEntityClass<z.ZodObject<{
|
|
28
46
|
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
29
47
|
value: z.ZodType<string | number | boolean | Ref | DerivedColor, unknown, z.core.$ZodTypeInternals<string | number | boolean | Ref | DerivedColor, unknown>>;
|
|
30
|
-
}, z.core.$strip
|
|
48
|
+
}, z.core.$strip>>]>>;
|
|
31
49
|
}, z.core.$strip>, z.ZodObject<Omit<{
|
|
32
50
|
cssPrefix: z.ZodOptional<z.ZodString>;
|
|
33
51
|
cssVariables: z.ZodOptional<z.ZodBoolean>;
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { refSchema } from "../../framework/utils/refs.js";
|
|
2
2
|
import { oklchColor } from "../system/color.js";
|
|
3
|
+
import { orList } from "../../framework/defineSubEntity.js";
|
|
3
4
|
import { Font } from "../system/Font.js";
|
|
4
5
|
import { NATIVE_CONFIG_NAME } from "../../configs/platform.js";
|
|
5
6
|
import { prepareLinkedTokenBody } from "../system/linked-token-values.js";
|
|
@@ -66,7 +67,7 @@ const NativeToken = Token.extend({
|
|
|
66
67
|
entityName: "NativeToken",
|
|
67
68
|
fields: {
|
|
68
69
|
value: nativeTokenValue,
|
|
69
|
-
overrides: NativeOverride.optional(),
|
|
70
|
+
overrides: orList(NativeOverride).optional(),
|
|
70
71
|
cssVariable: null,
|
|
71
72
|
property: null
|
|
72
73
|
},
|
|
@@ -753,8 +753,9 @@ displayName: ({ member, path }) => typeof member.name === "string" && member.nam
|
|
|
753
753
|
bulkOverlayWrite: ({ accessor, path, overlay }) => ({ [`options.${accessor}.${path}`]: overlay })
|
|
754
754
|
});
|
|
755
755
|
/** An `override` or `extend` body with its `styles` as a list, in the stored form: the record keyed by
|
|
756
|
-
* each rule's condition, as `Component.item` stores one. Only a component
|
|
757
|
-
*
|
|
756
|
+
* each rule's condition, as `Component.item` stores one. Only a component has `styles`, so a list
|
|
757
|
+
* there is a rule list whatever accessor it sits under. A token's `overrides` list is stored as
|
|
758
|
+
* written and keyed where the overlay is read. */
|
|
758
759
|
function storedPinBody(body) {
|
|
759
760
|
if (!isPlainObject(body) || !Array.isArray(body.styles)) return body;
|
|
760
761
|
return {
|
|
@@ -44,10 +44,19 @@ declare function defineOverride<TValue extends z.ZodTypeAny>(value: TValue): Sub
|
|
|
44
44
|
declare const tokenFields: z.ZodObject<{
|
|
45
45
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
46
46
|
type: z.ZodOptional<z.ZodString>;
|
|
47
|
-
overrides: z.ZodOptional<
|
|
47
|
+
overrides: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodArray<z.ZodObject<{
|
|
48
48
|
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
49
49
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
50
|
-
}, z.core.$strip
|
|
50
|
+
}, z.core.$strip>>, z.ZodTransform<Record<string, {
|
|
51
|
+
on: OverrideCondition;
|
|
52
|
+
value: string | number | Ref | ComposedValue;
|
|
53
|
+
}>, {
|
|
54
|
+
on: OverrideCondition;
|
|
55
|
+
value: string | number | Ref | ComposedValue;
|
|
56
|
+
}[]>>, SubEntityClass<z.ZodObject<{
|
|
57
|
+
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
58
|
+
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
59
|
+
}, z.core.$strip>>]>>;
|
|
51
60
|
utility: z.ZodOptional<z.ZodBoolean>;
|
|
52
61
|
property: z.ZodOptional<z.ZodObject<{
|
|
53
62
|
syntax: z.ZodOptional<z.ZodString>;
|
|
@@ -61,10 +70,19 @@ type TokenBody = z.infer<typeof tokenFields>;
|
|
|
61
70
|
declare const TokenEntity: EntityClass<z.ZodObject<{
|
|
62
71
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
63
72
|
type: z.ZodOptional<z.ZodString>;
|
|
64
|
-
overrides: z.ZodOptional<
|
|
73
|
+
overrides: z.ZodOptional<z.ZodUnion<readonly [z.ZodPipe<z.ZodArray<z.ZodObject<{
|
|
74
|
+
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
75
|
+
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
76
|
+
}, z.core.$strip>>, z.ZodTransform<Record<string, {
|
|
77
|
+
on: OverrideCondition;
|
|
78
|
+
value: string | number | Ref | ComposedValue;
|
|
79
|
+
}>, {
|
|
80
|
+
on: OverrideCondition;
|
|
81
|
+
value: string | number | Ref | ComposedValue;
|
|
82
|
+
}[]>>, SubEntityClass<z.ZodObject<{
|
|
65
83
|
on: z.ZodType<OverrideCondition, unknown, z.core.$ZodTypeInternals<OverrideCondition, unknown>>;
|
|
66
84
|
value: z.ZodType<string | number | Ref | ComposedValue, unknown, z.core.$ZodTypeInternals<string | number | Ref | ComposedValue, unknown>>;
|
|
67
|
-
}, z.core.$strip
|
|
85
|
+
}, z.core.$strip>>]>>;
|
|
68
86
|
utility: z.ZodOptional<z.ZodBoolean>;
|
|
69
87
|
property: z.ZodOptional<z.ZodObject<{
|
|
70
88
|
syntax: z.ZodOptional<z.ZodString>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { isRef, kindOf, pathOf, ref, refKey, sourceOf } from "../../framework/utils/refs.js";
|
|
2
2
|
import { composedValueSchemas } from "./composed-values.js";
|
|
3
3
|
import { defineEntity } from "../../framework/defineEntity.js";
|
|
4
|
-
import { defineSubEntity } from "../../framework/defineSubEntity.js";
|
|
4
|
+
import { defineSubEntity, orList } from "../../framework/defineSubEntity.js";
|
|
5
5
|
import { Font } from "./Font.js";
|
|
6
6
|
import { Modifier } from "./Modifier.js";
|
|
7
7
|
import { spellTokenRead } from "./token-values.js";
|
|
@@ -112,7 +112,8 @@ function defineOverride(value) {
|
|
|
112
112
|
on: config ? declaredCondition(config) : overrideConditionSchema,
|
|
113
113
|
value
|
|
114
114
|
}),
|
|
115
|
-
key: (override) => overrideKey(override.on)
|
|
115
|
+
key: (override) => overrideKey(override.on),
|
|
116
|
+
listed: true
|
|
116
117
|
});
|
|
117
118
|
}
|
|
118
119
|
const Override = defineOverride(tokenValue);
|
|
@@ -128,7 +129,7 @@ const TokenEntity = defineEntity({
|
|
|
128
129
|
fields: z.object({
|
|
129
130
|
value: tokenValue.describe("The base value: a literal, a ref to another token, or a composed value such as a gradient."),
|
|
130
131
|
type: z.string().optional().describe("The CSS value type, when the value alone does not say it."),
|
|
131
|
-
overrides: Override.optional().describe("Per-mode values, keyed by the condition
|
|
132
|
+
overrides: orList(Override).optional().describe("Per-mode values, a list of `{ on, value }`. Stored keyed by the condition each applies under."),
|
|
132
133
|
utility: z.boolean().optional().describe("`false` keeps the token out of its group's values, so a style prop that takes the group writes no class for it — `spacing/scale` powers `--spacing` without becoming a `p-scale`. A ref naming the token still resolves."),
|
|
133
134
|
property: z.strictObject({
|
|
134
135
|
syntax: z.string().optional().describe("The `@property` syntax, as `<length>`. Defaults to `*`."),
|
|
@@ -73,7 +73,7 @@ interface RecordedSource {
|
|
|
73
73
|
* The dense-counter `2` a short-lived scheme stamped before the chain existed reads as the mint
|
|
74
74
|
* that replaced it (see `detectedWireVersion`).
|
|
75
75
|
*/
|
|
76
|
-
declare const SERIALIZED_CONFIG_VERSION =
|
|
76
|
+
declare const SERIALIZED_CONFIG_VERSION = 20261013164300;
|
|
77
77
|
interface SerializedConfig {
|
|
78
78
|
/** See {@link SERIALIZED_CONFIG_VERSION}. Always written; a stored artifact may lack it. */
|
|
79
79
|
readonly version: number;
|
|
@@ -2179,9 +2179,8 @@ declare class Config {
|
|
|
2179
2179
|
* only the reached ones would leave those rows absent from the artifact. Reachability stays the
|
|
2180
2180
|
* floor either way, so a ref always brings its target whether or not a declaration claims it.
|
|
2181
2181
|
*
|
|
2182
|
-
*
|
|
2183
|
-
*
|
|
2184
|
-
* drift, and the drift would look like a token that emits but isn't validated.
|
|
2182
|
+
* Preserves the original source definitions for saved configs and Web emission. Native emission
|
|
2183
|
+
* and condition validation use runtimeSourceClosure to follow the definitions after overrides.
|
|
2185
2184
|
*
|
|
2186
2185
|
* `kind` narrows it for a caller that emits or validates one kind, which is the caller's business
|
|
2187
2186
|
* to name; the walk itself follows refs wherever they go, so borrowing something other than a token
|
|
@@ -2190,6 +2189,14 @@ declare class Config {
|
|
|
2190
2189
|
* Sorted, so anything built from it is deterministic.
|
|
2191
2190
|
*/
|
|
2192
2191
|
sourceClosure(slug: string, kind?: string): string[];
|
|
2192
|
+
/** References used after local overrides; sourceClosure also preserves the original bases. */
|
|
2193
|
+
runtimeSourceClosure({
|
|
2194
|
+
slug,
|
|
2195
|
+
kind
|
|
2196
|
+
}: {
|
|
2197
|
+
slug: string;
|
|
2198
|
+
kind?: string;
|
|
2199
|
+
}): string[];
|
|
2193
2200
|
/**
|
|
2194
2201
|
* The walk behind {@link sourceClosure}, run once per snapshot and source set.
|
|
2195
2202
|
*
|
package/dist/framework/Config.js
CHANGED
|
@@ -272,7 +272,8 @@ function cachesFor(snapshot, sources) {
|
|
|
272
272
|
membersIndexed: /* @__PURE__ */ new Set(),
|
|
273
273
|
leaves: /* @__PURE__ */ new Map(),
|
|
274
274
|
computed: /* @__PURE__ */ new Map(),
|
|
275
|
-
closures: /* @__PURE__ */ new Map()
|
|
275
|
+
closures: /* @__PURE__ */ new Map(),
|
|
276
|
+
runtimeClosures: /* @__PURE__ */ new Map()
|
|
276
277
|
};
|
|
277
278
|
buckets.push(bucket);
|
|
278
279
|
return bucket;
|
|
@@ -318,6 +319,37 @@ function leafOf(field) {
|
|
|
318
319
|
function wholeBodySchema(entry, ctx = {}) {
|
|
319
320
|
return dataSchema(entry.schemas, "create", ctx) ?? dataSchema(entry.schemas, "replace", ctx);
|
|
320
321
|
}
|
|
322
|
+
/**
|
|
323
|
+
* An overlay whose bodies hold a list for a collection keyed by its members (`defineSubEntity({ key })`),
|
|
324
|
+
* with each list written as the record that collection is stored as. A pin stores its bodies as
|
|
325
|
+
* authored, and the overlay is laid onto the source key by key, so a list left as written would
|
|
326
|
+
* replace the source's record rather than add to it. A later member wins over an earlier one with
|
|
327
|
+
* the same key.
|
|
328
|
+
*/
|
|
329
|
+
function keyedOverlay(entry, overlay) {
|
|
330
|
+
if (!entry) return overlay;
|
|
331
|
+
const keyed = (body) => {
|
|
332
|
+
if (!body) return body;
|
|
333
|
+
let out;
|
|
334
|
+
for (const [field, sub] of Object.entries(entry.subEntities)) {
|
|
335
|
+
const members = body[field];
|
|
336
|
+
if (!sub.key || !Array.isArray(members)) continue;
|
|
337
|
+
const record = {};
|
|
338
|
+
for (const member of members) record[sub.key(member)] = member;
|
|
339
|
+
out ??= { ...body };
|
|
340
|
+
out[field] = record;
|
|
341
|
+
}
|
|
342
|
+
return out ?? body;
|
|
343
|
+
};
|
|
344
|
+
const override = keyed(overlay.override);
|
|
345
|
+
const extend = keyed(overlay.extend);
|
|
346
|
+
if (override === overlay.override && extend === overlay.extend) return overlay;
|
|
347
|
+
return {
|
|
348
|
+
...overlay,
|
|
349
|
+
override,
|
|
350
|
+
extend
|
|
351
|
+
};
|
|
352
|
+
}
|
|
321
353
|
/** The sub-entity a field path names, at either depth. */
|
|
322
354
|
function subEntityAt(entry, field) {
|
|
323
355
|
const slash = field.indexOf("/");
|
|
@@ -3764,7 +3796,7 @@ var Config = class Config {
|
|
|
3764
3796
|
const overlay = entry.bulkOverlay?.(args);
|
|
3765
3797
|
if (overlay !== void 0) return {
|
|
3766
3798
|
claimed,
|
|
3767
|
-
overlay
|
|
3799
|
+
overlay: keyedOverlay(this.entityOf(kind), overlay)
|
|
3768
3800
|
};
|
|
3769
3801
|
if (claimed) return { claimed: true };
|
|
3770
3802
|
}
|
|
@@ -4352,9 +4384,8 @@ var Config = class Config {
|
|
|
4352
4384
|
* only the reached ones would leave those rows absent from the artifact. Reachability stays the
|
|
4353
4385
|
* floor either way, so a ref always brings its target whether or not a declaration claims it.
|
|
4354
4386
|
*
|
|
4355
|
-
*
|
|
4356
|
-
*
|
|
4357
|
-
* drift, and the drift would look like a token that emits but isn't validated.
|
|
4387
|
+
* Preserves the original source definitions for saved configs and Web emission. Native emission
|
|
4388
|
+
* and condition validation use runtimeSourceClosure to follow the definitions after overrides.
|
|
4358
4389
|
*
|
|
4359
4390
|
* `kind` narrows it for a caller that emits or validates one kind, which is the caller's business
|
|
4360
4391
|
* to name; the walk itself follows refs wherever they go, so borrowing something other than a token
|
|
@@ -4366,10 +4397,25 @@ var Config = class Config {
|
|
|
4366
4397
|
const cache = this.caches.closures;
|
|
4367
4398
|
const hit = cache.get(slug);
|
|
4368
4399
|
if (hit) return kind === void 0 ? hit : hit.filter((target) => kindOf(target) === kind);
|
|
4369
|
-
const targets = this.computeSourceClosure(
|
|
4400
|
+
const targets = this.computeSourceClosure({
|
|
4401
|
+
slug,
|
|
4402
|
+
includeExtensionBases: true
|
|
4403
|
+
});
|
|
4370
4404
|
cache.set(slug, targets);
|
|
4371
4405
|
return kind === void 0 ? targets : targets.filter((target) => kindOf(target) === kind);
|
|
4372
4406
|
}
|
|
4407
|
+
/** References used after local overrides; sourceClosure also preserves the original bases. */
|
|
4408
|
+
runtimeSourceClosure({ slug, kind }) {
|
|
4409
|
+
let targets = this.caches.runtimeClosures.get(slug);
|
|
4410
|
+
if (!targets) {
|
|
4411
|
+
targets = this.computeSourceClosure({
|
|
4412
|
+
slug,
|
|
4413
|
+
includeExtensionBases: false
|
|
4414
|
+
});
|
|
4415
|
+
this.caches.runtimeClosures.set(slug, targets);
|
|
4416
|
+
}
|
|
4417
|
+
return kind === void 0 ? targets : targets.filter((target) => kindOf(target) === kind);
|
|
4418
|
+
}
|
|
4373
4419
|
/**
|
|
4374
4420
|
* The walk behind {@link sourceClosure}, run once per snapshot and source set.
|
|
4375
4421
|
*
|
|
@@ -4378,7 +4424,7 @@ var Config = class Config {
|
|
|
4378
4424
|
* over a config that is routinely megabytes, for one answer that cannot change while the snapshot
|
|
4379
4425
|
* and its sources are fixed.
|
|
4380
4426
|
*/
|
|
4381
|
-
computeSourceClosure(slug) {
|
|
4427
|
+
computeSourceClosure({ slug, includeExtensionBases }) {
|
|
4382
4428
|
const source = this.sourceFor(slug);
|
|
4383
4429
|
if (!source) return [];
|
|
4384
4430
|
const queue = [];
|
|
@@ -4386,6 +4432,7 @@ var Config = class Config {
|
|
|
4386
4432
|
for (const item of this.state.snapshot.slice(owned).items.values()) {
|
|
4387
4433
|
const stored = item.toJSON();
|
|
4388
4434
|
if (!isExtendedRef(stored)) continue;
|
|
4435
|
+
if (!includeExtensionBases && this.resolve(owned, item.path)) continue;
|
|
4389
4436
|
for (const target of collectRefs(stored)) {
|
|
4390
4437
|
if (sourceOf(target) !== slug) continue;
|
|
4391
4438
|
queue.push(`${kindOf(target)}:${pathOf(target)}`);
|
|
@@ -4396,7 +4443,11 @@ var Config = class Config {
|
|
|
4396
4443
|
queue.push(`${kindOf(target)}:${pathOf(target)}`);
|
|
4397
4444
|
}
|
|
4398
4445
|
}
|
|
4399
|
-
for (const target of this.adoptedFrom(slug))
|
|
4446
|
+
for (const target of this.adoptedFrom(slug)) {
|
|
4447
|
+
const local = this.storedBody(kindOf(target), pathOf(target));
|
|
4448
|
+
if (!includeExtensionBases && isExtendedRef(local) && !isMintedRow(local) && this.resolve(kindOf(target), pathOf(target))) continue;
|
|
4449
|
+
queue.push(target);
|
|
4450
|
+
}
|
|
4400
4451
|
const reached = /* @__PURE__ */ new Set();
|
|
4401
4452
|
while (queue.length > 0) {
|
|
4402
4453
|
const target = queue.pop();
|
|
@@ -4979,6 +5030,8 @@ var Config = class Config {
|
|
|
4979
5030
|
for (const { bag } of sites(body)) for (const prop of Object.keys(bag)) {
|
|
4980
5031
|
const target = `style-property:${prop}`;
|
|
4981
5032
|
if (members.has(target)) continue;
|
|
5033
|
+
const local = this.storedBody("style-property", prop);
|
|
5034
|
+
if (local && !isMintedRow(local)) continue;
|
|
4982
5035
|
const declared = source.resolve("style-property", prop);
|
|
4983
5036
|
if (!declared) continue;
|
|
4984
5037
|
members.add(target);
|
|
@@ -5027,15 +5080,37 @@ var Config = class Config {
|
|
|
5027
5080
|
}
|
|
5028
5081
|
}
|
|
5029
5082
|
};
|
|
5083
|
+
const visitExtension = ({ kind, extension, linked = false }) => {
|
|
5084
|
+
const base = source.resolve(kind, pathOf(extension));
|
|
5085
|
+
if (!base) return;
|
|
5086
|
+
const body = this.laidLinkedBody({
|
|
5087
|
+
kind,
|
|
5088
|
+
path: pathOf(extension),
|
|
5089
|
+
body: qualifyRefs({
|
|
5090
|
+
value: base.toJSON(),
|
|
5091
|
+
source: slug,
|
|
5092
|
+
owns: (name) => source.ownedKinds().includes(name)
|
|
5093
|
+
}),
|
|
5094
|
+
extend: extension.extend
|
|
5095
|
+
});
|
|
5096
|
+
visitEntity(kind, body, false, linked);
|
|
5097
|
+
visitBags(kind, body, linked);
|
|
5098
|
+
};
|
|
5030
5099
|
for (const kind of this.ownedKinds()) {
|
|
5031
5100
|
const slice = this.state.snapshot.slice(kind);
|
|
5032
5101
|
for (const [, stored] of slice.items) {
|
|
5033
5102
|
const body = stored.toJSON();
|
|
5034
5103
|
if (isMintedRow(body)) continue;
|
|
5104
|
+
if (isExtendedRef(body) && sourceOf(body) === slug) {
|
|
5105
|
+
visitExtension({
|
|
5106
|
+
kind,
|
|
5107
|
+
extension: body
|
|
5108
|
+
});
|
|
5109
|
+
continue;
|
|
5110
|
+
}
|
|
5035
5111
|
if (isRef(body) && sourceOf(body) === slug) {
|
|
5036
5112
|
const theirs = source.resolve(kindOf(body), pathOf(body))?.toJSON();
|
|
5037
5113
|
if (theirs) visitEntity(kind, theirs, true);
|
|
5038
|
-
if (isExtendedRef(body)) visit(body.extend);
|
|
5039
5114
|
continue;
|
|
5040
5115
|
}
|
|
5041
5116
|
visitEntity(kind, body);
|
|
@@ -5047,6 +5122,15 @@ var Config = class Config {
|
|
|
5047
5122
|
}
|
|
5048
5123
|
}
|
|
5049
5124
|
for (const target of this.adoptedFrom(slug)) {
|
|
5125
|
+
const local = this.storedBody(kindOf(target), pathOf(target));
|
|
5126
|
+
if (isExtendedRef(local) && !isMintedRow(local) && sourceOf(local) === slug) {
|
|
5127
|
+
visitExtension({
|
|
5128
|
+
kind: kindOf(target),
|
|
5129
|
+
extension: local,
|
|
5130
|
+
linked: true
|
|
5131
|
+
});
|
|
5132
|
+
continue;
|
|
5133
|
+
}
|
|
5050
5134
|
const body = source.resolve(kindOf(target), pathOf(target))?.toJSON();
|
|
5051
5135
|
if (body) visitEntity(kindOf(target), body, true, true);
|
|
5052
5136
|
}
|
|
@@ -5749,7 +5833,7 @@ var Config = class Config {
|
|
|
5749
5833
|
* links from the provided sources. A declared `linkedKind` with no provided source throws. */
|
|
5750
5834
|
hydrateFrom(stored, options) {
|
|
5751
5835
|
const claimed = schemaVersionOf(stored);
|
|
5752
|
-
if (claimed >
|
|
5836
|
+
if (claimed > 20261013164300) throw new SchemaVersionTooNew(claimed);
|
|
5753
5837
|
const wire = upgradeSerializedConfig(stored);
|
|
5754
5838
|
if (!Array.isArray(wire.ownedKinds) || typeof wire.items !== "object" || wire.items === null) throw new ConfigFormatError(`Config "${stored.name ?? "system-config"}" cannot be hydrated: this is not a serialized config-v2 config (no "ownedKinds"/"items"). A pre-cutover build artifact converts through the registered cutover migration — import the config type's module (e.g. \`configs/system\`) before hydrating, or port the repo once with \`uds migrate\`.`);
|
|
5755
5839
|
const leftover = wire.options;
|
|
@@ -16,7 +16,7 @@ interface KindSignature {
|
|
|
16
16
|
readonly collections: Record<string, string>;
|
|
17
17
|
/** The group node's own fields, when the kind carries any. */
|
|
18
18
|
readonly group?: string;
|
|
19
|
-
/** A real entry from this config,
|
|
19
|
+
/** A real entry from this config, as it is authored. */
|
|
20
20
|
readonly example?: unknown;
|
|
21
21
|
}
|
|
22
22
|
interface AuthoringSignatureOptions {
|
|
@@ -75,6 +75,19 @@ function authoringSignature(schema, options) {
|
|
|
75
75
|
const json = jsonSchema(schema);
|
|
76
76
|
return json === void 0 ? void 0 : renderSignature(withoutMetadata(json), options);
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* A real entry, spelled the way it is authored. A collection whose schema offers only a list (see
|
|
80
|
+
* `withDeprecated`) is stored as the record keyed by its members, so the example writes its members
|
|
81
|
+
* as that list, and a reader copying it never learns the deprecated record.
|
|
82
|
+
*/
|
|
83
|
+
function authoredExample({ item, fields }) {
|
|
84
|
+
const body = item.toJSON();
|
|
85
|
+
const properties = fields?.properties;
|
|
86
|
+
if (!properties) return { [item.path]: body };
|
|
87
|
+
const authored = { ...body };
|
|
88
|
+
for (const [field, value] of Object.entries(body)) if (properties[field]?.type === "array" && value && typeof value === "object" && !Array.isArray(value)) authored[field] = Object.values(value);
|
|
89
|
+
return { [item.path]: authored };
|
|
90
|
+
}
|
|
78
91
|
/** Every owned kind's authoring shape as signatures, with a real example where the config has one. */
|
|
79
92
|
function authoringSignatures(config, { depth, memberDepth = depth } = {}) {
|
|
80
93
|
return config.ownedKinds().flatMap((kind) => {
|
|
@@ -87,14 +100,18 @@ function authoringSignatures(config, { depth, memberDepth = depth } = {}) {
|
|
|
87
100
|
if (signature) collections[field] = singleton ? `one section, no key (\`sub-update/${field}\`): ${signature}` : signature;
|
|
88
101
|
}
|
|
89
102
|
const first = config.list(kind)[0];
|
|
103
|
+
const create = dataSchemaOf(config, entity.schemas.create);
|
|
90
104
|
return [{
|
|
91
105
|
kind,
|
|
92
106
|
label: entity.label,
|
|
93
107
|
refHelper: entity.entityName,
|
|
94
|
-
create: authoringSignature(
|
|
108
|
+
create: authoringSignature(create, { depth }),
|
|
95
109
|
collections,
|
|
96
110
|
group: authoringSignature(entity.groupCreateSchema, { depth }),
|
|
97
|
-
example: first ? {
|
|
111
|
+
example: first ? authoredExample({
|
|
112
|
+
item: first,
|
|
113
|
+
fields: jsonSchema(create)
|
|
114
|
+
}) : void 0
|
|
98
115
|
}];
|
|
99
116
|
});
|
|
100
117
|
}
|
|
@@ -137,14 +154,18 @@ function authoringReference(config) {
|
|
|
137
154
|
collections[field] = jsonSchema(dataSchemaOf(config, entity.schemas[`sub-create/${field}`]));
|
|
138
155
|
}
|
|
139
156
|
const first = config.list(kind)[0];
|
|
157
|
+
const fields = jsonSchema(dataSchemaOf(config, entity.schemas.create));
|
|
140
158
|
return [{
|
|
141
159
|
kind,
|
|
142
160
|
label: entity.label,
|
|
143
161
|
refHelper: entity.entityName,
|
|
144
|
-
fields
|
|
162
|
+
fields,
|
|
145
163
|
collections,
|
|
146
164
|
groupFields: jsonSchema(entity.groupCreateSchema),
|
|
147
|
-
example: first ? {
|
|
165
|
+
example: first ? authoredExample({
|
|
166
|
+
item: first,
|
|
167
|
+
fields
|
|
168
|
+
}) : void 0
|
|
148
169
|
}];
|
|
149
170
|
}) };
|
|
150
171
|
}
|
|
@@ -36,6 +36,9 @@ type SubEntityClass<F extends z.ZodTypeAny = z.ZodTypeAny> = CollectionSchema<F>
|
|
|
36
36
|
* caller, so key and value can't drift, two members with the same identity can't both exist, and
|
|
37
37
|
* an edit that changes the identity moves the entry. Omit when the key is arbitrary. */
|
|
38
38
|
readonly key?: (member: unknown) => string;
|
|
39
|
+
/** The collection is authored as a list of its members, which carry their own `key`. The keyed
|
|
40
|
+
* record it is stored as is still read but no longer offered: see {@link orList}. */
|
|
41
|
+
readonly listed?: true;
|
|
39
42
|
/** Whether a member DECLARES nothing — a style rule whose every layer bag is empty. Asked only
|
|
40
43
|
* when a \`sub-update\` would bring the member into being: a delta made entirely of removals has
|
|
41
44
|
* nothing to remove from a member that is not there, so creating one files an entry that emits
|
|
@@ -143,6 +146,7 @@ declare function defineSubEntity<F extends z.ZodTypeAny>(spec: {
|
|
|
143
146
|
*/
|
|
144
147
|
base?: z.ZodTypeAny;
|
|
145
148
|
key?: (member: unknown) => string;
|
|
149
|
+
listed?: true;
|
|
146
150
|
vacant?: (member: unknown) => boolean;
|
|
147
151
|
schemas?: UserSchemas;
|
|
148
152
|
namespaces?: string;
|
|
@@ -161,6 +165,9 @@ declare function defineSubEntity<F extends z.ZodTypeAny>(spec: {
|
|
|
161
165
|
* Two members with the same key are one member, the later one, as the key derivation on write
|
|
162
166
|
* already treats a record whose keys disagree with their members — unless `merge` says how the two
|
|
163
167
|
* combine, in which case the member is `merge(earlier, later)`, placed where the later one was.
|
|
168
|
+
*
|
|
169
|
+
* A collection declared `listed` still takes the keyed record but offers only the list, see
|
|
170
|
+
* {@link withDeprecated}.
|
|
164
171
|
*/
|
|
165
172
|
declare function orList<F extends z.ZodTypeAny>(collection: SubEntityClass<F>, {
|
|
166
173
|
merge
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { kindOf, memberOf, memberRef, pathOf } from "./utils/refs.js";
|
|
2
2
|
import { resolveSchema } from "./schemas.js";
|
|
3
3
|
import { titleCase } from "./registry.js";
|
|
4
|
+
import { withDeprecated } from "./utils/deprecated.js";
|
|
4
5
|
import { z } from "zod";
|
|
5
6
|
//#region src/framework/defineSubEntity.ts
|
|
6
7
|
/**
|
|
@@ -78,6 +79,7 @@ function defineSubEntity(spec) {
|
|
|
78
79
|
fields: spec.fields,
|
|
79
80
|
base: spec.base,
|
|
80
81
|
key: spec.key,
|
|
82
|
+
...spec.listed ? { listed: true } : {},
|
|
81
83
|
vacant: spec.vacant,
|
|
82
84
|
schemas: spec.schemas,
|
|
83
85
|
namespaces: spec.namespaces,
|
|
@@ -126,6 +128,9 @@ function defineSubEntity(spec) {
|
|
|
126
128
|
* Two members with the same key are one member, the later one, as the key derivation on write
|
|
127
129
|
* already treats a record whose keys disagree with their members — unless `merge` says how the two
|
|
128
130
|
* combine, in which case the member is `merge(earlier, later)`, placed where the later one was.
|
|
131
|
+
*
|
|
132
|
+
* A collection declared `listed` still takes the keyed record but offers only the list, see
|
|
133
|
+
* {@link withDeprecated}.
|
|
129
134
|
*/
|
|
130
135
|
function orList(collection, { merge } = {}) {
|
|
131
136
|
const key = collection.key;
|
|
@@ -142,6 +147,10 @@ function orList(collection, { merge } = {}) {
|
|
|
142
147
|
}
|
|
143
148
|
return keyed;
|
|
144
149
|
});
|
|
150
|
+
if (collection.listed) return withDeprecated({
|
|
151
|
+
offered: listed,
|
|
152
|
+
deprecated: collection
|
|
153
|
+
});
|
|
145
154
|
return z.union([listed, collection]);
|
|
146
155
|
}
|
|
147
156
|
//#endregion
|
|
@@ -15,7 +15,7 @@ import { Patch, SerializedConfig } from "./Config.js";
|
|
|
15
15
|
* sets this constant to its own older timestamp; the merge ref then carries a registered migration
|
|
16
16
|
* newer than the constant, and the assertion fails until the author re-mints.
|
|
17
17
|
*/
|
|
18
|
-
declare const CURRENT_SCHEMA_VERSION =
|
|
18
|
+
declare const CURRENT_SCHEMA_VERSION = 20261013164300;
|
|
19
19
|
/** What the walkers need to see of an envelope — loose on purpose, so a typed `SerializedConfig`
|
|
20
20
|
* and a raw old-shape record both flow in without casts. */
|
|
21
21
|
interface VersionStamped {
|
|
@@ -13,7 +13,7 @@ import { ConfigFormatError } from "./rejection.js";
|
|
|
13
13
|
* sets this constant to its own older timestamp; the merge ref then carries a registered migration
|
|
14
14
|
* newer than the constant, and the assertion fails until the author re-mints.
|
|
15
15
|
*/
|
|
16
|
-
const CURRENT_SCHEMA_VERSION =
|
|
16
|
+
const CURRENT_SCHEMA_VERSION = 20261013164300;
|
|
17
17
|
/** The mint that moved `options` into the `settings` kind — restated here, rather than imported
|
|
18
18
|
* from the migration that owns it, because that migration imports this module. */
|
|
19
19
|
const SETTINGS_AS_KIND_VERSION = 20260908171448;
|
|
@@ -45,7 +45,7 @@ function registerSchemaMigrations(...migrations) {
|
|
|
45
45
|
for (const migration of migrations) {
|
|
46
46
|
if (migration.version !== 1 && !isMintTimestamp(migration.version)) throw new Error(`Schema migration version ${migration.version} is not a mint timestamp — mint one with \`date +%Y%m%d%H%M%S\`, like a supabase migration.`);
|
|
47
47
|
if (REGISTERED.has(migration.version)) throw new Error(`A schema migration at version ${migration.version} is already registered.`);
|
|
48
|
-
if (migration.version >
|
|
48
|
+
if (migration.version > 20261013164300) throw new Error(`Schema migration ${migration.version} is newer than CURRENT_SCHEMA_VERSION (${CURRENT_SCHEMA_VERSION}) — a stale branch merged, or the mint forgot to bump the constant. Re-mint: set CURRENT_SCHEMA_VERSION to the newest migration version.`);
|
|
49
49
|
REGISTERED.set(migration.version, migration);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
@@ -102,7 +102,7 @@ function pendingFor(version, target, options) {
|
|
|
102
102
|
* Already-current input passes through untouched — same reference, so hot paths pay nothing.
|
|
103
103
|
*/
|
|
104
104
|
function upgradeSerializedConfig(json, options) {
|
|
105
|
-
const target = options?.target ??
|
|
105
|
+
const target = options?.target ?? 20261013164300;
|
|
106
106
|
const version = detectedWireVersion(json);
|
|
107
107
|
if (version > target) throw new SchemaVersionTooNew(version, target);
|
|
108
108
|
const raw = json;
|
|
@@ -160,7 +160,7 @@ function upgradedSources(json, options) {
|
|
|
160
160
|
* meaning under the current schema and replay skips it — reported by the caller, not swallowed here.
|
|
161
161
|
*/
|
|
162
162
|
function upgradePatch(patch, writtenAt, options) {
|
|
163
|
-
const target = options?.target ??
|
|
163
|
+
const target = options?.target ?? 20261013164300;
|
|
164
164
|
if (writtenAt > target) throw new SchemaVersionTooNew(writtenAt, target);
|
|
165
165
|
let current = patch;
|
|
166
166
|
for (const migration of pendingFor(writtenAt, target, options)) {
|
|
@@ -179,7 +179,7 @@ function upgradePatch(patch, writtenAt, options) {
|
|
|
179
179
|
* stamp would cause.
|
|
180
180
|
*/
|
|
181
181
|
function upgradeDraftEntries(draft, options) {
|
|
182
|
-
const target = options?.target ??
|
|
182
|
+
const target = options?.target ?? 20261013164300;
|
|
183
183
|
const entries = [];
|
|
184
184
|
const held = [];
|
|
185
185
|
const retired = [];
|
|
@@ -430,7 +430,10 @@ function unstatableConditions(config) {
|
|
|
430
430
|
for (const slug of config.sourceSlugs()) {
|
|
431
431
|
const source = config.sourceFor(slug);
|
|
432
432
|
if (!source) continue;
|
|
433
|
-
for (const target of config.
|
|
433
|
+
for (const target of config.runtimeSourceClosure({
|
|
434
|
+
slug,
|
|
435
|
+
kind: "token"
|
|
436
|
+
})) {
|
|
434
437
|
const token = pathOf(target);
|
|
435
438
|
const { overrides } = source.resolve("token", token)?.toJSON() ?? {};
|
|
436
439
|
if (!overrides) continue;
|