@wp-typia/project-tools 0.16.12 → 0.16.14

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 (34) hide show
  1. package/README.md +0 -1
  2. package/dist/runtime/block-generator-service-core.d.ts +8 -0
  3. package/dist/runtime/block-generator-service-core.js +274 -0
  4. package/dist/runtime/block-generator-service-spec.d.ts +104 -0
  5. package/dist/runtime/block-generator-service-spec.js +139 -0
  6. package/dist/runtime/block-generator-service.d.ts +2 -110
  7. package/dist/runtime/block-generator-service.js +2 -389
  8. package/dist/runtime/cli-diagnostics.js +76 -4
  9. package/dist/runtime/cli-doctor-workspace.d.ts +9 -5
  10. package/dist/runtime/cli-doctor-workspace.js +18 -6
  11. package/dist/runtime/cli-help.js +1 -1
  12. package/dist/runtime/cli-prompt.js +78 -19
  13. package/dist/runtime/cli-scaffold.d.ts +8 -1
  14. package/dist/runtime/cli-scaffold.js +47 -4
  15. package/dist/runtime/migration-maintenance-fixtures.d.ts +23 -0
  16. package/dist/runtime/migration-maintenance-fixtures.js +126 -0
  17. package/dist/runtime/migration-maintenance-verify.d.ts +26 -0
  18. package/dist/runtime/migration-maintenance-verify.js +262 -0
  19. package/dist/runtime/migration-maintenance.d.ts +2 -51
  20. package/dist/runtime/migration-maintenance.js +2 -380
  21. package/dist/runtime/migrations.d.ts +0 -3
  22. package/dist/runtime/scaffold-answer-resolution.d.ts +37 -0
  23. package/dist/runtime/scaffold-answer-resolution.js +138 -0
  24. package/dist/runtime/scaffold-apply-utils.d.ts +1 -7
  25. package/dist/runtime/scaffold-apply-utils.js +4 -105
  26. package/dist/runtime/scaffold-documents.d.ts +34 -0
  27. package/dist/runtime/scaffold-documents.js +144 -0
  28. package/dist/runtime/scaffold-onboarding.d.ts +12 -0
  29. package/dist/runtime/scaffold-onboarding.js +42 -5
  30. package/dist/runtime/scaffold-template-variables.d.ts +9 -0
  31. package/dist/runtime/scaffold-template-variables.js +111 -0
  32. package/dist/runtime/scaffold.d.ts +11 -9
  33. package/dist/runtime/scaffold.js +6 -202
  34. package/package.json +3 -3
@@ -1,230 +1,34 @@
1
1
  import fs from "node:fs";
2
2
  import { promises as fsp } from "node:fs";
3
3
  import path from "node:path";
4
- import { execSync } from "node:child_process";
5
- import { PACKAGE_MANAGER_IDS, getPackageManager, } from "./package-managers.js";
4
+ import { getPackageManager } from "./package-managers.js";
6
5
  import { buildGitignore, buildReadme, mergeTextLines, replaceTextRecursively, } from "./scaffold-apply-utils.js";
7
- import { buildBlockCssClassName, buildFrontendCssClassName, normalizeBlockSlug, resolveScaffoldIdentifiers, validateBlockSlug, validateNamespace, } from "./scaffold-identifiers.js";
8
6
  import { applyGeneratedProjectDxPackageJson, applyLocalDevPresetFiles, } from "./local-dev-presets.js";
9
7
  import { applyMigrationUiCapability } from "./migration-ui-capability.js";
10
- import { getPackageVersions } from "./package-versions.js";
11
8
  import { applyWorkspaceMigrationCapability, ensureScaffoldDirectory, isOfficialWorkspaceProject, seedBuiltInPersistenceArtifacts, writeStarterManifestFiles, } from "./scaffold-bootstrap.js";
12
9
  import { defaultInstallDependencies, normalizePackageJson, normalizePackageManagerFiles, removeUnexpectedLockfiles, } from "./scaffold-package-manager-files.js";
13
- import { toPascalCase, toSnakeCase, toTitleCase, } from "./string-case.js";
14
- import { BUILTIN_BLOCK_METADATA_VERSION, COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS, getBuiltInTemplateMetadataDefaults, getRemovedBuiltInTemplateMessage, isRemovedBuiltInTemplateId, } from "./template-defaults.js";
15
10
  import { copyInterpolatedDirectory } from "./template-render.js";
16
- import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, TEMPLATE_IDS, getTemplateById, isBuiltInTemplateId, } from "./template-registry.js";
11
+ import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
17
12
  import { resolveTemplateSource } from "./template-source.js";
18
- import { BlockGeneratorService, buildTemplateVariablesFromBlockSpec, createBuiltInBlockSpec, } from "./block-generator-service.js";
13
+ import { BlockGeneratorService, } from "./block-generator-service.js";
14
+ import { getTemplateVariables } from "./scaffold-template-variables.js";
19
15
  const WORKSPACE_TEMPLATE_ALIAS = "workspace";
20
16
  export const DATA_STORAGE_MODES = ["post-meta", "custom-table"];
21
17
  export const PERSISTENCE_POLICIES = ["authenticated", "public"];
22
18
  export { buildBlockCssClassName } from "./scaffold-identifiers.js";
19
+ export { collectScaffoldAnswers, detectAuthor, getDefaultAnswers, resolvePackageManagerId, resolveTemplateId, } from "./scaffold-answer-resolution.js";
20
+ export { getTemplateVariables } from "./scaffold-template-variables.js";
23
21
  export function isDataStorageMode(value) {
24
22
  return DATA_STORAGE_MODES.includes(value);
25
23
  }
26
24
  export function isPersistencePolicy(value) {
27
25
  return PERSISTENCE_POLICIES.includes(value);
28
26
  }
29
- export function detectAuthor() {
30
- try {
31
- return (execSync("git config user.name", {
32
- encoding: "utf8",
33
- stdio: ["ignore", "pipe", "ignore"],
34
- }).trim() || "Your Name");
35
- }
36
- catch {
37
- return "Your Name";
38
- }
39
- }
40
- export function getDefaultAnswers(projectName, templateId) {
41
- const template = isBuiltInTemplateId(templateId) ? getTemplateById(templateId) : null;
42
- const slugDefault = normalizeBlockSlug(projectName) || "my-wp-typia-block";
43
- return {
44
- author: detectAuthor(),
45
- dataStorageMode: templateId === "persistence" ? "custom-table" : undefined,
46
- description: template?.description ?? "A WordPress block scaffolded from a remote template",
47
- namespace: slugDefault,
48
- persistencePolicy: templateId === "persistence" ? "authenticated" : undefined,
49
- phpPrefix: toSnakeCase(slugDefault),
50
- slug: slugDefault,
51
- textDomain: slugDefault,
52
- title: toTitleCase(slugDefault),
53
- };
54
- }
55
27
  function normalizeTemplateSelection(templateId) {
56
28
  return templateId === WORKSPACE_TEMPLATE_ALIAS
57
29
  ? OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE
58
30
  : templateId;
59
31
  }
60
- export async function resolveTemplateId({ templateId, yes = false, isInteractive = false, selectTemplate, }) {
61
- if (templateId) {
62
- const normalizedTemplateId = normalizeTemplateSelection(templateId);
63
- if (isRemovedBuiltInTemplateId(templateId)) {
64
- throw new Error(getRemovedBuiltInTemplateMessage(templateId));
65
- }
66
- if (isBuiltInTemplateId(normalizedTemplateId)) {
67
- return getTemplateById(normalizedTemplateId).id;
68
- }
69
- return normalizedTemplateId;
70
- }
71
- if (yes) {
72
- return "basic";
73
- }
74
- if (!isInteractive || !selectTemplate) {
75
- throw new Error(`Template is required in non-interactive mode. Use --template <${TEMPLATE_IDS.join("|")}|./path|github:owner/repo/path[#ref]|npm-package>.`);
76
- }
77
- return normalizeTemplateSelection(await selectTemplate());
78
- }
79
- export async function resolvePackageManagerId({ packageManager, yes = false, isInteractive = false, selectPackageManager, }) {
80
- if (packageManager) {
81
- return getPackageManager(packageManager).id;
82
- }
83
- if (yes) {
84
- throw new Error(`Package manager is required when using --yes. Use --package-manager <${PACKAGE_MANAGER_IDS.join("|")}>.`);
85
- }
86
- if (!isInteractive || !selectPackageManager) {
87
- throw new Error(`Package manager is required in non-interactive mode. Use --package-manager <${PACKAGE_MANAGER_IDS.join("|")}>.`);
88
- }
89
- return selectPackageManager();
90
- }
91
- export async function collectScaffoldAnswers({ projectName, templateId, yes = false, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, textDomain, }) {
92
- const defaults = getDefaultAnswers(projectName, templateId);
93
- if (yes) {
94
- const identifiers = resolveScaffoldIdentifiers({
95
- namespace: namespace ?? defaults.namespace,
96
- phpPrefix,
97
- slug: defaults.slug,
98
- textDomain,
99
- });
100
- return {
101
- ...defaults,
102
- dataStorageMode: dataStorageMode ?? defaults.dataStorageMode,
103
- namespace: identifiers.namespace,
104
- persistencePolicy: persistencePolicy ?? defaults.persistencePolicy,
105
- phpPrefix: identifiers.phpPrefix,
106
- textDomain: identifiers.textDomain,
107
- };
108
- }
109
- if (!promptText) {
110
- throw new Error("Interactive answers require a promptText callback.");
111
- }
112
- const identifiers = resolveScaffoldIdentifiers({
113
- namespace: namespace ?? (await promptText("Namespace", defaults.namespace, validateNamespace)),
114
- phpPrefix,
115
- slug: await promptText("Block slug", defaults.slug, validateBlockSlug),
116
- textDomain,
117
- });
118
- return {
119
- author: await promptText("Author", defaults.author),
120
- dataStorageMode: dataStorageMode ?? defaults.dataStorageMode,
121
- description: await promptText("Description", defaults.description),
122
- namespace: identifiers.namespace,
123
- persistencePolicy: persistencePolicy ?? defaults.persistencePolicy,
124
- phpPrefix: identifiers.phpPrefix,
125
- slug: identifiers.slug,
126
- textDomain: identifiers.textDomain,
127
- title: await promptText("Block title", toTitleCase(identifiers.slug)),
128
- };
129
- }
130
- export function getTemplateVariables(templateId, answers) {
131
- if (isBuiltInTemplateId(templateId)) {
132
- return buildTemplateVariablesFromBlockSpec(createBuiltInBlockSpec({
133
- answers,
134
- dataStorageMode: answers.dataStorageMode,
135
- persistencePolicy: answers.persistencePolicy,
136
- templateId,
137
- }));
138
- }
139
- const { apiClientPackageVersion, blockRuntimePackageVersion, blockTypesPackageVersion, projectToolsPackageVersion, restPackageVersion, } = getPackageVersions();
140
- const template = isBuiltInTemplateId(templateId) ? getTemplateById(templateId) : null;
141
- const metadataDefaults = isBuiltInTemplateId(templateId)
142
- ? getBuiltInTemplateMetadataDefaults(templateId)
143
- : null;
144
- const identifiers = resolveScaffoldIdentifiers({
145
- namespace: answers.namespace,
146
- phpPrefix: answers.phpPrefix,
147
- slug: answers.slug,
148
- textDomain: answers.textDomain,
149
- });
150
- const slug = identifiers.slug;
151
- const slugSnakeCase = toSnakeCase(slug);
152
- const pascalCase = toPascalCase(slug);
153
- const title = answers.title.trim();
154
- const namespace = identifiers.namespace;
155
- const description = answers.description.trim();
156
- const textDomain = identifiers.textDomain;
157
- const phpPrefix = identifiers.phpPrefix;
158
- const phpPrefixUpper = phpPrefix.toUpperCase();
159
- const compoundChildTitle = `${title} Item`;
160
- const cssClassName = buildBlockCssClassName(namespace, slug);
161
- const compoundChildCssClassName = buildBlockCssClassName(namespace, `${slug}-item`);
162
- const compoundPersistenceEnabled = templateId === "persistence"
163
- ? true
164
- : templateId === "compound"
165
- ? Boolean(answers.dataStorageMode || answers.persistencePolicy)
166
- : false;
167
- const dataStorageMode = templateId === "persistence" || compoundPersistenceEnabled
168
- ? answers.dataStorageMode ?? "custom-table"
169
- : "custom-table";
170
- const persistencePolicy = templateId === "persistence" || compoundPersistenceEnabled
171
- ? answers.persistencePolicy ?? "authenticated"
172
- : "authenticated";
173
- return {
174
- apiClientPackageVersion,
175
- author: answers.author.trim(),
176
- blockRuntimePackageVersion,
177
- blockMetadataVersion: BUILTIN_BLOCK_METADATA_VERSION,
178
- blockTypesPackageVersion,
179
- category: metadataDefaults?.category ?? template?.defaultCategory ?? "widgets",
180
- icon: metadataDefaults?.icon ?? "smiley",
181
- compoundChildTitle,
182
- compoundChildCategory: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.category,
183
- compoundChildCssClassName,
184
- compoundChildIcon: COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS.icon,
185
- compoundChildTitleJson: JSON.stringify(compoundChildTitle),
186
- compoundPersistenceEnabled: compoundPersistenceEnabled ? "true" : "false",
187
- projectToolsPackageVersion,
188
- cssClassName,
189
- dataStorageMode,
190
- dashCase: slug,
191
- description,
192
- frontendCssClassName: buildFrontendCssClassName(cssClassName),
193
- isAuthenticatedPersistencePolicy: persistencePolicy === "authenticated" ? "true" : "false",
194
- isPublicPersistencePolicy: persistencePolicy === "public" ? "true" : "false",
195
- bootstrapCredentialDeclarations: persistencePolicy === "public"
196
- ? "publicWriteExpiresAt?: number & tags.Type< 'uint32' >;\n\tpublicWriteToken?: string & tags.MinLength< 1 > & tags.MaxLength< 512 >;"
197
- : "restNonce?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
198
- persistencePolicyDescriptionJson: JSON.stringify(persistencePolicy === "authenticated"
199
- ? "Writes require a logged-in user and a valid REST nonce."
200
- : "Anonymous writes use signed short-lived public tokens, per-request ids, and coarse rate limiting."),
201
- keyword: slug.replace(/-/g, " "),
202
- namespace,
203
- needsMigration: "{{needsMigration}}",
204
- pascalCase,
205
- phpPrefix,
206
- phpPrefixUpper,
207
- restPackageVersion,
208
- publicWriteRequestIdDeclaration: persistencePolicy === "public"
209
- ? "publicWriteRequestId: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;"
210
- : "publicWriteRequestId?: string & tags.MinLength< 1 > & tags.MaxLength< 128 >;",
211
- restWriteAuthIntent: persistencePolicy === "public"
212
- ? "public-write-protected"
213
- : "authenticated",
214
- restWriteAuthMechanism: persistencePolicy === "public" ? "public-signed-token" : "rest-nonce",
215
- restWriteAuthMode: persistencePolicy === "public" ? "public-signed-token" : "authenticated-rest-nonce",
216
- slug,
217
- slugCamelCase: pascalCase.charAt(0).toLowerCase() + pascalCase.slice(1),
218
- slugKebabCase: slug,
219
- slugSnakeCase,
220
- textDomain,
221
- textdomain: textDomain,
222
- title,
223
- titleJson: JSON.stringify(title),
224
- titleCase: pascalCase,
225
- persistencePolicy,
226
- };
227
- }
228
32
  export async function scaffoldProject({ projectDir, templateId, answers, dataStorageMode, persistencePolicy, packageManager, externalLayerId, externalLayerSource, externalLayerSourceLabel, repositoryReference, cwd = process.cwd(), allowExistingDir = false, noInstall = false, installDependencies = undefined, variant, withMigrationUi = false, withTestPreset = false, withWpEnv = false, }) {
229
33
  const resolvedTemplateId = normalizeTemplateSelection(templateId);
230
34
  const resolvedPackageManager = getPackageManager(packageManager).id;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wp-typia/project-tools",
3
- "version": "0.16.12",
3
+ "version": "0.16.14",
4
4
  "description": "Project orchestration and programmatic tooling for wp-typia",
5
5
  "packageManager": "bun@1.3.11",
6
6
  "type": "module",
@@ -120,8 +120,8 @@
120
120
  },
121
121
  "dependencies": {
122
122
  "@wp-typia/api-client": "^0.4.5",
123
- "@wp-typia/block-runtime": "^0.4.9",
124
- "@wp-typia/rest": "^0.3.9",
123
+ "@wp-typia/block-runtime": "^0.4.10",
124
+ "@wp-typia/rest": "^0.3.10",
125
125
  "@wp-typia/block-types": "^0.2.4",
126
126
  "mustache": "^4.2.0",
127
127
  "npm-package-arg": "^13.0.0",