@wp-typia/create 0.1.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 (95) hide show
  1. package/README.md +43 -0
  2. package/dist/cli.js +2492 -0
  3. package/dist/runtime/cli-core.js +222 -0
  4. package/dist/runtime/index.js +4 -0
  5. package/dist/runtime/migration-constants.js +14 -0
  6. package/dist/runtime/migration-diff.js +521 -0
  7. package/dist/runtime/migration-fixtures.js +89 -0
  8. package/dist/runtime/migration-manifest.js +129 -0
  9. package/dist/runtime/migration-project.js +167 -0
  10. package/dist/runtime/migration-render.js +267 -0
  11. package/dist/runtime/migration-types.js +1 -0
  12. package/dist/runtime/migration-utils.js +184 -0
  13. package/dist/runtime/migrations.js +232 -0
  14. package/dist/runtime/package-managers.js +135 -0
  15. package/dist/runtime/scaffold.js +334 -0
  16. package/dist/runtime/template-registry.js +75 -0
  17. package/package.json +65 -0
  18. package/templates/advanced/README.md.mustache +150 -0
  19. package/templates/advanced/block.json.mustache +43 -0
  20. package/templates/advanced/index.js +21 -0
  21. package/templates/advanced/package.json.mustache +47 -0
  22. package/templates/advanced/render.php.mustache +83 -0
  23. package/templates/advanced/scripts/lib/typia-metadata-core.ts +1413 -0
  24. package/templates/advanced/scripts/sync-types-to-block-json.ts.mustache +32 -0
  25. package/templates/advanced/src/admin/migration-dashboard.tsx.mustache +315 -0
  26. package/templates/advanced/src/components/ErrorBoundary.tsx.mustache +47 -0
  27. package/templates/advanced/src/deprecated.ts.mustache +2 -0
  28. package/templates/advanced/src/edit.tsx.mustache +97 -0
  29. package/templates/advanced/src/hooks/useDebounce.ts.mustache +20 -0
  30. package/templates/advanced/src/hooks/useLocalStorage.ts.mustache +31 -0
  31. package/templates/advanced/src/hooks.ts.mustache +56 -0
  32. package/templates/advanced/src/index.tsx.mustache +18 -0
  33. package/templates/advanced/src/migration-detector.ts.mustache +9 -0
  34. package/templates/advanced/src/migrations/config.ts.mustache +8 -0
  35. package/templates/advanced/src/migrations/examples/rename-transform-union/README.md.mustache +23 -0
  36. package/templates/advanced/src/migrations/examples/rename-transform-union/fixture.example.json.mustache +36 -0
  37. package/templates/advanced/src/migrations/examples/rename-transform-union/rule.example.ts.mustache +47 -0
  38. package/templates/advanced/src/migrations/fixtures/README.md.mustache +3 -0
  39. package/templates/advanced/src/migrations/generated/deprecated.ts.mustache +3 -0
  40. package/templates/advanced/src/migrations/generated/registry.ts.mustache +9 -0
  41. package/templates/advanced/src/migrations/generated/verify.ts.mustache +1 -0
  42. package/templates/advanced/src/migrations/helpers.ts.mustache +354 -0
  43. package/templates/advanced/src/migrations/index.ts.mustache +616 -0
  44. package/templates/advanced/src/migrations/rules/README.md.mustache +3 -0
  45. package/templates/advanced/src/migrations/versions/README.md.mustache +3 -0
  46. package/templates/advanced/src/save.tsx.mustache +12 -0
  47. package/templates/advanced/src/style.scss.mustache +84 -0
  48. package/templates/advanced/src/types.ts.mustache +46 -0
  49. package/templates/advanced/src/utils/classnames.ts.mustache +51 -0
  50. package/templates/advanced/src/utils/debounce.ts.mustache +37 -0
  51. package/templates/advanced/src/utils/index.ts.mustache +7 -0
  52. package/templates/advanced/src/utils/uuid.ts.mustache +17 -0
  53. package/templates/advanced/src/validators.ts.mustache +39 -0
  54. package/templates/advanced/src/view.ts.mustache +59 -0
  55. package/templates/advanced/tsconfig.json.mustache +20 -0
  56. package/templates/advanced/webpack.config.js.mustache +95 -0
  57. package/templates/basic/package.json.mustache +39 -0
  58. package/templates/basic/scripts/lib/typia-metadata-core.ts +1413 -0
  59. package/templates/basic/scripts/sync-types-to-block-json.ts +25 -0
  60. package/templates/basic/src/block.json +51 -0
  61. package/templates/basic/src/edit.tsx +85 -0
  62. package/templates/basic/src/hooks.ts +75 -0
  63. package/templates/basic/src/index.tsx +37 -0
  64. package/templates/basic/src/save.tsx +27 -0
  65. package/templates/basic/src/style.scss +42 -0
  66. package/templates/basic/src/types.ts +48 -0
  67. package/templates/basic/src/validators.ts +39 -0
  68. package/templates/basic/tsconfig.json +20 -0
  69. package/templates/basic/webpack.config.js +89 -0
  70. package/templates/full/package.json.mustache +40 -0
  71. package/templates/full/scripts/lib/typia-metadata-core.ts +1413 -0
  72. package/templates/full/scripts/sync-types-to-block-json.ts.mustache +32 -0
  73. package/templates/full/src/block.json.mustache +120 -0
  74. package/templates/full/src/edit.tsx.mustache +300 -0
  75. package/templates/full/src/editor.scss.mustache +251 -0
  76. package/templates/full/src/hooks.ts.mustache +141 -0
  77. package/templates/full/src/index.tsx.mustache +27 -0
  78. package/templates/full/src/save.tsx.mustache +39 -0
  79. package/templates/full/src/style.scss.mustache +224 -0
  80. package/templates/full/src/types.ts.mustache +35 -0
  81. package/templates/full/src/validators.ts.mustache +84 -0
  82. package/templates/full/tsconfig.json.mustache +20 -0
  83. package/templates/full/webpack.config.js.mustache +89 -0
  84. package/templates/interactivity/package.json.mustache +41 -0
  85. package/templates/interactivity/scripts/lib/typia-metadata-core.ts +1413 -0
  86. package/templates/interactivity/scripts/sync-types-to-block-json.ts.mustache +32 -0
  87. package/templates/interactivity/src/block.json.mustache +74 -0
  88. package/templates/interactivity/src/edit.tsx.mustache +206 -0
  89. package/templates/interactivity/src/index.tsx.mustache +20 -0
  90. package/templates/interactivity/src/interactivity.ts.mustache +183 -0
  91. package/templates/interactivity/src/save.tsx.mustache +87 -0
  92. package/templates/interactivity/src/style.scss.mustache +60 -0
  93. package/templates/interactivity/src/types.ts.mustache +30 -0
  94. package/templates/interactivity/tsconfig.json.mustache +20 -0
  95. package/templates/interactivity/webpack.config.js.mustache +89 -0
@@ -0,0 +1,222 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import readline from "node:readline";
5
+ import { access, constants as fsConstants, rm, writeFile } from "node:fs/promises";
6
+ import { execFileSync } from "node:child_process";
7
+ import { collectScaffoldAnswers, resolvePackageManagerId, resolveTemplateId, scaffoldProject, } from "./scaffold.js";
8
+ import { PACKAGE_MANAGER_IDS, formatInstallCommand, formatRunScript, } from "./package-managers.js";
9
+ import { TEMPLATE_IDS, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
10
+ export function createReadlinePrompt() {
11
+ const rl = readline.createInterface({
12
+ input: process.stdin,
13
+ output: process.stdout,
14
+ });
15
+ return {
16
+ async text(message, defaultValue, validate) {
17
+ const suffix = defaultValue ? ` (${defaultValue})` : "";
18
+ const answer = await new Promise((resolve) => {
19
+ rl.question(`${message}${suffix}: `, resolve);
20
+ });
21
+ const value = String(answer).trim() || defaultValue;
22
+ if (validate) {
23
+ const result = validate(value);
24
+ if (result !== true) {
25
+ console.error(`❌ ${typeof result === "string" ? result : "Invalid input"}`);
26
+ return this.text(message, defaultValue, validate);
27
+ }
28
+ }
29
+ return value;
30
+ },
31
+ async select(message, options, defaultValue = 1) {
32
+ console.log(message);
33
+ options.forEach((option, index) => {
34
+ const hint = option.hint ? ` - ${option.hint}` : "";
35
+ console.log(` ${index + 1}. ${option.label}${hint}`);
36
+ });
37
+ const answer = await this.text("Choice", String(defaultValue));
38
+ const numericChoice = Number(answer);
39
+ if (!Number.isNaN(numericChoice) && options[numericChoice - 1]) {
40
+ return options[numericChoice - 1].value;
41
+ }
42
+ const directChoice = options.find((option) => option.value === answer);
43
+ if (directChoice) {
44
+ return directChoice.value;
45
+ }
46
+ console.error(`❌ Invalid selection: ${answer}`);
47
+ return this.select(message, options, defaultValue);
48
+ },
49
+ close() {
50
+ rl.close();
51
+ },
52
+ };
53
+ }
54
+ export function formatHelpText() {
55
+ return `Usage:
56
+ wp-typia <project-dir> [--template <id>] [--yes] [--no-install] [--package-manager <id>]
57
+ wp-typia templates list
58
+ wp-typia templates inspect <id>
59
+ wp-typia migrations <init|snapshot|diff|scaffold|verify> [...]
60
+ wp-typia doctor
61
+
62
+ Templates: ${TEMPLATE_IDS.join(", ")}
63
+ Package managers: ${PACKAGE_MANAGER_IDS.join(", ")}`;
64
+ }
65
+ export function formatTemplateSummary(template) {
66
+ return `${template.id.padEnd(14)} ${template.description}`;
67
+ }
68
+ export function formatTemplateFeatures(template) {
69
+ return ` ${template.features.join(" • ")}`;
70
+ }
71
+ export function formatTemplateDetails(template) {
72
+ return [
73
+ template.id,
74
+ template.description,
75
+ `Category: ${template.defaultCategory}`,
76
+ `Path: ${template.templateDir}`,
77
+ `Features: ${template.features.join(", ")}`,
78
+ ].join("\n");
79
+ }
80
+ function readCommandVersion(command, args = ["--version"]) {
81
+ try {
82
+ return execFileSync(command, args, {
83
+ encoding: "utf8",
84
+ stdio: ["ignore", "pipe", "ignore"],
85
+ }).trim();
86
+ }
87
+ catch {
88
+ return null;
89
+ }
90
+ }
91
+ function compareMajorVersion(actualVersion, minimumMajor) {
92
+ const parsed = Number.parseInt(actualVersion.replace(/^v/, "").split(".")[0] ?? "", 10);
93
+ return Number.isFinite(parsed) && parsed >= minimumMajor;
94
+ }
95
+ async function checkWritableDirectory(directory) {
96
+ try {
97
+ await access(directory, fsConstants.W_OK);
98
+ return true;
99
+ }
100
+ catch {
101
+ return false;
102
+ }
103
+ }
104
+ async function checkTempDirectory() {
105
+ const tempFile = path.join(os.tmpdir(), `wp-typia-${Date.now()}.tmp`);
106
+ try {
107
+ await writeFile(tempFile, "ok", "utf8");
108
+ await rm(tempFile, { force: true });
109
+ return true;
110
+ }
111
+ catch {
112
+ return false;
113
+ }
114
+ }
115
+ export async function getDoctorChecks(cwd) {
116
+ const checks = [];
117
+ const bunVersion = readCommandVersion("bun");
118
+ const nodeVersion = readCommandVersion("node");
119
+ const gitVersion = readCommandVersion("git");
120
+ const cwdWritable = await checkWritableDirectory(cwd);
121
+ const tempWritable = await checkTempDirectory();
122
+ checks.push({
123
+ status: bunVersion && compareMajorVersion(bunVersion, 1) ? "pass" : "fail",
124
+ label: "Bun",
125
+ detail: bunVersion ? `Detected ${bunVersion}` : "Not available",
126
+ });
127
+ checks.push({
128
+ status: nodeVersion && compareMajorVersion(nodeVersion, 16) ? "pass" : "fail",
129
+ label: "Node",
130
+ detail: nodeVersion ? `Detected ${nodeVersion}` : "Not available",
131
+ });
132
+ checks.push({
133
+ status: gitVersion ? "pass" : "fail",
134
+ label: "git",
135
+ detail: gitVersion ?? "Not available",
136
+ });
137
+ checks.push({
138
+ status: cwdWritable ? "pass" : "fail",
139
+ label: "Current directory",
140
+ detail: cwdWritable ? "Writable" : "Not writable",
141
+ });
142
+ checks.push({
143
+ status: tempWritable ? "pass" : "fail",
144
+ label: "Temp directory",
145
+ detail: tempWritable ? "Writable" : "Not writable",
146
+ });
147
+ for (const template of listTemplates()) {
148
+ const hasAssets = fs.existsSync(template.templateDir) &&
149
+ fs.existsSync(path.join(template.templateDir, "package.json.mustache"));
150
+ checks.push({
151
+ status: hasAssets ? "pass" : "fail",
152
+ label: `Template ${template.id}`,
153
+ detail: hasAssets ? template.templateDir : "Missing core template assets",
154
+ });
155
+ }
156
+ return checks;
157
+ }
158
+ export async function runDoctor(cwd, { renderLine = (check) => console.log(`${check.status.toUpperCase()} ${check.label}: ${check.detail}`) } = {}) {
159
+ const checks = await getDoctorChecks(cwd);
160
+ for (const check of checks) {
161
+ renderLine(check);
162
+ }
163
+ if (checks.some((check) => check.status === "fail")) {
164
+ throw new Error("Doctor found one or more failing checks.");
165
+ }
166
+ return checks;
167
+ }
168
+ export function getNextSteps({ projectInput, projectDir, packageManager, noInstall, }) {
169
+ const steps = [`cd ${path.isAbsolute(projectInput) ? projectDir : projectInput}`];
170
+ if (noInstall) {
171
+ steps.push(formatInstallCommand(packageManager));
172
+ }
173
+ steps.push(formatRunScript(packageManager, "start"));
174
+ return steps;
175
+ }
176
+ export async function runScaffoldFlow({ projectInput, cwd = process.cwd(), templateId, packageManager, yes = false, noInstall = false, isInteractive = false, allowExistingDir = false, selectTemplate, selectPackageManager, promptText, installDependencies = undefined, }) {
177
+ if (!projectInput) {
178
+ throw new Error("Project directory is required. Usage: wp-typia <project-dir>");
179
+ }
180
+ const resolvedTemplateId = await resolveTemplateId({
181
+ templateId,
182
+ yes,
183
+ isInteractive,
184
+ selectTemplate,
185
+ });
186
+ const resolvedPackageManager = await resolvePackageManagerId({
187
+ packageManager,
188
+ yes,
189
+ isInteractive,
190
+ selectPackageManager,
191
+ });
192
+ const projectDir = path.resolve(cwd, projectInput);
193
+ const projectName = path.basename(projectDir);
194
+ const answers = await collectScaffoldAnswers({
195
+ projectName,
196
+ templateId: resolvedTemplateId,
197
+ yes,
198
+ promptText,
199
+ });
200
+ const result = await scaffoldProject({
201
+ answers,
202
+ allowExistingDir,
203
+ installDependencies,
204
+ noInstall,
205
+ packageManager: resolvedPackageManager,
206
+ projectDir,
207
+ templateId: resolvedTemplateId,
208
+ });
209
+ return {
210
+ projectDir,
211
+ projectInput,
212
+ packageManager: resolvedPackageManager,
213
+ result,
214
+ nextSteps: getNextSteps({
215
+ projectInput,
216
+ projectDir,
217
+ packageManager: resolvedPackageManager,
218
+ noInstall,
219
+ }),
220
+ };
221
+ }
222
+ export { getTemplateById, getTemplateSelectOptions, listTemplates };
@@ -0,0 +1,4 @@
1
+ export { scaffoldProject, collectScaffoldAnswers, getDefaultAnswers, getTemplateVariables, resolvePackageManagerId, resolveTemplateId, } from "./scaffold.js";
2
+ export { formatMigrationHelpText, parseMigrationArgs, runMigrationCommand, } from "./migrations.js";
3
+ export { PACKAGE_MANAGER_IDS, PACKAGE_MANAGERS, formatInstallCommand, formatRunScript, getPackageManager, getPackageManagerSelectOptions, transformPackageManagerText, } from "./package-managers.js";
4
+ export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
@@ -0,0 +1,14 @@
1
+ import path from "node:path";
2
+ export const ROOT_BLOCK_JSON = "block.json";
3
+ export const ROOT_MANIFEST = "typia.manifest.json";
4
+ export const ROOT_PHP_MIGRATION_REGISTRY = "typia-migration-registry.php";
5
+ export const ROOT_SAVE_FILE = path.join("src", "save.tsx");
6
+ export const ROOT_TYPES_FILE = path.join("src", "types.ts");
7
+ export const MIGRATIONS_DIR = path.join("src", "migrations");
8
+ export const CONFIG_FILE = path.join(MIGRATIONS_DIR, "config.ts");
9
+ export const GENERATED_DIR = path.join(MIGRATIONS_DIR, "generated");
10
+ export const FIXTURES_DIR = path.join(MIGRATIONS_DIR, "fixtures");
11
+ export const RULES_DIR = path.join(MIGRATIONS_DIR, "rules");
12
+ export const SNAPSHOT_DIR = path.join(MIGRATIONS_DIR, "versions");
13
+ export const SUPPORTED_PROJECT_FILES = ["package.json", ROOT_BLOCK_JSON, ROOT_SAVE_FILE, ROOT_TYPES_FILE];
14
+ export const MIGRATION_TODO_PREFIX = "TODO MIGRATION:";