@wp-typia/project-tools 0.16.11 → 0.16.13
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/README.md +9 -3
- package/dist/runtime/block-generator-service-core.d.ts +8 -0
- package/dist/runtime/block-generator-service-core.js +274 -0
- package/dist/runtime/block-generator-service-spec.d.ts +104 -0
- package/dist/runtime/block-generator-service-spec.js +139 -0
- package/dist/runtime/block-generator-service.d.ts +2 -110
- package/dist/runtime/block-generator-service.js +2 -389
- package/dist/runtime/built-in-block-artifact-documents.d.ts +3 -0
- package/dist/runtime/built-in-block-artifact-documents.js +2 -0
- package/dist/runtime/built-in-block-artifact-types.d.ts +51 -0
- package/dist/runtime/built-in-block-artifact-types.js +304 -0
- package/dist/runtime/built-in-block-artifacts.js +4 -803
- package/dist/runtime/built-in-block-attribute-emitters.d.ts +71 -0
- package/dist/runtime/built-in-block-attribute-emitters.js +176 -0
- package/dist/runtime/built-in-block-attribute-specs.d.ts +38 -0
- package/dist/runtime/built-in-block-attribute-specs.js +358 -0
- package/dist/runtime/built-in-block-code-templates/basic.d.ts +4 -0
- package/dist/runtime/built-in-block-code-templates/basic.js +249 -0
- package/dist/runtime/built-in-block-code-templates/compound-child.d.ts +4 -0
- package/dist/runtime/built-in-block-code-templates/compound-child.js +138 -0
- package/dist/runtime/built-in-block-code-templates/compound-parent.d.ts +6 -0
- package/dist/runtime/built-in-block-code-templates/compound-parent.js +227 -0
- package/dist/runtime/built-in-block-code-templates/compound-persistence.d.ts +4 -0
- package/dist/runtime/built-in-block-code-templates/compound-persistence.js +478 -0
- package/dist/runtime/built-in-block-code-templates/compound.d.ts +3 -0
- package/dist/runtime/built-in-block-code-templates/compound.js +3 -0
- package/dist/runtime/built-in-block-code-templates/interactivity.d.ts +5 -0
- package/dist/runtime/built-in-block-code-templates/interactivity.js +547 -0
- package/dist/runtime/built-in-block-code-templates/persistence.d.ts +5 -0
- package/dist/runtime/built-in-block-code-templates/persistence.js +550 -0
- package/dist/runtime/built-in-block-code-templates/shared.d.ts +16 -0
- package/dist/runtime/built-in-block-code-templates/shared.js +53 -0
- package/dist/runtime/built-in-block-code-templates.d.ts +5 -32
- package/dist/runtime/built-in-block-code-templates.js +5 -2230
- package/dist/runtime/cli-add-block-config.d.ts +6 -0
- package/dist/runtime/cli-add-block-config.js +143 -0
- package/dist/runtime/cli-add-block-legacy-validator.d.ts +4 -0
- package/dist/runtime/cli-add-block-legacy-validator.js +168 -0
- package/dist/runtime/cli-add-block.js +3 -301
- package/dist/runtime/cli-add-workspace-assets.d.ts +38 -0
- package/dist/runtime/cli-add-workspace-assets.js +399 -0
- package/dist/runtime/cli-add-workspace.d.ts +2 -38
- package/dist/runtime/cli-add-workspace.js +5 -396
- package/dist/runtime/cli-diagnostics.js +76 -4
- package/dist/runtime/cli-doctor-environment.d.ts +12 -0
- package/dist/runtime/cli-doctor-environment.js +123 -0
- package/dist/runtime/cli-doctor-workspace.d.ts +18 -0
- package/dist/runtime/cli-doctor-workspace.js +308 -0
- package/dist/runtime/cli-doctor.d.ts +4 -2
- package/dist/runtime/cli-doctor.js +10 -405
- package/dist/runtime/cli-help.js +1 -1
- package/dist/runtime/cli-scaffold.d.ts +8 -1
- package/dist/runtime/cli-scaffold.js +47 -4
- package/dist/runtime/migration-command-surface.d.ts +67 -0
- package/dist/runtime/migration-command-surface.js +189 -0
- package/dist/runtime/migration-diff-rename.d.ts +13 -0
- package/dist/runtime/migration-diff-rename.js +192 -0
- package/dist/runtime/migration-diff-transform.d.ts +14 -0
- package/dist/runtime/migration-diff-transform.js +105 -0
- package/dist/runtime/migration-diff.js +12 -297
- package/dist/runtime/migration-generated-artifacts.d.ts +3 -0
- package/dist/runtime/migration-generated-artifacts.js +41 -0
- package/dist/runtime/migration-maintenance-fixtures.d.ts +23 -0
- package/dist/runtime/migration-maintenance-fixtures.js +126 -0
- package/dist/runtime/migration-maintenance-verify.d.ts +26 -0
- package/dist/runtime/migration-maintenance-verify.js +262 -0
- package/dist/runtime/migration-maintenance.d.ts +2 -0
- package/dist/runtime/migration-maintenance.js +2 -0
- package/dist/runtime/migration-planning.d.ts +23 -0
- package/dist/runtime/migration-planning.js +131 -0
- package/dist/runtime/migration-project-config-source.d.ts +6 -0
- package/dist/runtime/migration-project-config-source.js +424 -0
- package/dist/runtime/migration-project-layout-discovery.d.ts +61 -0
- package/dist/runtime/migration-project-layout-discovery.js +337 -0
- package/dist/runtime/migration-project-layout-paths.d.ts +135 -0
- package/dist/runtime/migration-project-layout-paths.js +288 -0
- package/dist/runtime/migration-project-layout.d.ts +3 -0
- package/dist/runtime/migration-project-layout.js +2 -0
- package/dist/runtime/migration-project-workspace.d.ts +47 -0
- package/dist/runtime/migration-project-workspace.js +212 -0
- package/dist/runtime/migration-project.d.ts +4 -94
- package/dist/runtime/migration-project.js +3 -1101
- package/dist/runtime/migration-render-diff-rule.d.ts +5 -0
- package/dist/runtime/migration-render-diff-rule.js +120 -0
- package/dist/runtime/migration-render-execution.d.ts +3 -0
- package/dist/runtime/migration-render-execution.js +428 -0
- package/dist/runtime/migration-render-generated.d.ts +27 -0
- package/dist/runtime/migration-render-generated.js +230 -0
- package/dist/runtime/migration-render-support.d.ts +3 -0
- package/dist/runtime/migration-render-support.js +16 -0
- package/dist/runtime/migration-render.d.ts +3 -33
- package/dist/runtime/migration-render.js +3 -789
- package/dist/runtime/migrations.d.ts +24 -121
- package/dist/runtime/migrations.js +12 -700
- package/dist/runtime/scaffold-apply-utils.d.ts +9 -0
- package/dist/runtime/scaffold-apply-utils.js +27 -4
- package/dist/runtime/scaffold-bootstrap.d.ts +45 -0
- package/dist/runtime/scaffold-bootstrap.js +185 -0
- package/dist/runtime/scaffold-onboarding.d.ts +12 -0
- package/dist/runtime/scaffold-onboarding.js +42 -5
- package/dist/runtime/scaffold-package-manager-files.d.ts +35 -0
- package/dist/runtime/scaffold-package-manager-files.js +79 -0
- package/dist/runtime/scaffold.d.ts +1 -12
- package/dist/runtime/scaffold.js +11 -394
- package/dist/runtime/template-source-contracts.d.ts +81 -0
- package/dist/runtime/template-source-contracts.js +1 -0
- package/dist/runtime/template-source-external.d.ts +21 -0
- package/dist/runtime/template-source-external.js +184 -0
- package/dist/runtime/template-source-locators.d.ts +4 -0
- package/dist/runtime/template-source-locators.js +72 -0
- package/dist/runtime/template-source-normalization.d.ts +7 -0
- package/dist/runtime/template-source-normalization.js +53 -0
- package/dist/runtime/template-source-remote.d.ts +23 -0
- package/dist/runtime/template-source-remote.js +336 -0
- package/dist/runtime/template-source-seeds.d.ts +12 -0
- package/dist/runtime/template-source-seeds.js +243 -0
- package/dist/runtime/template-source.d.ts +4 -86
- package/dist/runtime/template-source.js +9 -828
- package/package.json +4 -4
|
@@ -8,6 +8,15 @@ export interface InstallDependenciesOptions {
|
|
|
8
8
|
projectDir: string;
|
|
9
9
|
}
|
|
10
10
|
export declare function ensureDirectory(targetDir: string, allowExisting?: boolean): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Builds the generated README markdown for one scaffolded project.
|
|
13
|
+
*
|
|
14
|
+
* @param templateId Scaffold template family or template identifier.
|
|
15
|
+
* @param variables Interpolated scaffold variables used in generated content.
|
|
16
|
+
* @param packageManager Package manager used to format install and script commands.
|
|
17
|
+
* @param options Optional README sections enabled by scaffold presets.
|
|
18
|
+
* @returns Markdown README content for the generated project root.
|
|
19
|
+
*/
|
|
11
20
|
export declare function buildReadme(templateId: string, variables: ScaffoldTemplateVariables, packageManager: PackageManagerId, { withMigrationUi, withTestPreset, withWpEnv, }?: {
|
|
12
21
|
withMigrationUi?: boolean;
|
|
13
22
|
withTestPreset?: boolean;
|
|
@@ -8,7 +8,7 @@ import { applyMigrationUiCapability } from "./migration-ui-capability.js";
|
|
|
8
8
|
import { getPackageVersions } from "./package-versions.js";
|
|
9
9
|
import { ensureMigrationDirectories, writeInitialMigrationScaffold, writeMigrationConfig, } from "./migration-project.js";
|
|
10
10
|
import { syncPersistenceRestArtifacts, } from "./persistence-rest-artifacts.js";
|
|
11
|
-
import { getCompoundExtensionWorkflowSection, getOptionalOnboardingNote, getOptionalOnboardingSteps, getPhpRestExtensionPointsSection, getTemplateSourceOfTruthNote, } from "./scaffold-onboarding.js";
|
|
11
|
+
import { getCompoundExtensionWorkflowSection, getInitialCommitCommands, getInitialCommitNote, getOptionalOnboardingNote, getOptionalOnboardingSteps, getQuickStartWorkflowNote, getPhpRestExtensionPointsSection, getTemplateSourceOfTruthNote, } from "./scaffold-onboarding.js";
|
|
12
12
|
import { getStarterManifestFiles, stringifyStarterManifest, } from "./starter-manifests.js";
|
|
13
13
|
import { stringifyBuiltInBlockJsonDocument, } from "./built-in-block-artifacts.js";
|
|
14
14
|
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, } from "./template-registry.js";
|
|
@@ -36,10 +36,20 @@ export async function ensureDirectory(targetDir, allowExisting = false) {
|
|
|
36
36
|
throw new Error(`Target directory is not empty: ${targetDir}`);
|
|
37
37
|
}
|
|
38
38
|
}
|
|
39
|
+
/**
|
|
40
|
+
* Builds the generated README markdown for one scaffolded project.
|
|
41
|
+
*
|
|
42
|
+
* @param templateId Scaffold template family or template identifier.
|
|
43
|
+
* @param variables Interpolated scaffold variables used in generated content.
|
|
44
|
+
* @param packageManager Package manager used to format install and script commands.
|
|
45
|
+
* @param options Optional README sections enabled by scaffold presets.
|
|
46
|
+
* @returns Markdown README content for the generated project root.
|
|
47
|
+
*/
|
|
39
48
|
export function buildReadme(templateId, variables, packageManager, { withMigrationUi = false, withTestPreset = false, withWpEnv = false, } = {}) {
|
|
40
49
|
const optionalOnboardingSteps = getOptionalOnboardingSteps(packageManager, templateId, {
|
|
41
50
|
compoundPersistenceEnabled: variables.compoundPersistenceEnabled === "true",
|
|
42
51
|
});
|
|
52
|
+
const initialCommitCommands = getInitialCommitCommands();
|
|
43
53
|
const sourceOfTruthNote = getTemplateSourceOfTruthNote(templateId, {
|
|
44
54
|
compoundPersistenceEnabled: variables.compoundPersistenceEnabled === "true",
|
|
45
55
|
});
|
|
@@ -70,20 +80,25 @@ ${variables.description}
|
|
|
70
80
|
|
|
71
81
|
${templateId}
|
|
72
82
|
|
|
73
|
-
##
|
|
83
|
+
## Quick Start
|
|
74
84
|
|
|
75
85
|
\`\`\`bash
|
|
76
86
|
${formatInstallCommand(packageManager)}
|
|
77
87
|
${formatRunScript(packageManager, developmentScript)}
|
|
78
88
|
\`\`\`
|
|
79
89
|
|
|
80
|
-
|
|
90
|
+
${getQuickStartWorkflowNote(packageManager, templateId, {
|
|
91
|
+
compoundPersistenceEnabled,
|
|
92
|
+
})}
|
|
93
|
+
|
|
94
|
+
## Build and Verify
|
|
81
95
|
|
|
82
96
|
\`\`\`bash
|
|
83
97
|
${formatRunScript(packageManager, "build")}
|
|
98
|
+
${formatRunScript(packageManager, "typecheck")}
|
|
84
99
|
\`\`\`
|
|
85
100
|
|
|
86
|
-
##
|
|
101
|
+
## Advanced Sync
|
|
87
102
|
|
|
88
103
|
\`\`\`bash
|
|
89
104
|
${optionalOnboardingSteps.join("\n")}
|
|
@@ -93,6 +108,14 @@ ${getOptionalOnboardingNote(packageManager, templateId, {
|
|
|
93
108
|
compoundPersistenceEnabled,
|
|
94
109
|
})}
|
|
95
110
|
|
|
111
|
+
## Before First Commit
|
|
112
|
+
|
|
113
|
+
\`\`\`bash
|
|
114
|
+
${initialCommitCommands.join("\n")}
|
|
115
|
+
\`\`\`
|
|
116
|
+
|
|
117
|
+
${getInitialCommitNote()}
|
|
118
|
+
|
|
96
119
|
${sourceOfTruthNote}${publicPersistencePolicyNote ? `\n\n${publicPersistencePolicyNote}` : ""}${migrationSection ? `\n\n${migrationSection}` : ""}${compoundExtensionWorkflowSection ? `\n\n${compoundExtensionWorkflowSection}` : ""}${wpEnvSection ? `\n\n${wpEnvSection}` : ""}${testPresetSection ? `\n\n${testPresetSection}` : ""}${phpRestExtensionPointsSection ? `\n\n${phpRestExtensionPointsSection}` : ""}
|
|
97
120
|
`;
|
|
98
121
|
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import type { PackageManagerId } from "./package-managers.js";
|
|
2
|
+
import type { ScaffoldTemplateVariables } from "./scaffold.js";
|
|
3
|
+
import type { BuiltInTemplateId } from "./template-registry.js";
|
|
4
|
+
/**
|
|
5
|
+
* Ensures the scaffold target directory exists and is empty unless explicitly allowed.
|
|
6
|
+
*
|
|
7
|
+
* @param targetDir Absolute project directory that will receive scaffold output.
|
|
8
|
+
* @param allowExisting Whether an existing non-empty directory should be accepted.
|
|
9
|
+
* @returns A promise that resolves once the directory precondition is satisfied.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureScaffoldDirectory(targetDir: string, allowExisting?: boolean): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Writes built-in starter manifest files into a scaffolded project.
|
|
14
|
+
*
|
|
15
|
+
* @param targetDir Absolute scaffold target directory.
|
|
16
|
+
* @param templateId Built-in template id being scaffolded.
|
|
17
|
+
* @param variables Resolved scaffold template variables.
|
|
18
|
+
* @returns A promise that resolves after all starter manifests are written.
|
|
19
|
+
*/
|
|
20
|
+
export declare function writeStarterManifestFiles(targetDir: string, templateId: string, variables: ScaffoldTemplateVariables): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Seed REST-derived persistence artifacts into a newly scaffolded built-in
|
|
23
|
+
* project before the first manual `sync-rest` run.
|
|
24
|
+
*
|
|
25
|
+
* @param targetDir Absolute scaffold target directory.
|
|
26
|
+
* @param templateId Built-in template id being scaffolded.
|
|
27
|
+
* @param variables Resolved scaffold template variables for the project.
|
|
28
|
+
* @returns A promise that resolves after any required persistence artifacts are generated.
|
|
29
|
+
*/
|
|
30
|
+
export declare function seedBuiltInPersistenceArtifacts(targetDir: string, templateId: BuiltInTemplateId, variables: ScaffoldTemplateVariables): Promise<void>;
|
|
31
|
+
/**
|
|
32
|
+
* Detects whether a scaffolded project is the official workspace template.
|
|
33
|
+
*
|
|
34
|
+
* @param projectDir Absolute scaffold target directory.
|
|
35
|
+
* @returns `true` when the project metadata identifies the official workspace template.
|
|
36
|
+
*/
|
|
37
|
+
export declare function isOfficialWorkspaceProject(projectDir: string): boolean;
|
|
38
|
+
/**
|
|
39
|
+
* Adds migration scripts and starter workspace files to the official workspace template.
|
|
40
|
+
*
|
|
41
|
+
* @param projectDir Absolute scaffold target directory.
|
|
42
|
+
* @param packageManager Package manager used for generated script commands.
|
|
43
|
+
* @returns A promise that resolves after scripts and migration starter files are written.
|
|
44
|
+
*/
|
|
45
|
+
export declare function applyWorkspaceMigrationCapability(projectDir: string, packageManager: PackageManagerId): Promise<void>;
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { promises as fsp } from "node:fs";
|
|
3
|
+
import path from "node:path";
|
|
4
|
+
import { formatPackageExecCommand } from "./package-managers.js";
|
|
5
|
+
import { ensureMigrationDirectories, writeInitialMigrationScaffold, writeMigrationConfig, } from "./migration-project.js";
|
|
6
|
+
import { syncPersistenceRestArtifacts } from "./persistence-rest-artifacts.js";
|
|
7
|
+
import { getPackageVersions } from "./package-versions.js";
|
|
8
|
+
import { getStarterManifestFiles, stringifyStarterManifest } from "./starter-manifests.js";
|
|
9
|
+
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, PROJECT_TOOLS_PACKAGE_ROOT, } from "./template-registry.js";
|
|
10
|
+
const EPHEMERAL_NODE_MODULES_LINK_TYPE = process.platform === "win32" ? "junction" : "dir";
|
|
11
|
+
/**
|
|
12
|
+
* Ensures the scaffold target directory exists and is empty unless explicitly allowed.
|
|
13
|
+
*
|
|
14
|
+
* @param targetDir Absolute project directory that will receive scaffold output.
|
|
15
|
+
* @param allowExisting Whether an existing non-empty directory should be accepted.
|
|
16
|
+
* @returns A promise that resolves once the directory precondition is satisfied.
|
|
17
|
+
*/
|
|
18
|
+
export async function ensureScaffoldDirectory(targetDir, allowExisting = false) {
|
|
19
|
+
if (!fs.existsSync(targetDir)) {
|
|
20
|
+
await fsp.mkdir(targetDir, { recursive: true });
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
if (allowExisting) {
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const entries = await fsp.readdir(targetDir);
|
|
27
|
+
if (entries.length > 0) {
|
|
28
|
+
throw new Error(`Target directory is not empty: ${targetDir}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Writes built-in starter manifest files into a scaffolded project.
|
|
33
|
+
*
|
|
34
|
+
* @param targetDir Absolute scaffold target directory.
|
|
35
|
+
* @param templateId Built-in template id being scaffolded.
|
|
36
|
+
* @param variables Resolved scaffold template variables.
|
|
37
|
+
* @returns A promise that resolves after all starter manifests are written.
|
|
38
|
+
*/
|
|
39
|
+
export async function writeStarterManifestFiles(targetDir, templateId, variables) {
|
|
40
|
+
const manifests = getStarterManifestFiles(templateId, variables);
|
|
41
|
+
for (const { document, relativePath } of manifests) {
|
|
42
|
+
const destinationPath = path.join(targetDir, relativePath);
|
|
43
|
+
await fsp.mkdir(path.dirname(destinationPath), { recursive: true });
|
|
44
|
+
await fsp.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Seed REST-derived persistence artifacts into a newly scaffolded built-in
|
|
49
|
+
* project before the first manual `sync-rest` run.
|
|
50
|
+
*
|
|
51
|
+
* @param targetDir Absolute scaffold target directory.
|
|
52
|
+
* @param templateId Built-in template id being scaffolded.
|
|
53
|
+
* @param variables Resolved scaffold template variables for the project.
|
|
54
|
+
* @returns A promise that resolves after any required persistence artifacts are generated.
|
|
55
|
+
*/
|
|
56
|
+
export async function seedBuiltInPersistenceArtifacts(targetDir, templateId, variables) {
|
|
57
|
+
const needsPersistenceArtifacts = templateId === "persistence" ||
|
|
58
|
+
(templateId === "compound" && variables.compoundPersistenceEnabled === "true");
|
|
59
|
+
if (!needsPersistenceArtifacts) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
await withEphemeralScaffoldNodeModules(targetDir, async () => {
|
|
63
|
+
if (templateId === "persistence") {
|
|
64
|
+
await syncPersistenceRestArtifacts({
|
|
65
|
+
apiTypesFile: path.join("src", "api-types.ts"),
|
|
66
|
+
outputDir: "src",
|
|
67
|
+
projectDir: targetDir,
|
|
68
|
+
variables,
|
|
69
|
+
});
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
await syncPersistenceRestArtifacts({
|
|
73
|
+
apiTypesFile: path.join("src", "blocks", variables.slugKebabCase, "api-types.ts"),
|
|
74
|
+
outputDir: path.join("src", "blocks", variables.slugKebabCase),
|
|
75
|
+
projectDir: targetDir,
|
|
76
|
+
variables,
|
|
77
|
+
});
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Detects whether a scaffolded project is the official workspace template.
|
|
82
|
+
*
|
|
83
|
+
* @param projectDir Absolute scaffold target directory.
|
|
84
|
+
* @returns `true` when the project metadata identifies the official workspace template.
|
|
85
|
+
*/
|
|
86
|
+
export function isOfficialWorkspaceProject(projectDir) {
|
|
87
|
+
const packageJsonPath = path.join(projectDir, "package.json");
|
|
88
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, "utf8"));
|
|
92
|
+
return (packageJson.wpTypia?.projectType === "workspace" &&
|
|
93
|
+
packageJson.wpTypia?.templatePackage === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE);
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Adds migration scripts and starter workspace files to the official workspace template.
|
|
97
|
+
*
|
|
98
|
+
* @param projectDir Absolute scaffold target directory.
|
|
99
|
+
* @param packageManager Package manager used for generated script commands.
|
|
100
|
+
* @returns A promise that resolves after scripts and migration starter files are written.
|
|
101
|
+
*/
|
|
102
|
+
export async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
|
|
103
|
+
const packageJsonPath = path.join(projectDir, "package.json");
|
|
104
|
+
const packageJson = JSON.parse(await fsp.readFile(packageJsonPath, "utf8"));
|
|
105
|
+
const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
|
|
106
|
+
const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0"
|
|
107
|
+
? "wp-typia"
|
|
108
|
+
: `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
|
|
109
|
+
const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
|
|
110
|
+
packageJson.scripts = {
|
|
111
|
+
...(packageJson.scripts ?? {}),
|
|
112
|
+
"migration:init": migrationCli("init --current-migration-version v1"),
|
|
113
|
+
"migration:snapshot": migrationCli("snapshot"),
|
|
114
|
+
"migration:diff": migrationCli("diff"),
|
|
115
|
+
"migration:scaffold": migrationCli("scaffold"),
|
|
116
|
+
"migration:doctor": migrationCli("doctor --all"),
|
|
117
|
+
"migration:fixtures": migrationCli("fixtures --all"),
|
|
118
|
+
"migration:verify": migrationCli("verify --all"),
|
|
119
|
+
"migration:fuzz": migrationCli("fuzz --all"),
|
|
120
|
+
};
|
|
121
|
+
await fsp.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}\n`, "utf8");
|
|
122
|
+
writeMigrationConfig(projectDir, {
|
|
123
|
+
blocks: [],
|
|
124
|
+
currentMigrationVersion: "v1",
|
|
125
|
+
snapshotDir: "src/migrations/versions",
|
|
126
|
+
supportedMigrationVersions: ["v1"],
|
|
127
|
+
});
|
|
128
|
+
ensureMigrationDirectories(projectDir, []);
|
|
129
|
+
writeInitialMigrationScaffold(projectDir, "v1", []);
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Locate a node_modules directory containing `typia` relative to the project
|
|
133
|
+
* tools package root.
|
|
134
|
+
*
|
|
135
|
+
* Search order:
|
|
136
|
+
* 1. `PROJECT_TOOLS_PACKAGE_ROOT/node_modules`
|
|
137
|
+
* 2. The monorepo root resolved from `PROJECT_TOOLS_PACKAGE_ROOT`
|
|
138
|
+
* 3. The monorepo root `node_modules`
|
|
139
|
+
*
|
|
140
|
+
* @returns The first matching path, or `null` when no candidate contains `typia`.
|
|
141
|
+
*/
|
|
142
|
+
function resolveScaffoldGeneratorNodeModulesPath() {
|
|
143
|
+
const candidates = [
|
|
144
|
+
path.join(PROJECT_TOOLS_PACKAGE_ROOT, "node_modules"),
|
|
145
|
+
path.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", ".."),
|
|
146
|
+
path.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "node_modules"),
|
|
147
|
+
];
|
|
148
|
+
for (const candidate of candidates) {
|
|
149
|
+
if (fs.existsSync(path.join(candidate, "typia", "package.json"))) {
|
|
150
|
+
return candidate;
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
return null;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Temporarily symlink a scaffold generator node_modules directory into the
|
|
157
|
+
* target project while running an async callback.
|
|
158
|
+
*
|
|
159
|
+
* The helper resolves the source path via `resolveScaffoldGeneratorNodeModulesPath()`
|
|
160
|
+
* and uses `EPHEMERAL_NODE_MODULES_LINK_TYPE` for the symlink. The temporary
|
|
161
|
+
* link is removed in the `finally` block so cleanup still happens if the
|
|
162
|
+
* callback throws.
|
|
163
|
+
*
|
|
164
|
+
* @param targetDir Absolute scaffold target directory.
|
|
165
|
+
* @param callback Async work that requires a resolvable `node_modules`.
|
|
166
|
+
* @returns A promise that resolves after the callback and cleanup complete.
|
|
167
|
+
*/
|
|
168
|
+
async function withEphemeralScaffoldNodeModules(targetDir, callback) {
|
|
169
|
+
const targetNodeModulesPath = path.join(targetDir, "node_modules");
|
|
170
|
+
if (fs.existsSync(targetNodeModulesPath)) {
|
|
171
|
+
await callback();
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const sourceNodeModulesPath = resolveScaffoldGeneratorNodeModulesPath();
|
|
175
|
+
if (!sourceNodeModulesPath) {
|
|
176
|
+
throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
|
|
177
|
+
}
|
|
178
|
+
await fsp.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE);
|
|
179
|
+
try {
|
|
180
|
+
await callback();
|
|
181
|
+
}
|
|
182
|
+
finally {
|
|
183
|
+
await fsp.rm(targetNodeModulesPath, { force: true, recursive: true });
|
|
184
|
+
}
|
|
185
|
+
}
|
|
@@ -14,10 +14,22 @@ export declare function getOptionalSyncScriptNames(templateId: string, options?:
|
|
|
14
14
|
* Formats optional onboarding sync commands for the selected package manager.
|
|
15
15
|
*/
|
|
16
16
|
export declare function getOptionalOnboardingSteps(packageManager: PackageManagerId, templateId: string, options?: SyncOnboardingOptions): string[];
|
|
17
|
+
/**
|
|
18
|
+
* Returns the quick-start note explaining the scaffold's primary local loop.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getQuickStartWorkflowNote(packageManager: PackageManagerId, templateId?: string, options?: SyncOnboardingOptions): string;
|
|
17
21
|
/**
|
|
18
22
|
* Returns the onboarding note explaining when manual sync is optional.
|
|
19
23
|
*/
|
|
20
24
|
export declare function getOptionalOnboardingNote(packageManager: PackageManagerId, templateId?: string, options?: SyncOnboardingOptions): string;
|
|
25
|
+
/**
|
|
26
|
+
* Returns the recommended version-control commands for a fresh scaffold.
|
|
27
|
+
*/
|
|
28
|
+
export declare function getInitialCommitCommands(): string[];
|
|
29
|
+
/**
|
|
30
|
+
* Returns the version-control note shown after the initial scaffold.
|
|
31
|
+
*/
|
|
32
|
+
export declare function getInitialCommitNote(): string;
|
|
21
33
|
/**
|
|
22
34
|
* Returns source-of-truth guidance for generated artifacts by template mode.
|
|
23
35
|
*/
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { formatRunScript } from "./package-managers.js";
|
|
2
2
|
import { getPrimaryDevelopmentScript } from "./local-dev-presets.js";
|
|
3
3
|
import { OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE, isBuiltInTemplateId, } from "./template-registry.js";
|
|
4
|
+
const INITIAL_COMMIT_COMMANDS = [
|
|
5
|
+
"git init",
|
|
6
|
+
"git add .",
|
|
7
|
+
'git commit -m "Initial scaffold"',
|
|
8
|
+
];
|
|
4
9
|
function templateHasPersistenceSync(templateId, { compoundPersistenceEnabled = false } = {}) {
|
|
5
10
|
return templateId === "persistence" || (templateId === "compound" && compoundPersistenceEnabled);
|
|
6
11
|
}
|
|
@@ -28,6 +33,24 @@ export function getOptionalSyncScriptNames(templateId, options = {}) {
|
|
|
28
33
|
export function getOptionalOnboardingSteps(packageManager, templateId, options = {}) {
|
|
29
34
|
return getOptionalSyncScriptNames(templateId, options).map((scriptName) => formatRunScript(packageManager, scriptName));
|
|
30
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Returns the quick-start note explaining the scaffold's primary local loop.
|
|
38
|
+
*/
|
|
39
|
+
export function getQuickStartWorkflowNote(packageManager, templateId = "basic", options = {}) {
|
|
40
|
+
const developmentScript = getPrimaryDevelopmentScript(templateId);
|
|
41
|
+
const devCommand = formatRunScript(packageManager, developmentScript);
|
|
42
|
+
const startCommand = formatRunScript(packageManager, "start");
|
|
43
|
+
if (developmentScript === "start") {
|
|
44
|
+
return `${startCommand} is the primary local entry point for this template. If the template also exposes a dedicated watch mode or alternate editor workflow, follow that template-specific documentation alongside the generated project scripts.`;
|
|
45
|
+
}
|
|
46
|
+
if (developmentScript !== "dev") {
|
|
47
|
+
return `${devCommand} is the primary local entry point for this template. Use ${startCommand} when you want the scaffold's one-shot startup flow instead of the watch-oriented workflow.`;
|
|
48
|
+
}
|
|
49
|
+
if (templateHasPersistenceSync(templateId, options)) {
|
|
50
|
+
return `${devCommand} keeps the editor, type-derived artifacts, and REST-derived artifacts moving together during local development. Use ${startCommand} when you want a one-shot sync plus editor startup without the long-running watch loop.`;
|
|
51
|
+
}
|
|
52
|
+
return `${devCommand} keeps the editor and type-derived artifacts moving together during local development. Use ${startCommand} when you want a one-shot sync plus editor startup without the long-running watch loop.`;
|
|
53
|
+
}
|
|
31
54
|
/**
|
|
32
55
|
* Returns the onboarding note explaining when manual sync is optional.
|
|
33
56
|
*/
|
|
@@ -46,18 +69,32 @@ export function getOptionalOnboardingNote(packageManager, templateId = "basic",
|
|
|
46
69
|
const advancedPersistenceNote = templateHasPersistenceSync(templateId, options)
|
|
47
70
|
? ` ${syncRestCommand} remains available for advanced REST-only refreshes, but it now fails fast when type-derived artifacts are stale; run \`${syncCommand}\` or \`${syncTypesCommand}\` first.`
|
|
48
71
|
: "";
|
|
72
|
+
const isCustomTemplate = !isBuiltInTemplateId(templateId) &&
|
|
73
|
+
templateId !== OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE;
|
|
49
74
|
const fallbackCustomTemplateNote = !hasUnifiedSync &&
|
|
50
75
|
syncSteps.length > 0 &&
|
|
51
|
-
|
|
52
|
-
templateId !== OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE
|
|
76
|
+
isCustomTemplate
|
|
53
77
|
? `Run ${syncSteps.join(" then ")} manually before build, typecheck, or commit. ${syncCheckCommand} verifies the current type-derived artifacts without rewriting them.${optionalSyncScripts.includes("sync-rest") ? ` ${syncRestCommand} remains available for REST-only refreshes after ${syncTypesCommand}.` : ""}`
|
|
54
78
|
: null;
|
|
55
79
|
if (fallbackCustomTemplateNote) {
|
|
56
80
|
return fallbackCustomTemplateNote;
|
|
57
81
|
}
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
82
|
+
if (isCustomTemplate && syncSteps.length === 0) {
|
|
83
|
+
return "No optional sync command was detected for this custom template. Follow the template's own artifact-refresh guidance before build, typecheck, or your first commit.";
|
|
84
|
+
}
|
|
85
|
+
return `You usually do not need to run ${syncCommand} during a normal ${formatRunScript(packageManager, developmentScript)} session. Run ${syncCommand} manually when you want a reviewable artifact refresh before ${formatRunScript(packageManager, "build")}, ${typecheckCommand}, or your first commit. ${syncTypesCommand} stays warn-only by default; use \`${failOnLossySyncCommand}\` to fail only on lossy WordPress projections, or \`${strictSyncCommand}\` for the stricter CI-oriented report.${advancedPersistenceNote} They do not create migration history. If this directory is new, create your first Git commit after that refresh.`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Returns the recommended version-control commands for a fresh scaffold.
|
|
89
|
+
*/
|
|
90
|
+
export function getInitialCommitCommands() {
|
|
91
|
+
return [...INITIAL_COMMIT_COMMANDS];
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Returns the version-control note shown after the initial scaffold.
|
|
95
|
+
*/
|
|
96
|
+
export function getInitialCommitNote() {
|
|
97
|
+
return "Skip `git init` if this directory already lives inside an existing repository. If you want generated artifacts refreshed before the first checkpoint, run your manual sync step first and then create the commit.";
|
|
61
98
|
}
|
|
62
99
|
/**
|
|
63
100
|
* Returns source-of-truth guidance for generated artifacts by template mode.
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import type { PackageManagerId } from "./package-managers.js";
|
|
2
|
+
/**
|
|
3
|
+
* Normalizes scaffolded package-manager specific files for the selected toolchain.
|
|
4
|
+
*
|
|
5
|
+
* @param targetDir Absolute scaffold target directory.
|
|
6
|
+
* @param packageManagerId Selected package manager id.
|
|
7
|
+
* @returns A promise that resolves after any package-manager sidecar files are updated.
|
|
8
|
+
*/
|
|
9
|
+
export declare function normalizePackageManagerFiles(targetDir: string, packageManagerId: PackageManagerId): Promise<void>;
|
|
10
|
+
/**
|
|
11
|
+
* Rewrites the generated package.json for the selected package manager.
|
|
12
|
+
*
|
|
13
|
+
* @param targetDir Absolute scaffold target directory.
|
|
14
|
+
* @param packageManagerId Selected package manager id.
|
|
15
|
+
* @returns A promise that resolves after the package.json file is normalized.
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizePackageJson(targetDir: string, packageManagerId: PackageManagerId): Promise<void>;
|
|
18
|
+
/**
|
|
19
|
+
* Removes lockfiles that do not match the selected package manager.
|
|
20
|
+
*
|
|
21
|
+
* @param targetDir Absolute scaffold target directory.
|
|
22
|
+
* @param packageManagerId Selected package manager id.
|
|
23
|
+
* @returns A promise that resolves after stale lockfiles are removed.
|
|
24
|
+
*/
|
|
25
|
+
export declare function removeUnexpectedLockfiles(targetDir: string, packageManagerId: PackageManagerId): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Installs scaffolded project dependencies with the selected package manager.
|
|
28
|
+
*
|
|
29
|
+
* @param options Absolute target directory and selected package manager id.
|
|
30
|
+
* @returns A promise that resolves after the install command completes.
|
|
31
|
+
*/
|
|
32
|
+
export declare function defaultInstallDependencies({ projectDir, packageManager, }: {
|
|
33
|
+
projectDir: string;
|
|
34
|
+
packageManager: PackageManagerId;
|
|
35
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { promises as fsp } from "node:fs";
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import path from "node:path";
|
|
5
|
+
import { formatInstallCommand, getPackageManager, transformPackageManagerText, } from "./package-managers.js";
|
|
6
|
+
const LOCKFILES = {
|
|
7
|
+
bun: ["bun.lock", "bun.lockb"],
|
|
8
|
+
npm: ["package-lock.json"],
|
|
9
|
+
pnpm: ["pnpm-lock.yaml"],
|
|
10
|
+
yarn: ["yarn.lock"],
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Normalizes scaffolded package-manager specific files for the selected toolchain.
|
|
14
|
+
*
|
|
15
|
+
* @param targetDir Absolute scaffold target directory.
|
|
16
|
+
* @param packageManagerId Selected package manager id.
|
|
17
|
+
* @returns A promise that resolves after any package-manager sidecar files are updated.
|
|
18
|
+
*/
|
|
19
|
+
export async function normalizePackageManagerFiles(targetDir, packageManagerId) {
|
|
20
|
+
const yarnRcPath = path.join(targetDir, ".yarnrc.yml");
|
|
21
|
+
if (packageManagerId === "yarn") {
|
|
22
|
+
await fsp.writeFile(yarnRcPath, "nodeLinker: node-modules\n", "utf8");
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
await fsp.rm(yarnRcPath, { force: true });
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Rewrites the generated package.json for the selected package manager.
|
|
29
|
+
*
|
|
30
|
+
* @param targetDir Absolute scaffold target directory.
|
|
31
|
+
* @param packageManagerId Selected package manager id.
|
|
32
|
+
* @returns A promise that resolves after the package.json file is normalized.
|
|
33
|
+
*/
|
|
34
|
+
export async function normalizePackageJson(targetDir, packageManagerId) {
|
|
35
|
+
const packageJsonPath = path.join(targetDir, "package.json");
|
|
36
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const packageManager = getPackageManager(packageManagerId);
|
|
40
|
+
const packageJson = JSON.parse(await fsp.readFile(packageJsonPath, "utf8"));
|
|
41
|
+
packageJson.packageManager = packageManager.packageManagerField;
|
|
42
|
+
if (packageJson.scripts) {
|
|
43
|
+
for (const [key, value] of Object.entries(packageJson.scripts)) {
|
|
44
|
+
if (typeof value === "string") {
|
|
45
|
+
packageJson.scripts[key] = transformPackageManagerText(value, packageManagerId);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
await fsp.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}\n`, "utf8");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Removes lockfiles that do not match the selected package manager.
|
|
53
|
+
*
|
|
54
|
+
* @param targetDir Absolute scaffold target directory.
|
|
55
|
+
* @param packageManagerId Selected package manager id.
|
|
56
|
+
* @returns A promise that resolves after stale lockfiles are removed.
|
|
57
|
+
*/
|
|
58
|
+
export async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
|
|
59
|
+
const keep = new Set(LOCKFILES[packageManagerId] ?? []);
|
|
60
|
+
const allLockfiles = Object.values(LOCKFILES).flat();
|
|
61
|
+
await Promise.all(allLockfiles.map(async (filename) => {
|
|
62
|
+
if (keep.has(filename)) {
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
await fsp.rm(path.join(targetDir, filename), { force: true });
|
|
66
|
+
}));
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Installs scaffolded project dependencies with the selected package manager.
|
|
70
|
+
*
|
|
71
|
+
* @param options Absolute target directory and selected package manager id.
|
|
72
|
+
* @returns A promise that resolves after the install command completes.
|
|
73
|
+
*/
|
|
74
|
+
export async function defaultInstallDependencies({ projectDir, packageManager, }) {
|
|
75
|
+
execSync(formatInstallCommand(packageManager), {
|
|
76
|
+
cwd: projectDir,
|
|
77
|
+
stdio: "inherit",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
@@ -138,17 +138,7 @@ export interface ScaffoldProjectResult {
|
|
|
138
138
|
variables: ScaffoldTemplateVariables;
|
|
139
139
|
warnings: string[];
|
|
140
140
|
}
|
|
141
|
-
|
|
142
|
-
* Builds the generated WordPress wrapper CSS class for a scaffolded block.
|
|
143
|
-
*
|
|
144
|
-
* Returns `wp-block-{namespace}-{slug}` when a non-empty namespace is present,
|
|
145
|
-
* or `wp-block-{slug}` when the namespace is empty or undefined. When the
|
|
146
|
-
* normalized namespace equals the normalized slug, appends `-block` so the
|
|
147
|
-
* generated class avoids repeated namespace segments without colliding with the
|
|
148
|
-
* default core wrapper classes. Both inputs are normalized and validated with
|
|
149
|
-
* the same scaffold identifier rules used for block names.
|
|
150
|
-
*/
|
|
151
|
-
export declare function buildBlockCssClassName(namespace: string | undefined, slug: string): string;
|
|
141
|
+
export { buildBlockCssClassName } from "./scaffold-identifiers.js";
|
|
152
142
|
export declare function isDataStorageMode(value: string): value is DataStorageMode;
|
|
153
143
|
export declare function isPersistencePolicy(value: string): value is PersistencePolicy;
|
|
154
144
|
export declare function detectAuthor(): string;
|
|
@@ -158,4 +148,3 @@ export declare function resolvePackageManagerId({ packageManager, yes, isInterac
|
|
|
158
148
|
export declare function collectScaffoldAnswers({ projectName, templateId, yes, dataStorageMode, namespace, persistencePolicy, phpPrefix, promptText, textDomain, }: CollectScaffoldAnswersOptions): Promise<ScaffoldAnswers>;
|
|
159
149
|
export declare function getTemplateVariables(templateId: string, answers: ScaffoldAnswers): ScaffoldTemplateVariables;
|
|
160
150
|
export declare function scaffoldProject({ projectDir, templateId, answers, dataStorageMode, persistencePolicy, packageManager, externalLayerId, externalLayerSource, externalLayerSourceLabel, repositoryReference, cwd, allowExistingDir, noInstall, installDependencies, variant, withMigrationUi, withTestPreset, withWpEnv, }: ScaffoldProjectOptions): Promise<ScaffoldProjectResult>;
|
|
161
|
-
export {};
|