@wp-typia/project-tools 0.16.10 → 0.16.12

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.
Files changed (104) hide show
  1. package/README.md +9 -3
  2. package/dist/runtime/built-in-block-artifact-documents.d.ts +3 -0
  3. package/dist/runtime/built-in-block-artifact-documents.js +2 -0
  4. package/dist/runtime/built-in-block-artifact-types.d.ts +51 -0
  5. package/dist/runtime/built-in-block-artifact-types.js +304 -0
  6. package/dist/runtime/built-in-block-artifacts.js +4 -803
  7. package/dist/runtime/built-in-block-attribute-emitters.d.ts +71 -0
  8. package/dist/runtime/built-in-block-attribute-emitters.js +176 -0
  9. package/dist/runtime/built-in-block-attribute-specs.d.ts +38 -0
  10. package/dist/runtime/built-in-block-attribute-specs.js +358 -0
  11. package/dist/runtime/built-in-block-code-templates/basic.d.ts +4 -0
  12. package/dist/runtime/built-in-block-code-templates/basic.js +249 -0
  13. package/dist/runtime/built-in-block-code-templates/compound-child.d.ts +4 -0
  14. package/dist/runtime/built-in-block-code-templates/compound-child.js +138 -0
  15. package/dist/runtime/built-in-block-code-templates/compound-parent.d.ts +6 -0
  16. package/dist/runtime/built-in-block-code-templates/compound-parent.js +227 -0
  17. package/dist/runtime/built-in-block-code-templates/compound-persistence.d.ts +4 -0
  18. package/dist/runtime/built-in-block-code-templates/compound-persistence.js +478 -0
  19. package/dist/runtime/built-in-block-code-templates/compound.d.ts +3 -0
  20. package/dist/runtime/built-in-block-code-templates/compound.js +3 -0
  21. package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +5 -0
  22. package/dist/runtime/built-in-block-code-templates/interactivity.js +547 -0
  23. package/dist/runtime/built-in-block-code-templates/persistence.d.ts +5 -0
  24. package/dist/runtime/built-in-block-code-templates/persistence.js +550 -0
  25. package/dist/runtime/built-in-block-code-templates/shared.d.ts +16 -0
  26. package/dist/runtime/built-in-block-code-templates/shared.js +53 -0
  27. package/dist/runtime/built-in-block-code-templates.d.ts +5 -32
  28. package/dist/runtime/built-in-block-code-templates.js +5 -2230
  29. package/dist/runtime/cli-add-block-config.d.ts +6 -0
  30. package/dist/runtime/cli-add-block-config.js +143 -0
  31. package/dist/runtime/cli-add-block-legacy-validator.d.ts +4 -0
  32. package/dist/runtime/cli-add-block-legacy-validator.js +168 -0
  33. package/dist/runtime/cli-add-block.js +3 -301
  34. package/dist/runtime/cli-add-workspace-assets.d.ts +38 -0
  35. package/dist/runtime/cli-add-workspace-assets.js +399 -0
  36. package/dist/runtime/cli-add-workspace.d.ts +2 -38
  37. package/dist/runtime/cli-add-workspace.js +5 -396
  38. package/dist/runtime/cli-doctor-environment.d.ts +12 -0
  39. package/dist/runtime/cli-doctor-environment.js +123 -0
  40. package/dist/runtime/cli-doctor-workspace.d.ts +14 -0
  41. package/dist/runtime/cli-doctor-workspace.js +296 -0
  42. package/dist/runtime/cli-doctor.d.ts +4 -2
  43. package/dist/runtime/cli-doctor.js +10 -405
  44. package/dist/runtime/cli-help.js +1 -1
  45. package/dist/runtime/cli-scaffold.js +1 -1
  46. package/dist/runtime/migration-command-surface.d.ts +67 -0
  47. package/dist/runtime/migration-command-surface.js +189 -0
  48. package/dist/runtime/migration-diff-rename.d.ts +13 -0
  49. package/dist/runtime/migration-diff-rename.js +192 -0
  50. package/dist/runtime/migration-diff-transform.d.ts +14 -0
  51. package/dist/runtime/migration-diff-transform.js +105 -0
  52. package/dist/runtime/migration-diff.js +12 -297
  53. package/dist/runtime/migration-generated-artifacts.d.ts +3 -0
  54. package/dist/runtime/migration-generated-artifacts.js +41 -0
  55. package/dist/runtime/migration-maintenance.d.ts +51 -0
  56. package/dist/runtime/migration-maintenance.js +380 -0
  57. package/dist/runtime/migration-planning.d.ts +23 -0
  58. package/dist/runtime/migration-planning.js +131 -0
  59. package/dist/runtime/migration-project-config-source.d.ts +6 -0
  60. package/dist/runtime/migration-project-config-source.js +424 -0
  61. package/dist/runtime/migration-project-layout-discovery.d.ts +61 -0
  62. package/dist/runtime/migration-project-layout-discovery.js +337 -0
  63. package/dist/runtime/migration-project-layout-paths.d.ts +135 -0
  64. package/dist/runtime/migration-project-layout-paths.js +288 -0
  65. package/dist/runtime/migration-project-layout.d.ts +3 -0
  66. package/dist/runtime/migration-project-layout.js +2 -0
  67. package/dist/runtime/migration-project-workspace.d.ts +47 -0
  68. package/dist/runtime/migration-project-workspace.js +212 -0
  69. package/dist/runtime/migration-project.d.ts +4 -94
  70. package/dist/runtime/migration-project.js +3 -1101
  71. package/dist/runtime/migration-render-diff-rule.d.ts +5 -0
  72. package/dist/runtime/migration-render-diff-rule.js +120 -0
  73. package/dist/runtime/migration-render-execution.d.ts +3 -0
  74. package/dist/runtime/migration-render-execution.js +428 -0
  75. package/dist/runtime/migration-render-generated.d.ts +27 -0
  76. package/dist/runtime/migration-render-generated.js +230 -0
  77. package/dist/runtime/migration-render-support.d.ts +3 -0
  78. package/dist/runtime/migration-render-support.js +16 -0
  79. package/dist/runtime/migration-render.d.ts +3 -33
  80. package/dist/runtime/migration-render.js +3 -789
  81. package/dist/runtime/migration-ui-capability.js +1 -1
  82. package/dist/runtime/migrations.d.ts +24 -118
  83. package/dist/runtime/migrations.js +12 -700
  84. package/dist/runtime/scaffold-bootstrap.d.ts +45 -0
  85. package/dist/runtime/scaffold-bootstrap.js +185 -0
  86. package/dist/runtime/scaffold-package-manager-files.d.ts +35 -0
  87. package/dist/runtime/scaffold-package-manager-files.js +79 -0
  88. package/dist/runtime/scaffold.d.ts +1 -12
  89. package/dist/runtime/scaffold.js +10 -393
  90. package/dist/runtime/template-source-contracts.d.ts +81 -0
  91. package/dist/runtime/template-source-contracts.js +1 -0
  92. package/dist/runtime/template-source-external.d.ts +21 -0
  93. package/dist/runtime/template-source-external.js +184 -0
  94. package/dist/runtime/template-source-locators.d.ts +4 -0
  95. package/dist/runtime/template-source-locators.js +72 -0
  96. package/dist/runtime/template-source-normalization.d.ts +7 -0
  97. package/dist/runtime/template-source-normalization.js +53 -0
  98. package/dist/runtime/template-source-remote.d.ts +23 -0
  99. package/dist/runtime/template-source-remote.js +336 -0
  100. package/dist/runtime/template-source-seeds.d.ts +12 -0
  101. package/dist/runtime/template-source-seeds.js +243 -0
  102. package/dist/runtime/template-source.d.ts +4 -86
  103. package/dist/runtime/template-source.js +9 -828
  104. package/package.json +5 -5
@@ -1,5 +1,7 @@
1
1
  import fs from "node:fs";
2
- import { flattenManifestLeafAttributes, getAttributeByCurrentPath, getManifestDefaultValue, hasManifestDefault, } from "./migration-manifest.js";
2
+ import { flattenManifestLeafAttributes, getManifestDefaultValue, hasManifestDefault, } from "./migration-manifest.js";
3
+ import { createRenameCandidates } from "./migration-diff-rename.js";
4
+ import { createTransformSuggestions, describeConstraintChange, } from "./migration-diff-transform.js";
3
5
  import { createMissingBlockSnapshotMessage, getAvailableSnapshotVersionsForBlock, getSnapshotManifestPath, } from "./migration-project.js";
4
6
  import { isNumber, readJson } from "./migration-utils.js";
5
7
  export function createMigrationDiff(state, blockOrFromVersion, fromVersionOrToVersion, maybeToVersion) {
@@ -79,7 +81,15 @@ export function createMigrationDiff(state, blockOrFromVersion, fromVersionOrToVe
79
81
  });
80
82
  }
81
83
  }
82
- const renameCandidates = createRenameCandidates(oldAttributes, newAttributes, removedKeys, addedKeys, oldLeafAttributes, newLeafAttributes);
84
+ const renameCandidates = createRenameCandidates({
85
+ addedKeys,
86
+ isUnionRenameCompatible: (oldAttribute, newAttribute) => compareUnionAttribute(oldAttribute, newAttribute, "$rename").status === "auto",
87
+ newAttributes,
88
+ newLeafAttributes,
89
+ oldAttributes,
90
+ oldLeafAttributes,
91
+ removedKeys,
92
+ });
83
93
  const activeRenameCandidates = renameCandidates.filter((candidate) => candidate.autoApply);
84
94
  for (const candidate of activeRenameCandidates) {
85
95
  removeOutcomeByPath(autoItems, candidate.legacyPath, "drop");
@@ -234,301 +244,6 @@ function hasStricterConstraints(oldAttribute, newAttribute) {
234
244
  }
235
245
  return false;
236
246
  }
237
- function createRenameCandidates(oldAttributes, newAttributes, removedKeys, addedKeys, oldLeafAttributes, newLeafAttributes) {
238
- const assessments = [];
239
- for (const currentPath of addedKeys) {
240
- const nextAttribute = newAttributes[currentPath];
241
- if (!nextAttribute)
242
- continue;
243
- for (const legacyPath of removedKeys) {
244
- const previous = oldAttributes[legacyPath];
245
- if (!previous)
246
- continue;
247
- const candidate = assessRenameCandidate(previous, nextAttribute, legacyPath, currentPath);
248
- if (candidate) {
249
- assessments.push(candidate);
250
- }
251
- }
252
- }
253
- const oldLeafMap = new Map(oldLeafAttributes.map((descriptor) => [descriptor.currentPath, descriptor]));
254
- const newLeafMap = new Map(newLeafAttributes.map((descriptor) => [descriptor.currentPath, descriptor]));
255
- const removedLeafDescriptors = oldLeafAttributes.filter((descriptor) => !newLeafMap.has(descriptor.currentPath));
256
- const addedLeafDescriptors = newLeafAttributes.filter((descriptor) => !oldLeafMap.has(descriptor.currentPath));
257
- for (const nextDescriptor of addedLeafDescriptors) {
258
- if (!nextDescriptor.currentPath.includes(".")) {
259
- continue;
260
- }
261
- for (const previousDescriptor of removedLeafDescriptors) {
262
- if (!previousDescriptor.currentPath.includes(".")) {
263
- continue;
264
- }
265
- const candidate = assessRenameCandidate(previousDescriptor.attribute, nextDescriptor.attribute, previousDescriptor.currentPath, nextDescriptor.currentPath);
266
- if (candidate) {
267
- assessments.push(candidate);
268
- }
269
- }
270
- }
271
- return assessments
272
- .map((candidate) => {
273
- const currentMatches = assessments
274
- .filter((item) => item.currentPath === candidate.currentPath)
275
- .sort((left, right) => right.score - left.score);
276
- const legacyMatches = assessments
277
- .filter((item) => item.legacyPath === candidate.legacyPath)
278
- .sort((left, right) => right.score - left.score);
279
- const currentLeader = currentMatches[0];
280
- const legacyLeader = legacyMatches[0];
281
- const currentHasTie = currentMatches.length > 1 && Math.abs((currentMatches[1]?.score ?? 0) - currentLeader.score) < 0.05;
282
- const legacyHasTie = legacyMatches.length > 1 && Math.abs((legacyMatches[1]?.score ?? 0) - legacyLeader.score) < 0.05;
283
- return {
284
- ...candidate,
285
- autoApply: currentLeader.legacyPath === candidate.legacyPath &&
286
- legacyLeader.currentPath === candidate.currentPath &&
287
- !currentHasTie &&
288
- !legacyHasTie &&
289
- candidate.score >= 0.6,
290
- };
291
- })
292
- .filter((candidate, index, list) => {
293
- const firstMatch = list.findIndex((item) => item.currentPath === candidate.currentPath && item.legacyPath === candidate.legacyPath);
294
- return firstMatch === index;
295
- })
296
- .sort((left, right) => right.score - left.score);
297
- }
298
- function createTransformSuggestions({ oldAttributes, newAttributes, addedKeys, removedKeys, manualItems, renameCandidates, oldLeafAttributes, newLeafAttributes, }) {
299
- const suggestions = [];
300
- const activeRenameTargets = new Set(renameCandidates.filter((candidate) => candidate.autoApply).map((candidate) => candidate.currentPath));
301
- const oldLeafMap = new Map(oldLeafAttributes.map((descriptor) => [descriptor.currentPath, descriptor]));
302
- const newLeafMap = new Map(newLeafAttributes.map((descriptor) => [descriptor.currentPath, descriptor]));
303
- for (const currentPath of [
304
- ...new Set([
305
- ...Object.keys(newAttributes),
306
- ...manualItems.map((item) => item.path),
307
- ...newLeafAttributes.map((item) => item.currentPath),
308
- ]),
309
- ]) {
310
- if (activeRenameTargets.has(currentPath)) {
311
- continue;
312
- }
313
- const manualItem = manualItems.find((item) => item.path === currentPath || item.path.startsWith(`${currentPath}.`));
314
- const currentAttribute = newLeafMap.get(currentPath)?.attribute ??
315
- getAttributeByCurrentPath(newAttributes, currentPath) ??
316
- null;
317
- if (!manualItem || !currentAttribute) {
318
- continue;
319
- }
320
- const exactLegacy = oldLeafMap.get(currentPath)?.attribute ??
321
- getAttributeByCurrentPath(oldAttributes, currentPath) ??
322
- null;
323
- if (exactLegacy && exactLegacy.ts.kind !== currentAttribute.ts.kind) {
324
- suggestions.push({
325
- bodyLines: buildTransformBodyLines(currentAttribute, currentPath),
326
- attribute: currentAttribute,
327
- currentPath,
328
- legacyPath: currentPath,
329
- reason: `semantic coercion suggested for ${manualItem.kind}`,
330
- });
331
- continue;
332
- }
333
- const bestRenameCandidate = renameCandidates.find((candidate) => candidate.currentPath === currentPath);
334
- if (bestRenameCandidate && !bestRenameCandidate.autoApply) {
335
- suggestions.push({
336
- bodyLines: buildTransformBodyLines(currentAttribute, bestRenameCandidate.legacyPath),
337
- attribute: currentAttribute,
338
- currentPath,
339
- legacyPath: bestRenameCandidate.legacyPath,
340
- reason: `review coercion from ${bestRenameCandidate.legacyPath}`,
341
- });
342
- continue;
343
- }
344
- const addedCurrent = addedKeys.includes(currentPath) ||
345
- (newLeafMap.has(currentPath) && !oldLeafMap.has(currentPath));
346
- if (!addedCurrent) {
347
- continue;
348
- }
349
- const compatibleLegacyPath = [
350
- ...removedKeys,
351
- ...oldLeafAttributes
352
- .filter((descriptor) => !newLeafMap.has(descriptor.currentPath))
353
- .map((descriptor) => descriptor.currentPath),
354
- ].find((legacyPath) => passesNameSimilarityRule(legacyPath, currentPath));
355
- if (compatibleLegacyPath) {
356
- suggestions.push({
357
- bodyLines: buildTransformBodyLines(currentAttribute, compatibleLegacyPath),
358
- attribute: currentAttribute,
359
- currentPath,
360
- legacyPath: compatibleLegacyPath,
361
- reason: `review coercion from ${compatibleLegacyPath}`,
362
- });
363
- }
364
- }
365
- return suggestions;
366
- }
367
- function isRenameCandidateShapeCompatible(oldAttribute, newAttribute) {
368
- if (!oldAttribute || !newAttribute || oldAttribute.ts.kind !== newAttribute.ts.kind) {
369
- return false;
370
- }
371
- if (["string", "number", "boolean"].includes(oldAttribute.ts.kind)) {
372
- return hasRenameCompatibleConstraints(oldAttribute, newAttribute);
373
- }
374
- if (oldAttribute.ts.kind === "union") {
375
- return compareUnionAttribute(oldAttribute, newAttribute, "$rename").status === "auto";
376
- }
377
- return false;
378
- }
379
- function assessRenameCandidate(oldAttribute, newAttribute, legacyPath, currentPath) {
380
- if (!isRenameCandidateShapeCompatible(oldAttribute, newAttribute)) {
381
- return null;
382
- }
383
- const baseScore = scoreRenameSimilarity(legacyPath, currentPath);
384
- const score = getParentPath(legacyPath) === getParentPath(currentPath) ? Math.max(baseScore, 0.75) : baseScore;
385
- return {
386
- autoApply: false,
387
- currentPath,
388
- legacyPath,
389
- reason: describeRenameReason(oldAttribute, legacyPath, currentPath, score),
390
- score,
391
- };
392
- }
393
- function hasRenameCompatibleConstraints(oldAttribute, newAttribute) {
394
- const oldEnum = oldAttribute.wp.enum ?? null;
395
- const nextEnum = newAttribute.wp.enum ?? null;
396
- if (oldEnum && nextEnum) {
397
- const oldIsSubset = oldEnum.every((value) => nextEnum.includes(value));
398
- if (!oldIsSubset) {
399
- return false;
400
- }
401
- }
402
- else if (oldEnum && !nextEnum) {
403
- return false;
404
- }
405
- const oldConstraints = oldAttribute.typia.constraints ?? {};
406
- const nextConstraints = newAttribute.typia.constraints ?? {};
407
- return [
408
- compareMinimumBound(oldConstraints.minLength, nextConstraints.minLength),
409
- compareMaximumBound(oldConstraints.maxLength, nextConstraints.maxLength),
410
- compareMinimumBound(oldConstraints.minimum, nextConstraints.minimum),
411
- compareMaximumBound(oldConstraints.maximum, nextConstraints.maximum),
412
- comparePatternBound(oldConstraints.pattern, nextConstraints.pattern),
413
- comparePatternBound(oldConstraints.format, nextConstraints.format),
414
- comparePatternBound(oldConstraints.typeTag, nextConstraints.typeTag),
415
- ].every(Boolean);
416
- }
417
- function compareMinimumBound(oldValue, nextValue) {
418
- if (nextValue === null || nextValue === undefined)
419
- return true;
420
- if (oldValue === null || oldValue === undefined)
421
- return true;
422
- return Number(oldValue) <= Number(nextValue);
423
- }
424
- function compareMaximumBound(oldValue, nextValue) {
425
- if (nextValue === null || nextValue === undefined)
426
- return true;
427
- if (oldValue === null || oldValue === undefined)
428
- return true;
429
- return Number(oldValue) >= Number(nextValue);
430
- }
431
- function comparePatternBound(oldValue, nextValue) {
432
- return oldValue === nextValue || oldValue === null || oldValue === undefined;
433
- }
434
- function scoreRenameSimilarity(legacyPath, currentPath) {
435
- const legacy = normalizeFieldName(legacyPath);
436
- const current = normalizeFieldName(currentPath);
437
- if (legacy === current)
438
- return 1;
439
- if (shareAliasGroup(legacy, current))
440
- return 0.9;
441
- const legacyTokens = tokenizeFieldName(legacy);
442
- const currentTokens = tokenizeFieldName(current);
443
- const overlap = legacyTokens.filter((token) => currentTokens.includes(token));
444
- const jaccard = overlap.length / new Set([...legacyTokens, ...currentTokens]).size;
445
- if (legacy.includes(current) || current.includes(legacy)) {
446
- return Math.max(jaccard, 0.7);
447
- }
448
- if (legacyTokens.length > 0 &&
449
- currentTokens.length > 0 &&
450
- legacyTokens[legacyTokens.length - 1] === currentTokens[currentTokens.length - 1]) {
451
- return Math.max(jaccard, 0.6);
452
- }
453
- return jaccard;
454
- }
455
- function passesNameSimilarityRule(legacyPath, currentPath) {
456
- return scoreRenameSimilarity(legacyPath, currentPath) >= 0.6;
457
- }
458
- function normalizeFieldName(name) {
459
- return String(name)
460
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
461
- .replace(/[^a-zA-Z0-9]+/g, " ")
462
- .trim()
463
- .toLowerCase()
464
- .replace(/\s+/g, "");
465
- }
466
- function tokenizeFieldName(name) {
467
- return String(name)
468
- .replace(/([a-z0-9])([A-Z])/g, "$1 $2")
469
- .toLowerCase()
470
- .split(/[^a-z0-9]+/)
471
- .filter(Boolean);
472
- }
473
- function getParentPath(pathLabel) {
474
- const segments = String(pathLabel).split(".");
475
- return segments.length <= 1 ? "" : segments.slice(0, -1).join(".");
476
- }
477
- function shareAliasGroup(left, right) {
478
- const aliasGroups = [
479
- ["content", "headline", "body", "text", "copy", "message"],
480
- ["id", "uniqueid", "uuid"],
481
- ["visible", "isvisible", "show", "shown", "enabled"],
482
- ["align", "alignment", "textalign"],
483
- ["count", "clickcount", "counter"],
484
- ["url", "href", "link"],
485
- ];
486
- return aliasGroups.some((group) => group.includes(left) && group.includes(right));
487
- }
488
- function describeRenameReason(attribute, legacyPath, currentPath, score) {
489
- if (attribute.ts.kind === "union") {
490
- return `compatible discriminated union (${legacyPath} → ${currentPath})`;
491
- }
492
- if (score >= 0.9)
493
- return "high-confidence compatible field";
494
- if (score >= 0.6)
495
- return "name-similar compatible field";
496
- return "compatible field requiring review";
497
- }
498
- function buildTransformBodyLines(attribute, legacyPath) {
499
- switch (attribute.ts.kind) {
500
- case "string":
501
- return [`// return typeof legacyValue === "string" ? legacyValue : String(legacyValue ?? "");`];
502
- case "number":
503
- return [
504
- `// const numericValue = typeof legacyValue === "number" ? legacyValue : Number(legacyValue ?? 0);`,
505
- `// return Number.isNaN(numericValue) ? undefined : numericValue;`,
506
- ];
507
- case "boolean":
508
- return [`// return typeof legacyValue === "boolean" ? legacyValue : Boolean(legacyValue);`];
509
- case "union":
510
- return [
511
- `// const legacyObject = typeof legacyValue === "object" && legacyValue !== null ? legacyValue : {};`,
512
- `// return legacyObject; // adjust discriminator / branch fields before verify`,
513
- ];
514
- default:
515
- return [`// return legacyValue; // customize migration from ${legacyPath}`];
516
- }
517
- }
518
- function describeConstraintChange(oldAttribute, newAttribute) {
519
- const details = [];
520
- const oldConstraints = oldAttribute.typia.constraints;
521
- const nextConstraints = newAttribute.typia.constraints;
522
- if (newAttribute.wp.enum && JSON.stringify(newAttribute.wp.enum) !== JSON.stringify(oldAttribute.wp.enum)) {
523
- details.push("enum changed");
524
- }
525
- for (const key of ["minLength", "maxLength", "minimum", "maximum", "pattern", "format", "typeTag"]) {
526
- if (oldConstraints[key] !== nextConstraints[key]) {
527
- details.push(`${key}: ${oldConstraints[key]} -> ${nextConstraints[key]}`);
528
- }
529
- }
530
- return details.join(", ");
531
- }
532
247
  function autoOutcome(pathLabel, kind, detail) {
533
248
  return { detail, kind, path: pathLabel, status: "auto" };
534
249
  }
@@ -0,0 +1,3 @@
1
+ import type { GeneratedMigrationEntry, MigrationProjectState } from "./migration-types.js";
2
+ export declare function collectGeneratedMigrationEntries(state: MigrationProjectState): GeneratedMigrationEntry[];
3
+ export declare function regenerateGeneratedArtifacts(projectDir: string): void;
@@ -0,0 +1,41 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import { ROOT_PHP_MIGRATION_REGISTRY } from "./migration-constants.js";
4
+ import { createMigrationDiff } from "./migration-diff.js";
5
+ import { createMigrationFuzzPlan } from "./migration-fuzz-plan.js";
6
+ import { discoverMigrationEntries, getGeneratedDirForBlock, getSnapshotManifestPath, loadMigrationProject, } from "./migration-project.js";
7
+ import { renderFuzzFile, renderGeneratedDeprecatedFile, renderGeneratedMigrationIndexFile, renderMigrationRegistryFile, renderPhpMigrationRegistryFile, renderVerifyFile, } from "./migration-render.js";
8
+ import { createMigrationRiskSummary } from "./migration-risk.js";
9
+ import { readJson } from "./migration-utils.js";
10
+ export function collectGeneratedMigrationEntries(state) {
11
+ return discoverMigrationEntries(state).map((entry) => {
12
+ const block = state.blocks.find((target) => target.key === entry.block.key);
13
+ if (!block) {
14
+ throw new Error(`Unknown migration block target: ${entry.block.key}`);
15
+ }
16
+ const diff = createMigrationDiff(state, entry.block, entry.fromVersion, entry.toVersion);
17
+ const legacyManifest = readJson(getSnapshotManifestPath(state.projectDir, entry.block, entry.fromVersion));
18
+ return {
19
+ diff,
20
+ entry,
21
+ fuzzPlan: createMigrationFuzzPlan(legacyManifest, block.currentManifest, diff),
22
+ riskSummary: createMigrationRiskSummary(diff),
23
+ };
24
+ });
25
+ }
26
+ export function regenerateGeneratedArtifacts(projectDir) {
27
+ const state = loadMigrationProject(projectDir);
28
+ const generatedEntries = collectGeneratedMigrationEntries(state);
29
+ for (const block of state.blocks) {
30
+ const blockGeneratedEntries = generatedEntries.filter(({ entry }) => entry.block.key === block.key);
31
+ const entries = blockGeneratedEntries.map(({ entry }) => entry);
32
+ const generatedDir = getGeneratedDirForBlock(state.paths, block);
33
+ fs.mkdirSync(generatedDir, { recursive: true });
34
+ fs.writeFileSync(path.join(generatedDir, "registry.ts"), renderMigrationRegistryFile(state, block.key, blockGeneratedEntries), "utf8");
35
+ fs.writeFileSync(path.join(generatedDir, "deprecated.ts"), renderGeneratedDeprecatedFile(state, block.key, entries), "utf8");
36
+ fs.writeFileSync(path.join(generatedDir, "verify.ts"), renderVerifyFile(state, block.key, entries), "utf8");
37
+ fs.writeFileSync(path.join(generatedDir, "fuzz.ts"), renderFuzzFile(state, block.key, blockGeneratedEntries), "utf8");
38
+ }
39
+ fs.writeFileSync(path.join(state.paths.generatedDir, "index.ts"), renderGeneratedMigrationIndexFile(state, generatedEntries.map(({ entry }) => entry)), "utf8");
40
+ fs.writeFileSync(path.join(projectDir, ROOT_PHP_MIGRATION_REGISTRY), renderPhpMigrationRegistryFile(state, generatedEntries.map(({ entry }) => entry)), "utf8");
41
+ }
@@ -0,0 +1,51 @@
1
+ import type { FixturesOptions, FuzzOptions, VerifyOptions } from './migration-command-surface.js';
2
+ /**
3
+ * Run deterministic migration verification against generated fixtures.
4
+ *
5
+ * @param projectDir Absolute or relative project directory containing the migration workspace.
6
+ * @param options Verification scope and console rendering options.
7
+ * @returns Verified legacy versions.
8
+ */
9
+ export declare function verifyProjectMigrations(projectDir: string, { all, fromMigrationVersion, renderLine, }?: VerifyOptions): {
10
+ verifiedVersions: string[];
11
+ };
12
+ /**
13
+ * Validate the migration workspace without mutating files.
14
+ *
15
+ * @param projectDir Absolute or relative project directory containing the migration workspace.
16
+ * @param options Doctor scope and console rendering options.
17
+ * @returns Structured doctor check results for the selected legacy versions.
18
+ */
19
+ export declare function doctorProjectMigrations(projectDir: string, { all, fromMigrationVersion, renderLine, }?: VerifyOptions): {
20
+ checkedVersions: string[];
21
+ checks: {
22
+ detail: string;
23
+ label: string;
24
+ status: "fail" | "pass";
25
+ }[];
26
+ };
27
+ /**
28
+ * Generate or refresh migration fixtures for one or more legacy edges.
29
+ *
30
+ * @param projectDir Absolute or relative project directory containing the migration workspace.
31
+ * @param options Fixture generation scope and refresh options.
32
+ * @returns Generated and skipped legacy versions.
33
+ */
34
+ export declare function fixturesProjectMigrations(projectDir: string, { all, confirmOverwrite, force, fromMigrationVersion, isInteractive, renderLine, toMigrationVersion, }?: FixturesOptions): {
35
+ generatedVersions: string[];
36
+ skippedVersions: string[];
37
+ };
38
+ /**
39
+ * Run seeded migration fuzz verification against generated fuzz artifacts.
40
+ *
41
+ * @param projectDir Absolute or relative project directory containing the migration workspace.
42
+ * @param options Fuzz scope, iteration count, seed, and console rendering options.
43
+ * @returns Fuzzed legacy versions and the effective seed.
44
+ */
45
+ export declare function fuzzProjectMigrations(projectDir: string, { all, fromMigrationVersion, iterations, renderLine, seed, }?: FuzzOptions): {
46
+ fuzzedVersions: never[];
47
+ seed?: undefined;
48
+ } | {
49
+ fuzzedVersions: string[];
50
+ seed: number | undefined;
51
+ };