@wp-typia/project-tools 0.23.1 → 0.24.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.
Files changed (152) hide show
  1. package/dist/runtime/built-in-block-non-ts-basic-artifacts.d.ts +9 -0
  2. package/dist/runtime/built-in-block-non-ts-basic-artifacts.js +84 -0
  3. package/dist/runtime/built-in-block-non-ts-compound-artifacts.d.ts +9 -0
  4. package/dist/runtime/built-in-block-non-ts-compound-artifacts.js +36 -0
  5. package/dist/runtime/built-in-block-non-ts-compound-templates.d.ts +23 -0
  6. package/dist/runtime/built-in-block-non-ts-compound-templates.js +453 -0
  7. package/dist/runtime/built-in-block-non-ts-family-artifacts.d.ts +8 -26
  8. package/dist/runtime/built-in-block-non-ts-family-artifacts.js +8 -1034
  9. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.d.ts +9 -0
  10. package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.js +83 -0
  11. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.d.ts +9 -0
  12. package/dist/runtime/built-in-block-non-ts-persistence-artifacts.js +33 -0
  13. package/dist/runtime/built-in-block-non-ts-persistence-templates.d.ts +23 -0
  14. package/dist/runtime/built-in-block-non-ts-persistence-templates.js +395 -0
  15. package/dist/runtime/cli-add-collision.js +8 -0
  16. package/dist/runtime/cli-add-help.js +10 -7
  17. package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
  18. package/dist/runtime/cli-add-kind-ids.js +1 -0
  19. package/dist/runtime/cli-add-types.d.ts +28 -1
  20. package/dist/runtime/cli-add-types.js +2 -0
  21. package/dist/runtime/cli-add-workspace-ability-anchors.d.ts +24 -0
  22. package/dist/runtime/cli-add-workspace-ability-anchors.js +294 -0
  23. package/dist/runtime/cli-add-workspace-ability-registry.d.ts +10 -0
  24. package/dist/runtime/cli-add-workspace-ability-registry.js +51 -0
  25. package/dist/runtime/cli-add-workspace-ability-scaffold.d.ts +1 -1
  26. package/dist/runtime/cli-add-workspace-ability-scaffold.js +5 -311
  27. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +1 -1
  28. package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +4 -4
  29. package/dist/runtime/cli-add-workspace-ai-anchors.js +4 -232
  30. package/dist/runtime/cli-add-workspace-ai-scaffold.js +4 -2
  31. package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +1 -4
  32. package/dist/runtime/cli-add-workspace-ai-source-emitters.js +1 -145
  33. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.d.ts +5 -0
  34. package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.js +236 -0
  35. package/dist/runtime/cli-add-workspace-ai-sync-script-source.d.ts +4 -0
  36. package/dist/runtime/cli-add-workspace-ai-sync-script-source.js +145 -0
  37. package/dist/runtime/cli-add-workspace-assets.d.ts +6 -63
  38. package/dist/runtime/cli-add-workspace-assets.js +6 -950
  39. package/dist/runtime/cli-add-workspace-binding-source-anchors.d.ts +23 -0
  40. package/dist/runtime/cli-add-workspace-binding-source-anchors.js +112 -0
  41. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.d.ts +33 -0
  42. package/dist/runtime/cli-add-workspace-binding-source-source-emitters.js +436 -0
  43. package/dist/runtime/cli-add-workspace-binding-source-types.d.ts +20 -0
  44. package/dist/runtime/cli-add-workspace-binding-source-types.js +1 -0
  45. package/dist/runtime/cli-add-workspace-binding-source.d.ts +40 -0
  46. package/dist/runtime/cli-add-workspace-binding-source.js +275 -0
  47. package/dist/runtime/cli-add-workspace-block-style.d.ts +22 -0
  48. package/dist/runtime/cli-add-workspace-block-style.js +148 -0
  49. package/dist/runtime/cli-add-workspace-block-transform.d.ts +32 -0
  50. package/dist/runtime/cli-add-workspace-block-transform.js +197 -0
  51. package/dist/runtime/cli-add-workspace-contract.js +1 -1
  52. package/dist/runtime/cli-add-workspace-core-variation.d.ts +20 -0
  53. package/dist/runtime/cli-add-workspace-core-variation.js +322 -0
  54. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.d.ts +37 -0
  55. package/dist/runtime/cli-add-workspace-editor-plugin-anchors.js +206 -0
  56. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.d.ts +47 -0
  57. package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.js +219 -0
  58. package/dist/runtime/cli-add-workspace-editor-plugin.d.ts +22 -0
  59. package/dist/runtime/cli-add-workspace-editor-plugin.js +78 -0
  60. package/dist/runtime/cli-add-workspace-hooked-block.d.ts +23 -0
  61. package/dist/runtime/cli-add-workspace-hooked-block.js +57 -0
  62. package/dist/runtime/cli-add-workspace-integration-env-files.d.ts +33 -0
  63. package/dist/runtime/cli-add-workspace-integration-env-files.js +65 -0
  64. package/dist/runtime/cli-add-workspace-integration-env-package-json.d.ts +38 -0
  65. package/dist/runtime/cli-add-workspace-integration-env-package-json.js +122 -0
  66. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.d.ts +44 -0
  67. package/dist/runtime/cli-add-workspace-integration-env-source-emitters.js +262 -0
  68. package/dist/runtime/cli-add-workspace-integration-env.js +5 -345
  69. package/dist/runtime/cli-add-workspace-pattern-anchors.d.ts +10 -0
  70. package/dist/runtime/cli-add-workspace-pattern-anchors.js +95 -0
  71. package/dist/runtime/cli-add-workspace-pattern-options.d.ts +20 -0
  72. package/dist/runtime/cli-add-workspace-pattern-options.js +113 -0
  73. package/dist/runtime/cli-add-workspace-pattern-source-emitters.d.ts +20 -0
  74. package/dist/runtime/cli-add-workspace-pattern-source-emitters.js +57 -0
  75. package/dist/runtime/cli-add-workspace-pattern.d.ts +42 -0
  76. package/dist/runtime/cli-add-workspace-pattern.js +99 -0
  77. package/dist/runtime/cli-add-workspace-post-meta.js +1 -1
  78. package/dist/runtime/cli-add-workspace-registration-hooks.d.ts +50 -0
  79. package/dist/runtime/cli-add-workspace-registration-hooks.js +162 -0
  80. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +6 -9
  81. package/dist/runtime/cli-add-workspace-rest-anchors.js +6 -466
  82. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.d.ts +17 -0
  83. package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.js +108 -0
  84. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.d.ts +9 -0
  85. package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.js +142 -0
  86. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.d.ts +51 -0
  87. package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.js +415 -0
  88. package/dist/runtime/cli-add-workspace-rest-generated.js +5 -3
  89. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.d.ts +80 -0
  90. package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.js +238 -0
  91. package/dist/runtime/cli-add-workspace-rest-manual.js +3 -16
  92. package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +1 -7
  93. package/dist/runtime/cli-add-workspace-rest-php-templates.js +3 -322
  94. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.d.ts +33 -0
  95. package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.js +145 -0
  96. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.d.ts +9 -0
  97. package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.js +162 -0
  98. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.d.ts +7 -0
  99. package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.js +193 -0
  100. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +5 -99
  101. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +5 -663
  102. package/dist/runtime/cli-add-workspace-rest-source-utils.d.ts +17 -0
  103. package/dist/runtime/cli-add-workspace-rest-source-utils.js +50 -0
  104. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.d.ts +56 -0
  105. package/dist/runtime/cli-add-workspace-rest-sync-script-shared.js +122 -0
  106. package/dist/runtime/cli-add-workspace-rest-types.d.ts +3 -3
  107. package/dist/runtime/cli-add-workspace-variation.d.ts +22 -0
  108. package/dist/runtime/cli-add-workspace-variation.js +162 -0
  109. package/dist/runtime/cli-add-workspace.d.ts +42 -107
  110. package/dist/runtime/cli-add-workspace.js +42 -674
  111. package/dist/runtime/cli-add.d.ts +3 -3
  112. package/dist/runtime/cli-add.js +2 -2
  113. package/dist/runtime/cli-core.d.ts +2 -1
  114. package/dist/runtime/cli-core.js +1 -1
  115. package/dist/runtime/cli-doctor-workspace-bindings.js +59 -0
  116. package/dist/runtime/cli-doctor-workspace-block-addons.js +33 -5
  117. package/dist/runtime/cli-doctor.d.ts +2 -0
  118. package/dist/runtime/cli-doctor.js +13 -2
  119. package/dist/runtime/cli-help.js +6 -4
  120. package/dist/runtime/index.d.ts +5 -2
  121. package/dist/runtime/index.js +4 -2
  122. package/dist/runtime/local-dev-presets.js +2 -1
  123. package/dist/runtime/package-versions.d.ts +1 -0
  124. package/dist/runtime/package-versions.js +10 -2
  125. package/dist/runtime/pattern-catalog.d.ts +122 -0
  126. package/dist/runtime/pattern-catalog.js +471 -0
  127. package/dist/runtime/post-meta-binding-fields.d.ts +46 -0
  128. package/dist/runtime/post-meta-binding-fields.js +135 -0
  129. package/dist/runtime/typia-llm-json-schema.d.ts +24 -0
  130. package/dist/runtime/typia-llm-json-schema.js +33 -0
  131. package/dist/runtime/typia-llm-openapi-constraints.d.ts +20 -0
  132. package/dist/runtime/typia-llm-openapi-constraints.js +254 -0
  133. package/dist/runtime/typia-llm-projection.d.ts +25 -0
  134. package/dist/runtime/typia-llm-projection.js +58 -0
  135. package/dist/runtime/typia-llm-render.d.ts +21 -0
  136. package/dist/runtime/typia-llm-render.js +252 -0
  137. package/dist/runtime/typia-llm-sync.d.ts +10 -0
  138. package/dist/runtime/typia-llm-sync.js +63 -0
  139. package/dist/runtime/typia-llm-types.d.ts +197 -0
  140. package/dist/runtime/typia-llm-types.js +1 -0
  141. package/dist/runtime/typia-llm.d.ts +9 -255
  142. package/dist/runtime/typia-llm.js +5 -634
  143. package/dist/runtime/workspace-inventory-mutations.js +13 -0
  144. package/dist/runtime/workspace-inventory-section-descriptors.js +9 -1
  145. package/dist/runtime/workspace-inventory-templates.d.ts +2 -2
  146. package/dist/runtime/workspace-inventory-templates.js +9 -1
  147. package/dist/runtime/workspace-inventory-types.d.ts +9 -1
  148. package/package.json +8 -3
  149. package/templates/_shared/compound/core/scripts/block-config.ts.mustache +22 -0
  150. package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +103 -2
  151. package/templates/_shared/compound/core/src/inner-blocks-templates.ts.mustache +13 -0
  152. package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +22 -1
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Prefix every line in a multi-line source fragment.
3
+ *
4
+ * @param source Source fragment to indent.
5
+ * @param prefix Prefix to prepend to every line.
6
+ * @returns The source fragment with each line prefixed.
7
+ */
8
+ export function indentMultiline(source, prefix) {
9
+ return source
10
+ .split("\n")
11
+ .map((line) => `${prefix}${line}`)
12
+ .join("\n");
13
+ }
14
+ const RESOLVE_REST_NONCE_SOURCE = `function resolveRestNonce( fallback?: string ): string | undefined {
15
+ \tif ( typeof fallback === 'string' && fallback.length > 0 ) {
16
+ \t\treturn fallback;
17
+ \t}
18
+
19
+ \tif ( typeof window === 'undefined' ) {
20
+ \t\treturn undefined;
21
+ \t}
22
+
23
+ \tconst wpApiSettings = (
24
+ \t\twindow as typeof window & {
25
+ \t\t\twpApiSettings?: { nonce?: string };
26
+ \t\t}
27
+ \t).wpApiSettings;
28
+
29
+ \treturn typeof wpApiSettings?.nonce === 'string' &&
30
+ \t\twpApiSettings.nonce.length > 0
31
+ \t\t? wpApiSettings.nonce
32
+ \t\t: undefined;
33
+ }`;
34
+ /**
35
+ * Render the shared REST nonce helper in the formatting style expected by a
36
+ * generated source file.
37
+ *
38
+ * @param style Compact output is used by manual-contract shims; spaced output
39
+ * matches generated REST resource shims.
40
+ * @returns TypeScript source for the embedded `resolveRestNonce()` helper.
41
+ */
42
+ export function formatResolveRestNonceSource(style) {
43
+ if (style === "spaced") {
44
+ return RESOLVE_REST_NONCE_SOURCE;
45
+ }
46
+ return RESOLVE_REST_NONCE_SOURCE
47
+ .replace("function resolveRestNonce( fallback?: string ): string | undefined {", "function resolveRestNonce(fallback?: string): string | undefined {")
48
+ .replace("\tif ( typeof fallback === 'string' && fallback.length > 0 ) {", "\tif (typeof fallback === 'string' && fallback.length > 0) {")
49
+ .replace("\tif ( typeof window === 'undefined' ) {", "\tif (typeof window === 'undefined') {");
50
+ }
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Build the standard sync-rest patch failure message for missing anchors.
3
+ *
4
+ * @param functionName Name of the patcher that could not complete.
5
+ * @param syncRestScriptPath Path to the workspace sync-rest script.
6
+ * @param anchorDescription Human-readable description of the missing anchor.
7
+ * @param subject Configuration subject the patcher was trying to wire.
8
+ * @returns A formatted error message with manual recovery guidance.
9
+ */
10
+ export declare function getSyncRestPatchErrorMessage(functionName: string, syncRestScriptPath: string, anchorDescription: string, subject: string): string;
11
+ /**
12
+ * Add a required block-config value and type import to sync-rest source.
13
+ *
14
+ * @param options Import patching options.
15
+ * @param options.functionName Name of the calling patcher for error messages.
16
+ * @param options.nextSource Current sync-rest script source.
17
+ * @param options.subject Value and type names that must be imported.
18
+ * @param options.syncRestScriptPath Path to the target sync-rest script.
19
+ * @returns Source with the block-config import updated or left unchanged.
20
+ * @throws When the generated block-config import anchor cannot be found.
21
+ */
22
+ export declare function replaceBlockConfigImport({ functionName, nextSource, subject, syncRestScriptPath, }: {
23
+ functionName: string;
24
+ nextSource: string;
25
+ subject: {
26
+ configTypeName: string;
27
+ constName: string;
28
+ };
29
+ syncRestScriptPath: string;
30
+ }): string;
31
+ /**
32
+ * Render a sync-rest guard for the selected empty resource collections.
33
+ *
34
+ * @param options Guard rendering options.
35
+ * @param options.subjects Candidate guard subjects and conditions.
36
+ * @returns TypeScript source for the no-resources guard block.
37
+ */
38
+ export declare function buildNoResourcesGuard({ subjects, }: {
39
+ subjects: readonly {
40
+ condition: string;
41
+ include: boolean;
42
+ subject: string;
43
+ }[];
44
+ }): string;
45
+ /**
46
+ * Replace the generated no-resources guard in sync-rest source.
47
+ *
48
+ * @param nextSource Current sync-rest script source.
49
+ * @param replacement New no-resources guard source.
50
+ * @param functionName Name of the calling patcher for error messages.
51
+ * @param syncRestScriptPath Path to the target sync-rest script.
52
+ * @param subject Configuration subject the patcher was trying to wire.
53
+ * @returns Source with the no-resources guard replaced.
54
+ * @throws When the generated no-resources guard cannot be found.
55
+ */
56
+ export declare function replaceNoResourcesGuard(nextSource: string, replacement: string, functionName: string, syncRestScriptPath: string, subject: string): string;
@@ -0,0 +1,122 @@
1
+ import path from "node:path";
2
+ /**
3
+ * Build the standard sync-rest patch failure message for missing anchors.
4
+ *
5
+ * @param functionName Name of the patcher that could not complete.
6
+ * @param syncRestScriptPath Path to the workspace sync-rest script.
7
+ * @param anchorDescription Human-readable description of the missing anchor.
8
+ * @param subject Configuration subject the patcher was trying to wire.
9
+ * @returns A formatted error message with manual recovery guidance.
10
+ */
11
+ export function getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, anchorDescription, subject) {
12
+ return [
13
+ `${functionName} could not patch ${path.basename(syncRestScriptPath)}.`,
14
+ `Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
15
+ `Restore the generated template or add the ${subject} wiring manually before retrying.`,
16
+ ].join(" ");
17
+ }
18
+ const BLOCK_CONFIG_IMPORT_PATTERNS = [
19
+ /^import\s*\{\n(?:\t[^\n]*\n)+\} from ["']\.\/block-config["'];?$/mu,
20
+ /^import\s*\{[^\n]*\}\s*from\s*["']\.\/block-config["'];?$/mu,
21
+ ];
22
+ const BLOCK_CONFIG_VALUE_IMPORT_ORDER = [
23
+ "AI_FEATURES",
24
+ "BLOCKS",
25
+ "CONTRACTS",
26
+ "POST_META",
27
+ "REST_RESOURCES",
28
+ ];
29
+ const BLOCK_CONFIG_TYPE_IMPORT_ORDER = [
30
+ "WorkspaceAiFeatureConfig",
31
+ "WorkspaceBlockConfig",
32
+ "WorkspaceContractConfig",
33
+ "WorkspacePostMetaConfig",
34
+ "WorkspaceRestResourceConfig",
35
+ ];
36
+ /**
37
+ * Add a required block-config value and type import to sync-rest source.
38
+ *
39
+ * @param options Import patching options.
40
+ * @param options.functionName Name of the calling patcher for error messages.
41
+ * @param options.nextSource Current sync-rest script source.
42
+ * @param options.subject Value and type names that must be imported.
43
+ * @param options.syncRestScriptPath Path to the target sync-rest script.
44
+ * @returns Source with the block-config import updated or left unchanged.
45
+ * @throws When the generated block-config import anchor cannot be found.
46
+ */
47
+ export function replaceBlockConfigImport({ functionName, nextSource, subject, syncRestScriptPath, }) {
48
+ const importMatch = BLOCK_CONFIG_IMPORT_PATTERNS.map((pattern) => pattern.exec(nextSource)).find(Boolean) ?? null;
49
+ if (!importMatch) {
50
+ throw new Error(getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, "block-config import", subject.constName));
51
+ }
52
+ const importSource = importMatch[0];
53
+ if (importSource.includes(subject.constName) &&
54
+ importSource.includes(subject.configTypeName)) {
55
+ return nextSource;
56
+ }
57
+ if (!importSource.includes("BLOCKS") ||
58
+ !importSource.includes("WorkspaceBlockConfig")) {
59
+ throw new Error(getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, "BLOCKS import", subject.constName));
60
+ }
61
+ const replacement = [
62
+ "import {",
63
+ ...BLOCK_CONFIG_VALUE_IMPORT_ORDER.flatMap((constName) => constName === subject.constName || importSource.includes(constName)
64
+ ? [`\t${constName},`]
65
+ : []),
66
+ ...BLOCK_CONFIG_TYPE_IMPORT_ORDER.flatMap((configTypeName) => configTypeName === subject.configTypeName ||
67
+ importSource.includes(configTypeName)
68
+ ? [`\ttype ${configTypeName},`]
69
+ : []),
70
+ "} from './block-config';",
71
+ ].join("\n");
72
+ return nextSource.replace(importSource, replacement);
73
+ }
74
+ function formatNoResourcesSubject(subjects) {
75
+ if (subjects.length <= 2) {
76
+ return subjects.join(" or ");
77
+ }
78
+ const lastSubject = subjects[subjects.length - 1];
79
+ return `${subjects.slice(0, -1).join(", ")}, or ${lastSubject}`;
80
+ }
81
+ /**
82
+ * Render a sync-rest guard for the selected empty resource collections.
83
+ *
84
+ * @param options Guard rendering options.
85
+ * @param options.subjects Candidate guard subjects and conditions.
86
+ * @returns TypeScript source for the no-resources guard block.
87
+ */
88
+ export function buildNoResourcesGuard({ subjects, }) {
89
+ const includedSubjects = subjects.filter((subject) => subject.include);
90
+ const condition = includedSubjects.map(({ condition }, index) => index === includedSubjects.length - 1 ? condition : `${condition} &&`);
91
+ const noResourcesSubject = formatNoResourcesSubject(includedSubjects.map(({ subject }) => subject));
92
+ return [
93
+ "if (",
94
+ ...condition.map((line) => `\t\t${line}`),
95
+ "\t) {",
96
+ "\t\tconsole.log(",
97
+ "\t\t\toptions.check",
98
+ `\t\t\t\t? 'ℹ️ No ${noResourcesSubject} are registered yet. \`sync-rest --check\` is already clean.'`,
99
+ `\t\t\t\t: 'ℹ️ No ${noResourcesSubject} are registered yet.'`,
100
+ "\t\t);",
101
+ "\t\treturn;",
102
+ "\t}",
103
+ ].join("\n");
104
+ }
105
+ const NO_RESOURCES_GUARD_PATTERN = /if \(\s*restBlocks\.length === 0(?:\s*&&\s*standaloneContracts\.length === 0)?(?:\s*&&\s*postMetaContracts\.length === 0)?(?:\s*&&\s*restResources\.length === 0)?(?:\s*&&\s*aiFeatures\.length === 0)?\s*\) \{[\s\S]*?\n\t\treturn;\n\t\}/u;
106
+ /**
107
+ * Replace the generated no-resources guard in sync-rest source.
108
+ *
109
+ * @param nextSource Current sync-rest script source.
110
+ * @param replacement New no-resources guard source.
111
+ * @param functionName Name of the calling patcher for error messages.
112
+ * @param syncRestScriptPath Path to the target sync-rest script.
113
+ * @param subject Configuration subject the patcher was trying to wire.
114
+ * @returns Source with the no-resources guard replaced.
115
+ * @throws When the generated no-resources guard cannot be found.
116
+ */
117
+ export function replaceNoResourcesGuard(nextSource, replacement, functionName, syncRestScriptPath, subject) {
118
+ if (!NO_RESOURCES_GUARD_PATTERN.test(nextSource)) {
119
+ throw new Error(getSyncRestPatchErrorMessage(functionName, syncRestScriptPath, "no-resources guard", subject));
120
+ }
121
+ return nextSource.replace(NO_RESOURCES_GUARD_PATTERN, replacement);
122
+ }
@@ -58,8 +58,8 @@ export interface RunAddRestResourceCommandResult {
58
58
  * @property secretMaskedResponseFieldName Optional alias for
59
59
  * `secretStateFieldName`.
60
60
  * @property secretFieldName Optional write-only request secret field.
61
- * @property secretPreserveOnEmpty Optional true/false string or boolean for
62
- * blank-secret preservation. Defaults to true when `secretFieldName` is set.
61
+ * @property secretPreserveOnEmpty Optional normalized boolean for blank-secret
62
+ * preservation. Defaults to true when `secretFieldName` is set.
63
63
  * @property workspace Resolved official workspace project.
64
64
  */
65
65
  export interface ManualRestContractScaffoldOptions {
@@ -78,7 +78,7 @@ export interface ManualRestContractScaffoldOptions {
78
78
  secretFieldName: string | undefined;
79
79
  secretHasValueFieldName: string | undefined;
80
80
  secretMaskedResponseFieldName: string | undefined;
81
- secretPreserveOnEmpty: boolean | string | undefined;
81
+ secretPreserveOnEmpty: boolean | undefined;
82
82
  secretStateFieldName: string | undefined;
83
83
  workspace: WorkspaceProject;
84
84
  }
@@ -0,0 +1,22 @@
1
+ import { type RunAddVariationCommandOptions } from "./cli-add-shared.js";
2
+ /**
3
+ * Add one variation entry to an existing workspace block.
4
+ *
5
+ * @param options Command options for the variation scaffold workflow.
6
+ * @param options.blockName Target workspace block slug that will own the variation.
7
+ * @param options.cwd Working directory used to resolve the nearest official workspace.
8
+ * Defaults to `process.cwd()`.
9
+ * @param options.variationName Human-entered variation name that will be normalized
10
+ * and validated before files are written.
11
+ * @returns A promise that resolves with the normalized `blockSlug`,
12
+ * `variationSlug`, and owning `projectDir` after the variation files and
13
+ * inventory entry have been written successfully.
14
+ * @throws {Error} When the command is run outside an official workspace, when
15
+ * the target block is unknown, when the variation slug is invalid, or when a
16
+ * conflicting file or inventory entry already exists.
17
+ */
18
+ export declare function runAddVariationCommand({ blockName, cwd, variationName, }: RunAddVariationCommandOptions): Promise<{
19
+ blockSlug: string;
20
+ projectDir: string;
21
+ variationSlug: string;
22
+ }>;
@@ -0,0 +1,162 @@
1
+ import { promises as fsp } from "node:fs";
2
+ import path from "node:path";
3
+ import { pathExists } from "./fs-async.js";
4
+ import { assertVariationDoesNotExist, assertValidGeneratedSlug, normalizeBlockSlug, quoteTsString, resolveWorkspaceBlock, rollbackWorkspaceMutation, snapshotWorkspaceFiles, } from "./cli-add-shared.js";
5
+ import { ensureWorkspaceEntrypointCall } from "./cli-add-workspace-registration-hooks.js";
6
+ import { appendWorkspaceInventoryEntries, readWorkspaceInventoryAsync, } from "./workspace-inventory.js";
7
+ import { resolveWorkspaceProject } from "./workspace-project.js";
8
+ import { toKebabCase, toTitleCase } from "./string-case.js";
9
+ const VARIATIONS_IMPORT_LINE = "import { registerWorkspaceVariations } from './variations';";
10
+ const VARIATIONS_IMPORT_PATTERN = /^\s*import\s*\{\s*registerWorkspaceVariations\s*\}\s*from\s*["']\.\/variations["']\s*;?\s*$/mu;
11
+ const VARIATIONS_CALL_LINE = "registerWorkspaceVariations();";
12
+ const VARIATIONS_CALL_PATTERN = /registerWorkspaceVariations\s*\(\s*\)\s*;?/u;
13
+ function buildVariationConfigEntry(blockSlug, variationSlug) {
14
+ return [
15
+ "\t{",
16
+ `\t\tblock: ${quoteTsString(blockSlug)},`,
17
+ `\t\tfile: ${quoteTsString(`src/blocks/${blockSlug}/variations/${variationSlug}.ts`)},`,
18
+ `\t\tslug: ${quoteTsString(variationSlug)},`,
19
+ "\t},",
20
+ ].join("\n");
21
+ }
22
+ function buildVariationConstName(variationSlug) {
23
+ const identifierSegments = toKebabCase(variationSlug)
24
+ .split("-")
25
+ .filter(Boolean);
26
+ return `workspaceVariation_${identifierSegments.join("_")}`;
27
+ }
28
+ function getVariationConstBindings(variationSlugs) {
29
+ const seenConstNames = new Map();
30
+ return variationSlugs.map((variationSlug) => {
31
+ const constName = buildVariationConstName(variationSlug);
32
+ const previousSlug = seenConstNames.get(constName);
33
+ if (previousSlug && previousSlug !== variationSlug) {
34
+ throw new Error(`Variation slugs "${previousSlug}" and "${variationSlug}" generate the same registry identifier "${constName}". Rename one of the variations.`);
35
+ }
36
+ seenConstNames.set(constName, variationSlug);
37
+ return { constName, variationSlug };
38
+ });
39
+ }
40
+ function buildVariationSource(variationSlug, textDomain) {
41
+ const variationTitle = toTitleCase(variationSlug);
42
+ const variationConstName = buildVariationConstName(variationSlug);
43
+ return `import type { BlockVariation } from '@wp-typia/block-types/blocks/registration';
44
+ import { __ } from '@wordpress/i18n';
45
+
46
+ export const ${variationConstName} = {
47
+ \tname: ${quoteTsString(variationSlug)},
48
+ \ttitle: __( ${quoteTsString(variationTitle)}, ${quoteTsString(textDomain)} ),
49
+ \tdescription: __(
50
+ \t\t${quoteTsString(`A starter variation for ${variationTitle}.`)},
51
+ \t\t${quoteTsString(textDomain)},
52
+ \t),
53
+ \tattributes: {},
54
+ \tscope: ['inserter'],
55
+ } satisfies BlockVariation;
56
+ `;
57
+ }
58
+ function buildVariationIndexSource(variationSlugs) {
59
+ const variationBindings = getVariationConstBindings(variationSlugs);
60
+ const importLines = variationBindings
61
+ .map(({ constName, variationSlug }) => {
62
+ return `import { ${constName} } from './${variationSlug}';`;
63
+ })
64
+ .join("\n");
65
+ const variationConstNames = variationBindings
66
+ .map(({ constName }) => constName)
67
+ .join(",\n\t\t");
68
+ return `import { registerBlockVariation } from '@wordpress/blocks';
69
+ import metadata from '../block.json';
70
+ ${importLines ? `\n${importLines}` : ""}
71
+
72
+ const WORKSPACE_VARIATIONS = [
73
+ \t${variationConstNames}
74
+ \t// wp-typia add variation entries
75
+ ];
76
+
77
+ export function registerWorkspaceVariations() {
78
+ \tfor (const variation of WORKSPACE_VARIATIONS) {
79
+ \t\tregisterBlockVariation(metadata.name, variation);
80
+ \t}
81
+ }
82
+ `;
83
+ }
84
+ async function ensureVariationRegistrationHook(blockIndexPath) {
85
+ await ensureWorkspaceEntrypointCall({
86
+ blockIndexPath,
87
+ callLine: VARIATIONS_CALL_LINE,
88
+ callPattern: VARIATIONS_CALL_PATTERN,
89
+ importLine: VARIATIONS_IMPORT_LINE,
90
+ importPattern: VARIATIONS_IMPORT_PATTERN,
91
+ });
92
+ }
93
+ async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
94
+ const variationsDir = path.join(projectDir, "src", "blocks", blockSlug, "variations");
95
+ const variationsIndexPath = path.join(variationsDir, "index.ts");
96
+ await fsp.mkdir(variationsDir, { recursive: true });
97
+ const existingVariationSlugs = (await fsp.readdir(variationsDir))
98
+ .filter((entry) => entry.endsWith(".ts") && entry !== "index.ts")
99
+ .map((entry) => entry.replace(/\.ts$/u, ""));
100
+ const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
101
+ await fsp.writeFile(variationsIndexPath, buildVariationIndexSource(nextVariationSlugs), "utf8");
102
+ }
103
+ /**
104
+ * Add one variation entry to an existing workspace block.
105
+ *
106
+ * @param options Command options for the variation scaffold workflow.
107
+ * @param options.blockName Target workspace block slug that will own the variation.
108
+ * @param options.cwd Working directory used to resolve the nearest official workspace.
109
+ * Defaults to `process.cwd()`.
110
+ * @param options.variationName Human-entered variation name that will be normalized
111
+ * and validated before files are written.
112
+ * @returns A promise that resolves with the normalized `blockSlug`,
113
+ * `variationSlug`, and owning `projectDir` after the variation files and
114
+ * inventory entry have been written successfully.
115
+ * @throws {Error} When the command is run outside an official workspace, when
116
+ * the target block is unknown, when the variation slug is invalid, or when a
117
+ * conflicting file or inventory entry already exists.
118
+ */
119
+ export async function runAddVariationCommand({ blockName, cwd = process.cwd(), variationName, }) {
120
+ const workspace = resolveWorkspaceProject(cwd);
121
+ const blockSlug = normalizeBlockSlug(blockName);
122
+ const variationSlug = assertValidGeneratedSlug("Variation name", normalizeBlockSlug(variationName), "wp-typia add variation <name> --block <block-slug>");
123
+ const inventory = await readWorkspaceInventoryAsync(workspace.projectDir);
124
+ resolveWorkspaceBlock(inventory, blockSlug);
125
+ assertVariationDoesNotExist(workspace.projectDir, blockSlug, variationSlug, inventory);
126
+ const blockConfigPath = path.join(workspace.projectDir, "scripts", "block-config.ts");
127
+ const blockIndexPath = path.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
128
+ const variationsDir = path.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
129
+ const variationFilePath = path.join(variationsDir, `${variationSlug}.ts`);
130
+ const variationsIndexPath = path.join(variationsDir, "index.ts");
131
+ const shouldRemoveVariationsDirOnRollback = !(await pathExists(variationsDir));
132
+ const mutationSnapshot = {
133
+ fileSources: await snapshotWorkspaceFiles([
134
+ blockConfigPath,
135
+ blockIndexPath,
136
+ variationsIndexPath,
137
+ ]),
138
+ snapshotDirs: [],
139
+ targetPaths: [
140
+ variationFilePath,
141
+ ...(shouldRemoveVariationsDirOnRollback ? [variationsDir] : []),
142
+ ],
143
+ };
144
+ try {
145
+ await fsp.mkdir(variationsDir, { recursive: true });
146
+ await fsp.writeFile(variationFilePath, buildVariationSource(variationSlug, workspace.workspace.textDomain), "utf8");
147
+ await writeVariationRegistry(workspace.projectDir, blockSlug, variationSlug);
148
+ await ensureVariationRegistrationHook(blockIndexPath);
149
+ await appendWorkspaceInventoryEntries(workspace.projectDir, {
150
+ variationEntries: [buildVariationConfigEntry(blockSlug, variationSlug)],
151
+ });
152
+ return {
153
+ blockSlug,
154
+ projectDir: workspace.projectDir,
155
+ variationSlug,
156
+ };
157
+ }
158
+ catch (error) {
159
+ await rollbackWorkspaceMutation(mutationSnapshot);
160
+ throw error;
161
+ }
162
+ }
@@ -1,136 +1,71 @@
1
- import type { HookedBlockPositionId } from "./hooked-blocks.js";
2
- import { type RunAddBlockStyleCommandOptions, type RunAddBlockTransformCommandOptions, type RunAddHookedBlockCommandOptions, type RunAddVariationCommandOptions } from "./cli-add-shared.js";
1
+ /**
2
+ * Compatibility facade for workspace add commands.
3
+ *
4
+ * Keep the public runtime import path stable while each workflow lives in a
5
+ * focused implementation module.
6
+ */
7
+ /**
8
+ * Re-export the typed workflow ability scaffold workflow from the focused
9
+ * ability runtime helper module.
10
+ */
11
+ export { runAddAbilityCommand } from "./cli-add-workspace-ability.js";
3
12
  /**
4
13
  * Re-export the DataViews admin screen scaffold workflow from the focused
5
14
  * admin-view runtime helper module.
6
15
  */
7
- export { runAddAdminViewCommand, } from "./cli-add-workspace-admin-view.js";
16
+ export { runAddAdminViewCommand } from "./cli-add-workspace-admin-view.js";
17
+ /**
18
+ * Re-export the server-only AI feature scaffold workflow from the focused
19
+ * AI-feature runtime helper module.
20
+ */
21
+ export { runAddAiFeatureCommand } from "./cli-add-workspace-ai.js";
8
22
  /**
9
23
  * Re-export focused workspace asset scaffold commands from the companion
10
24
  * `cli-add-workspace-assets` module.
11
25
  */
12
- export { runAddEditorPluginCommand, runAddBindingSourceCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
26
+ export { runAddBindingSourceCommand, runAddEditorPluginCommand, runAddPatternCommand, } from "./cli-add-workspace-assets.js";
13
27
  /**
14
- * Re-export the local integration environment scaffold workflow from the
15
- * focused integration-env runtime helper module.
28
+ * Re-export the block style scaffold workflow from the focused block-style
29
+ * runtime helper module.
16
30
  */
17
- export { runAddIntegrationEnvCommand } from "./cli-add-workspace-integration-env.js";
31
+ export { runAddBlockStyleCommand } from "./cli-add-workspace-block-style.js";
18
32
  /**
19
- * Re-export the plugin-level REST resource scaffold workflow from the focused
20
- * rest-resource runtime helper module.
33
+ * Re-export the block transform scaffold workflow from the focused
34
+ * block-transform runtime helper module.
21
35
  */
22
- export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
36
+ export { runAddBlockTransformCommand, } from "./cli-add-workspace-block-transform.js";
23
37
  /**
24
38
  * Re-export the standalone contract scaffold workflow from the focused
25
39
  * contract runtime helper module.
26
40
  */
27
41
  export { runAddContractCommand } from "./cli-add-workspace-contract.js";
28
42
  /**
29
- * Re-export the typed post-meta contract scaffold workflow from the focused
30
- * post-meta runtime helper module.
43
+ * Re-export the generic core/external block variation scaffold workflow from
44
+ * the focused core-variation runtime helper module.
31
45
  */
32
- export { runAddPostMetaCommand } from "./cli-add-workspace-post-meta.js";
46
+ export { runAddCoreVariationCommand } from "./cli-add-workspace-core-variation.js";
33
47
  /**
34
- * Re-export the typed workflow ability scaffold workflow from the focused
35
- * ability runtime helper module.
48
+ * Re-export the hooked-block scaffold workflow from the focused hooked-block
49
+ * runtime helper module.
36
50
  */
37
- export { runAddAbilityCommand } from "./cli-add-workspace-ability.js";
51
+ export { runAddHookedBlockCommand } from "./cli-add-workspace-hooked-block.js";
38
52
  /**
39
- * Re-export the server-only AI feature scaffold workflow from the focused
40
- * AI-feature runtime helper module.
41
- */
42
- export { runAddAiFeatureCommand } from "./cli-add-workspace-ai.js";
43
- /**
44
- * Add one variation entry to an existing workspace block.
45
- *
46
- * @param options Command options for the variation scaffold workflow.
47
- * @param options.blockName Target workspace block slug that will own the variation.
48
- * @param options.cwd Working directory used to resolve the nearest official workspace.
49
- * Defaults to `process.cwd()`.
50
- * @param options.variationName Human-entered variation name that will be normalized
51
- * and validated before files are written.
52
- * @returns A promise that resolves with the normalized `blockSlug`,
53
- * `variationSlug`, and owning `projectDir` after the variation files and
54
- * inventory entry have been written successfully.
55
- * @throws {Error} When the command is run outside an official workspace, when
56
- * the target block is unknown, when the variation slug is invalid, or when a
57
- * conflicting file or inventory entry already exists.
53
+ * Re-export the local integration environment scaffold workflow from the
54
+ * focused integration-env runtime helper module.
58
55
  */
59
- export declare function runAddVariationCommand({ blockName, cwd, variationName, }: RunAddVariationCommandOptions): Promise<{
60
- blockSlug: string;
61
- projectDir: string;
62
- variationSlug: string;
63
- }>;
56
+ export { runAddIntegrationEnvCommand } from "./cli-add-workspace-integration-env.js";
64
57
  /**
65
- * Add one Block Styles registration to an existing workspace block.
66
- *
67
- * @param options Command options for the Block Styles scaffold workflow.
68
- * @param options.blockName Target workspace block slug that will own the style.
69
- * @param options.cwd Working directory used to resolve the nearest official workspace.
70
- * Defaults to `process.cwd()`.
71
- * @param options.styleName Human-entered style name that will be normalized and
72
- * validated before files are written.
73
- * @returns A promise that resolves with the normalized `blockSlug`, `styleSlug`,
74
- * and owning `projectDir` after the style module, style registry, entrypoint
75
- * hook, and inventory entry have been written successfully.
76
- * @throws {Error} When the command is run outside an official workspace, when
77
- * the target block is unknown, when the style slug is invalid, or when a
78
- * conflicting file or inventory entry already exists.
58
+ * Re-export the typed post-meta contract scaffold workflow from the focused
59
+ * post-meta runtime helper module.
79
60
  */
80
- export declare function runAddBlockStyleCommand({ blockName, cwd, styleName, }: RunAddBlockStyleCommandOptions): Promise<{
81
- blockSlug: string;
82
- projectDir: string;
83
- styleSlug: string;
84
- }>;
61
+ export { runAddPostMetaCommand } from "./cli-add-workspace-post-meta.js";
85
62
  /**
86
- * Add one block-to-block transform registration to an existing workspace block.
87
- *
88
- * @param options Command options for the block transform scaffold workflow.
89
- * @param options.cwd Working directory used to resolve the nearest official workspace.
90
- * Defaults to `process.cwd()`.
91
- * @param options.fromBlockName Source block name for `--from`. This must be the
92
- * full `namespace/block` form because transforms may originate from WordPress
93
- * core or third-party blocks outside the workspace.
94
- * @param options.toBlockName Target block for `--to`. A workspace block slug is
95
- * resolved against the workspace namespace, while a full `namespace/block` name
96
- * must still point at an existing workspace block.
97
- * @param options.transformName Human-entered transform name that will be
98
- * normalized and validated before files are written.
99
- * @returns A promise that resolves with the normalized target `blockSlug`,
100
- * resolved `fromBlockName`, resolved `toBlockName`, `transformSlug`, and owning
101
- * `projectDir` after the transform module, transform registry, entrypoint hook,
102
- * and inventory entry have been written successfully.
103
- * @throws {Error} When the command is run outside an official workspace, when
104
- * the target block is unknown, when `--from` is not a full block name, when
105
- * `--to` uses a non-workspace namespace, when the target block entrypoint does
106
- * not expose `registration.settings`, when the transform slug is invalid, or
107
- * when a conflicting file or inventory entry already exists.
63
+ * Re-export the plugin-level REST resource scaffold workflow from the focused
64
+ * rest-resource runtime helper module.
108
65
  */
109
- export declare function runAddBlockTransformCommand({ cwd, fromBlockName, toBlockName, transformName, }: RunAddBlockTransformCommandOptions): Promise<{
110
- blockSlug: string;
111
- fromBlockName: string;
112
- projectDir: string;
113
- toBlockName: string;
114
- transformSlug: string;
115
- }>;
66
+ export { runAddRestResourceCommand } from "./cli-add-workspace-rest.js";
116
67
  /**
117
- * Add one `blockHooks` entry to an existing official workspace block.
118
- *
119
- * @param options Command options for the hooked-block workflow.
120
- * @param options.anchorBlockName Full block name that will anchor the insertion.
121
- * @param options.blockName Existing workspace block slug to patch.
122
- * @param options.cwd Working directory used to resolve the nearest official workspace.
123
- * Defaults to `process.cwd()`.
124
- * @param options.position Hook position to store in `block.json`.
125
- * @returns A promise that resolves with the normalized target block slug, anchor
126
- * block name, position, and owning project directory after `block.json` is written.
127
- * @throws {Error} When the command is run outside an official workspace, when
128
- * the target block is unknown, when required flags are missing, or when the
129
- * block already defines a hook for the requested anchor.
68
+ * Re-export the block variation scaffold workflow from the focused variation
69
+ * runtime helper module.
130
70
  */
131
- export declare function runAddHookedBlockCommand({ anchorBlockName, blockName, cwd, position, }: RunAddHookedBlockCommandOptions): Promise<{
132
- anchorBlockName: string;
133
- blockSlug: string;
134
- position: HookedBlockPositionId;
135
- projectDir: string;
136
- }>;
71
+ export { runAddVariationCommand } from "./cli-add-workspace-variation.js";