@kubuild/core 0.7.0 → 0.8.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/document/command-tree-utils.d.ts +22 -1
- package/dist/document/command-tree-utils.d.ts.map +1 -1
- package/dist/document/commands.d.ts +19 -2
- package/dist/document/commands.d.ts.map +1 -1
- package/dist/index.cjs +203 -42
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +205 -44
- package/dist/index.js.map +1 -1
- package/dist/io/load-project.d.ts.map +1 -1
- package/dist/io/migration.d.ts +8 -1
- package/dist/io/migration.d.ts.map +1 -1
- package/dist/io/template-utils.d.ts +8 -3
- package/dist/io/template-utils.d.ts.map +1 -1
- package/dist/types/interfaces.d.ts +43 -2
- package/dist/types/interfaces.d.ts.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -316,26 +316,84 @@ function defaultIdGenerator(oldId, existingIds) {
|
|
|
316
316
|
}
|
|
317
317
|
return candidate;
|
|
318
318
|
}
|
|
319
|
-
|
|
319
|
+
var NODE_ID_REFERENCE_KEYS = /* @__PURE__ */ new Set([
|
|
320
|
+
"modalId",
|
|
321
|
+
"modalNodeId",
|
|
322
|
+
"targetModalId",
|
|
323
|
+
"targetNodeId",
|
|
324
|
+
"nodeId",
|
|
325
|
+
"formId",
|
|
326
|
+
"targetId"
|
|
327
|
+
]);
|
|
328
|
+
var ANCHOR_REFERENCE_KEYS = /* @__PURE__ */ new Set(["url", "href"]);
|
|
329
|
+
function remapReferenceValue(key, value, idMap) {
|
|
330
|
+
if (typeof value !== "string") return value;
|
|
331
|
+
if (NODE_ID_REFERENCE_KEYS.has(key)) {
|
|
332
|
+
return idMap.get(value) ?? idMap.get(value.trim()) ?? value;
|
|
333
|
+
}
|
|
334
|
+
if (ANCHOR_REFERENCE_KEYS.has(key) && value.startsWith("#")) {
|
|
335
|
+
const mapped = idMap.get(value.slice(1));
|
|
336
|
+
return mapped ? `#${mapped}` : value;
|
|
337
|
+
}
|
|
338
|
+
return value;
|
|
339
|
+
}
|
|
340
|
+
function remapReferenceRecord(record, idMap) {
|
|
341
|
+
for (const [key, value] of Object.entries(record)) {
|
|
342
|
+
record[key] = remapReferenceValue(key, value, idMap);
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
function remapStepReferences(steps, idMap) {
|
|
346
|
+
if (!Array.isArray(steps)) return;
|
|
347
|
+
for (const step of steps) {
|
|
348
|
+
if (step.payload && typeof step.payload === "object") {
|
|
349
|
+
remapReferenceRecord(step.payload, idMap);
|
|
350
|
+
}
|
|
351
|
+
remapStepReferences(step.onSuccess, idMap);
|
|
352
|
+
remapStepReferences(step.onError, idMap);
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function remapNodeReferences(node, idMap) {
|
|
356
|
+
if (node.props && typeof node.props === "object") {
|
|
357
|
+
remapReferenceRecord(node.props, idMap);
|
|
358
|
+
const legacyAction = node.props.action;
|
|
359
|
+
if (legacyAction && typeof legacyAction === "object" && legacyAction.payload && typeof legacyAction.payload === "object" && !Array.isArray(legacyAction.payload)) {
|
|
360
|
+
remapReferenceRecord(legacyAction.payload, idMap);
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
if (node.formConfig && typeof node.formConfig.formId === "string") {
|
|
364
|
+
node.formConfig.formId = idMap.get(node.formConfig.formId) ?? node.formConfig.formId;
|
|
365
|
+
}
|
|
366
|
+
if (Array.isArray(node.actions)) {
|
|
367
|
+
for (const pipeline of node.actions) {
|
|
368
|
+
remapStepReferences(pipeline.steps, idMap);
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
function cloneNodeTreeWithFreshIds(root, idGen) {
|
|
320
373
|
const idMap = /* @__PURE__ */ new Map();
|
|
321
|
-
const
|
|
374
|
+
const clonedNodes = [];
|
|
322
375
|
function cloneRecursive(node) {
|
|
323
|
-
const newId = idGen(node.id);
|
|
376
|
+
const newId = idGen(node.id, node);
|
|
324
377
|
idMap.set(node.id, newId);
|
|
325
|
-
const
|
|
326
|
-
const
|
|
327
|
-
|
|
328
|
-
return {
|
|
378
|
+
const { children, ...rest } = node;
|
|
379
|
+
const cloned = {
|
|
380
|
+
...deepClone(rest),
|
|
329
381
|
id: newId,
|
|
330
|
-
|
|
331
|
-
...clonedProps ? { props: clonedProps } : {},
|
|
332
|
-
...clonedStyles ? { styles: clonedStyles } : {},
|
|
333
|
-
children: clonedChildren
|
|
382
|
+
children: children ? children.map((child) => cloneRecursive(child)) : []
|
|
334
383
|
};
|
|
384
|
+
clonedNodes.push(cloned);
|
|
385
|
+
return cloned;
|
|
335
386
|
}
|
|
336
387
|
const clonedNode = cloneRecursive(root);
|
|
388
|
+
for (const cloned of clonedNodes) {
|
|
389
|
+
remapNodeReferences(cloned, idMap);
|
|
390
|
+
}
|
|
337
391
|
return { clonedNode, idMap };
|
|
338
392
|
}
|
|
393
|
+
function cloneTreeWithNewIds(root, idGenerator, existingIds) {
|
|
394
|
+
const idGen = idGenerator || ((oldId) => defaultIdGenerator(oldId, existingIds));
|
|
395
|
+
return cloneNodeTreeWithFreshIds(root, (oldId) => idGen(oldId));
|
|
396
|
+
}
|
|
339
397
|
|
|
340
398
|
// src/document/commands.ts
|
|
341
399
|
import {
|
|
@@ -343,7 +401,9 @@ import {
|
|
|
343
401
|
ResponsiveStylesSchema,
|
|
344
402
|
AnimationConfigSchema,
|
|
345
403
|
ActionPipelineSchema,
|
|
346
|
-
FormConfigSchema
|
|
404
|
+
FormConfigSchema,
|
|
405
|
+
ThemeSchema,
|
|
406
|
+
THEME_TOKEN_GROUPS
|
|
347
407
|
} from "@kubuild/schema";
|
|
348
408
|
function insertNode(document, params) {
|
|
349
409
|
const { parentId, node, index } = params;
|
|
@@ -883,6 +943,53 @@ function replaceNode(document, params) {
|
|
|
883
943
|
}
|
|
884
944
|
};
|
|
885
945
|
}
|
|
946
|
+
function updateTheme(document, params) {
|
|
947
|
+
const { theme, merge = true } = params;
|
|
948
|
+
const newDoc = deepClone(document);
|
|
949
|
+
const previousTheme = newDoc.theme ? deepClone(newDoc.theme) : void 0;
|
|
950
|
+
if (theme === null) {
|
|
951
|
+
delete newDoc.theme;
|
|
952
|
+
} else {
|
|
953
|
+
const next = {};
|
|
954
|
+
for (const group of THEME_TOKEN_GROUPS) {
|
|
955
|
+
const base = merge ? { ...previousTheme?.[group] ?? {} } : {};
|
|
956
|
+
const patch = theme[group];
|
|
957
|
+
if (patch === null) {
|
|
958
|
+
continue;
|
|
959
|
+
}
|
|
960
|
+
if (patch) {
|
|
961
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
962
|
+
if (value === null) {
|
|
963
|
+
delete base[key];
|
|
964
|
+
} else {
|
|
965
|
+
base[key] = value;
|
|
966
|
+
}
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
if (Object.keys(base).length > 0) {
|
|
970
|
+
next[group] = base;
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
const parsed = ThemeSchema.parse(next);
|
|
974
|
+
if (Object.keys(parsed).length > 0) {
|
|
975
|
+
newDoc.theme = parsed;
|
|
976
|
+
} else {
|
|
977
|
+
delete newDoc.theme;
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
return {
|
|
981
|
+
document: newDoc,
|
|
982
|
+
event: {
|
|
983
|
+
type: "THEME_UPDATED",
|
|
984
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
985
|
+
nodeId: newDoc.document.id,
|
|
986
|
+
payload: {
|
|
987
|
+
theme: newDoc.theme,
|
|
988
|
+
previousTheme
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
};
|
|
992
|
+
}
|
|
886
993
|
|
|
887
994
|
// src/document/artboards.ts
|
|
888
995
|
import {
|
|
@@ -4094,7 +4201,8 @@ import {
|
|
|
4094
4201
|
// src/io/migration.ts
|
|
4095
4202
|
import {
|
|
4096
4203
|
CURRENT_SCHEMA_VERSION as CURRENT_SCHEMA_VERSION4,
|
|
4097
|
-
SCHEMA_NAME as SCHEMA_NAME5
|
|
4204
|
+
SCHEMA_NAME as SCHEMA_NAME5,
|
|
4205
|
+
getCanonicalTextPropRule
|
|
4098
4206
|
} from "@kubuild/schema";
|
|
4099
4207
|
var MigrationRegistry = class {
|
|
4100
4208
|
steps = /* @__PURE__ */ new Map();
|
|
@@ -4267,6 +4375,56 @@ defaultMigrationRegistry.register({
|
|
|
4267
4375
|
return migrated;
|
|
4268
4376
|
}
|
|
4269
4377
|
});
|
|
4378
|
+
function canonicalizeTextPropsInPlace(root, basePath = "document") {
|
|
4379
|
+
const changed = [];
|
|
4380
|
+
const walk2 = (value, path) => {
|
|
4381
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return;
|
|
4382
|
+
const node = value;
|
|
4383
|
+
const props = node.props;
|
|
4384
|
+
const rule = typeof node.type === "string" ? getCanonicalTextPropRule(node.type) : void 0;
|
|
4385
|
+
if (rule && props && typeof props === "object" && !Array.isArray(props)) {
|
|
4386
|
+
const record = props;
|
|
4387
|
+
const presentAliases = rule.aliases.filter((alias) => record[alias] !== void 0);
|
|
4388
|
+
if (presentAliases.length > 0) {
|
|
4389
|
+
const displayedKey = rule.legacyReadOrder.find((key) => record[key] !== void 0);
|
|
4390
|
+
if (node.type === "text" && displayedKey === "content" && record.as === void 0 && record.tag === void 0) {
|
|
4391
|
+
record.as = "p";
|
|
4392
|
+
}
|
|
4393
|
+
if (displayedKey !== void 0 && displayedKey !== rule.canonical) {
|
|
4394
|
+
record[rule.canonical] = record[displayedKey];
|
|
4395
|
+
}
|
|
4396
|
+
for (const alias of presentAliases) {
|
|
4397
|
+
delete record[alias];
|
|
4398
|
+
changed.push(`${path}.props.${alias}`);
|
|
4399
|
+
}
|
|
4400
|
+
}
|
|
4401
|
+
}
|
|
4402
|
+
if (Array.isArray(node.children)) {
|
|
4403
|
+
node.children.forEach((child, index) => walk2(child, `${path}.children.${index}`));
|
|
4404
|
+
}
|
|
4405
|
+
};
|
|
4406
|
+
walk2(root, basePath);
|
|
4407
|
+
return changed;
|
|
4408
|
+
}
|
|
4409
|
+
defaultMigrationRegistry.register({
|
|
4410
|
+
fromVersion: "1.1.0",
|
|
4411
|
+
toVersion: "1.2.0",
|
|
4412
|
+
description: "Rename deprecated text prop aliases to canonical names (heading/text/paragraph/link/badge/blockquote -> text, button -> label)",
|
|
4413
|
+
migrate: (rawDoc, context) => {
|
|
4414
|
+
const migrated = deepClone(rawDoc);
|
|
4415
|
+
migrated.version = "1.2.0";
|
|
4416
|
+
const changed = canonicalizeTextPropsInPlace(migrated.document);
|
|
4417
|
+
if (changed.length > 0) {
|
|
4418
|
+
context.warn({
|
|
4419
|
+
code: "PROP_ALIAS_MIGRATED",
|
|
4420
|
+
message: "Deprecated text prop aliases were renamed to their canonical names.",
|
|
4421
|
+
step: "1.1.0->1.2.0",
|
|
4422
|
+
paths: changed
|
|
4423
|
+
});
|
|
4424
|
+
}
|
|
4425
|
+
return migrated;
|
|
4426
|
+
}
|
|
4427
|
+
});
|
|
4270
4428
|
function canMigrate(sourceVersion, targetVersion = CURRENT_SCHEMA_VERSION4, registry = defaultMigrationRegistry) {
|
|
4271
4429
|
if (!sourceVersion || !targetVersion) return false;
|
|
4272
4430
|
if (sourceVersion === targetVersion) return true;
|
|
@@ -4371,6 +4529,16 @@ function migrateDocument(rawDocument, options = {}) {
|
|
|
4371
4529
|
};
|
|
4372
4530
|
}
|
|
4373
4531
|
if (dryRun) {
|
|
4532
|
+
const simulatedWarnings = [];
|
|
4533
|
+
try {
|
|
4534
|
+
let simulated = deepClone(doc);
|
|
4535
|
+
for (let i = 0; i < path.length - 1; i++) {
|
|
4536
|
+
const step = registry.getStep(path[i], path[i + 1]);
|
|
4537
|
+
if (!step) break;
|
|
4538
|
+
simulated = step.migrate(simulated, { warn: (w) => simulatedWarnings.push(w) });
|
|
4539
|
+
}
|
|
4540
|
+
} catch {
|
|
4541
|
+
}
|
|
4374
4542
|
return {
|
|
4375
4543
|
success: true,
|
|
4376
4544
|
diagnostic: {
|
|
@@ -4379,7 +4547,8 @@ function migrateDocument(rawDocument, options = {}) {
|
|
|
4379
4547
|
targetVersion,
|
|
4380
4548
|
migrationPath: path,
|
|
4381
4549
|
stepsApplied: path.length - 1,
|
|
4382
|
-
dryRun: true
|
|
4550
|
+
dryRun: true,
|
|
4551
|
+
...simulatedWarnings.length > 0 ? { warnings: simulatedWarnings } : {}
|
|
4383
4552
|
}
|
|
4384
4553
|
};
|
|
4385
4554
|
}
|
|
@@ -5198,8 +5367,21 @@ import {
|
|
|
5198
5367
|
ProjectDocumentSchema,
|
|
5199
5368
|
PROJECT_SCHEMA_NAME as PROJECT_SCHEMA_NAME2,
|
|
5200
5369
|
CURRENT_PROJECT_SCHEMA_VERSION as CURRENT_PROJECT_SCHEMA_VERSION2,
|
|
5370
|
+
CURRENT_SCHEMA_VERSION as CURRENT_SCHEMA_VERSION6,
|
|
5201
5371
|
looksLikeProjectDocument
|
|
5202
5372
|
} from "@kubuild/schema";
|
|
5373
|
+
function migrateProjectArtboards(project) {
|
|
5374
|
+
let changed = false;
|
|
5375
|
+
const artboards = project.artboards.map((artboard) => {
|
|
5376
|
+
const version = artboard.document.version;
|
|
5377
|
+
if (version === CURRENT_SCHEMA_VERSION6 || !canMigrate(version)) return artboard;
|
|
5378
|
+
const migration = migrateDocument(artboard.document);
|
|
5379
|
+
if (!migration.success || !migration.document) return artboard;
|
|
5380
|
+
changed = true;
|
|
5381
|
+
return { ...artboard, document: migration.document };
|
|
5382
|
+
});
|
|
5383
|
+
return changed ? { ...project, artboards } : project;
|
|
5384
|
+
}
|
|
5203
5385
|
var DEFAULT_PAGE_ARTBOARD_ID = "artboard-page-1";
|
|
5204
5386
|
function wrapPageDocumentAsProject(document, options = {}) {
|
|
5205
5387
|
const artboardId = options.artboardId ?? DEFAULT_PAGE_ARTBOARD_ID;
|
|
@@ -5249,7 +5431,7 @@ function loadProjectDocument(raw) {
|
|
|
5249
5431
|
}
|
|
5250
5432
|
return {
|
|
5251
5433
|
success: true,
|
|
5252
|
-
project: parsed.data,
|
|
5434
|
+
project: migrateProjectArtboards(parsed.data),
|
|
5253
5435
|
wrappedFromLegacyPage: false,
|
|
5254
5436
|
errors: []
|
|
5255
5437
|
};
|
|
@@ -5720,21 +5902,11 @@ function compareManifestsSemantically(expected, actual, options = {}) {
|
|
|
5720
5902
|
// src/io/template-utils.ts
|
|
5721
5903
|
import {
|
|
5722
5904
|
TemplateRecordSchema,
|
|
5905
|
+
BUILTIN_COMPONENT_TYPES,
|
|
5723
5906
|
collectNodeIds as collectNodeIds2,
|
|
5724
5907
|
isTemplateRecord
|
|
5725
5908
|
} from "@kubuild/schema";
|
|
5726
|
-
var CORE_BUILTIN_COMPONENTS =
|
|
5727
|
-
"page",
|
|
5728
|
-
"section",
|
|
5729
|
-
"container",
|
|
5730
|
-
"columns",
|
|
5731
|
-
"column",
|
|
5732
|
-
"heading",
|
|
5733
|
-
"text",
|
|
5734
|
-
"image",
|
|
5735
|
-
"button",
|
|
5736
|
-
"collection"
|
|
5737
|
-
]);
|
|
5909
|
+
var CORE_BUILTIN_COMPONENTS = new Set(BUILTIN_COMPONENT_TYPES);
|
|
5738
5910
|
function validateTemplate(value) {
|
|
5739
5911
|
const parseResult = TemplateRecordSchema.safeParse(value);
|
|
5740
5912
|
if (parseResult.success) {
|
|
@@ -5845,22 +6017,6 @@ function saveDraftAsTemplate(draft, metadata, options = {}) {
|
|
|
5845
6017
|
custom: metadata.custom ? deepClone(metadata.custom) : void 0
|
|
5846
6018
|
});
|
|
5847
6019
|
}
|
|
5848
|
-
function cloneTreeWithFreshIds(root, idGen) {
|
|
5849
|
-
function cloneRec(node) {
|
|
5850
|
-
const newId = idGen(node.id, node);
|
|
5851
|
-
const clonedProps = node.props ? deepClone(node.props) : void 0;
|
|
5852
|
-
const clonedStyles = node.styles ? deepClone(node.styles) : void 0;
|
|
5853
|
-
const clonedChildren = node.children ? node.children.map((child) => cloneRec(child)) : [];
|
|
5854
|
-
return {
|
|
5855
|
-
id: newId,
|
|
5856
|
-
type: node.type,
|
|
5857
|
-
...clonedProps ? { props: clonedProps } : {},
|
|
5858
|
-
...clonedStyles ? { styles: clonedStyles } : {},
|
|
5859
|
-
children: clonedChildren
|
|
5860
|
-
};
|
|
5861
|
-
}
|
|
5862
|
-
return cloneRec(root);
|
|
5863
|
-
}
|
|
5864
6020
|
function cloneTemplateAsPage(templateOrDoc, options = {}) {
|
|
5865
6021
|
let sourceDoc;
|
|
5866
6022
|
let templateOrigin = null;
|
|
@@ -5896,7 +6052,7 @@ function cloneTemplateAsPage(templateOrDoc, options = {}) {
|
|
|
5896
6052
|
return candidate;
|
|
5897
6053
|
};
|
|
5898
6054
|
const idGen = options.idGenerator || defaultIdGen;
|
|
5899
|
-
const clonedRootNode =
|
|
6055
|
+
const { clonedNode: clonedRootNode } = cloneNodeTreeWithFreshIds(sourceDoc.document, idGen);
|
|
5900
6056
|
const rootPageNode = {
|
|
5901
6057
|
...clonedRootNode,
|
|
5902
6058
|
type: "page"
|
|
@@ -6307,6 +6463,7 @@ export {
|
|
|
6307
6463
|
DocumentHistoryManager,
|
|
6308
6464
|
HistoryEngine,
|
|
6309
6465
|
MigrationRegistry,
|
|
6466
|
+
NODE_ID_REFERENCE_KEYS,
|
|
6310
6467
|
RuntimeStateStore,
|
|
6311
6468
|
addArtboard,
|
|
6312
6469
|
applyFieldTransform,
|
|
@@ -6314,7 +6471,9 @@ export {
|
|
|
6314
6471
|
buildSampleVariablesFromCatalog,
|
|
6315
6472
|
calculateChecksum,
|
|
6316
6473
|
canMigrate,
|
|
6474
|
+
canonicalizeTextPropsInPlace,
|
|
6317
6475
|
checkZipBomb,
|
|
6476
|
+
cloneNodeTreeWithFreshIds,
|
|
6318
6477
|
cloneTemplateAsPage,
|
|
6319
6478
|
cloneTreeWithNewIds,
|
|
6320
6479
|
collectArtboardReferenceNodes,
|
|
@@ -6391,6 +6550,7 @@ export {
|
|
|
6391
6550
|
previewImportPackage,
|
|
6392
6551
|
remapAssetReferences,
|
|
6393
6552
|
remapDocumentAssetReferences,
|
|
6553
|
+
remapNodeReferences,
|
|
6394
6554
|
removeArtboard,
|
|
6395
6555
|
removeNode,
|
|
6396
6556
|
renameArtboard,
|
|
@@ -6418,6 +6578,7 @@ export {
|
|
|
6418
6578
|
updateFormConfig,
|
|
6419
6579
|
updateProps,
|
|
6420
6580
|
updateStyle,
|
|
6581
|
+
updateTheme,
|
|
6421
6582
|
validateDocument,
|
|
6422
6583
|
validateDocumentSecurity,
|
|
6423
6584
|
validateFieldValue,
|