@yahoo/uds-create-config 2.20.0 → 2.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/Config.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CssVarRef } from "./types/css-values.js";
2
- import { AnyStylePropDefinition, BuildOptions, CanvasRole, CanvasRoleEntry, CanvasRolesDefinitionInput, CanvasRolesInputConstraint, ComponentDefinition, ComponentGroupDefinition, CompositeStyleDefinition, GlobalStylesDef, LinkedComponentsInput, LinkedSystemEntry, ModeDefinition, ModifierDefinition, MotionDefinitionInput, PlaygroundOptions, SerializedConfig, TokenGroupDefinition, TokenModifierKey } from "./types.js";
2
+ import { AnyStylePropDefinition, BuildOptions, CanvasRole, CanvasRoleEntry, CanvasRolesDefinitionInput, CanvasRolesInputConstraint, ComponentDefinition, ComponentGroupDefinition, CompositeStyleDefinition, GlobalStylesDef, LinkedSystemPin, LinkedSystemsInput, ModeDefinition, ModifierDefinition, MotionDefinitionInput, PlaygroundOptions, SerializedConfig, SystemLink, TokenGroupDefinition, TokenModifierKey } from "./types.js";
3
3
  import { AssetGroupDefinition } from "./defineAssetGroup.js";
4
4
  import { AssetGroup } from "./AssetGroup.js";
5
5
  import { cssVar } from "./brands.js";
@@ -94,11 +94,12 @@ declare class Config {
94
94
  readonly motion: Map<string, MotionDef>;
95
95
  readonly canvasRoles: Map<CanvasRole, readonly CanvasRoleEntry[]>;
96
96
  /**
97
- * Components linked from other systems via {@link registerLinkedComponents},
98
- * keyed by the source system's database UUID. Declaration only — resolution
99
- * (materialized sources, rendering) is a separate, later concern.
97
+ * Source systems pinned via {@link registerLinkedSystems}, keyed by the
98
+ * source system's database UUID. A pin anchors every linked value from that
99
+ * system to one exact published version — registration validates each
100
+ * link-marked value against it.
100
101
  */
101
- readonly linkedComponents: Map<string, LinkedSystemEntry>;
102
+ readonly linkedSystems: Map<string, LinkedSystemPin>;
102
103
  /**
103
104
  * Set top-level config metadata in one call — the single scalar-setter,
104
105
  * replacing the former `withPrefix` / `withPreflight` / `withName` /
@@ -149,20 +150,6 @@ declare class Config {
149
150
  * `config.components.get(type)` when `type` may be a spec/registry key.
150
151
  */
151
152
  getComponent(type: string): Component | undefined;
152
- /**
153
- * Identify an id-qualified linked-component reference
154
- * (`'<systemId>:<Name>'`, e.g. `'96d1678f-…:Button'`). Returns the parsed
155
- * `{ systemId, name }` when the system id is a registered
156
- * {@link linkedComponents} entry AND the bare name is declared in its
157
- * `components` list; `undefined` otherwise (including bare names and
158
- * namespaced registry keys). This is declaration-lookup only — it never
159
- * returns a renderable {@link Component}; resolution is deferred to the
160
- * materialization/rendering work.
161
- */
162
- getLinkedComponentRef(type: string): {
163
- systemId: string;
164
- name: string;
165
- } | undefined;
166
153
  /**
167
154
  * The bare, human-readable component name for a spec `type` — strips this
168
155
  * registry's `<namespace>:` prefix (`'uds:Text'` → `'Text'`) for display, and
@@ -331,18 +318,19 @@ declare class Config {
331
318
  registerComposites(composites: Record<string, CompositeStyleDefinition>): this;
332
319
  registerMotion(motion: Record<string, MotionDefinitionInput>): this;
333
320
  /**
334
- * Declare components linked from other systems. Each record key is the
335
- * source system's database UUID (the identity — globally unique, immutable,
336
- * rename-proof); the entry carries the system's display-name snapshot at
337
- * link time, an exact published version pin, and the bare names of the
338
- * linked components.
321
+ * Pin the source systems this config links values from. Each record key is
322
+ * the source system's database UUID (the identity — globally unique,
323
+ * immutable, rename-proof); the pin carries the system's display-name
324
+ * snapshot at link time and an exact published version.
339
325
  *
340
- * This is a data-only declaration: no imported component values, no
341
- * layer/prop specs. A linked component's qualified reference is
342
- * `<systemId>:<Name>` (see {@link getLinkedComponentRef}); resolution to a
343
- * renderable component is deferred to the materialization/rendering work.
326
+ * One pin per system, one version per pin. Every linked value registered
327
+ * afterwards (a barrel value carrying a `link` marker) is validated against
328
+ * its pin — an unpinned system or a version mismatch throws at
329
+ * registration, so pins must appear before the `register*` calls that use
330
+ * them. The pin's `name` also feeds the registry folder slug the pull
331
+ * pipeline derives.
344
332
  */
345
- registerLinkedComponents(input: LinkedComponentsInput): this;
333
+ registerLinkedSystems(input: LinkedSystemsInput): this;
346
334
  registerComponents(components: Record<string, ComponentDefinition>): this;
347
335
  /**
348
336
  * Build a single component from its definition with this config's context
@@ -437,6 +425,13 @@ declare class Config {
437
425
  registerProviders(providers: Record<string, ProviderComponent<Record<never, never>>>): this;
438
426
  get derived(): {
439
427
  readonly tokens: ReadonlyMap<string, Token>;
428
+ /**
429
+ * Provenance index for linked tokens — `"<systemId>:<sourceKey>"` →
430
+ * token. A `token()` ref authored inside a linked token names SOURCE-
431
+ * system groups, so it resolves through this index (rename-proof: the
432
+ * consumer's local group name never appears in the key).
433
+ */
434
+ readonly tokensBySource: ReadonlyMap<string, Token>;
440
435
  readonly cssVarRefs: Readonly<Record<string, Readonly<Record<string, CssVarRef>>>>;
441
436
  /**
442
437
  * Reverse lookup: a style modifier key (`_dark`) → the mode option that
@@ -446,6 +441,16 @@ declare class Config {
446
441
  */
447
442
  readonly modeOptionsByModifier: ReadonlyMap<TokenModifierKey, ModeOption>;
448
443
  };
444
+ /**
445
+ * Resolve a `token()` ref, provenance-aware — the ONE lookup every ref
446
+ * consumer (registration wiring, `validate()`, codegen emission) should
447
+ * use. A ref authored on a linked token (`context` set) names the SOURCE
448
+ * system's groups, so it resolves through the provenance index only —
449
+ * falling back to the consumer's own keys would let a coincidentally-named
450
+ * local group silently shadow a missing source group. Local refs resolve
451
+ * against consumer keys.
452
+ */
453
+ resolveTokenRef(ref: string, context?: SystemLink): Token | undefined;
449
454
  /**
450
455
  * Validate cross-references. Throws on cycles in token aliases or on
451
456
  * unknown refs in markers (`token()`, `composite()`, `mode()`,
package/dist/Config.js CHANGED
@@ -65,11 +65,12 @@ var Config = class Config {
65
65
  motion = /* @__PURE__ */ new Map();
66
66
  canvasRoles = /* @__PURE__ */ new Map();
67
67
  /**
68
- * Components linked from other systems via {@link registerLinkedComponents},
69
- * keyed by the source system's database UUID. Declaration only — resolution
70
- * (materialized sources, rendering) is a separate, later concern.
68
+ * Source systems pinned via {@link registerLinkedSystems}, keyed by the
69
+ * source system's database UUID. A pin anchors every linked value from that
70
+ * system to one exact published version — registration validates each
71
+ * link-marked value against it.
71
72
  */
72
- linkedComponents = /* @__PURE__ */ new Map();
73
+ linkedSystems = /* @__PURE__ */ new Map();
73
74
  #derived;
74
75
  /**
75
76
  * Set top-level config metadata in one call — the single scalar-setter,
@@ -134,27 +135,6 @@ var Config = class Config {
134
135
  if (namespace !== void 0 && namespace === this.namespace) return this.components.get(name);
135
136
  }
136
137
  /**
137
- * Identify an id-qualified linked-component reference
138
- * (`'<systemId>:<Name>'`, e.g. `'96d1678f-…:Button'`). Returns the parsed
139
- * `{ systemId, name }` when the system id is a registered
140
- * {@link linkedComponents} entry AND the bare name is declared in its
141
- * `components` list; `undefined` otherwise (including bare names and
142
- * namespaced registry keys). This is declaration-lookup only — it never
143
- * returns a renderable {@link Component}; resolution is deferred to the
144
- * materialization/rendering work.
145
- */
146
- getLinkedComponentRef(type) {
147
- const { namespace: systemId, name } = parseRegistryKey(type);
148
- if (systemId === void 0) return void 0;
149
- const entry = this.linkedComponents.get(systemId);
150
- if (!entry) return void 0;
151
- if (entry.components !== "all" && !entry.components.includes(name)) return;
152
- return {
153
- systemId,
154
- name
155
- };
156
- }
157
- /**
158
138
  * The bare, human-readable component name for a spec `type` — strips this
159
139
  * registry's `<namespace>:` prefix (`'uds:Text'` → `'Text'`) for display, and
160
140
  * the `foreign:` sentinel third-party leaves carry (`'foreign:CopyIcon'` →
@@ -900,13 +880,16 @@ var Config = class Config {
900
880
  return this;
901
881
  }
902
882
  registerTokenGroups(groups) {
903
- for (const [namespace, def] of Object.entries(groups)) this.tokenGroups.set(namespace, new TokenGroup({
904
- namespace,
905
- prefixGetter: () => this.prefix,
906
- definition: def,
907
- tokenLookup: (ref) => this.derived.tokens.get(ref),
908
- stylePropertiesLookup: (ns) => this.#stylePropertiesFor(ns)
909
- }));
883
+ for (const [namespace, def] of Object.entries(groups)) {
884
+ for (const [tokenName, tokenDef] of Object.entries(def.tokens)) this.#assertLinkedTokenPinned(namespace, tokenName, tokenDef.link);
885
+ this.tokenGroups.set(namespace, new TokenGroup({
886
+ namespace,
887
+ prefixGetter: () => this.prefix,
888
+ definition: def,
889
+ tokenLookup: (ref, context) => this.resolveTokenRef(ref, context),
890
+ stylePropertiesLookup: (ns) => this.#stylePropertiesFor(ns)
891
+ }));
892
+ }
910
893
  this.#invalidate();
911
894
  return this;
912
895
  }
@@ -938,24 +921,24 @@ var Config = class Config {
938
921
  return this;
939
922
  }
940
923
  /**
941
- * Declare components linked from other systems. Each record key is the
942
- * source system's database UUID (the identity — globally unique, immutable,
943
- * rename-proof); the entry carries the system's display-name snapshot at
944
- * link time, an exact published version pin, and the bare names of the
945
- * linked components.
924
+ * Pin the source systems this config links values from. Each record key is
925
+ * the source system's database UUID (the identity — globally unique,
926
+ * immutable, rename-proof); the pin carries the system's display-name
927
+ * snapshot at link time and an exact published version.
946
928
  *
947
- * This is a data-only declaration: no imported component values, no
948
- * layer/prop specs. A linked component's qualified reference is
949
- * `<systemId>:<Name>` (see {@link getLinkedComponentRef}); resolution to a
950
- * renderable component is deferred to the materialization/rendering work.
929
+ * One pin per system, one version per pin. Every linked value registered
930
+ * afterwards (a barrel value carrying a `link` marker) is validated against
931
+ * its pin — an unpinned system or a version mismatch throws at
932
+ * registration, so pins must appear before the `register*` calls that use
933
+ * them. The pin's `name` also feeds the registry folder slug the pull
934
+ * pipeline derives.
951
935
  */
952
- registerLinkedComponents(input) {
953
- for (const [systemId, entry] of Object.entries(input)) {
954
- validateLinkedSystemEntry(systemId, entry, this.linkedComponents);
955
- this.linkedComponents.set(systemId, {
956
- name: entry.name,
957
- version: entry.version,
958
- components: entry.components === "all" ? "all" : [...entry.components]
936
+ registerLinkedSystems(input) {
937
+ for (const [systemId, pin] of Object.entries(input)) {
938
+ validateLinkedSystemPin(systemId, pin, this.linkedSystems);
939
+ this.linkedSystems.set(systemId, {
940
+ name: pin.name,
941
+ version: pin.version
959
942
  });
960
943
  }
961
944
  return this;
@@ -1254,11 +1237,13 @@ var Config = class Config {
1254
1237
  get derived() {
1255
1238
  if (!this.#derived) {
1256
1239
  const tokens = /* @__PURE__ */ new Map();
1240
+ const tokensBySource = /* @__PURE__ */ new Map();
1257
1241
  const cssVarRefs = {};
1258
1242
  for (const [namespace, group] of this.tokenGroups) {
1259
1243
  const groupRefs = {};
1260
1244
  for (const [name, token] of group.tokens) {
1261
1245
  tokens.set(`${namespace}/${name}`, token);
1246
+ if (token.link) tokensBySource.set(`${token.link.systemId}:${token.link.sourceKey}`, token);
1262
1247
  groupRefs[name] = token.derived.cssVarRef;
1263
1248
  }
1264
1249
  cssVarRefs[namespace] = groupRefs;
@@ -1272,12 +1257,39 @@ var Config = class Config {
1272
1257
  }
1273
1258
  this.#derived = {
1274
1259
  tokens,
1260
+ tokensBySource,
1275
1261
  cssVarRefs,
1276
1262
  modeOptionsByModifier
1277
1263
  };
1278
1264
  }
1279
1265
  return this.#derived;
1280
1266
  }
1267
+ /**
1268
+ * Resolve a `token()` ref, provenance-aware — the ONE lookup every ref
1269
+ * consumer (registration wiring, `validate()`, codegen emission) should
1270
+ * use. A ref authored on a linked token (`context` set) names the SOURCE
1271
+ * system's groups, so it resolves through the provenance index only —
1272
+ * falling back to the consumer's own keys would let a coincidentally-named
1273
+ * local group silently shadow a missing source group. Local refs resolve
1274
+ * against consumer keys.
1275
+ */
1276
+ resolveTokenRef(ref, context) {
1277
+ if (context) return this.derived.tokensBySource.get(`${context.systemId}:${ref}`);
1278
+ return this.derived.tokens.get(ref);
1279
+ }
1280
+ /**
1281
+ * Pin-consistency gate for a link-marked token entering the registry.
1282
+ * Catches hand-forged markers (unpinned system), stale registry barrels
1283
+ * (version mismatch), and mis-kinded markers before they poison lookups.
1284
+ */
1285
+ #assertLinkedTokenPinned(groupName, tokenName, link) {
1286
+ if (!link) return;
1287
+ const label = `Config.registerTokenGroups: token "${groupName}/${tokenName}"`;
1288
+ if (link.kind !== "token") throw new Error(`${label} carries a "${link.kind}" link marker — a token entry can only carry kind "token" (a token-group link spreads to per-token markers).`);
1289
+ const pin = this.linkedSystems.get(link.systemId);
1290
+ if (!pin) throw new Error(`${label} is linked from system "${link.systemId}", which has no registerLinkedSystems pin — pin the system (name + exact version) before registering values linked from it.`);
1291
+ if (pin.version !== link.systemVersion) throw new Error(`${label} is linked at version "${link.systemVersion}" but system "${pin.name}" is pinned at "${pin.version}" — the registry barrel is stale; re-run \`uds pull\`.`);
1292
+ }
1281
1293
  #invalidate() {
1282
1294
  this.#derived = void 0;
1283
1295
  }
@@ -1334,7 +1346,7 @@ var Config = class Config {
1334
1346
  */
1335
1347
  validate() {
1336
1348
  const tokens = this.derived.tokens;
1337
- for (const [qualified, token] of tokens) visit(qualified, token, tokens, /* @__PURE__ */ new Set());
1349
+ for (const [qualified, token] of tokens) visit(qualified, token, (ref, context) => this.resolveTokenRef(ref, context), /* @__PURE__ */ new Set());
1338
1350
  for (const styleProp of this.styleProps.values()) for (const groupName of styleProp.consumedTokenGroups()) if (!this.tokenGroups.has(groupName)) throw new Error(`Style prop '${styleProp.name}' references unknown token group '${groupName}'`);
1339
1351
  for (const modifier of this.modifiers.values()) {
1340
1352
  const selector = modifier.selector;
@@ -1422,10 +1434,7 @@ var Config = class Config {
1422
1434
  out.canvasRoles = canvasRoles;
1423
1435
  }
1424
1436
  if (this.playgroundOptions.port !== void 0) out.playgroundOptions = { port: this.playgroundOptions.port };
1425
- if (this.linkedComponents.size > 0) out.linkedComponents = mapToRecord(this.linkedComponents, (entry) => ({
1426
- ...entry,
1427
- components: entry.components === "all" ? "all" : [...entry.components]
1428
- }));
1437
+ if (this.linkedSystems.size > 0) out.linkedSystems = mapToRecord(this.linkedSystems, (pin) => ({ ...pin }));
1429
1438
  return out;
1430
1439
  }
1431
1440
  /**
@@ -1444,12 +1453,12 @@ var Config = class Config {
1444
1453
  if (json.globalStyles) config.globalStyles = json.globalStyles;
1445
1454
  if (json.rawCss) config.rawCss = [...json.rawCss];
1446
1455
  if (json.modes) config.registerModes(json.modes);
1456
+ if (json.linkedSystems) config.registerLinkedSystems(json.linkedSystems);
1447
1457
  if (json.tokenGroups) config.registerTokenGroups(json.tokenGroups);
1448
1458
  if (json.styleProps) config.registerStyleProps(json.styleProps);
1449
1459
  if (json.modifiers) config.registerModifiers(json.modifiers);
1450
1460
  if (json.compositeStyles) config.registerComposites(json.compositeStyles);
1451
1461
  if (json.motion) config.registerMotion(json.motion);
1452
- if (json.linkedComponents) config.registerLinkedComponents(json.linkedComponents);
1453
1462
  const componentsByName = json.components ?? {};
1454
1463
  for (const def of Object.values(componentsByName)) if (def.sourceFilePath) attachSourcePath(def, def.sourceFilePath);
1455
1464
  const isSubcomponent = /* @__PURE__ */ new Set();
@@ -1569,20 +1578,15 @@ function parseRegistryKey(type) {
1569
1578
  const UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
1570
1579
  /** Exact `major.minor.patch` with optional prerelease/build — no ranges. */
1571
1580
  const EXACT_SEMVER_RE = /^\d+\.\d+\.\d+(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
1572
- function validateLinkedSystemEntry(systemId, entry, existing) {
1573
- const label = `Config.registerLinkedComponents: system id "${systemId}"`;
1574
- if (!UUID_RE.test(systemId)) throw new Error(`${label} must be a UUID — links are keyed by the source system's database id, not its slug or name.`);
1575
- if (existing.has(systemId)) throw new Error(`${label} is already linked ("${existing.get(systemId)?.name}") — update or remove the existing entry instead of re-linking.`);
1576
- if (entry.name.trim().length === 0) throw new Error(`${label}: name must be non-empty — it's the system's display-name snapshot at link time.`);
1577
- if (!EXACT_SEMVER_RE.test(entry.version)) throw new Error(`${label}: version "${entry.version}" must be an exact semver literal (e.g. "1.3.1") — ranges and tags are not supported.`);
1578
- if (entry.components === "all") return;
1579
- if (entry.components.length === 0) throw new Error(`${label}: at least one component name is required (or pass 'all' to link every component).`);
1580
- const seen = /* @__PURE__ */ new Set();
1581
- for (const name of entry.components) {
1582
- if (name.trim().length === 0) throw new Error(`${label}: component names must be non-empty strings.`);
1583
- if (seen.has(name)) throw new Error(`${label}: duplicate component "${name}".`);
1584
- seen.add(name);
1585
- }
1581
+ function validateLinkedSystemPin(systemId, pin, existing) {
1582
+ const label = `Config.registerLinkedSystems: system id "${systemId}"`;
1583
+ if (!UUID_RE.test(systemId)) throw new Error(`${label} must be a UUID — pins are keyed by the source system's database id, not its slug or name.`);
1584
+ if (existing.has(systemId)) {
1585
+ const prior = existing.get(systemId);
1586
+ throw new Error(`${label} is already pinned ("${prior?.name}" @ ${prior?.version}) — a config pins one version per system; update the existing pin instead of re-pinning.`);
1587
+ }
1588
+ if (pin.name.trim().length === 0) throw new Error(`${label}: name must be non-empty — it's the system's display-name snapshot at link time and feeds the registry folder slug.`);
1589
+ if (!EXACT_SEMVER_RE.test(pin.version)) throw new Error(`${label}: version "${pin.version}" must be an exact semver literal (e.g. "1.3.1") — ranges and tags are not supported.`);
1586
1590
  }
1587
1591
  function validateNamespace(value) {
1588
1592
  if (value.length === 0) throw new Error("Config.configure: namespace must be non-empty.");
@@ -1591,15 +1595,39 @@ function validateNamespace(value) {
1591
1595
  if (value === "foreign") throw new Error(`Config.configure: namespace "${FOREIGN_NAMESPACE}" is reserved for third-party leaf components (the \`${FOREIGN_NAMESPACE}:<Component>\` sentinel).`);
1592
1596
  return value;
1593
1597
  }
1594
- function visit(qualified, token, tokens, seen) {
1598
+ /**
1599
+ * Cross-reference walk for one token's alias chain, provenance-aware.
1600
+ * `resolve` is the config's `resolveTokenRef` — a ref on a linked token
1601
+ * resolves through the provenance index (source-system keys), a local ref
1602
+ * through consumer keys. A dangling ref on a linked token is a closure
1603
+ * violation (the source group it names was never linked), which gets its own
1604
+ * actionable error; a dangling local ref stays the classic unknown-token
1605
+ * error. Modifier refs are checked for linked tokens only — the closure rule
1606
+ * is new with linking, and local modifier behavior is unchanged.
1607
+ */
1608
+ function visit(qualified, token, resolve, seen) {
1595
1609
  if (seen.has(qualified)) throw new Error(`Token cycle detected at '${qualified}'`);
1596
- const value = token.value;
1597
- if (typeof value === "object" && value !== null && "ref" in value && typeof value.ref === "string") {
1598
- const next = tokens.get(value.ref);
1599
- if (!next) throw new Error(`Token '${qualified}' references unknown token '${value.ref}'`);
1600
- visit(value.ref, next, tokens, new Set(seen).add(qualified));
1610
+ const followRef = (ref) => {
1611
+ const next = resolve(ref, token.link);
1612
+ if (!next) {
1613
+ if (token.link) {
1614
+ const [sourceGroup] = ref.split("/");
1615
+ throw new Error(`Token '${qualified}' is linked from system "${token.link.systemId}" and references its token '${ref}', which nothing in this config provides — link the source system's "${sourceGroup}" group too (refs on linked tokens resolve by provenance, not by local group names).`);
1616
+ }
1617
+ throw new Error(`Token '${qualified}' references unknown token '${ref}'`);
1618
+ }
1619
+ visit(`${next.namespace}/${next.name}`, next, resolve, new Set(seen).add(qualified));
1620
+ };
1621
+ if (isTokenRefValue(token.value)) followRef(token.value.ref);
1622
+ if (token.link && token.modifiers) for (const value of Object.values(token.modifiers)) {
1623
+ const inner = typeof value === "object" && value !== null && "value" in value ? value.value : value;
1624
+ if (isTokenRefValue(inner)) followRef(inner.ref);
1601
1625
  }
1602
1626
  }
1627
+ /** A `token()` ref marker — `{ ref: 'ns/name' }` — in a value position. */
1628
+ function isTokenRefValue(value) {
1629
+ return typeof value === "object" && value !== null && "ref" in value && typeof value.ref === "string";
1630
+ }
1603
1631
  function stripName(entity) {
1604
1632
  const { name: _name, namespace: _namespace, ...rest } = entity.toJSON();
1605
1633
  return rest;
package/dist/Token.d.ts CHANGED
@@ -12,8 +12,15 @@ type ResolvedTokenLiteral = string | number | boolean | undefined;
12
12
  * Looks up another token by `namespace/name`. Injected by the parent
13
13
  * Config so `Token.derived.value` can chase `token()` aliases without
14
14
  * holding a back-ref to the whole config object.
15
+ *
16
+ * `context` is the provenance of the token the ref was authored on. A ref
17
+ * inside a linked token is written against the SOURCE system's group names
18
+ * (`token('base/carbon-5')` in a group linked from Yahoo OS means Yahoo OS's
19
+ * `base` group, whatever the consumer renamed it to), so the lookup resolves
20
+ * it through the link markers instead of the consumer's own keys. Local
21
+ * tokens pass no context and resolve against the consumer's keys directly.
15
22
  */
16
- type TokenSiblingLookup = (qualifiedName: string) => Token | undefined;
23
+ type TokenSiblingLookup = (qualifiedName: string, context?: SystemLink) => Token | undefined;
17
24
  declare class Token {
18
25
  #private;
19
26
  readonly name: string;
package/dist/Token.js CHANGED
@@ -43,6 +43,7 @@ var Token = class {
43
43
  const tokenValue = this.value;
44
44
  const tokenType = this.type;
45
45
  const modifiers = this.modifiers;
46
+ const link = this.link;
46
47
  const prefixGetter = this.#prefixGetter;
47
48
  const lookup = this.#lookup;
48
49
  const groupTypeGetter = this.#groupTypeGetter;
@@ -57,10 +58,10 @@ var Token = class {
57
58
  return `var(${buildCssVar(prefixGetter(), namespace, name)})`;
58
59
  },
59
60
  get value() {
60
- return chaseLiteral(tokenValue, lookup);
61
+ return chaseLiteral(tokenValue, lookup, link);
61
62
  },
62
63
  get cssValueType() {
63
- const literal = chaseLiteral(tokenValue, lookup);
64
+ const literal = chaseLiteral(tokenValue, lookup, link);
64
65
  return resolveTokenValueType({
65
66
  value: typeof literal === "string" ? literal : String(tokenValue),
66
67
  type: tokenType
@@ -68,7 +69,7 @@ var Token = class {
68
69
  },
69
70
  *modifierValues() {
70
71
  if (!modifiers) return;
71
- for (const [key, value] of Object.entries(modifiers)) yield [key, resolveModifierLiteral(value, lookup)];
72
+ for (const [key, value] of Object.entries(modifiers)) yield [key, resolveModifierLiteral(value, lookup, link)];
72
73
  }
73
74
  };
74
75
  }
@@ -99,19 +100,20 @@ function collectModifiers(definition) {
99
100
  }
100
101
  return count > 0 ? modifiers : void 0;
101
102
  }
102
- function chaseLiteral(value, lookup, seen = /* @__PURE__ */ new Set()) {
103
+ function chaseLiteral(value, lookup, context, seen = /* @__PURE__ */ new Set()) {
103
104
  if (isTokenRef(value)) {
104
- if (seen.has(value.ref)) return void 0;
105
- seen.add(value.ref);
106
- const next = lookup(value.ref);
105
+ const seenKey = `${context?.systemId ?? ""}:${value.ref}`;
106
+ if (seen.has(seenKey)) return void 0;
107
+ seen.add(seenKey);
108
+ const next = lookup(value.ref, context);
107
109
  if (!next) return void 0;
108
- return chaseLiteral(next.value, lookup, seen);
110
+ return chaseLiteral(next.value, lookup, next.link, seen);
109
111
  }
110
112
  if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") return value;
111
113
  }
112
- function resolveModifierLiteral(value, lookup) {
113
- if (typeof value === "object" && value !== null && "value" in value) return chaseLiteral(value.value, lookup);
114
- return chaseLiteral(value, lookup);
114
+ function resolveModifierLiteral(value, lookup, context) {
115
+ if (typeof value === "object" && value !== null && "value" in value) return chaseLiteral(value.value, lookup, context);
116
+ return chaseLiteral(value, lookup, context);
115
117
  }
116
118
  //#endregion
117
119
  export { Token };
package/dist/index.d.ts CHANGED
@@ -5,7 +5,7 @@ import { ColorExpression, ColorSpace, ColorValue, GradientStop, GradientValue, L
5
5
  import { MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DRAG_AXES, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS } from "./motion-constants.js";
6
6
  import { CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS, CssPropertyWithKeywords } from "./types/css-property-keywords.js";
7
7
  import { ColorCssProperty, CssGlobalKeyword, CssPropertyName, CssPropertyValues } from "./types/css-properties.js";
8
- import { AnyStylePropDefinition, ArbitrarySpec, BaseStyles, BuildOptions, CanvasRole, CanvasRoleEntry, CanvasRoleEntryInput, CanvasRolesDefinition, CanvasRolesDefinitionInput, CanvasRolesInputConstraint, ComponentDefinition, ComponentGroupDefinition, ComponentMetadata, CompositeStyleDefinition, CompositeStyleObject, CompoundPropsEntry, CssMotionDefinition, CssMotionFields, CssSlotMotion, FontAssetMember, GlobalStylesDef, JsMotionDefinition, JsMotionFields, JsSlotMotion, LayerInput, LinkedComponentsInput, LinkedSystemEntry, LiteralFor, ModeDefinition, ModeOptionDefinition, ModifierDefinition, MotionDefinitionInput, MotionDragBox, MotionKeyframes, MotionMetadata, MotionState, MotionStateKeyframe, MotionTransition, MotionVariants, MotionViewportOptions, OpacityPairSpec, PlaygroundOptions, PlaygroundPage, PlaygroundSpec, PreviewDefinition, PropBinding, SerializedAssetGroup, SerializedComponentGroup, SerializedConfig, SerializedFontAssetGroup, SerializedIconAssetGroup, SerializedPlaygroundOptions, SerializedTokenGroup, SlotMotion, StylePropDefinition, StylePropMetadata, StylePropProperty, SystemLink, TokenDefinition, TokenDefinitionFor, TokenGroupDefinition, TokenGroupDefinitionFor, TokenModifierKey, TokenModifierValue, TokenType, TokenValue, ValuesEntry } from "./types.js";
8
+ import { AnyStylePropDefinition, ArbitrarySpec, BaseStyles, BuildOptions, CanvasRole, CanvasRoleEntry, CanvasRoleEntryInput, CanvasRolesDefinition, CanvasRolesDefinitionInput, CanvasRolesInputConstraint, ComponentDefinition, ComponentGroupDefinition, ComponentMetadata, CompositeStyleDefinition, CompositeStyleObject, CompoundPropsEntry, CssMotionDefinition, CssMotionFields, CssSlotMotion, FontAssetMember, GlobalStylesDef, JsMotionDefinition, JsMotionFields, JsSlotMotion, LayerInput, LinkedSystemPin, LinkedSystemsInput, LiteralFor, ModeDefinition, ModeOptionDefinition, ModifierDefinition, MotionDefinitionInput, MotionDragBox, MotionKeyframes, MotionMetadata, MotionState, MotionStateKeyframe, MotionTransition, MotionVariants, MotionViewportOptions, OpacityPairSpec, PlaygroundOptions, PlaygroundPage, PlaygroundSpec, PreviewDefinition, PropBinding, SerializedAssetGroup, SerializedComponentGroup, SerializedConfig, SerializedFontAssetGroup, SerializedIconAssetGroup, SerializedPlaygroundOptions, SerializedTokenGroup, SlotMotion, StylePropDefinition, StylePropMetadata, StylePropProperty, SystemLink, TokenDefinition, TokenDefinitionFor, TokenGroupDefinition, TokenGroupDefinitionFor, TokenModifierKey, TokenModifierValue, TokenType, TokenValue, ValuesEntry } from "./types.js";
9
9
  import { AssetGroupBuilder, AssetGroupConfig, AssetGroupDefinition, FontAssetGroupConfig, FontAssetGroupDefinition, IconAssetGroupConfig, IconAssetGroupDefinition, IconAssetMember, IconAssetMetadata, defineAssetGroup, defineAssetIcon } from "./defineAssetGroup.js";
10
10
  import { AssetGroup } from "./AssetGroup.js";
11
11
  import { resolveAssetRefCss, resolveFontStack } from "./asset-value.js";
@@ -32,8 +32,9 @@ import { ConfigDiagnostic, ConfigDiagnosticDefinition, ConfigValidationError } f
32
32
  import { ELEMENT_MARKER_KIND, ElementMarker, OpaqueLeafPredicate, hasElementMarkerDeep, isElementLikeValue, isElementMarker, reviveElementMarkersDeep, serializeElementsDeep } from "./element-marker.js";
33
33
  import { collectFontFaceCss, deriveFontFaceCss, familiesInRawCss } from "./font-face.js";
34
34
  import { interpolate } from "./interpolate.js";
35
+ import { RegistryAliasSource, buildRegistryAliases, slugifyLinkedName } from "./registry-aliases.js";
35
36
  import { resolveRegistryDir } from "./registry-dir.js";
36
37
  import { ModeBackedModifierDefinition, ModeBackedModifierInput, ModeBackedModifierLookup, ModifierTree, OverrideModeRef, OverrideRow, buildModeBackedModifierLookup, buildNestedModifierUpdate, createModeBackedModifierLookup, mergeModifierUpdates, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, overrideRowsToModifierTree, resolveOverrideRow, resolveOverrideRowValue } from "./token-override-rows.js";
37
38
  import { rem } from "./units.js";
38
39
  import { EntityKind } from "@yahoo/uds-create-types/entity";
39
- export { ASSET_CLASS_CAPABILITIES, type AnyRef, type AnyStylePropDefinition, type ArbitrarySpec, AssetGroup, type AssetGroupBuilder, type AssetGroupConfig, type AssetGroupDefinition, type AssetGroupName, type AssetGroupRef, type AssetKind, type AssetName, type AssetRef, type BaseStyles, type BooleanMarker, type BoundComponent, type BuildOptions, CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS, type CanvasRole, type CanvasRoleEntry, type CanvasRoleEntryInput, type CanvasRolesDefinition, type CanvasRolesDefinitionInput, type CanvasRolesInputConstraint, type ColorCssProperty, type ColorExpression, type ColorFn, type ColorKeyword, type ColorSpace, type ColorValue, Component, type ComponentBuilder, type ComponentBuilderMethods, type ComponentDefinition, ComponentGroup, type ComponentGroupDefinition, type ComponentKind, type ComponentMetadata, type ComponentName, type ComponentRef, type ComponentRenderFn, type CompositeInfo, type CompositeName, type CompositeRef, type CompositeRefBuilder, CompositeStyle, type CompositeStyleDefinition, type CompositeStyleObject, type CompoundPropsEntry, Config, type ConfigCallbackHelpers, type ConfigDiagnostic, type ConfigDiagnosticDefinition, ConfigValidationError, type Css, type CssAngle, type CssClassName, type CssColor, type CssDeclaration, type CssGlobalKeyword, type CssLength, CssMotionDef, type CssMotionDefinition, type CssMotionFields, type CssPercentage, type CssPropertyName, type CssPropertyValues, type CssPropertyWithKeywords, type CssRatio, type CssSelector, type CssSlotMotion, type CssTime, type CssValue, type CssValueTypeName, type CssVar, type CssVarRef, type DataAttrs, type DefineComponentFn, type DefinedComponent, type DefinedMotion, type DefinedProvider, type DefinedStyleProp, type DefinedTokenGroup, type DependenciesQuery, type DependencyKind, type DependencyRef, type DependentsQuery, ELEMENT_MARKER_KIND, type ElementMarker, type EntityKind, type FontAssetGroupConfig, type FontAssetGroupDefinition, type FontAssetMember, type FunctionInfo, type GlobalStylesDef, type GradientStop, type GradientValue, type HexColor, type HslColor, type IconAssetGroupConfig, type IconAssetGroupDefinition, type IconAssetMember, type IconAssetMetadata, JsMotionDef, type JsMotionDefinition, type JsMotionFields, type JsSlotMotion, Layer, type LayerInput, type LayerMarker, type LayerPropsMap, type LengthOrPercent, type LineDirection, type LinearGradientExpr, type LinkedComponentsInput, type LinkedSystemEntry, type LiteralFor, MOTION_CSS_DEFINITION_KEYS, MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DEFINITION_KEYS, MOTION_JS_DRAG_AXES, MOTION_JS_FIELD_KEYS, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS, type MixExpr, Mode, type ModeBackedModifierDefinition, type ModeBackedModifierInput, type ModeBackedModifierLookup, type ModeDefinition, type ModeName, ModeOption, type ModeOptionDefinition, type ModeRef, Modifier, type ModifierDefinition, type ModifierTree, type MotionDef, type MotionDefinitionInput, type MotionDragBox, type MotionKeyframes, type MotionMarker, type MotionMetadata, type MotionName, type MotionState, type MotionStateKeyframe, type MotionTransition, type MotionVariants, type MotionViewportOptions, type NumberMarker, type OpacityPairSpec, type OpaqueLeafPredicate, type OverrideModeRef, type OverrideRow, PREVIEW_SEED_KEY, type PlaygroundOptions, type PlaygroundPage, type PlaygroundSpec, type PreviewAxisMarker, type PreviewCallbackHelpers, type PreviewDefinition, type PreviewPropsRule, type PrimitivePropKind, type PropBase, type PropBinding, type PropInfo, type PropKind, Provider, type RadialGradientExpr, type RadialSize, type RawToken, type RegisteredAssetGroups, type RegisteredComponents, type RegisteredCompositeStyles, type RegisteredModes, type RegisteredModifiers, type RegisteredMotion, type RegisteredStyleProps, type RegisteredTokenGroups, type RequiredBrand, type ResolvedCompoundOverrides, type ResolvedTokenLiteral, type RgbColor, SOURCE_PATH_KEY, type SerializedAssetGroup, type SerializedComponentGroup, type SerializedConfig, type SerializedFontAssetGroup, type SerializedIconAssetGroup, type SerializedPlaygroundOptions, type SerializedTokenGroup, type SlotInfo, type SlotMarker, type SlotMotion, type SlotRef, type SlotValueKind, type SlotValueType, type StringMarker, StyleProp, type StylePropDefinition, type StylePropInfo, type StylePropKeyword, type StylePropMetadata, type StylePropName, type StylePropProperty, type StylePropRef, type StylePropTokenUsage, type SystemLink, type TagName, type TagRef, Token, type TokenDefinition, type TokenDefinitionFor, TokenGroup, type TokenGroupDefinition, type TokenGroupDefinitionFor, type TokenGroupMetadata, type TokenGroupName, type TokenGroupRef, type TokenModifierKey, type TokenModifierValue, type TokenName, type TokenQualifiedName, type TokenRawNameRegistry, type TokenRawValue, type TokenRef, type TokenRefToCss, type TokenType, type TokenValue, type TypedSlotRef, type ValuesEntry, type VariantInfo, type VariantMarker, type VariantMarkerArray, type VariantMarkerObject, alpha, asChild, asset, assetGroup, attachSourcePath, boolean, buildModeBackedModifierLookup, buildNestedModifierUpdate, captureCallerPath, collectFontFaceCss, component, composite, createModeBackedModifierLookup, cssClassName, cssDeclaration, cssSelector, cssVar, defineAssetGroup, defineAssetIcon, defineComponent, defineComponentGroup, defineCompositeStyle, defineMode, defineModifier, defineMotion, defineProvider, defineStyleProp, defineTokenGroup, deriveFontFaceCss, familiesInRawCss, findComponentReferrers, hasElementMarkerDeep, interpolate, isAssetGroupRef, isAssetRef, isBoolMarker, isColorExpression, isComponentRef, isCompositeRef, isElementLikeValue, isElementMarker, isLayerMarker, isLinearGradientExpr, isMixExpr, isModeRef, isMotionMarker, isNumberMarker, isPlaceable, isPreviewAxisMarker, isRadialGradientExpr, isSafeClassNameValue, isSlotMarker, isStringMarker, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, isVariantArrayMarker, isVariantMarker, linearGradient, makeTokenRefToCss, matchesPreviewWhen, mergeModifierUpdates, mix, mode, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, motion, number, overrideRowsToModifierTree, parseRegistryKey, radialGradient, readSourcePath, rem, resolveAssetRefCss, resolveColorExpression, resolveFontStack, resolveOverrideRow, resolveOverrideRowValue, resolvePreviewRules, resolveRegistryDir, reviveElementMarkersDeep, serializeElementsDeep, slot, string, styleProp, tag, token, tokenGroup, variant };
40
+ export { ASSET_CLASS_CAPABILITIES, type AnyRef, type AnyStylePropDefinition, type ArbitrarySpec, AssetGroup, type AssetGroupBuilder, type AssetGroupConfig, type AssetGroupDefinition, type AssetGroupName, type AssetGroupRef, type AssetKind, type AssetName, type AssetRef, type BaseStyles, type BooleanMarker, type BoundComponent, type BuildOptions, CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS, type CanvasRole, type CanvasRoleEntry, type CanvasRoleEntryInput, type CanvasRolesDefinition, type CanvasRolesDefinitionInput, type CanvasRolesInputConstraint, type ColorCssProperty, type ColorExpression, type ColorFn, type ColorKeyword, type ColorSpace, type ColorValue, Component, type ComponentBuilder, type ComponentBuilderMethods, type ComponentDefinition, ComponentGroup, type ComponentGroupDefinition, type ComponentKind, type ComponentMetadata, type ComponentName, type ComponentRef, type ComponentRenderFn, type CompositeInfo, type CompositeName, type CompositeRef, type CompositeRefBuilder, CompositeStyle, type CompositeStyleDefinition, type CompositeStyleObject, type CompoundPropsEntry, Config, type ConfigCallbackHelpers, type ConfigDiagnostic, type ConfigDiagnosticDefinition, ConfigValidationError, type Css, type CssAngle, type CssClassName, type CssColor, type CssDeclaration, type CssGlobalKeyword, type CssLength, CssMotionDef, type CssMotionDefinition, type CssMotionFields, type CssPercentage, type CssPropertyName, type CssPropertyValues, type CssPropertyWithKeywords, type CssRatio, type CssSelector, type CssSlotMotion, type CssTime, type CssValue, type CssValueTypeName, type CssVar, type CssVarRef, type DataAttrs, type DefineComponentFn, type DefinedComponent, type DefinedMotion, type DefinedProvider, type DefinedStyleProp, type DefinedTokenGroup, type DependenciesQuery, type DependencyKind, type DependencyRef, type DependentsQuery, ELEMENT_MARKER_KIND, type ElementMarker, type EntityKind, type FontAssetGroupConfig, type FontAssetGroupDefinition, type FontAssetMember, type FunctionInfo, type GlobalStylesDef, type GradientStop, type GradientValue, type HexColor, type HslColor, type IconAssetGroupConfig, type IconAssetGroupDefinition, type IconAssetMember, type IconAssetMetadata, JsMotionDef, type JsMotionDefinition, type JsMotionFields, type JsSlotMotion, Layer, type LayerInput, type LayerMarker, type LayerPropsMap, type LengthOrPercent, type LineDirection, type LinearGradientExpr, type LinkedSystemPin, type LinkedSystemsInput, type LiteralFor, MOTION_CSS_DEFINITION_KEYS, MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DEFINITION_KEYS, MOTION_JS_DRAG_AXES, MOTION_JS_FIELD_KEYS, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS, type MixExpr, Mode, type ModeBackedModifierDefinition, type ModeBackedModifierInput, type ModeBackedModifierLookup, type ModeDefinition, type ModeName, ModeOption, type ModeOptionDefinition, type ModeRef, Modifier, type ModifierDefinition, type ModifierTree, type MotionDef, type MotionDefinitionInput, type MotionDragBox, type MotionKeyframes, type MotionMarker, type MotionMetadata, type MotionName, type MotionState, type MotionStateKeyframe, type MotionTransition, type MotionVariants, type MotionViewportOptions, type NumberMarker, type OpacityPairSpec, type OpaqueLeafPredicate, type OverrideModeRef, type OverrideRow, PREVIEW_SEED_KEY, type PlaygroundOptions, type PlaygroundPage, type PlaygroundSpec, type PreviewAxisMarker, type PreviewCallbackHelpers, type PreviewDefinition, type PreviewPropsRule, type PrimitivePropKind, type PropBase, type PropBinding, type PropInfo, type PropKind, Provider, type RadialGradientExpr, type RadialSize, type RawToken, type RegisteredAssetGroups, type RegisteredComponents, type RegisteredCompositeStyles, type RegisteredModes, type RegisteredModifiers, type RegisteredMotion, type RegisteredStyleProps, type RegisteredTokenGroups, type RegistryAliasSource, type RequiredBrand, type ResolvedCompoundOverrides, type ResolvedTokenLiteral, type RgbColor, SOURCE_PATH_KEY, type SerializedAssetGroup, type SerializedComponentGroup, type SerializedConfig, type SerializedFontAssetGroup, type SerializedIconAssetGroup, type SerializedPlaygroundOptions, type SerializedTokenGroup, type SlotInfo, type SlotMarker, type SlotMotion, type SlotRef, type SlotValueKind, type SlotValueType, type StringMarker, StyleProp, type StylePropDefinition, type StylePropInfo, type StylePropKeyword, type StylePropMetadata, type StylePropName, type StylePropProperty, type StylePropRef, type StylePropTokenUsage, type SystemLink, type TagName, type TagRef, Token, type TokenDefinition, type TokenDefinitionFor, TokenGroup, type TokenGroupDefinition, type TokenGroupDefinitionFor, type TokenGroupMetadata, type TokenGroupName, type TokenGroupRef, type TokenModifierKey, type TokenModifierValue, type TokenName, type TokenQualifiedName, type TokenRawNameRegistry, type TokenRawValue, type TokenRef, type TokenRefToCss, type TokenType, type TokenValue, type TypedSlotRef, type ValuesEntry, type VariantInfo, type VariantMarker, type VariantMarkerArray, type VariantMarkerObject, alpha, asChild, asset, assetGroup, attachSourcePath, boolean, buildModeBackedModifierLookup, buildNestedModifierUpdate, buildRegistryAliases, captureCallerPath, collectFontFaceCss, component, composite, createModeBackedModifierLookup, cssClassName, cssDeclaration, cssSelector, cssVar, defineAssetGroup, defineAssetIcon, defineComponent, defineComponentGroup, defineCompositeStyle, defineMode, defineModifier, defineMotion, defineProvider, defineStyleProp, defineTokenGroup, deriveFontFaceCss, familiesInRawCss, findComponentReferrers, hasElementMarkerDeep, interpolate, isAssetGroupRef, isAssetRef, isBoolMarker, isColorExpression, isComponentRef, isCompositeRef, isElementLikeValue, isElementMarker, isLayerMarker, isLinearGradientExpr, isMixExpr, isModeRef, isMotionMarker, isNumberMarker, isPlaceable, isPreviewAxisMarker, isRadialGradientExpr, isSafeClassNameValue, isSlotMarker, isStringMarker, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, isVariantArrayMarker, isVariantMarker, linearGradient, makeTokenRefToCss, matchesPreviewWhen, mergeModifierUpdates, mix, mode, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, motion, number, overrideRowsToModifierTree, parseRegistryKey, radialGradient, readSourcePath, rem, resolveAssetRefCss, resolveColorExpression, resolveFontStack, resolveOverrideRow, resolveOverrideRowValue, resolvePreviewRules, resolveRegistryDir, reviveElementMarkersDeep, serializeElementsDeep, slot, slugifyLinkedName, string, styleProp, tag, token, tokenGroup, variant };
package/dist/index.js CHANGED
@@ -27,8 +27,9 @@ import { asChild, boolean, defineComponent, defineComponentGroup, defineComposit
27
27
  import { collectFontFaceCss, deriveFontFaceCss, familiesInRawCss } from "./font-face.js";
28
28
  import { interpolate } from "./interpolate.js";
29
29
  import { MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DRAG_AXES, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS } from "./motion-constants.js";
30
+ import { buildRegistryAliases, slugifyLinkedName } from "./registry-aliases.js";
30
31
  import { resolveRegistryDir } from "./registry-dir.js";
31
32
  import { buildModeBackedModifierLookup, buildNestedModifierUpdate, createModeBackedModifierLookup, mergeModifierUpdates, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, overrideRowsToModifierTree, resolveOverrideRow, resolveOverrideRowValue } from "./token-override-rows.js";
32
33
  import { CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS } from "./types/css-property-keywords.js";
33
34
  import { rem } from "./units.js";
34
- export { ASSET_CLASS_CAPABILITIES, AssetGroup, CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS, Component, ComponentGroup, CompositeStyle, Config, ConfigValidationError, CssMotionDef, ELEMENT_MARKER_KIND, JsMotionDef, Layer, MOTION_CSS_DEFINITION_KEYS, MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DEFINITION_KEYS, MOTION_JS_DRAG_AXES, MOTION_JS_FIELD_KEYS, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS, Mode, ModeOption, Modifier, PREVIEW_SEED_KEY, Provider, SOURCE_PATH_KEY, StyleProp, Token, TokenGroup, alpha, asChild, asset, assetGroup, attachSourcePath, boolean, buildModeBackedModifierLookup, buildNestedModifierUpdate, captureCallerPath, collectFontFaceCss, component, composite, createModeBackedModifierLookup, cssClassName, cssDeclaration, cssSelector, cssVar, defineAssetGroup, defineAssetIcon, defineComponent, defineComponentGroup, defineCompositeStyle, defineMode, defineModifier, defineMotion, defineProvider, defineStyleProp, defineTokenGroup, deriveFontFaceCss, familiesInRawCss, findComponentReferrers, hasElementMarkerDeep, interpolate, isAssetGroupRef, isAssetRef, isBoolMarker, isColorExpression, isComponentRef, isCompositeRef, isElementLikeValue, isElementMarker, isLayerMarker, isLinearGradientExpr, isMixExpr, isModeRef, isMotionMarker, isNumberMarker, isPlaceable, isPreviewAxisMarker, isRadialGradientExpr, isSafeClassNameValue, isSlotMarker, isStringMarker, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, isVariantArrayMarker, isVariantMarker, linearGradient, makeTokenRefToCss, matchesPreviewWhen, mergeModifierUpdates, mix, mode, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, motion, number, overrideRowsToModifierTree, parseRegistryKey, radialGradient, readSourcePath, rem, resolveAssetRefCss, resolveColorExpression, resolveFontStack, resolveOverrideRow, resolveOverrideRowValue, resolvePreviewRules, resolveRegistryDir, reviveElementMarkersDeep, serializeElementsDeep, slot, string, styleProp, tag, token, tokenGroup, variant };
35
+ export { ASSET_CLASS_CAPABILITIES, AssetGroup, CSS_GLOBAL_KEYWORDS, CSS_PROPERTY_KEYWORDS, Component, ComponentGroup, CompositeStyle, Config, ConfigValidationError, CssMotionDef, ELEMENT_MARKER_KIND, JsMotionDef, Layer, MOTION_CSS_DEFINITION_KEYS, MOTION_CSS_DIRECTIONS, MOTION_CSS_FILL_MODES, MOTION_CSS_PLAY_STATES, MOTION_CSS_PROPERTY_PREFIXES, MOTION_JS_DEFINITION_KEYS, MOTION_JS_DRAG_AXES, MOTION_JS_FIELD_KEYS, MOTION_JS_LAYOUT_MODES, MOTION_JS_REPEAT_TYPES, MOTION_JS_SPRING_FIELDS, MOTION_JS_TRANSITION_TYPES, MOTION_JS_TWEEN_FIELDS, Mode, ModeOption, Modifier, PREVIEW_SEED_KEY, Provider, SOURCE_PATH_KEY, StyleProp, Token, TokenGroup, alpha, asChild, asset, assetGroup, attachSourcePath, boolean, buildModeBackedModifierLookup, buildNestedModifierUpdate, buildRegistryAliases, captureCallerPath, collectFontFaceCss, component, composite, createModeBackedModifierLookup, cssClassName, cssDeclaration, cssSelector, cssVar, defineAssetGroup, defineAssetIcon, defineComponent, defineComponentGroup, defineCompositeStyle, defineMode, defineModifier, defineMotion, defineProvider, defineStyleProp, defineTokenGroup, deriveFontFaceCss, familiesInRawCss, findComponentReferrers, hasElementMarkerDeep, interpolate, isAssetGroupRef, isAssetRef, isBoolMarker, isColorExpression, isComponentRef, isCompositeRef, isElementLikeValue, isElementMarker, isLayerMarker, isLinearGradientExpr, isMixExpr, isModeRef, isMotionMarker, isNumberMarker, isPlaceable, isPreviewAxisMarker, isRadialGradientExpr, isSafeClassNameValue, isSlotMarker, isStringMarker, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, isVariantArrayMarker, isVariantMarker, linearGradient, makeTokenRefToCss, matchesPreviewWhen, mergeModifierUpdates, mix, mode, modifierIdToPath, modifierPathToId, modifierTreeToOverrideRows, motion, number, overrideRowsToModifierTree, parseRegistryKey, radialGradient, readSourcePath, rem, resolveAssetRefCss, resolveColorExpression, resolveFontStack, resolveOverrideRow, resolveOverrideRowValue, resolvePreviewRules, resolveRegistryDir, reviveElementMarkersDeep, serializeElementsDeep, slot, slugifyLinkedName, string, styleProp, tag, token, tokenGroup, variant };
@@ -0,0 +1,33 @@
1
+ //#region src/registry-aliases.d.ts
2
+ /**
3
+ * Import-alias slugs for the linked-system registry (UDS-2771).
4
+ * Each top-level linked dependency gets a stable folder alias — the slug
5
+ * derives from the entry's `name` in the consumer's own
6
+ * `registerLinkedSystems` pin (stable across remote renames, fixable
7
+ * locally on collision). The pull materializer uses these aliases to
8
+ * rewrite a node's own `@uds-registry/{slug}` imports into relative paths,
9
+ * keeping the on-disk tree self-contained; the link patch applier uses the
10
+ * same slugs for the consumer's own barrel imports.
11
+ */
12
+ /** One top-level declared dependency, as needed for alias building. */
13
+ interface RegistryAliasSource {
14
+ systemId: string;
15
+ version: string;
16
+ /** Display name from the consumer's registerLinkedSystems pin. */
17
+ name: string;
18
+ }
19
+ /**
20
+ * Slug for one linked system's import alias: lowercase, hyphen-separated,
21
+ * ASCII-safe. Names that reduce to nothing get a generic fallback (the
22
+ * collision suffix in {@link buildRegistryAliases} keeps them distinct).
23
+ */
24
+ declare function slugifyLinkedName(name: string): string;
25
+ /**
26
+ * Map top-level declared dependencies to `slug → {systemId}@{version}` (the
27
+ * registry folder name). Colliding slugs keep declaration order: the first
28
+ * wins the bare slug, later ones get a `-{systemId-prefix}` suffix — still
29
+ * deterministic across machines.
30
+ */
31
+ declare function buildRegistryAliases(roots: RegistryAliasSource[]): Record<string, string>;
32
+ //#endregion
33
+ export { RegistryAliasSource, buildRegistryAliases, slugifyLinkedName };
@@ -0,0 +1,27 @@
1
+ //#region src/registry-aliases.ts
2
+ /**
3
+ * Slug for one linked system's import alias: lowercase, hyphen-separated,
4
+ * ASCII-safe. Names that reduce to nothing get a generic fallback (the
5
+ * collision suffix in {@link buildRegistryAliases} keeps them distinct).
6
+ */
7
+ function slugifyLinkedName(name) {
8
+ const slug = name.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/^-+|-+$/g, "");
9
+ return slug === "" ? "linked-system" : slug;
10
+ }
11
+ /**
12
+ * Map top-level declared dependencies to `slug → {systemId}@{version}` (the
13
+ * registry folder name). Colliding slugs keep declaration order: the first
14
+ * wins the bare slug, later ones get a `-{systemId-prefix}` suffix — still
15
+ * deterministic across machines.
16
+ */
17
+ function buildRegistryAliases(roots) {
18
+ const aliases = {};
19
+ for (const root of roots) {
20
+ let slug = slugifyLinkedName(root.name);
21
+ if (aliases[slug] !== void 0) slug = `${slug}-${root.systemId.slice(0, 8)}`;
22
+ aliases[slug] = `${root.systemId}@${root.version}`;
23
+ }
24
+ return aliases;
25
+ }
26
+ //#endregion
27
+ export { buildRegistryAliases, slugifyLinkedName };
@@ -9,8 +9,8 @@
9
9
  * 1. `buildOptions.registryDir` when the consumer sets one;
10
10
  * 2. `<componentsDir>/registry` — the default, keeping the registry inside
11
11
  * the design system's own subtree;
12
- * 3. `.uds-registry` — the legacy project-root layout, for configs that
13
- * declare no `componentsDir`.
12
+ * 3. `registry` at the project root, for configs that declare no
13
+ * `componentsDir`.
14
14
  */
15
15
  interface RegistryDirOptions {
16
16
  componentsDir?: string;
@@ -4,7 +4,7 @@ const normalize = (p) => p.replace(/\\/g, "/").replace(/\/+$/, "");
4
4
  function resolveRegistryDir(buildOptions) {
5
5
  if (buildOptions?.registryDir) return normalize(buildOptions.registryDir);
6
6
  if (buildOptions?.componentsDir) return `${normalize(buildOptions.componentsDir)}/registry`;
7
- return ".uds-registry";
7
+ return "registry";
8
8
  }
9
9
  //#endregion
10
10
  export { resolveRegistryDir };