@yahoo/uds-create-config 2.33.1 → 2.35.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.
@@ -0,0 +1,99 @@
1
+ import { slugifyLinkedName } from "./registry-aliases.js";
2
+ //#region src/linkedNodePrefixes.ts
3
+ /**
4
+ * Node-scoped CSS-prefix assignment for materialized linked systems.
5
+ *
6
+ * Every linked node (`{systemId}@{version}`) regenerates its CSS at consumer
7
+ * build time from its sealed `config.json`, with its `prefix` overridden to a
8
+ * composed, collision-free identity: `<consumerPrefix>-linked-<slug>`. One
9
+ * prefix per NODE (not per link path) — the module graph resolves each node's
10
+ * files once, so its lowered class names can only carry one prefix; sharing a
11
+ * node between parents shares byte-identical sealed content, so sharing the
12
+ * prefix is correct.
13
+ *
14
+ * The assignment must be identical everywhere it's consumed (pull-time shim
15
+ * generation, `uds build` CSS regeneration, the bundler loaders), so every
16
+ * consumer derives it from the same inputs with the same pure functions:
17
+ * node identities from the registry tree, display names from the declaring
18
+ * configs' `registerLinkedSystems` entries ({@link resolveDeclaredNames}),
19
+ * and the consumer's own prefix. Nothing is persisted — the registry tree is
20
+ * the source of truth.
21
+ */
22
+ /** CSS identifiers can't start with a digit (or a hyphen-digit pair) —
23
+ * prepend a letter sentinel when a candidate would. */
24
+ function ensureCssIdentStart(candidate) {
25
+ return /^[a-zA-Z_]/.test(candidate) ? candidate : `x${candidate}`;
26
+ }
27
+ /** `1.5.0` → `v1-5-0` — a CSS-safe version fragment. */
28
+ function versionFragment(version) {
29
+ return `v${version.replace(/[^a-zA-Z0-9]+/g, "-")}`;
30
+ }
31
+ function nodeKey(node) {
32
+ return `${node.systemId}@${node.version}`;
33
+ }
34
+ /**
35
+ * Assign each node in a linked closure its slug + composed CSS prefix,
36
+ * keyed by `{systemId}@{version}`.
37
+ *
38
+ * Deterministic and input-order independent: nodes are processed sorted by
39
+ * `(systemId, version)`. Within a slug-collision group the first sorted node
40
+ * keeps the bare slug; a different system appends `-x<systemId[0..8]>`; the
41
+ * same system at another version appends `-v<version>` — so every node in
42
+ * the closure gets a unique, stable prefix.
43
+ *
44
+ * `consumerPrefix` is the consuming system's own `Config.prefix`. An empty
45
+ * prefix is disallowed as a base (a bare `linked-…` could collide with the
46
+ * consumer's unprefixed classes) — the node's own uuid fragment substitutes.
47
+ */
48
+ function assignLinkedNodePrefixes(nodes, consumerPrefix) {
49
+ const sorted = [...nodes].sort((a, b) => a.systemId.localeCompare(b.systemId) || a.version.localeCompare(b.version));
50
+ const byslug = /* @__PURE__ */ new Map();
51
+ for (const node of sorted) {
52
+ const slug = slugifyLinkedName(node.name);
53
+ const group = byslug.get(slug);
54
+ if (group) group.push(node);
55
+ else byslug.set(slug, [node]);
56
+ }
57
+ const out = /* @__PURE__ */ new Map();
58
+ const usedSlugs = /* @__PURE__ */ new Set();
59
+ for (const [slug, group] of byslug) {
60
+ const systemsInOrder = [];
61
+ for (const node of group) if (!systemsInOrder.includes(node.systemId)) systemsInOrder.push(node.systemId);
62
+ for (const node of group) {
63
+ const systemRank = systemsInOrder.indexOf(node.systemId);
64
+ const versionsOfSystem = group.filter((n) => n.systemId === node.systemId);
65
+ let finalSlug = slug;
66
+ if (systemRank > 0) finalSlug += `-x${node.systemId.slice(0, 8)}`;
67
+ if (versionsOfSystem.length > 1 && versionsOfSystem.indexOf(node) > 0) finalSlug += `-${versionFragment(node.version)}`;
68
+ const collisionBase = finalSlug;
69
+ let collisionIndex = 2;
70
+ while (usedSlugs.has(finalSlug)) {
71
+ finalSlug = `${collisionBase}-${collisionIndex}`;
72
+ collisionIndex++;
73
+ }
74
+ usedSlugs.add(finalSlug);
75
+ const base = ensureCssIdentStart(consumerPrefix === "" ? `x${node.systemId.slice(0, 8)}` : consumerPrefix);
76
+ out.set(nodeKey(node), {
77
+ slug: finalSlug,
78
+ cssPrefix: `${base}-linked-${finalSlug}`
79
+ });
80
+ }
81
+ }
82
+ return out;
83
+ }
84
+ /**
85
+ * Resolve each node's display name from the closure's declarations. A node
86
+ * can be declared by several parents under different name snapshots; the
87
+ * winner is the declaration with the lowest `declarerKey` in sort order (the
88
+ * consumer's own declarations sort first as `''`), so every tool that walks
89
+ * the same closure derives the same names — and therefore the same slugs and
90
+ * CSS prefixes — without any persisted mapping.
91
+ */
92
+ function resolveDeclaredNames(declarations) {
93
+ const sorted = [...declarations].sort((a, b) => a.key.localeCompare(b.key) || a.declarerKey.localeCompare(b.declarerKey));
94
+ const names = /* @__PURE__ */ new Map();
95
+ for (const decl of sorted) if (!names.has(decl.key)) names.set(decl.key, decl.name);
96
+ return names;
97
+ }
98
+ //#endregion
99
+ export { assignLinkedNodePrefixes, resolveDeclaredNames };
@@ -1,7 +1,7 @@
1
1
  import { LinkedSystemPin, LinkedSystemsInput } from "../types.js";
2
2
  import { ConfigValidationError } from "../config-diagnostics.js";
3
3
  import { NativeComponentDefinition, NativeComponentGroupDefinition, NativeComponentPropMarker, NativeComponentPropsFromMarkers, NativeComponentStyles, NativeLayerDefinition, NativeLayerKind, SerializedNativeComponentGroup } from "./components.js";
4
- import { NativeAssetGroupDefinition, NativeBuildOptions, NativeDefaultModes, NativeFontAssetGroupDefinition, NativeModeDefinition, NativeStyleEngine, NativeTokenGroupDefinition, SerializedNativeConfig } from "./types.js";
4
+ import { NativeAssetGroupDefinition, NativeBuildOptions, NativeDefaultModes, NativeDependencyPolicy, NativeFontAssetGroupDefinition, NativeModeDefinition, NativeStyleEngine, NativeTokenGroupDefinition, SerializedNativeConfig } from "./types.js";
5
5
  import { NativeConfigDiagnostic } from "./validation.js";
6
6
 
7
7
  //#region src/native/NativeConfig.d.ts
@@ -15,6 +15,7 @@ declare class NativeConfig {
15
15
  namespace?: string;
16
16
  styleEngine?: NativeStyleEngine;
17
17
  buildOptions?: NativeBuildOptions;
18
+ dependencyPolicy?: NativeDependencyPolicy;
18
19
  defaultModes?: NativeDefaultModes;
19
20
  readonly modes: Map<string, NativeModeDefinition>;
20
21
  readonly tokenGroups: Map<string, NativeTokenGroupDefinition>;
@@ -33,6 +34,7 @@ declare class NativeConfig {
33
34
  namespace?: string;
34
35
  styleEngine?: NativeStyleEngine;
35
36
  buildOptions?: NativeBuildOptions;
37
+ dependencyPolicy?: NativeDependencyPolicy;
36
38
  defaultModes?: NativeDefaultModes;
37
39
  }): this;
38
40
  registerModes(modes: Record<string, NativeModeDefinition>): this;
@@ -15,6 +15,7 @@ var NativeConfig = class NativeConfig {
15
15
  namespace;
16
16
  styleEngine;
17
17
  buildOptions;
18
+ dependencyPolicy;
18
19
  defaultModes;
19
20
  modes = /* @__PURE__ */ new Map();
20
21
  tokenGroups = /* @__PURE__ */ new Map();
@@ -46,6 +47,15 @@ var NativeConfig = class NativeConfig {
46
47
  this.styleEngine = options.styleEngine;
47
48
  }
48
49
  if (options.buildOptions !== void 0) this.buildOptions = { ...options.buildOptions };
50
+ if (options.dependencyPolicy !== void 0) {
51
+ const diagnostics = validateSerializedNativeConfig({
52
+ schemaVersion: NativeConfig.SCHEMA_VERSION,
53
+ platform: "native",
54
+ dependencyPolicy: options.dependencyPolicy
55
+ });
56
+ if (diagnostics.length > 0) throw new NativeConfigValidationError(diagnostics);
57
+ this.dependencyPolicy = Object.fromEntries(Object.entries(options.dependencyPolicy).map(([name, policy]) => [name, { ...policy }]));
58
+ }
49
59
  if (options.defaultModes !== void 0) this.defaultModes = { ...options.defaultModes };
50
60
  return this;
51
61
  }
@@ -118,6 +128,7 @@ var NativeConfig = class NativeConfig {
118
128
  config.namespace = json.namespace;
119
129
  config.styleEngine = json.styleEngine;
120
130
  config.buildOptions = json.buildOptions ? { ...json.buildOptions } : void 0;
131
+ config.dependencyPolicy = json.dependencyPolicy ? Object.fromEntries(Object.entries(json.dependencyPolicy).map(([name, policy]) => [name, { ...policy }])) : void 0;
121
132
  config.defaultModes = json.defaultModes ? { ...json.defaultModes } : void 0;
122
133
  for (const [name, mode] of Object.entries(json.modes ?? {})) config.modes.set(name, mode);
123
134
  for (const [name, group] of Object.entries(json.tokenGroups ?? {})) config.tokenGroups.set(name, group);
@@ -136,6 +147,7 @@ var NativeConfig = class NativeConfig {
136
147
  if (this.namespace !== void 0) out.namespace = this.namespace;
137
148
  if (this.styleEngine !== void 0) out.styleEngine = this.styleEngine;
138
149
  if (this.buildOptions !== void 0) out.buildOptions = { ...this.buildOptions };
150
+ if (this.dependencyPolicy !== void 0) out.dependencyPolicy = Object.fromEntries(Object.entries(this.dependencyPolicy).map(([name, policy]) => [name, { ...policy }]));
139
151
  if (this.defaultModes !== void 0) out.defaultModes = { ...this.defaultModes };
140
152
  if (this.modes.size > 0) out.modes = Object.fromEntries(this.modes);
141
153
  if (this.tokenGroups.size > 0) out.tokenGroups = Object.fromEntries(this.tokenGroups);
@@ -3,7 +3,7 @@ import { ColorSpace, MixExpr, alpha, mix } from "../colorExpressions.js";
3
3
  import { SystemLink, TokenType } from "../types.js";
4
4
  import { DefinedTokenGroupValue } from "../factories.js";
5
5
  import { NativeComponentBuilder, NativeComponentDefinition, NativeComponentGroupDefinition, NativeComponentProps, NativeComponentStyleHelpers, NativeComponentStyledBuilder, NativeComponentStyles, NativeLayerDefinition, NativeLayerKind, NativeLayerStyle, NativeLayerStyles, NativeRenderProps, NativeStyleValue, RegisteredNativeComponent, SerializedNativeComponentGroup, defineNativeComponent, defineNativeComponentGroup, nativeLayer } from "./components.js";
6
- import { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig } from "./types.js";
6
+ import { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeDependencyPolicy, NativeDependencyPolicyEntry, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig } from "./types.js";
7
7
  import { NativeAssetGroupBuilder, NativeFontAssetGroupConfig, defineAssetGroup } from "./assets.js";
8
8
  import { defineMode } from "./modes.js";
9
9
  import { NativeConfigDiagnostic, NativeConfigDiagnosticCode, validateSerializedNativeConfig } from "./validation.js";
@@ -56,6 +56,13 @@ interface NativeBuildOptions {
56
56
  /** Trusted root containing native component definitions and render source. */
57
57
  componentsDir?: string;
58
58
  }
59
+ /** Where a consuming project must make a native component dependency available. */
60
+ interface NativeDependencyPolicyEntry {
61
+ providedBy: 'consumer' | 'registry';
62
+ /** Semver range accepted by the system that authored the components. */
63
+ version: string;
64
+ }
65
+ type NativeDependencyPolicy = Record<string, NativeDependencyPolicyEntry>;
59
66
  interface NativeFontAssetMember {
60
67
  /** Family identifier React Native consumes after the app registers the font. */
61
68
  fontFamily: string;
@@ -74,6 +81,7 @@ interface SerializedNativeConfig {
74
81
  namespace?: string;
75
82
  styleEngine?: NativeStyleEngine;
76
83
  buildOptions?: NativeBuildOptions;
84
+ dependencyPolicy?: NativeDependencyPolicy;
77
85
  defaultModes?: NativeDefaultModes;
78
86
  modes?: Record<string, NativeModeDefinition>;
79
87
  tokenGroups?: Record<string, NativeTokenGroupDefinition>;
@@ -84,4 +92,4 @@ interface SerializedNativeConfig {
84
92
  linkedSystems?: Record<string, LinkedSystemPin>;
85
93
  }
86
94
  //#endregion
87
- export { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig };
95
+ export { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeDependencyPolicy, NativeDependencyPolicyEntry, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig };
@@ -1,7 +1,7 @@
1
1
  import { ConfigDiagnostic } from "../config-diagnostics.js";
2
2
 
3
3
  //#region src/native/validation.d.ts
4
- type NativeConfigDiagnosticCode = 'INVALID_SCHEMA' | 'UNSUPPORTED_SCHEMA_VERSION' | 'PLATFORM_MISMATCH' | 'INVALID_NAMESPACE' | 'INVALID_NATIVE_VALUE' | 'UNSUPPORTED_NATIVE_FIELD' | 'INCOMPLETE_OS_VALUE' | 'NESTED_OS_VALUE' | 'INVALID_REFERENCE' | 'UNRESOLVED_TOKEN_REFERENCE' | 'TOKEN_REFERENCE_CYCLE' | 'UNRESOLVED_ASSET_REFERENCE' | 'UNOWNED_MODIFIER' | 'DUPLICATE_MODIFIER' | 'INVALID_DEFAULT_MODE' | 'INVALID_MODE_CONDITION' | 'INVALID_MODE_COMBINATION' | 'UNSUPPORTED_COLOR_EXPRESSION';
4
+ type NativeConfigDiagnosticCode = 'INVALID_SCHEMA' | 'UNSUPPORTED_SCHEMA_VERSION' | 'PLATFORM_MISMATCH' | 'INVALID_NAMESPACE' | 'INVALID_NATIVE_VALUE' | 'UNSUPPORTED_NATIVE_FIELD' | 'INCOMPLETE_OS_VALUE' | 'NESTED_OS_VALUE' | 'INVALID_REFERENCE' | 'UNRESOLVED_TOKEN_REFERENCE' | 'TOKEN_REFERENCE_CYCLE' | 'UNRESOLVED_ASSET_REFERENCE' | 'UNOWNED_MODIFIER' | 'DUPLICATE_MODIFIER' | 'INVALID_DEFAULT_MODE' | 'INVALID_DEPENDENCY_POLICY' | 'INVALID_MODE_CONDITION' | 'INVALID_MODE_COMBINATION' | 'UNSUPPORTED_COLOR_EXPRESSION';
5
5
  type NativeConfigDiagnostic = ConfigDiagnostic<NativeConfigDiagnosticCode>;
6
6
  declare function validateSerializedNativeConfig(input: unknown, expectedSchemaVersion?: number): NativeConfigDiagnostic[];
7
7
  //#endregion
@@ -3,6 +3,7 @@ import { isMixExpr } from "../colorExpressions.js";
3
3
  import { EXACT_SEMVER_RE, UUID_RE } from "../linked-system-pins.js";
4
4
  import { createModeBackedModifierLookup, modifierTreeToOverrideRows, resolveOverrideRow } from "../token-override-rows.js";
5
5
  import { isOperatingSystemValue } from "./values.js";
6
+ import { validRange } from "semver";
6
7
  //#region src/native/validation.ts
7
8
  const TOP_LEVEL_KEYS = new Set([
8
9
  "schemaVersion",
@@ -11,6 +12,7 @@ const TOP_LEVEL_KEYS = new Set([
11
12
  "namespace",
12
13
  "styleEngine",
13
14
  "buildOptions",
15
+ "dependencyPolicy",
14
16
  "defaultModes",
15
17
  "modes",
16
18
  "tokenGroups",
@@ -21,6 +23,7 @@ const TOP_LEVEL_KEYS = new Set([
21
23
  ]);
22
24
  const LINKED_SYSTEM_PIN_KEYS = new Set(["name", "version"]);
23
25
  const BUILD_OPTIONS_KEYS = new Set(["componentsDir"]);
26
+ const DEPENDENCY_POLICY_KEYS = new Set(["providedBy", "version"]);
24
27
  const COMPONENT_KEYS = new Set([
25
28
  "id",
26
29
  "layers",
@@ -104,6 +107,7 @@ function validateSerializedNativeConfig(input, expectedSchemaVersion = 4) {
104
107
  validateNamespace(input.namespace, diagnostics);
105
108
  validateStyleEngine(input.styleEngine, diagnostics);
106
109
  validateBuildOptions(input.buildOptions, diagnostics);
110
+ validateDependencyPolicy(input.dependencyPolicy, diagnostics);
107
111
  validateModes(input.modes, diagnostics);
108
112
  validateDefaultModes(input.defaultModes, input.modes, diagnostics);
109
113
  validateAssetGroups(input.assetGroups, diagnostics);
@@ -115,6 +119,29 @@ function validateSerializedNativeConfig(input, expectedSchemaVersion = 4) {
115
119
  validateModifierOwnership(input, diagnostics);
116
120
  return dedupe(diagnostics);
117
121
  }
122
+ function validateDependencyPolicy(value, diagnostics) {
123
+ if (value === void 0) return;
124
+ const definition = { kind: "config" };
125
+ if (!isRecord(value)) {
126
+ push(diagnostics, "INVALID_DEPENDENCY_POLICY", ["dependencyPolicy"], definition, "dependencyPolicy must be a record keyed by npm package name.");
127
+ return;
128
+ }
129
+ for (const [name, policy] of Object.entries(value)) {
130
+ const path = ["dependencyPolicy", name];
131
+ if (!isValidPackageName(name)) push(diagnostics, "INVALID_DEPENDENCY_POLICY", path, definition, `"${name}" is not a valid npm package name.`);
132
+ if (!isRecord(policy)) {
133
+ push(diagnostics, "INVALID_DEPENDENCY_POLICY", path, definition, "Dependency policy entries must be plain objects.");
134
+ continue;
135
+ }
136
+ reportUnknownKeys(policy, DEPENDENCY_POLICY_KEYS, path, definition, diagnostics);
137
+ if (policy.providedBy !== "consumer" && policy.providedBy !== "registry") push(diagnostics, "INVALID_DEPENDENCY_POLICY", [...path, "providedBy"], definition, "providedBy must be either \"consumer\" or \"registry\".");
138
+ if (typeof policy.version !== "string" || validRange(policy.version) === null) push(diagnostics, "INVALID_DEPENDENCY_POLICY", [...path, "version"], definition, "version must be a valid semver range.");
139
+ }
140
+ }
141
+ function isValidPackageName(name) {
142
+ if (name.length === 0 || name.length > 214 || name !== name.toLowerCase()) return false;
143
+ return /^(?:@[a-z0-9~][a-z0-9._~-]*\/)?[a-z0-9~][a-z0-9._~-]*$/.test(name);
144
+ }
118
145
  function validateLinkedSystems(value, diagnostics) {
119
146
  if (value === void 0) return;
120
147
  const definition = { kind: "config" };
package/dist/native.d.ts CHANGED
@@ -2,11 +2,11 @@ import { AssetRef, TokenRef, asset, token } from "./refs.js";
2
2
  import { ColorSpace, MixExpr, alpha, mix } from "./colorExpressions.js";
3
3
  import { SystemLink, TokenType } from "./types.js";
4
4
  import { NativeComponentBuilder, NativeComponentDefinition, NativeComponentGroupDefinition, NativeComponentProps, NativeComponentStyleHelpers, NativeComponentStyledBuilder, NativeComponentStyles, NativeLayerDefinition, NativeLayerKind, NativeLayerStyle, NativeLayerStyles, NativeRenderProps, NativeStyleValue, RegisteredNativeComponent, SerializedNativeComponentGroup, defineNativeComponent, defineNativeComponentGroup, nativeLayer } from "./native/components.js";
5
- import { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig } from "./native/types.js";
5
+ import { ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeDefaultModes, NativeDependencyPolicy, NativeDependencyPolicyEntry, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeSelectableValue, NativeStyleEngine, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, SerializedNativeConfig } from "./native/types.js";
6
6
  import { NativeAssetGroupBuilder, NativeFontAssetGroupConfig, defineAssetGroup } from "./native/assets.js";
7
7
  import { defineMode } from "./native/modes.js";
8
8
  import { NativeConfigDiagnostic, NativeConfigDiagnosticCode, validateSerializedNativeConfig } from "./native/validation.js";
9
9
  import { NativeConfig, NativeConfigValidationError } from "./native/NativeConfig.js";
10
10
  import { isOperatingSystemValue, operatingSystem } from "./native/values.js";
11
11
  import { DefinedNativeTokenGroup, defineTokenGroup } from "./native/index.js";
12
- export { AssetRef, ColorSpace, DefinedNativeTokenGroup, MixExpr, ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupBuilder, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeComponentBuilder, NativeComponentDefinition, NativeComponentGroupDefinition, NativeComponentProps, NativeComponentStyleHelpers, NativeComponentStyledBuilder, NativeComponentStyles, NativeConfig, NativeConfigDiagnostic, NativeConfigDiagnosticCode, NativeConfigValidationError, NativeDefaultModes, NativeFontAssetGroupConfig, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLayerDefinition, NativeLayerKind, NativeLayerStyle, NativeLayerStyles, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeRenderProps, NativeSelectableValue, NativeStyleEngine, NativeStyleValue, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, RegisteredNativeComponent, SerializedNativeComponentGroup, SerializedNativeConfig, SystemLink, TokenRef, TokenType, alpha, asset, defineAssetGroup, defineMode, defineNativeComponent, defineNativeComponentGroup, defineTokenGroup, isOperatingSystemValue, mix, nativeLayer, operatingSystem, token, validateSerializedNativeConfig };
12
+ export { AssetRef, ColorSpace, DefinedNativeTokenGroup, MixExpr, ModeDefinition, NativeAppearanceModeOption, NativeAssetGroupBuilder, NativeAssetGroupDefinition, NativeBuildOptions, NativeColorExpression, NativeComponentBuilder, NativeComponentDefinition, NativeComponentGroupDefinition, NativeComponentProps, NativeComponentStyleHelpers, NativeComponentStyledBuilder, NativeComponentStyles, NativeConfig, NativeConfigDiagnostic, NativeConfigDiagnosticCode, NativeConfigValidationError, NativeDefaultModes, NativeDependencyPolicy, NativeDependencyPolicyEntry, NativeFontAssetGroupConfig, NativeFontAssetGroupDefinition, NativeFontAssetMember, NativeLayerDefinition, NativeLayerKind, NativeLayerStyle, NativeLayerStyles, NativeLiteral, NativeModeDefinition, NativeModeOptionDefinition, NativeRenderProps, NativeSelectableValue, NativeStyleEngine, NativeStyleValue, NativeTokenDefinition, NativeTokenGroupDefinition, NativeTokenValue, NativeViewportModeOption, OperatingSystemInput, OperatingSystemValue, RegisteredNativeComponent, SerializedNativeComponentGroup, SerializedNativeConfig, SystemLink, TokenRef, TokenType, alpha, asset, defineAssetGroup, defineMode, defineNativeComponent, defineNativeComponentGroup, defineTokenGroup, isOperatingSystemValue, mix, nativeLayer, operatingSystem, token, validateSerializedNativeConfig };
package/dist/refs.d.ts CHANGED
@@ -85,6 +85,18 @@ type TagName = string;
85
85
  interface TokenRef<TName extends string = string> {
86
86
  readonly __kind: 'token';
87
87
  readonly ref: TName;
88
+ /**
89
+ * Namespace scope for refs authored in extension payloads. Absent on
90
+ * source-authored refs (they resolve in their own system's namespace).
91
+ * `'consumer'` is stamped by the extension merge on plain `token()` refs
92
+ * — a consumer-authored ref always means the consumer's own tokens.
93
+ */
94
+ readonly scope?: 'consumer';
95
+ /** Pinned-system scope from a registry barrel's `token()` utility. */
96
+ readonly system?: {
97
+ readonly id: string;
98
+ readonly version: string;
99
+ };
88
100
  }
89
101
  interface TokenGroupRef<TName extends string = string> {
90
102
  readonly __kind: 'tokenGroup';
@@ -153,6 +165,13 @@ type AnyRef = TokenRef | TokenGroupRef | CompositeRef | ModeRef | StylePropRef |
153
165
  /** Doc-alignment alias kept for ergonomic import. */
154
166
  type TokenQualifiedName = TokenName;
155
167
  declare function token<TName extends TokenName>(ref: TName): TokenRef<TName>;
168
+ /**
169
+ * Curried factory behind a registry barrel's `token()` utility —
170
+ * `yahooOs.token('color/red-1')` names THAT system's token, letting a
171
+ * consumer mix references across pinned systems unambiguously. The plain
172
+ * `token()` import always means the consumer's own namespace.
173
+ */
174
+ declare function systemToken(systemId: string, version: string): <TName extends TokenName>(ref: TName) => TokenRef<TName>;
156
175
  declare function tokenGroup<TName extends TokenGroupName>(ref: TName): TokenGroupRef<TName>;
157
176
  /**
158
177
  * `composite(ref)` returns a bare `CompositeRef` plus an `.on(layer)`
@@ -182,4 +201,4 @@ declare function isComponentRef(value: unknown): value is ComponentRef;
182
201
  declare function isAssetGroupRef(value: unknown): value is AssetGroupRef;
183
202
  declare function isAssetRef(value: unknown): value is AssetRef;
184
203
  //#endregion
185
- export { AnyRef, AssetGroupName, AssetGroupRef, AssetName, AssetRef, ComponentName, ComponentRef, CompositeName, CompositeRef, CompositeRefBuilder, ModeName, ModeRef, MotionName, RegisteredAssetGroups, RegisteredComponents, RegisteredCompositeStyles, RegisteredModes, RegisteredModifiers, RegisteredMotion, RegisteredStyleProps, RegisteredTokenGroups, StylePropName, StylePropRef, TagName, TagRef, TokenGroupName, TokenGroupRef, TokenName, TokenQualifiedName, TokenRawNameRegistry, TokenRef, asset, assetGroup, component, composite, isAssetGroupRef, isAssetRef, isComponentRef, isCompositeRef, isModeRef, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, mode, styleProp, tag, token, tokenGroup };
204
+ export { AnyRef, AssetGroupName, AssetGroupRef, AssetName, AssetRef, ComponentName, ComponentRef, CompositeName, CompositeRef, CompositeRefBuilder, ModeName, ModeRef, MotionName, RegisteredAssetGroups, RegisteredComponents, RegisteredCompositeStyles, RegisteredModes, RegisteredModifiers, RegisteredMotion, RegisteredStyleProps, RegisteredTokenGroups, StylePropName, StylePropRef, TagName, TagRef, TokenGroupName, TokenGroupRef, TokenName, TokenQualifiedName, TokenRawNameRegistry, TokenRef, asset, assetGroup, component, composite, isAssetGroupRef, isAssetRef, isComponentRef, isCompositeRef, isModeRef, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, mode, styleProp, systemToken, tag, token, tokenGroup };
package/dist/refs.js CHANGED
@@ -5,6 +5,22 @@ function token(ref) {
5
5
  ref
6
6
  };
7
7
  }
8
+ /**
9
+ * Curried factory behind a registry barrel's `token()` utility —
10
+ * `yahooOs.token('color/red-1')` names THAT system's token, letting a
11
+ * consumer mix references across pinned systems unambiguously. The plain
12
+ * `token()` import always means the consumer's own namespace.
13
+ */
14
+ function systemToken(systemId, version) {
15
+ return (ref) => ({
16
+ __kind: "token",
17
+ ref,
18
+ system: {
19
+ id: systemId,
20
+ version
21
+ }
22
+ });
23
+ }
8
24
  function tokenGroup(ref) {
9
25
  return {
10
26
  __kind: "tokenGroup",
@@ -110,4 +126,4 @@ function isAssetRef(value) {
110
126
  return isRefOf(value, "asset");
111
127
  }
112
128
  //#endregion
113
- export { asset, assetGroup, component, composite, isAssetGroupRef, isAssetRef, isComponentRef, isCompositeRef, isModeRef, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, mode, styleProp, tag, token, tokenGroup };
129
+ export { asset, assetGroup, component, composite, isAssetGroupRef, isAssetRef, isComponentRef, isCompositeRef, isModeRef, isStylePropRef, isTagRef, isTokenGroupRef, isTokenRef, mode, styleProp, systemToken, tag, token, tokenGroup };