@yahoo/uds-create-config 5.57.0 → 5.57.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/entities/system/LinkedSystem.js +2 -2
- package/dist/entities/system/copy-plan.js +55 -7
- package/dist/entities/system/link-plan.d.ts +3 -0
- package/dist/entities/system/link-plan.js +24 -0
- package/dist/framework/Config.d.ts +48 -0
- package/dist/framework/Config.js +97 -11
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -352,7 +352,7 @@ const LinkedSystemDefinition = defineEntity({
|
|
|
352
352
|
input: unlinkInput,
|
|
353
353
|
readOnly: false,
|
|
354
354
|
label: "Unlink from",
|
|
355
|
-
description: "Stop following a linked system's entities, in `link`'s shape or everything when `data` is omitted. The rows the declaration minted go with it, and so do the linked rows that point at them, since left linked they would bring them back; nothing of yours moves. A row of yours pointing at one of theirs refuses this — `copy` what is used first, or `break` with `keep: true`. `unlink-plan` names everything that goes.",
|
|
355
|
+
description: "Stop following a linked system's entities, in `link`'s shape or everything when `data` is omitted. The rows the declaration minted go with it, and so do the linked rows that point at them, since left linked they would bring them back, and the pin's `options` entries left with no row to adjust; nothing of yours moves. A row of yours pointing at one of theirs refuses this — `copy` what is used first, or `break` with `keep: true`. `unlink-plan` names everything that goes.",
|
|
356
356
|
scope: "item",
|
|
357
357
|
approval: "reference-change",
|
|
358
358
|
title: (entity) => `Unlink from ${entity}`,
|
|
@@ -374,7 +374,7 @@ const LinkedSystemDefinition = defineEntity({
|
|
|
374
374
|
input: unlinkInput,
|
|
375
375
|
readOnly: true,
|
|
376
376
|
label: "Plan an unlink",
|
|
377
|
-
description: "What `unlink` with the same input removes — the minted rows the narrower declaration no longer reaches, with the linked rows taken along because they point at them named in `cascade` — and why the config would refuse it, a collision it would leave among them. Writes nothing.",
|
|
377
|
+
description: "What `unlink` with the same input removes — the minted rows the narrower declaration no longer reaches, with the linked rows taken along because they point at them named in `cascade`, and the `options` entries of the pin that go with them in `dropped` — and why the config would refuse it, a collision it would leave among them. Writes nothing.",
|
|
378
378
|
scope: "item",
|
|
379
379
|
title: (entity) => `Plan unlinking from ${entity}`,
|
|
380
380
|
example: pinExample,
|
|
@@ -96,10 +96,20 @@ function planCopy({ config, input }) {
|
|
|
96
96
|
const taking = [];
|
|
97
97
|
const folders = [];
|
|
98
98
|
const reused = [];
|
|
99
|
+
/** Folders this config draws through another pin, which a copied ref binds to as it does a reused row. */
|
|
100
|
+
const heldFolders = /* @__PURE__ */ new Set();
|
|
99
101
|
/** Every `kind:path` `take` has answered, whichever way, so the walk below visits each once. */
|
|
100
102
|
const seen = /* @__PURE__ */ new Set();
|
|
101
103
|
const declared = declarationOf(config, slug);
|
|
102
104
|
const folder = (kind, path) => {
|
|
105
|
+
const through = config.groupBorrowedFrom({
|
|
106
|
+
kind,
|
|
107
|
+
groupPath: path
|
|
108
|
+
});
|
|
109
|
+
if (through !== void 0 && through !== slug && input.onConflict !== "replace") {
|
|
110
|
+
heldFolders.add(`${kind}:${path}`);
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
103
113
|
if (!folders.some((f) => f.kind === kind && f.path === path)) folders.push({
|
|
104
114
|
kind,
|
|
105
115
|
path
|
|
@@ -258,6 +268,32 @@ function planCopy({ config, input }) {
|
|
|
258
268
|
}
|
|
259
269
|
}
|
|
260
270
|
if (taking.length === 0 && wholesale) rejectData(`"${slug}" has nothing to copy.`);
|
|
271
|
+
/**
|
|
272
|
+
* The files of a sibling a copied render imports, when the sibling itself isn't copied — this config
|
|
273
|
+
* holds that path already, through another pin or as its own. The render imports the source's
|
|
274
|
+
* module, not whatever answers the path here, so that module lands without the component, and so do
|
|
275
|
+
* the files of the siblings it imports in turn. A copied sibling brings its own files.
|
|
276
|
+
*/
|
|
277
|
+
const siblingFiles = ({ sibling, component }) => {
|
|
278
|
+
const key = `files:${sibling}`;
|
|
279
|
+
if (seen.has(key)) return;
|
|
280
|
+
seen.add(key);
|
|
281
|
+
if (taking.some((row) => row.kind === "component" && row.at === sibling)) return;
|
|
282
|
+
for (const path of renderSourceFiles({
|
|
283
|
+
source,
|
|
284
|
+
path: sibling
|
|
285
|
+
})) takeFile({
|
|
286
|
+
path,
|
|
287
|
+
component
|
|
288
|
+
});
|
|
289
|
+
for (const next of renderImportedComponents({
|
|
290
|
+
source,
|
|
291
|
+
path: sibling
|
|
292
|
+
})) siblingFiles({
|
|
293
|
+
sibling: next,
|
|
294
|
+
component
|
|
295
|
+
});
|
|
296
|
+
};
|
|
261
297
|
/** Take what `body` points at by ref. */
|
|
262
298
|
const follow = (body) => {
|
|
263
299
|
for (const target of collectRefs(body)) {
|
|
@@ -318,12 +354,18 @@ function planCopy({ config, input }) {
|
|
|
318
354
|
for (const sibling of renderImportedComponents({
|
|
319
355
|
source,
|
|
320
356
|
path: row.theirs
|
|
321
|
-
}))
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
357
|
+
})) {
|
|
358
|
+
take({
|
|
359
|
+
kind: "component",
|
|
360
|
+
theirs: sibling,
|
|
361
|
+
at: sibling,
|
|
362
|
+
named: false
|
|
363
|
+
});
|
|
364
|
+
siblingFiles({
|
|
365
|
+
sibling,
|
|
366
|
+
component: row.theirs
|
|
367
|
+
});
|
|
368
|
+
}
|
|
327
369
|
for (const path of renderSourceFiles({
|
|
328
370
|
source,
|
|
329
371
|
path: row.theirs
|
|
@@ -336,11 +378,17 @@ function planCopy({ config, input }) {
|
|
|
336
378
|
const arriving = new Set([
|
|
337
379
|
...taking.map((row) => `${row.kind}:${row.at}`),
|
|
338
380
|
...reused.map((row) => `${row.kind}:${row.path}`),
|
|
381
|
+
...heldFolders,
|
|
339
382
|
...folders.map((folder) => `${folder.kind}:${folder.path}`)
|
|
340
383
|
]);
|
|
341
384
|
const patches = [];
|
|
342
385
|
for (const { kind, path } of folders) {
|
|
343
|
-
const meta = ownMeta(
|
|
386
|
+
const meta = ownMeta(config.copyOfGroup({
|
|
387
|
+
slug,
|
|
388
|
+
kind,
|
|
389
|
+
path,
|
|
390
|
+
alongside: arriving
|
|
391
|
+
}) ?? {});
|
|
344
392
|
const pointed = config.groupBorrowedFrom({
|
|
345
393
|
kind,
|
|
346
394
|
groupPath: path
|
|
@@ -64,6 +64,9 @@ interface UnlinkPlan {
|
|
|
64
64
|
/** Linked rows unlinked with the named ones because they point at them: left linked, they would
|
|
65
65
|
* bring the named rows back on the next derive. */
|
|
66
66
|
readonly cascade: readonly EntityAddress[];
|
|
67
|
+
/** The pin's `options` entries that go with the unlink: one on a path that stops deriving, and one
|
|
68
|
+
* on a path drawn from elsewhere that names a row that goes. Neither has a row to adjust. */
|
|
69
|
+
readonly dropped: readonly EntityAddress[];
|
|
67
70
|
/** Why the config would refuse. `undefined` when it would go through. */
|
|
68
71
|
readonly blocked?: string;
|
|
69
72
|
/** The paths the unlink would leave two linked systems offering as different entities, when that
|
|
@@ -329,6 +329,7 @@ function planUnlink({ config, input }) {
|
|
|
329
329
|
declared: void 0,
|
|
330
330
|
removed: [],
|
|
331
331
|
cascade: [],
|
|
332
|
+
dropped: [],
|
|
332
333
|
patches: []
|
|
333
334
|
};
|
|
334
335
|
let declared;
|
|
@@ -397,16 +398,39 @@ function planUnlink({ config, input }) {
|
|
|
397
398
|
}
|
|
398
399
|
if (input.data !== void 0 && removed.length === 0) blocked = stillReached({ slug });
|
|
399
400
|
}
|
|
401
|
+
const dropped = after ? deadDirectives({
|
|
402
|
+
config,
|
|
403
|
+
after,
|
|
404
|
+
slug,
|
|
405
|
+
removed
|
|
406
|
+
}) : [];
|
|
407
|
+
if (dropped.length > 0) {
|
|
408
|
+
const update = patches[patches.length - 1];
|
|
409
|
+
if (dropped.length === config.sourceDirectives(slug).length) update.data.options = null;
|
|
410
|
+
else for (const { accessor, path } of dropped) update.data[`options.${accessor}.${path}`] = null;
|
|
411
|
+
}
|
|
400
412
|
return {
|
|
401
413
|
declared,
|
|
402
414
|
removed,
|
|
403
415
|
cascade,
|
|
416
|
+
dropped: dropped.map(({ kind, path }) => ({
|
|
417
|
+
kind,
|
|
418
|
+
path
|
|
419
|
+
})),
|
|
404
420
|
...blocked === void 0 ? {} : { blocked },
|
|
405
421
|
...refused.collisions ? { collisions: refused.collisions } : {},
|
|
406
422
|
patches
|
|
407
423
|
};
|
|
408
424
|
}
|
|
409
425
|
/**
|
|
426
|
+
* The pin's directives an unlink leaves with nothing to do: on a path that no longer derives through
|
|
427
|
+
* the pin, and either on a row the unlink retires or naming one.
|
|
428
|
+
*/
|
|
429
|
+
function deadDirectives({ config, after, slug, removed }) {
|
|
430
|
+
const gone = new Set(removed.map(({ kind, path }) => `${kind}:${path}`));
|
|
431
|
+
return config.sourceDirectives(slug).filter((directive) => directive.kind !== void 0 && after.resolve(directive.kind, directive.path)?.borrowedFrom !== slug && (gone.has(`${directive.kind}:${directive.path}`) || collectRefs(config.sourceOverlay(slug, directive.kind, directive.path)).some((target) => gone.has(target))));
|
|
432
|
+
}
|
|
433
|
+
/**
|
|
410
434
|
* Leave paths of a linked system out, with a `!` entry each in the pin's `link`. Stronger than
|
|
411
435
|
* `unlink`: nothing derives there however the link reaches it, a linked token naming it included,
|
|
412
436
|
* and the linked tokens' overrides under an excluded modifier are left out of the build. `link` with
|
|
@@ -1942,6 +1942,42 @@ declare class Config {
|
|
|
1942
1942
|
alongside?: ReadonlySet<string>;
|
|
1943
1943
|
extend?: Record<string, unknown>;
|
|
1944
1944
|
}): Record<string, unknown> | undefined;
|
|
1945
|
+
/**
|
|
1946
|
+
* One of a source's folders' meta as a copy stores it — its refs spelled from here as
|
|
1947
|
+
* {@link copyOf} spells a body's. The meta as the source holds it names its own pins by their slugs
|
|
1948
|
+
* there: the Bridge's `icons` folder names `package:@yahoo/uds-icons@yos`, and stored as it was that
|
|
1949
|
+
* names a pin this config doesn't have. `undefined` when the source has no folder there.
|
|
1950
|
+
*/
|
|
1951
|
+
copyOfGroup({
|
|
1952
|
+
slug,
|
|
1953
|
+
kind,
|
|
1954
|
+
path,
|
|
1955
|
+
alongside
|
|
1956
|
+
}: {
|
|
1957
|
+
slug: string;
|
|
1958
|
+
kind: string;
|
|
1959
|
+
path: string; /** `kind:path` targets landing as this config's own in the same edit. */
|
|
1960
|
+
alongside?: ReadonlySet<string>;
|
|
1961
|
+
}): Record<string, unknown> | undefined;
|
|
1962
|
+
/**
|
|
1963
|
+
* `body` with each ref routed through another system's pin (`@yos-v3~yos`) respelled through this
|
|
1964
|
+
* config's own pin to the same system, where that pin's source holds the target too: a copy then
|
|
1965
|
+
* names what this config reaches directly rather than keeping the pin it came through referenced.
|
|
1966
|
+
* Bare when this config already holds the target as a pointer through that pin.
|
|
1967
|
+
*/
|
|
1968
|
+
private throughDirectPins;
|
|
1969
|
+
/**
|
|
1970
|
+
* The pin of this config's own that reaches the system a routed source ends at — `yahoo-os` for
|
|
1971
|
+
* `yos-v3~yos`, when this config pins directly what `yos-v3` pins as `yos`. Matched on the pin
|
|
1972
|
+
* kind's `sourceOrigin`, so the two pins may name different versions. `undefined` for a source of
|
|
1973
|
+
* one hop, or one whose system no pin here reaches.
|
|
1974
|
+
*
|
|
1975
|
+
* The two pins match when they agree on every origin field both set, and share at least one. Not on
|
|
1976
|
+
* the whole key: a pin by path is stamped with its sibling's id when it's pushed, so the Bridge's
|
|
1977
|
+
* `yos` reads `configPath` and `systemId` where this config's pin to the same system names only the
|
|
1978
|
+
* id — and a `configPath` is relative to the config holding it, so it can't be compared across two.
|
|
1979
|
+
*/
|
|
1980
|
+
private directRoute;
|
|
1945
1981
|
/**
|
|
1946
1982
|
* Whether a copied row no longer matches what its source offers at the path it was copied from.
|
|
1947
1983
|
*
|
|
@@ -2255,6 +2291,16 @@ declare class Config {
|
|
|
2255
2291
|
* that reaches derivation — a deleted extension whose source reached the row — says what it did.
|
|
2256
2292
|
*/
|
|
2257
2293
|
private assertDerivedDropsUnreferenced;
|
|
2294
|
+
/**
|
|
2295
|
+
* Whether every directive of `pin` that names `target` sits on a path that no longer derives through
|
|
2296
|
+
* it — retired by this derivation, or drawn from another source already. Such a directive lays its
|
|
2297
|
+
* value over no row, so it goes with the link rather than being stranded by it: a pin's own
|
|
2298
|
+
* `options` never refuse removing its link. A directive on a row the pin still mints does, since
|
|
2299
|
+
* that row would be left pointing at nothing.
|
|
2300
|
+
*
|
|
2301
|
+
* `false` when `pin` is not a source, or names `target` somewhere other than a directive.
|
|
2302
|
+
*/
|
|
2303
|
+
private directivesGoWith;
|
|
2258
2304
|
/**
|
|
2259
2305
|
* This config with a row for every entity it inherits — the build's output. A pin patch runs this
|
|
2260
2306
|
* inside {@link apply}; a source attaching runs it through the session.
|
|
@@ -2513,6 +2559,8 @@ declare class Config {
|
|
|
2513
2559
|
*/
|
|
2514
2560
|
sourceIdentityKey(kind: string, path: string): string | undefined;
|
|
2515
2561
|
private sourceKey;
|
|
2562
|
+
/** Each of a pin's `of` fields as it reads, `''` where unset, in the kind's order. */
|
|
2563
|
+
private sourceFields;
|
|
2516
2564
|
/**
|
|
2517
2565
|
* Where what this config shows at `path` originates: the system it was first authored in, followed
|
|
2518
2566
|
* through however many pins it took to get here. `undefined` for a row this config authored itself.
|
package/dist/framework/Config.js
CHANGED
|
@@ -3935,25 +3935,85 @@ var Config = class Config {
|
|
|
3935
3935
|
path,
|
|
3936
3936
|
derives
|
|
3937
3937
|
});
|
|
3938
|
-
if (!theirs
|
|
3939
|
-
const laid = overlayBody({
|
|
3938
|
+
if (!theirs) return void 0;
|
|
3939
|
+
const laid = extend ? overlayBody({
|
|
3940
3940
|
overlay: {
|
|
3941
3941
|
extend,
|
|
3942
3942
|
hidden: false
|
|
3943
3943
|
},
|
|
3944
3944
|
theirs
|
|
3945
|
-
});
|
|
3946
|
-
|
|
3945
|
+
}) : void 0;
|
|
3946
|
+
return this.throughDirectPins(laid ? this.laidLinkedBody({
|
|
3947
3947
|
kind,
|
|
3948
3948
|
path,
|
|
3949
3949
|
body: theirs,
|
|
3950
3950
|
extend: laid,
|
|
3951
3951
|
source: this.sourceFor(slug)
|
|
3952
|
-
});
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3952
|
+
}) : theirs);
|
|
3953
|
+
}
|
|
3954
|
+
/**
|
|
3955
|
+
* One of a source's folders' meta as a copy stores it — its refs spelled from here as
|
|
3956
|
+
* {@link copyOf} spells a body's. The meta as the source holds it names its own pins by their slugs
|
|
3957
|
+
* there: the Bridge's `icons` folder names `package:@yahoo/uds-icons@yos`, and stored as it was that
|
|
3958
|
+
* names a pin this config doesn't have. `undefined` when the source has no folder there.
|
|
3959
|
+
*/
|
|
3960
|
+
copyOfGroup({ slug, kind, path, alongside }) {
|
|
3961
|
+
const source = this.sourceFor(slug);
|
|
3962
|
+
const meta = source?.groups(kind).find((group) => group.path === path)?.meta;
|
|
3963
|
+
if (!source || !meta) return void 0;
|
|
3964
|
+
return this.throughDirectPins(qualifyRefs({
|
|
3965
|
+
value: meta,
|
|
3966
|
+
source: slug,
|
|
3967
|
+
owns: (kindName) => source.ownedKinds().includes(kindName),
|
|
3968
|
+
namesItAlready: (target) => alongside?.has(`${kindOf(target)}:${pathOf(target)}`) === true || this.borrowsExactly(target, slug)
|
|
3969
|
+
}));
|
|
3970
|
+
}
|
|
3971
|
+
/**
|
|
3972
|
+
* `body` with each ref routed through another system's pin (`@yos-v3~yos`) respelled through this
|
|
3973
|
+
* config's own pin to the same system, where that pin's source holds the target too: a copy then
|
|
3974
|
+
* names what this config reaches directly rather than keeping the pin it came through referenced.
|
|
3975
|
+
* Bare when this config already holds the target as a pointer through that pin.
|
|
3976
|
+
*/
|
|
3977
|
+
throughDirectPins(body) {
|
|
3978
|
+
let respelled = body;
|
|
3979
|
+
for (const target of new Set(collectRefs(body))) {
|
|
3980
|
+
const { kind, path, source } = splitRef(target);
|
|
3981
|
+
if (source === void 0) continue;
|
|
3982
|
+
const direct = this.directRoute(source);
|
|
3983
|
+
if (direct === void 0 || !this.sourceFor(direct)?.resolve(kind, path)) continue;
|
|
3984
|
+
const through = ref(kind, path, direct);
|
|
3985
|
+
respelled = rewriteRefs(respelled, `${kind}:${path}@${source}`, this.borrowsExactly(through, direct) ? `${kind}:${path}` : through.__ref);
|
|
3986
|
+
}
|
|
3987
|
+
return respelled;
|
|
3988
|
+
}
|
|
3989
|
+
/**
|
|
3990
|
+
* The pin of this config's own that reaches the system a routed source ends at — `yahoo-os` for
|
|
3991
|
+
* `yos-v3~yos`, when this config pins directly what `yos-v3` pins as `yos`. Matched on the pin
|
|
3992
|
+
* kind's `sourceOrigin`, so the two pins may name different versions. `undefined` for a source of
|
|
3993
|
+
* one hop, or one whose system no pin here reaches.
|
|
3994
|
+
*
|
|
3995
|
+
* The two pins match when they agree on every origin field both set, and share at least one. Not on
|
|
3996
|
+
* the whole key: a pin by path is stamped with its sibling's id when it's pushed, so the Bridge's
|
|
3997
|
+
* `yos` reads `configPath` and `systemId` where this config's pin to the same system names only the
|
|
3998
|
+
* id — and a `configPath` is relative to the config holding it, so it can't be compared across two.
|
|
3999
|
+
*/
|
|
4000
|
+
directRoute(source) {
|
|
4001
|
+
const hops = sourceHops(source);
|
|
4002
|
+
const last = hops.pop();
|
|
4003
|
+
if (last === void 0 || hops.length === 0) return void 0;
|
|
4004
|
+
let through = this;
|
|
4005
|
+
for (const hop of hops) through = through?.sourceFor(hop);
|
|
4006
|
+
if (!through) return void 0;
|
|
4007
|
+
for (const sourceKind of through.sourceKinds()) {
|
|
4008
|
+
const theirs = through.sourceFields(sourceKind, last, "sourceOrigin");
|
|
4009
|
+
if (theirs === void 0) continue;
|
|
4010
|
+
const direct = this.sourceSlugs().find((slug) => {
|
|
4011
|
+
const mine = this.sourceFields(sourceKind, slug, "sourceOrigin");
|
|
4012
|
+
const shared = theirs.flatMap((value, field) => value !== "" && mine?.[field] ? [field] : []);
|
|
4013
|
+
return shared.length > 0 && shared.every((field) => theirs[field] === mine?.[field]);
|
|
4014
|
+
});
|
|
4015
|
+
if (direct !== void 0) return direct;
|
|
4016
|
+
}
|
|
3957
4017
|
}
|
|
3958
4018
|
/**
|
|
3959
4019
|
* Whether a copied row no longer matches what its source offers at the path it was copied from.
|
|
@@ -4584,11 +4644,16 @@ var Config = class Config {
|
|
|
4584
4644
|
assertDerivedDropsUnreferenced({ action = "remove the link", derivation = this.rowDerivation() } = {}) {
|
|
4585
4645
|
const { snapshot } = this.state;
|
|
4586
4646
|
const contested = new Set(derivation.collisions.map(({ kind, path }) => `${kind}:${path}`));
|
|
4647
|
+
const retired = new Set(derivation.changes.filter((change) => change.value === void 0).map(({ kind, path }) => `${kind}:${path}`));
|
|
4587
4648
|
const stranded = [];
|
|
4588
4649
|
let collides = false;
|
|
4589
4650
|
for (const change of derivation.changes) {
|
|
4590
4651
|
if (change.value !== void 0) continue;
|
|
4591
|
-
const referrers = this.referrersOf(snapshot, change.kind, change.path).filter((referrer) => !isMintedAt(snapshot, referrer)
|
|
4652
|
+
const referrers = this.referrersOf(snapshot, change.kind, change.path).filter((referrer) => !isMintedAt(snapshot, referrer) && !this.directivesGoWith({
|
|
4653
|
+
pin: referrer,
|
|
4654
|
+
target: change,
|
|
4655
|
+
retired
|
|
4656
|
+
}));
|
|
4592
4657
|
if (referrers.length === 0) continue;
|
|
4593
4658
|
if (contested.has(`${change.kind}:${change.path}`)) collides = true;
|
|
4594
4659
|
stranded.push(`${change.kind}:${change.path} (used by ${referrers.join(", ")})`);
|
|
@@ -4598,6 +4663,23 @@ var Config = class Config {
|
|
|
4598
4663
|
reject("REFERRERS_BLOCK", `Cannot ${action} — it would take away ${stranded.join("; ")}. Copy what is used first (\`linked-system/copy\`), or break the link keeping its values (\`linked-system/break\` with \`keep: true\`).`);
|
|
4599
4664
|
}
|
|
4600
4665
|
/**
|
|
4666
|
+
* Whether every directive of `pin` that names `target` sits on a path that no longer derives through
|
|
4667
|
+
* it — retired by this derivation, or drawn from another source already. Such a directive lays its
|
|
4668
|
+
* value over no row, so it goes with the link rather than being stranded by it: a pin's own
|
|
4669
|
+
* `options` never refuse removing its link. A directive on a row the pin still mints does, since
|
|
4670
|
+
* that row would be left pointing at nothing.
|
|
4671
|
+
*
|
|
4672
|
+
* `false` when `pin` is not a source, or names `target` somewhere other than a directive.
|
|
4673
|
+
*/
|
|
4674
|
+
directivesGoWith({ pin, target, retired }) {
|
|
4675
|
+
if (!this.entityOf(kindOf(pin))?.sourceIdentity) return false;
|
|
4676
|
+
const slug = pathOf(pin);
|
|
4677
|
+
const aliases = new Set(this.refAliases(target.kind, target.path));
|
|
4678
|
+
const naming = this.sourceDirectives(slug).filter((directive) => directive.kind !== void 0 && collectRefs(this.sourceOverlay(slug, directive.kind, directive.path)).some((ref) => aliases.has(ref)));
|
|
4679
|
+
if (naming.length === 0) return false;
|
|
4680
|
+
return naming.every(({ kind, path }) => retired.has(`${kind}:${path}`) || this.resolve(kind, path)?.borrowedFrom !== slug);
|
|
4681
|
+
}
|
|
4682
|
+
/**
|
|
4601
4683
|
* This config with a row for every entity it inherits — the build's output. A pin patch runs this
|
|
4602
4684
|
* inside {@link apply}; a source attaching runs it through the session.
|
|
4603
4685
|
*
|
|
@@ -5415,6 +5497,10 @@ var Config = class Config {
|
|
|
5415
5497
|
return this.sourceKey(kind, path, "sourceIdentity");
|
|
5416
5498
|
}
|
|
5417
5499
|
sourceKey(kind, path, of) {
|
|
5500
|
+
return this.sourceFields(kind, path, of)?.join("\0");
|
|
5501
|
+
}
|
|
5502
|
+
/** Each of a pin's `of` fields as it reads, `''` where unset, in the kind's order. */
|
|
5503
|
+
sourceFields(kind, path, of) {
|
|
5418
5504
|
const entry = this.entityOf(kind);
|
|
5419
5505
|
const fields = entry?.[of] ?? entry?.sourceIdentity;
|
|
5420
5506
|
if (!fields) return void 0;
|
|
@@ -5423,7 +5509,7 @@ var Config = class Config {
|
|
|
5423
5509
|
return fields.map((field) => {
|
|
5424
5510
|
const value = body[field];
|
|
5425
5511
|
return value === void 0 ? "" : String(value);
|
|
5426
|
-
})
|
|
5512
|
+
});
|
|
5427
5513
|
}
|
|
5428
5514
|
/**
|
|
5429
5515
|
* Where what this config shows at `path` originates: the system it was first authored in, followed
|