@yahoo/uds-create-cli 5.69.0 → 5.70.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yahoo/uds-create-cli",
3
- "version": "5.69.0",
3
+ "version": "5.70.0",
4
4
  "publishConfig": {
5
5
  "access": "public"
6
6
  },
@@ -32,10 +32,10 @@
32
32
  "@modelcontextprotocol/sdk": "^1.32.2",
33
33
  "@orpc/client": "^1.13.9",
34
34
  "@orpc/contract": "^1.13.9",
35
- "@yahoo/uds-create-config": "5.69.0",
36
- "@yahoo/uds-create-loader": "5.69.0",
37
- "@yahoo/uds-create-types": "5.69.0",
38
- "@yahoo/uds-create-utils": "5.69.0",
35
+ "@yahoo/uds-create-config": "5.70.0",
36
+ "@yahoo/uds-create-loader": "5.70.0",
37
+ "@yahoo/uds-create-types": "5.70.0",
38
+ "@yahoo/uds-create-utils": "5.70.0",
39
39
  "esbuild": "^0.27.4",
40
40
  "ts-morph": "^27.0.2",
41
41
  "get-tsconfig": "^4.10.0",
@@ -52,13 +52,13 @@
52
52
  "lodash": "^4.17.23",
53
53
  "prettier": "^3.8.1"
54
54
  },
55
- "udsSchemaVersion": 20261102143821,
55
+ "udsSchemaVersion": 20261102185610,
56
56
  "optionalDependencies": {
57
- "@yahoo/uds-create-cli-darwin-arm64": "5.69.0",
58
- "@yahoo/uds-create-cli-darwin-x64": "5.69.0",
59
- "@yahoo/uds-create-cli-linux-arm64": "5.69.0",
60
- "@yahoo/uds-create-cli-linux-x64": "5.69.0",
61
- "@yahoo/uds-create-cli-linux-arm64-musl": "5.69.0",
62
- "@yahoo/uds-create-cli-linux-x64-musl": "5.69.0"
57
+ "@yahoo/uds-create-cli-darwin-arm64": "5.70.0",
58
+ "@yahoo/uds-create-cli-darwin-x64": "5.70.0",
59
+ "@yahoo/uds-create-cli-linux-arm64": "5.70.0",
60
+ "@yahoo/uds-create-cli-linux-x64": "5.70.0",
61
+ "@yahoo/uds-create-cli-linux-arm64-musl": "5.70.0",
62
+ "@yahoo/uds-create-cli-linux-x64-musl": "5.70.0"
63
63
  }
64
64
  }
@@ -89766,7 +89766,7 @@ var Entity = class {
89766
89766
  };
89767
89767
 
89768
89768
  // ../config/dist/framework/schema-version.js
89769
- var CURRENT_SCHEMA_VERSION = 20261102143821;
89769
+ var CURRENT_SCHEMA_VERSION = 20261102185610;
89770
89770
  var SETTINGS_AS_KIND_VERSION = 20260908171448;
89771
89771
  var SchemaVersionTooNew = class extends ConfigFormatError {
89772
89772
  found;
@@ -89786,7 +89786,7 @@ function registerSchemaMigrations(...migrations) {
89786
89786
  for (const migration of migrations) {
89787
89787
  if (migration.version !== 1 && !isMintTimestamp(migration.version)) throw new Error(`Schema migration version ${migration.version} is not a mint timestamp \u2014 mint one with \`date +%Y%m%d%H%M%S\`, like a supabase migration.`);
89788
89788
  if (REGISTERED.has(migration.version)) throw new Error(`A schema migration at version ${migration.version} is already registered.`);
89789
- if (migration.version > 20261102143821) throw new Error(`Schema migration ${migration.version} is newer than CURRENT_SCHEMA_VERSION (${CURRENT_SCHEMA_VERSION}) \u2014 a stale branch merged, or the mint forgot to bump the constant. Re-mint: set CURRENT_SCHEMA_VERSION to the newest migration version.`);
89789
+ if (migration.version > 20261102185610) throw new Error(`Schema migration ${migration.version} is newer than CURRENT_SCHEMA_VERSION (${CURRENT_SCHEMA_VERSION}) \u2014 a stale branch merged, or the mint forgot to bump the constant. Re-mint: set CURRENT_SCHEMA_VERSION to the newest migration version.`);
89790
89790
  REGISTERED.set(migration.version, migration);
89791
89791
  }
89792
89792
  }
@@ -89817,7 +89817,7 @@ function pendingFor(version2, target2, options) {
89817
89817
  return [...(options?.migrations ?? REGISTERED).values()].filter((m) => m.version > version2 && m.version <= target2).sort((a, b) => a.version - b.version);
89818
89818
  }
89819
89819
  function upgradeSerializedConfig(json2, options) {
89820
- const target2 = options?.target ?? 20261102143821;
89820
+ const target2 = options?.target ?? 20261102185610;
89821
89821
  const version2 = detectedWireVersion(json2);
89822
89822
  if (version2 > target2) throw new SchemaVersionTooNew(version2, target2);
89823
89823
  const raw = json2;
@@ -96703,7 +96703,7 @@ var Config = class Config2 {
96703
96703
  * links from the provided sources. A declared `linkedKind` with no provided source throws. */
96704
96704
  hydrateFrom(stored, options) {
96705
96705
  const claimed = schemaVersionOf(stored);
96706
- if (claimed > 20261102143821) throw new SchemaVersionTooNew(claimed);
96706
+ if (claimed > 20261102185610) throw new SchemaVersionTooNew(claimed);
96707
96707
  const wire = upgradeSerializedConfig(stored);
96708
96708
  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 \u2014 import the config type's module (e.g. \`configs/system\`) before hydrating.`);
96709
96709
  const leftover = wire.options;
@@ -98039,7 +98039,15 @@ function planLinkApplied({ config: config2, input: input2 }) {
98039
98039
  const shadows = [];
98040
98040
  const gains = /* @__PURE__ */ new Map();
98041
98041
  let leftAnywhere = false;
98042
+ const replacements = replacementTakes({
98043
+ config: config2,
98044
+ slug: slug2,
98045
+ source,
98046
+ input: input2
98047
+ });
98048
+ const landing = new Set(replacements.entries.map(({ kind, path: path2 }) => `${kind}:${path2}`));
98042
98049
  const shadow2 = (kind, path2) => {
98050
+ if (landing.has(`${kind}:${path2}`)) return true;
98043
98051
  const held = config2.resolve(kind, path2);
98044
98052
  if (!held || held.borrowedFrom === slug2) return true;
98045
98053
  if (sharedWithOrigin({
@@ -98119,7 +98127,7 @@ function planLinkApplied({ config: config2, input: input2 }) {
98119
98127
  if (path2 === "*") continue;
98120
98128
  rejectData(`Cannot link "${path2}" through "${slug2}" \u2014 the source has no ${kind} there.`, ["data", accessor]);
98121
98129
  }
98122
- const taken = entries.filter((entry) => {
98130
+ const taken2 = entries.filter((entry) => {
98123
98131
  const fit = config2.canBorrow({
98124
98132
  kind,
98125
98133
  path: entry.from,
@@ -98129,12 +98137,12 @@ function planLinkApplied({ config: config2, input: input2 }) {
98129
98137
  if (source.resolve(kind, path2)) rejectData(fit.error, ["data", accessor]);
98130
98138
  return false;
98131
98139
  }).filter((entry) => shadow2(kind, entry.from));
98132
- if (taken.length === entries.length) {
98140
+ if (taken2.length === entries.length) {
98133
98141
  if (path2 !== "*") gained.push(path2);
98134
98142
  continue;
98135
98143
  }
98136
98144
  whole = false;
98137
- gained.push(...taken.map((entry) => entry.from));
98145
+ gained.push(...taken2.map((entry) => entry.from));
98138
98146
  }
98139
98147
  if (whole) gains.set(accessor, "*");
98140
98148
  else if (gained.length > 0) gains.set(accessor, gained);
@@ -98184,12 +98192,13 @@ function planLinkApplied({ config: config2, input: input2 }) {
98184
98192
  declared2 = Object.keys(next).length === 0 ? current : next;
98185
98193
  }
98186
98194
  const planned = [
98195
+ ...replacements.patches,
98187
98196
  ...takes2,
98188
98197
  ...declares,
98189
98198
  ...shadows
98190
98199
  ];
98191
98200
  let result = planned.length > 0 ? applied(config2, planned) : void 0;
98192
- if (takes2.length > 0 && result && "failed" in result) throw result.failed;
98201
+ if ((takes2.length > 0 || replacements.patches.length > 0) && result && "failed" in result) throw result.failed;
98193
98202
  const { dropped, stranded, patches: drops } = takes2.length > 0 && result && "config" in result ? directivesTakenFrom({
98194
98203
  config: config2,
98195
98204
  slug: slug2,
@@ -98200,7 +98209,74 @@ function planLinkApplied({ config: config2, input: input2 }) {
98200
98209
  patches: []
98201
98210
  };
98202
98211
  if (drops.length > 0 && result && "config" in result) result = applied(result.config, drops);
98203
- const patches = [...planned, ...drops];
98212
+ const taken = [];
98213
+ const leaves2 = [];
98214
+ for (const entry of replacements.entries) {
98215
+ const { kind, accessor, path: path2, replaces, from } = entry;
98216
+ if (from === void 0 || !result || !("config" in result)) {
98217
+ taken.push({
98218
+ kind,
98219
+ path: replaces,
98220
+ with: path2,
98221
+ ...from ? { from } : {},
98222
+ excluded: false,
98223
+ dropped: []
98224
+ });
98225
+ continue;
98226
+ }
98227
+ const leftOut = { [accessor]: [replaces] };
98228
+ const keptFor = linkedDependents({
98229
+ config: result.config,
98230
+ slug: from,
98231
+ data: leftOut
98232
+ });
98233
+ if (keptFor.length > 0) {
98234
+ taken.push({
98235
+ kind,
98236
+ path: replaces,
98237
+ with: path2,
98238
+ from,
98239
+ excluded: false,
98240
+ keptFor,
98241
+ dropped: []
98242
+ });
98243
+ continue;
98244
+ }
98245
+ const exclusion = planExclude({
98246
+ config: result.config,
98247
+ input: {
98248
+ path: from,
98249
+ data: leftOut
98250
+ }
98251
+ });
98252
+ if (exclusion.blocked !== void 0) {
98253
+ taken.push({
98254
+ kind,
98255
+ path: replaces,
98256
+ with: path2,
98257
+ from,
98258
+ excluded: false,
98259
+ keptBecause: exclusion.blocked,
98260
+ dropped: []
98261
+ });
98262
+ continue;
98263
+ }
98264
+ leaves2.push(...exclusion.patches);
98265
+ result = applied(result.config, exclusion.patches);
98266
+ taken.push({
98267
+ kind,
98268
+ path: replaces,
98269
+ with: path2,
98270
+ from,
98271
+ excluded: true,
98272
+ dropped: exclusion.dropped
98273
+ });
98274
+ }
98275
+ const patches = [
98276
+ ...planned,
98277
+ ...drops,
98278
+ ...leaves2
98279
+ ];
98204
98280
  return {
98205
98281
  plan: {
98206
98282
  declared: declared2,
@@ -98214,6 +98290,7 @@ function planLinkApplied({ config: config2, input: input2 }) {
98214
98290
  addresses: addresses2,
98215
98291
  linked,
98216
98292
  extended,
98293
+ replaced: taken,
98217
98294
  dropped,
98218
98295
  shared,
98219
98296
  patches,
@@ -98225,6 +98302,71 @@ function planLinkApplied({ config: config2, input: input2 }) {
98225
98302
  after: stranded.length === 0 && result && "config" in result ? result.config : void 0
98226
98303
  };
98227
98304
  }
98305
+ function replacementTakes({ config: config2, slug: slug2, source, input: input2 }) {
98306
+ const entries = [];
98307
+ const patches = [];
98308
+ const accessors = config2.accessors();
98309
+ const landing = /* @__PURE__ */ new Map();
98310
+ for (const [accessor, pairs] of Object.entries(input2.replace ?? {})) {
98311
+ const kind = accessors[accessor]?.kind;
98312
+ if (!kind) rejectData(`Cannot replace anything through "${slug2}" \u2014 this system has no "${accessor}".`, ["replace", accessor]);
98313
+ for (const [replaces, path2] of Object.entries(pairs)) {
98314
+ const at = [
98315
+ "replace",
98316
+ accessor,
98317
+ replaces
98318
+ ];
98319
+ if (input2.data !== "*" && !covers({
98320
+ declared: input2.data,
98321
+ accessor,
98322
+ path: path2
98323
+ })) rejectData(`Cannot replace "${replaces}" with "${path2}" \u2014 \`data\` doesn't link "${path2}" through "${slug2}". Name it there too.`, at);
98324
+ if (!source.resolve(kind, path2)) rejectData(`Cannot replace "${replaces}" with "${path2}" \u2014 "${slug2}" has no ${kind} "${path2}".`, at);
98325
+ if (path2 === replaces) rejectData(`Cannot replace "${path2}" with itself \u2014 taking the source's "${path2}" over it is \`onLinked: 'take'\`.`, at);
98326
+ const twice = landing.get(`${kind}:${path2}`);
98327
+ if (twice !== void 0) rejectData(`Cannot replace both "${twice}" and "${replaces}" with "${path2}".`, at);
98328
+ const held = config2.resolve(kind, replaces);
98329
+ if (!held) rejectData(`Cannot replace "${replaces}" \u2014 this system has no ${kind} "${replaces}".`, at);
98330
+ if (held.borrowedFrom === slug2) rejectData(`Cannot replace "${replaces}" with "${path2}" \u2014 "${replaces}" already comes from "${slug2}".`, at);
98331
+ const occupied = config2.storedBody(kind, path2);
98332
+ if (occupied !== void 0 && !isMintedRow(occupied)) rejectData(`Cannot replace "${replaces}" with "${path2}" \u2014 this system already has a ${kind} of its own at "${path2}".`, at);
98333
+ landing.set(`${kind}:${path2}`, replaces);
98334
+ const from = held.borrowedFrom ?? declaredElsewhere({
98335
+ config: config2,
98336
+ slug: slug2,
98337
+ kind,
98338
+ path: replaces
98339
+ });
98340
+ const stored = config2.storedBody(kind, replaces);
98341
+ const minted = stored !== void 0 && isMintedRow(stored);
98342
+ entries.push({
98343
+ kind,
98344
+ accessor,
98345
+ path: path2,
98346
+ replaces,
98347
+ ...from ? { from } : {}
98348
+ });
98349
+ patches.push({
98350
+ kind,
98351
+ operation: minted ? "create" : "replace",
98352
+ path: replaces,
98353
+ data: {
98354
+ ...ref(kind, path2, slug2),
98355
+ extend: {}
98356
+ }
98357
+ }, {
98358
+ kind,
98359
+ operation: "rename",
98360
+ path: replaces,
98361
+ to: path2
98362
+ });
98363
+ }
98364
+ }
98365
+ return {
98366
+ entries,
98367
+ patches
98368
+ };
98369
+ }
98228
98370
  function directivesTakenFrom({ config: config2, slug: slug2, after: after5 }) {
98229
98371
  const key2 = (at) => `${at.slug}\0${at.accessor}\0${at.path}`;
98230
98372
  const already = new Set(danglingDirectives(config2).map(key2));
@@ -99029,7 +99171,16 @@ var linkInput = external_exports.object({
99029
99171
  data: external_exports.union([external_exports.literal("*"), external_exports.record(external_exports.string(), copyPaths)]),
99030
99172
  /** What to do at a path another linked system provides: `'take'` makes it follow this source,
99031
99173
  * `'keep'` leaves it where it comes from. Required when there is one; `link-plan` lists them. */
99032
- onLinked: external_exports.enum(["keep", "take"]).optional()
99174
+ onLinked: external_exports.enum(["keep", "take"]).optional(),
99175
+ /**
99176
+ * A component this config holds under one name, replaced with the source's of another name, keyed
99177
+ * by accessor: `{ components: { SelectContent: 'SelectMenu' } }` replaces the `SelectContent` this
99178
+ * config holds with the source's `SelectMenu`. Every ref to `SelectContent` is renamed to
99179
+ * `SelectMenu`, so design files and code follow the way they follow a rename, and the system
99180
+ * `SelectContent` came through stops deriving it unless its own rows still use it. Each source path
99181
+ * is one `data` names; `link-plan` lists each in `replaced`. A take at the same name is `onLinked`.
99182
+ */
99183
+ replace: external_exports.record(external_exports.string(), external_exports.record(external_exports.string().min(1), external_exports.string().min(1))).optional()
99033
99184
  });
99034
99185
  var unlinkInput = external_exports.object({
99035
99186
  path: pathInput("linked-system"),
@@ -99071,7 +99222,8 @@ function linkPlanInputOf(input2) {
99071
99222
  return {
99072
99223
  path: String(input2.path),
99073
99224
  data: input2.data,
99074
- ...input2.onLinked === void 0 ? {} : { onLinked: input2.onLinked }
99225
+ ...input2.onLinked === void 0 ? {} : { onLinked: input2.onLinked },
99226
+ ...input2.replace === void 0 ? {} : { replace: input2.replace }
99075
99227
  };
99076
99228
  }
99077
99229
  function linkExample({ config: config2, path: path2 }) {
@@ -99150,7 +99302,7 @@ var LinkedSystemDefinition = defineEntity({
99150
99302
  input: linkInput,
99151
99303
  readOnly: false,
99152
99304
  label: "Link from",
99153
- description: "Draw entities from a linked system, following the source: `data` names them by accessor \u2014 `{ tokens: ['color/brand', 'color'] }` takes an entity and a folder's members, `{ tokens: '*' }` every token, and `'*'` the whole system. What this config already holds at those paths is replaced by theirs, so run `linked-system/link-plan` with the same input first to see what that is. To hold their values as your own instead, `copy`.",
99305
+ description: "Draw entities from a linked system, following the source: `data` names them by accessor \u2014 `{ tokens: ['color/brand', 'color'] }` takes an entity and a folder's members, `{ tokens: '*' }` every token, and `'*'` the whole system. What this config already holds at those paths is replaced by theirs, so run `linked-system/link-plan` with the same input first to see what that is. To replace something this config holds under another name (the `SelectContent` it has with the source's `SelectMenu`), name the pair in `replace` (`{ components: { SelectContent: 'SelectMenu' } }`): every reference to the old name moves to the new one, in design files and code too. To hold their values as your own instead, `copy`.",
99154
99306
  scope: "item",
99155
99307
  approval: "reference-change",
99156
99308
  title: (entity) => `Link something from ${entity}`,
@@ -99173,7 +99325,7 @@ var LinkedSystemDefinition = defineEntity({
99173
99325
  input: linkInput,
99174
99326
  readOnly: true,
99175
99327
  label: "Plan a link",
99176
- description: "What `link` with the same input replaces \u2014 rows of yours deleted so the source shows through, every path another linked system provides (`linked`, turned into extensions when `onLinked` says take), the `options` entries another linked system holds at what a take moves, which it removes since they would apply to nothing (`dropped`), members left alone because they are already here from the same origin, paths another linked system declares that the link reaches as a different entity (`settled`), whose row stays, and why the config would refuse the link (`blocked`), a collision it would leave among them. Writes nothing.",
99328
+ description: "What `link` with the same input replaces \u2014 rows of yours deleted so the source shows through, every path another linked system provides (`linked`, turned into extensions when `onLinked` says take), the `options` entries another linked system holds at what a take moves, which it removes since they would apply to nothing (`dropped`), members left alone because they are already here from the same origin, paths another linked system declares that the link reaches as a different entity (`settled`), whose row stays, what `replace` replaces under another name (`replaced`: each path, what replaces it, the pin it came through, and whether it is left out of that pin or kept because rows of that pin still use it), and why the config would refuse the link (`blocked`), a collision it would leave among them. Writes nothing.",
99177
99329
  scope: "item",
99178
99330
  title: (entity) => `Plan a link from ${entity}`,
99179
99331
  example: linkExample,
@@ -100112,6 +100264,13 @@ var defaultColorsMigration = {
100112
100264
  }
100113
100265
  };
100114
100266
 
100267
+ // ../config/dist/migrations/20261102185610_link_replace.js
100268
+ var LINK_REPLACE_VERSION = 20261102185610;
100269
+ var linkReplaceMigration = {
100270
+ version: LINK_REPLACE_VERSION,
100271
+ up: (json2) => json2
100272
+ };
100273
+
100115
100274
  // ../../node_modules/css-tree/lib/generator/sourceMap.js
100116
100275
  var import_source_map_generator = __toESM(require_source_map_generator(), 1);
100117
100276
  var trackNodes = /* @__PURE__ */ new Set(["Atrule", "Selector", "Declaration"]);
@@ -102849,6 +103008,7 @@ if (!registeredSchemaMigrations().has(20261027205147)) registerSchemaMigrations(
102849
103008
  if (!registeredSchemaMigrations().has(20261030134149)) registerSchemaMigrations(componentMapPropsMigration);
102850
103009
  if (!registeredSchemaMigrations().has(20261030163028)) registerSchemaMigrations(layerPrefixMigration);
102851
103010
  if (!registeredSchemaMigrations().has(20261102143821)) registerSchemaMigrations(defaultColorsMigration);
103011
+ if (!registeredSchemaMigrations().has(20261102185610)) registerSchemaMigrations(linkReplaceMigration);
102852
103012
 
102853
103013
  // ../config/dist/capture/node-ops.js
102854
103014
  var DEFAULT_WIDTH = 1600;