@smallpen/local-package 0.1.0-alpha.5 → 0.1.0-alpha.9
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 +2 -2
- package/src/index.mjs +12 -2
- package/src/initialize.mjs +362 -125
- package/src/local-package.mjs +69 -13
- package/src/local-workspace-session.mjs +55 -1
- package/src/migrate-themes.mjs +116 -0
- package/src/render.mjs +1029 -436
- package/src/workspace.mjs +93 -2
package/src/workspace.mjs
CHANGED
|
@@ -2,7 +2,9 @@ import { realpath } from "node:fs/promises";
|
|
|
2
2
|
import { dirname, isAbsolute, posix, resolve, win32 } from "node:path";
|
|
3
3
|
|
|
4
4
|
import {
|
|
5
|
+
closestComponentVariant,
|
|
5
6
|
combineContextAxes,
|
|
7
|
+
findComponentVariant,
|
|
6
8
|
listEffectiveTokens,
|
|
7
9
|
projectScenario,
|
|
8
10
|
projectScreen,
|
|
@@ -294,13 +296,17 @@ const DEPENDENCY_PROJECTION_CODES = new Set([
|
|
|
294
296
|
]);
|
|
295
297
|
|
|
296
298
|
function validateWorkspaceProjections(product, foundation, libraries = []) {
|
|
299
|
+
// The Presentation being projected, so a failing Instance is found in it
|
|
300
|
+
// and not in another Screen that reuses its node id.
|
|
301
|
+
let projecting;
|
|
297
302
|
try {
|
|
298
303
|
for (const context of contextSelections(product, foundation)) {
|
|
299
304
|
listEffectiveTokens(product, { context, foundation, libraries });
|
|
300
305
|
}
|
|
301
306
|
for (const entry of product.manifest.entries.screens) {
|
|
302
307
|
const screen = product.entries[entry];
|
|
303
|
-
for (const presentation of screen.presentations) {
|
|
308
|
+
for (const [index, presentation] of screen.presentations.entries()) {
|
|
309
|
+
projecting = `${entry}.presentations[${index}]`;
|
|
304
310
|
projectScreen(product, screen.id, {
|
|
305
311
|
foundation,
|
|
306
312
|
libraries,
|
|
@@ -308,6 +314,7 @@ function validateWorkspaceProjections(product, foundation, libraries = []) {
|
|
|
308
314
|
});
|
|
309
315
|
}
|
|
310
316
|
}
|
|
317
|
+
projecting = undefined;
|
|
311
318
|
for (const scenario of product.domain.scenarios.values()) {
|
|
312
319
|
projectScenario(product, scenario.id, { foundation, libraries });
|
|
313
320
|
}
|
|
@@ -324,7 +331,9 @@ function validateWorkspaceProjections(product, foundation, libraries = []) {
|
|
|
324
331
|
if (!path && error.details.instanceId) {
|
|
325
332
|
const suffix = `.nodes.${error.details.instanceId}.instance.component`;
|
|
326
333
|
const usage = externalReferences(product).find((candidate) =>
|
|
327
|
-
|
|
334
|
+
projecting
|
|
335
|
+
? candidate.path === `${projecting}${suffix}`
|
|
336
|
+
: candidate.path.endsWith(suffix),
|
|
328
337
|
);
|
|
329
338
|
path = usage?.path;
|
|
330
339
|
reference = usage?.reference;
|
|
@@ -353,6 +362,83 @@ function validateWorkspaceProjections(product, foundation, libraries = []) {
|
|
|
353
362
|
}
|
|
354
363
|
}
|
|
355
364
|
|
|
365
|
+
// Instances of the Product whose selection no variant of their Component
|
|
366
|
+
// Set has any more (the Foundation renamed a value or deleted the variant).
|
|
367
|
+
// They still draw, with the closest variant (`degraded` conflicts let reads
|
|
368
|
+
// go on); the Product waits in Repair for one of the typed choices: select
|
|
369
|
+
// a variant, or remove the Instance (or retarget it, as any reference).
|
|
370
|
+
function staleInstanceConflicts(product, foundation, libraries = []) {
|
|
371
|
+
const sets = new Map([[product.manifest.packageId, product.domain.componentSets]]);
|
|
372
|
+
for (const owner of [foundation, ...libraries]) {
|
|
373
|
+
if (owner) sets.set(owner.manifest.packageId, owner.domain.componentSets);
|
|
374
|
+
}
|
|
375
|
+
const conflicts = [];
|
|
376
|
+
const check = (instance, path, nodePath, target) => {
|
|
377
|
+
const reference = instance?.component;
|
|
378
|
+
const componentSet = sets.get(reference?.packageId)?.get(reference?.assetId);
|
|
379
|
+
if (!componentSet || findComponentVariant(componentSet, instance.variant ?? {}).variant) {
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
382
|
+
const closest = closestComponentVariant(componentSet, instance.variant);
|
|
383
|
+
const select = closest
|
|
384
|
+
? [
|
|
385
|
+
{
|
|
386
|
+
action: "select-instance-variant",
|
|
387
|
+
referencePath: `${nodePath}.instance`,
|
|
388
|
+
selection: structuredClone(closest.selection),
|
|
389
|
+
validSelections: componentSet.variants.map((variant) =>
|
|
390
|
+
structuredClone(variant.selection),
|
|
391
|
+
),
|
|
392
|
+
...target,
|
|
393
|
+
},
|
|
394
|
+
]
|
|
395
|
+
: [];
|
|
396
|
+
conflicts.push({
|
|
397
|
+
...conflict(
|
|
398
|
+
"missing_variant",
|
|
399
|
+
`Instance ${target.nodeId} selects ${JSON.stringify(instance.variant ?? {})}, ` +
|
|
400
|
+
`which no variant of ${reference.assetId} has. It draws as ` +
|
|
401
|
+
`${JSON.stringify(closest?.selection ?? {})} until it is repaired`,
|
|
402
|
+
`${path}`,
|
|
403
|
+
[...select, ...referenceRepairChoices(path, reference)],
|
|
404
|
+
),
|
|
405
|
+
degraded: true,
|
|
406
|
+
reference: structuredClone(reference),
|
|
407
|
+
});
|
|
408
|
+
};
|
|
409
|
+
for (const entry of product.manifest.entries.screens) {
|
|
410
|
+
const screen = product.entries[entry];
|
|
411
|
+
screen.presentations.forEach((presentation, index) => {
|
|
412
|
+
for (const [nodeId, node] of Object.entries(presentation.nodes)) {
|
|
413
|
+
if (!node.instance) continue;
|
|
414
|
+
const nodePath = `${entry}.presentations[${index}].nodes.${nodeId}`;
|
|
415
|
+
check(node.instance, `${nodePath}.instance.component`, nodePath, {
|
|
416
|
+
nodeId,
|
|
417
|
+
presentationId: presentation.id,
|
|
418
|
+
screenId: screen.id,
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
for (const entry of product.manifest.entries.components) {
|
|
424
|
+
(product.entries[entry].componentSets ?? []).forEach((componentSet, setIndex) => {
|
|
425
|
+
componentSet.variants.forEach((variant, variantIndex) => {
|
|
426
|
+
for (const [nodeId, node] of Object.entries(variant.nodes)) {
|
|
427
|
+
if (!node.instance) continue;
|
|
428
|
+
const nodePath =
|
|
429
|
+
`${entry}.componentSets[${setIndex}].variants[${variantIndex}].nodes.${nodeId}`;
|
|
430
|
+
check(node.instance, `${nodePath}.instance.component`, nodePath, {
|
|
431
|
+
componentSetId: componentSet.id,
|
|
432
|
+
nodeId,
|
|
433
|
+
variantId: variant.id,
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
return conflicts;
|
|
440
|
+
}
|
|
441
|
+
|
|
356
442
|
function chooseLibrarySource(library) {
|
|
357
443
|
return {
|
|
358
444
|
action: "choose-library-source",
|
|
@@ -633,6 +719,11 @@ export async function resolveWorkspace(productLocator, options = {}) {
|
|
|
633
719
|
...validateWorkspaceProjections(product, foundation, resolved.libraries),
|
|
634
720
|
);
|
|
635
721
|
}
|
|
722
|
+
if (conflicts.length === 0) {
|
|
723
|
+
conflicts.push(
|
|
724
|
+
...staleInstanceConflicts(product, foundation, resolved.libraries),
|
|
725
|
+
);
|
|
726
|
+
}
|
|
636
727
|
if (conflicts.length > 0) {
|
|
637
728
|
return repair(product, conflicts, foundation, resolved.libraries, warnings);
|
|
638
729
|
}
|