wp-typia 0.23.0 → 0.23.1
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 +2 -1
- package/bin/routing-metadata.generated.js +4 -0
- package/dist-bunli/.bunli/commands.gen.js +4103 -3086
- package/dist-bunli/{cli-hhp1d348.js → cli-1170yyve.js} +8 -7
- package/dist-bunli/{cli-qse6myha.js → cli-8hxf9qw6.js} +11 -3
- package/dist-bunli/{cli-8reep89s.js → cli-9fx0qgb7.js} +2 -2
- package/dist-bunli/{cli-add-21bvpfgw.js → cli-add-xjaaa01x.js} +1560 -1525
- package/dist-bunli/{cli-52ke0ptp.js → cli-am5x7tb4.js} +8 -2
- package/dist-bunli/cli-ccax7s0s.js +34 -0
- package/dist-bunli/{cli-diagnostics-5dvztm7q.js → cli-diagnostics-10drxh34.js} +1 -1
- package/dist-bunli/{cli-doctor-wy2yjsge.js → cli-doctor-19e8313m.js} +602 -459
- package/dist-bunli/{cli-2rqf6t0b.js → cli-e4bwd81c.js} +8 -11
- package/dist-bunli/{cli-9npd9was.js → cli-epsczb1c.js} +12 -10
- package/dist-bunli/{cli-agywa5n6.js → cli-fp16mntv.js} +8 -4
- package/dist-bunli/{cli-init-xnsbxncv.js → cli-init-2b4yn2cc.js} +14 -10
- package/dist-bunli/{cli-ts9thts5.js → cli-k5q5v8g6.js} +184 -162
- package/dist-bunli/{cli-c2acv5dv.js → cli-nvs5atj1.js} +2 -2
- package/dist-bunli/{cli-prompt-614tq57c.js → cli-prompt-ncyg68rn.js} +1 -1
- package/dist-bunli/{cli-bq2v559b.js → cli-rdcga1bd.js} +31 -13
- package/dist-bunli/{cli-scaffold-zhp2ym8z.js → cli-scaffold-4tjw4jk5.js} +27 -15
- package/dist-bunli/{cli-templates-hc71dfc2.js → cli-templates-g8t4fm11.js} +3 -2
- package/dist-bunli/{cli-p95wr1q8.js → cli-tq730sqt.js} +6 -3
- package/dist-bunli/{cli-1meywwsy.js → cli-y7w3pybs.js} +848 -246
- package/dist-bunli/{cli-z5qkx2pn.js → cli-ymecd15q.js} +37 -10
- package/dist-bunli/cli.js +4 -4
- package/dist-bunli/{command-list-aqrkx021.js → command-list-vme7dr5v.js} +81 -45
- package/dist-bunli/{create-template-validation-rtec5sng.js → create-template-validation-4fr851vg.js} +5 -4
- package/dist-bunli/{migrations-bx0yvc2v.js → migrations-pb5vvtdp.js} +9 -8
- package/dist-bunli/node-cli.js +399 -317
- package/dist-bunli/{workspace-project-csnnggz6.js → workspace-project-gmv2a71z.js} +4 -3
- package/package.json +2 -2
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
parseTemplateLocator,
|
|
5
5
|
require_semver,
|
|
6
6
|
validateExplicitCreateTemplateId
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-9fx0qgb7.js";
|
|
8
8
|
import {
|
|
9
9
|
getBuiltInSharedTemplateLayerDir,
|
|
10
10
|
getBuiltInTemplateLayerDirs,
|
|
@@ -14,10 +14,10 @@ import {
|
|
|
14
14
|
isOmittableBuiltInTemplateLayerDir,
|
|
15
15
|
resolveBuiltInTemplateSource,
|
|
16
16
|
resolveBuiltInTemplateSourceFromLayerDirs
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-nvs5atj1.js";
|
|
18
18
|
import {
|
|
19
19
|
getPackageVersions
|
|
20
|
-
} from "./cli-
|
|
20
|
+
} from "./cli-fp16mntv.js";
|
|
21
21
|
import {
|
|
22
22
|
BUILTIN_BLOCK_METADATA_VERSION,
|
|
23
23
|
COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS,
|
|
@@ -32,18 +32,20 @@ import {
|
|
|
32
32
|
getTemplateById,
|
|
33
33
|
isBuiltInTemplateId,
|
|
34
34
|
normalizeTemplateLookupId
|
|
35
|
-
} from "./cli-
|
|
35
|
+
} from "./cli-8hxf9qw6.js";
|
|
36
36
|
import {
|
|
37
37
|
seedProjectMigrations
|
|
38
|
-
} from "./cli-
|
|
38
|
+
} from "./cli-epsczb1c.js";
|
|
39
39
|
import {
|
|
40
40
|
ensureMigrationDirectories,
|
|
41
41
|
isPlainObject,
|
|
42
42
|
stableJsonStringify,
|
|
43
43
|
writeInitialMigrationScaffold,
|
|
44
44
|
writeMigrationConfig
|
|
45
|
-
} from "./cli-
|
|
45
|
+
} from "./cli-e4bwd81c.js";
|
|
46
46
|
import {
|
|
47
|
+
assertValidGeneratedSlug,
|
|
48
|
+
assertValidIntegrationEnvService,
|
|
47
49
|
buildBlockCssClassName,
|
|
48
50
|
buildFrontendCssClassName,
|
|
49
51
|
getNodeErrorCode,
|
|
@@ -52,20 +54,25 @@ import {
|
|
|
52
54
|
pathExists,
|
|
53
55
|
readOptionalUtf8File,
|
|
54
56
|
resolveScaffoldIdentifiers,
|
|
57
|
+
rollbackWorkspaceMutation,
|
|
58
|
+
snapshotWorkspaceFiles,
|
|
55
59
|
toPascalCase,
|
|
56
60
|
toSegmentPascalCase,
|
|
57
61
|
toSnakeCase,
|
|
58
62
|
toTitleCase,
|
|
59
63
|
validateBlockSlug,
|
|
60
64
|
validateNamespace
|
|
61
|
-
} from "./cli-
|
|
65
|
+
} from "./cli-k5q5v8g6.js";
|
|
62
66
|
import {
|
|
63
67
|
createManagedTempRoot
|
|
64
68
|
} from "./cli-t73q5aqz.js";
|
|
65
69
|
import {
|
|
66
70
|
CLI_DIAGNOSTIC_CODES,
|
|
67
71
|
createCliDiagnosticCodeError
|
|
68
|
-
} from "./cli-
|
|
72
|
+
} from "./cli-tq730sqt.js";
|
|
73
|
+
import {
|
|
74
|
+
resolveWorkspaceProject
|
|
75
|
+
} from "./cli-1170yyve.js";
|
|
69
76
|
import {
|
|
70
77
|
PACKAGE_MANAGER_IDS,
|
|
71
78
|
formatInstallCommand,
|
|
@@ -73,7 +80,12 @@ import {
|
|
|
73
80
|
formatRunScript,
|
|
74
81
|
getPackageManager,
|
|
75
82
|
transformPackageManagerText
|
|
76
|
-
} from "./cli-
|
|
83
|
+
} from "./cli-am5x7tb4.js";
|
|
84
|
+
import {
|
|
85
|
+
readJsonFile,
|
|
86
|
+
readJsonFileSync,
|
|
87
|
+
safeJsonParse
|
|
88
|
+
} from "./cli-ccax7s0s.js";
|
|
77
89
|
import {
|
|
78
90
|
__toESM
|
|
79
91
|
} from "./cli-xnn9xjcy.js";
|
|
@@ -754,7 +766,9 @@ function getDevScript(packageManager, compoundPersistenceEnabled, templateId) {
|
|
|
754
766
|
}
|
|
755
767
|
async function mutatePackageJson(projectDir, mutate) {
|
|
756
768
|
const packageJsonPath = path2.join(projectDir, "package.json");
|
|
757
|
-
const packageJson =
|
|
769
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
770
|
+
context: "local dev package manifest"
|
|
771
|
+
});
|
|
758
772
|
mutate(packageJson);
|
|
759
773
|
await fsp2.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
760
774
|
`, "utf8");
|
|
@@ -2189,7 +2203,9 @@ function readGeneratedPackageJson(projectDir) {
|
|
|
2189
2203
|
if (!fs2.existsSync(packageJsonPath)) {
|
|
2190
2204
|
return null;
|
|
2191
2205
|
}
|
|
2192
|
-
return
|
|
2206
|
+
return readJsonFileSync(packageJsonPath, {
|
|
2207
|
+
context: "generated package manifest"
|
|
2208
|
+
});
|
|
2193
2209
|
}
|
|
2194
2210
|
function formatNonEmptyTargetDirectoryError(targetDir) {
|
|
2195
2211
|
return `Target directory is not empty: ${targetDir}. Choose a new project directory, or empty this directory before rerunning the scaffold.`;
|
|
@@ -2231,7 +2247,9 @@ function isWorkspaceProject(projectDir) {
|
|
|
2231
2247
|
}
|
|
2232
2248
|
async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
|
|
2233
2249
|
const packageJsonPath = path4.join(projectDir, "package.json");
|
|
2234
|
-
const packageJson =
|
|
2250
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
2251
|
+
context: "workspace package manifest"
|
|
2252
|
+
});
|
|
2235
2253
|
const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
|
|
2236
2254
|
const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0" ? "wp-typia" : `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
|
|
2237
2255
|
const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
|
|
@@ -2288,9 +2306,521 @@ async function withEphemeralScaffoldNodeModules(targetDir, callback) {
|
|
|
2288
2306
|
}
|
|
2289
2307
|
}
|
|
2290
2308
|
|
|
2309
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env.ts
|
|
2310
|
+
import { promises as fsp4 } from "fs";
|
|
2311
|
+
import path5 from "path";
|
|
2312
|
+
|
|
2313
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-mutation.ts
|
|
2314
|
+
var DEFAULT_PHP_SNIPPET_INSERTION_ANCHORS = [
|
|
2315
|
+
/add_action\(\s*["']init["']\s*,\s*["'][^"']+_load_textdomain["']\s*\);\s*\n/u,
|
|
2316
|
+
/\?>\s*$/u
|
|
2317
|
+
];
|
|
2318
|
+
|
|
2319
|
+
class WorkspaceMutationRollbackError extends Error {
|
|
2320
|
+
mutationError;
|
|
2321
|
+
rollbackError;
|
|
2322
|
+
constructor(mutationError, rollbackError) {
|
|
2323
|
+
super("Workspace mutation failed and rollback also failed.");
|
|
2324
|
+
this.name = "WorkspaceMutationRollbackError";
|
|
2325
|
+
this.mutationError = mutationError;
|
|
2326
|
+
this.rollbackError = rollbackError;
|
|
2327
|
+
}
|
|
2328
|
+
}
|
|
2329
|
+
async function executeWorkspaceMutationPlan({
|
|
2330
|
+
filePaths,
|
|
2331
|
+
run,
|
|
2332
|
+
snapshotDirs = [],
|
|
2333
|
+
targetPaths = []
|
|
2334
|
+
}) {
|
|
2335
|
+
const mutationSnapshot = {
|
|
2336
|
+
fileSources: await snapshotWorkspaceFiles(filePaths),
|
|
2337
|
+
snapshotDirs: [...snapshotDirs],
|
|
2338
|
+
targetPaths: [...targetPaths]
|
|
2339
|
+
};
|
|
2340
|
+
try {
|
|
2341
|
+
return await run();
|
|
2342
|
+
} catch (error) {
|
|
2343
|
+
try {
|
|
2344
|
+
await rollbackWorkspaceMutation(mutationSnapshot);
|
|
2345
|
+
} catch (rollbackError) {
|
|
2346
|
+
throw new WorkspaceMutationRollbackError(error, rollbackError);
|
|
2347
|
+
}
|
|
2348
|
+
throw error;
|
|
2349
|
+
}
|
|
2350
|
+
}
|
|
2351
|
+
function insertPhpSnippetBeforeWorkspaceAnchors(source, snippet) {
|
|
2352
|
+
for (const anchor of DEFAULT_PHP_SNIPPET_INSERTION_ANCHORS) {
|
|
2353
|
+
const candidate = source.replace(anchor, (match) => `${snippet}
|
|
2354
|
+
${match}`);
|
|
2355
|
+
if (candidate !== source) {
|
|
2356
|
+
return candidate;
|
|
2357
|
+
}
|
|
2358
|
+
}
|
|
2359
|
+
return `${source.trimEnd()}
|
|
2360
|
+
${snippet}
|
|
2361
|
+
`;
|
|
2362
|
+
}
|
|
2363
|
+
function appendPhpSnippetBeforeClosingTag(source, snippet) {
|
|
2364
|
+
const closingTagPattern = /\?>\s*$/u;
|
|
2365
|
+
if (closingTagPattern.test(source)) {
|
|
2366
|
+
return source.replace(closingTagPattern, `${snippet}
|
|
2367
|
+
?>`);
|
|
2368
|
+
}
|
|
2369
|
+
return `${source.trimEnd()}
|
|
2370
|
+
${snippet}
|
|
2371
|
+
`;
|
|
2372
|
+
}
|
|
2373
|
+
|
|
2374
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env.ts
|
|
2375
|
+
var WP_ENV_PACKAGE_VERSION = "^11.2.0";
|
|
2376
|
+
function buildWpEnvConfigSource() {
|
|
2377
|
+
return `${JSON.stringify({
|
|
2378
|
+
$schema: "https://schemas.wp.org/trunk/wp-env.json",
|
|
2379
|
+
core: null,
|
|
2380
|
+
port: 8888,
|
|
2381
|
+
testsEnvironment: false,
|
|
2382
|
+
plugins: ["."],
|
|
2383
|
+
config: {
|
|
2384
|
+
WP_DEBUG: true,
|
|
2385
|
+
WP_DEBUG_LOG: true,
|
|
2386
|
+
WP_DEBUG_DISPLAY: false,
|
|
2387
|
+
SCRIPT_DEBUG: true,
|
|
2388
|
+
WP_ENVIRONMENT_TYPE: "local"
|
|
2389
|
+
}
|
|
2390
|
+
}, null, 2)}
|
|
2391
|
+
`;
|
|
2392
|
+
}
|
|
2393
|
+
function buildDockerComposeSource() {
|
|
2394
|
+
return `services:
|
|
2395
|
+
integration-service:
|
|
2396
|
+
image: node:22-alpine
|
|
2397
|
+
working_dir: /workspace
|
|
2398
|
+
volumes:
|
|
2399
|
+
- .:/workspace
|
|
2400
|
+
command: >
|
|
2401
|
+
node -e "require('node:http').createServer((request, response) => {
|
|
2402
|
+
response.writeHead(request.url === '/health' ? 200 : 404, {
|
|
2403
|
+
'content-type': 'application/json'
|
|
2404
|
+
});
|
|
2405
|
+
response.end(JSON.stringify({
|
|
2406
|
+
ok: request.url === '/health',
|
|
2407
|
+
service: 'wp-typia-integration-starter'
|
|
2408
|
+
}));
|
|
2409
|
+
}).listen(3000, '0.0.0.0')"
|
|
2410
|
+
ports:
|
|
2411
|
+
- "3000:3000"
|
|
2412
|
+
`;
|
|
2413
|
+
}
|
|
2414
|
+
function buildIntegrationSmokeScriptSource(integrationEnvSlug) {
|
|
2415
|
+
return `import fs from "node:fs";
|
|
2416
|
+
import path from "node:path";
|
|
2417
|
+
import { fileURLToPath } from "node:url";
|
|
2418
|
+
|
|
2419
|
+
const ROOT_DIR = path.resolve(
|
|
2420
|
+
fileURLToPath(new URL("../..", import.meta.url)),
|
|
2421
|
+
);
|
|
2422
|
+
const ENV_FILE = path.join(ROOT_DIR, ".env");
|
|
2423
|
+
|
|
2424
|
+
function parseEnvValue(value) {
|
|
2425
|
+
const trimmed = value.trim();
|
|
2426
|
+
if (
|
|
2427
|
+
(trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
2428
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))
|
|
2429
|
+
) {
|
|
2430
|
+
return trimmed.slice(1, -1);
|
|
2431
|
+
}
|
|
2432
|
+
|
|
2433
|
+
return trimmed;
|
|
2434
|
+
}
|
|
2435
|
+
|
|
2436
|
+
function readEnvFile(filePath) {
|
|
2437
|
+
if (!fs.existsSync(filePath)) {
|
|
2438
|
+
return {};
|
|
2439
|
+
}
|
|
2440
|
+
|
|
2441
|
+
return Object.fromEntries(
|
|
2442
|
+
fs
|
|
2443
|
+
.readFileSync(filePath, "utf8")
|
|
2444
|
+
.split(/\\r?\\n/u)
|
|
2445
|
+
.map((line) => line.trim())
|
|
2446
|
+
.filter((line) => line.length > 0 && !line.startsWith("#"))
|
|
2447
|
+
.map((line) => {
|
|
2448
|
+
const separatorIndex = line.indexOf("=");
|
|
2449
|
+
if (separatorIndex === -1) {
|
|
2450
|
+
return null;
|
|
2451
|
+
}
|
|
2452
|
+
|
|
2453
|
+
return [
|
|
2454
|
+
line.slice(0, separatorIndex).trim(),
|
|
2455
|
+
parseEnvValue(line.slice(separatorIndex + 1)),
|
|
2456
|
+
];
|
|
2457
|
+
})
|
|
2458
|
+
.filter(Boolean),
|
|
2459
|
+
);
|
|
2460
|
+
}
|
|
2461
|
+
|
|
2462
|
+
const envFile = readEnvFile(ENV_FILE);
|
|
2463
|
+
|
|
2464
|
+
function getEnv(name, fallback) {
|
|
2465
|
+
return process.env[name] ?? envFile[name] ?? fallback;
|
|
2466
|
+
}
|
|
2467
|
+
|
|
2468
|
+
function resolveEndpointUrl(baseUrl, endpointPath) {
|
|
2469
|
+
const normalizedBaseUrl = new URL(baseUrl);
|
|
2470
|
+
if (!normalizedBaseUrl.pathname.endsWith("/")) {
|
|
2471
|
+
normalizedBaseUrl.pathname = \`\${normalizedBaseUrl.pathname}/\`;
|
|
2472
|
+
}
|
|
2473
|
+
|
|
2474
|
+
const relativePath = endpointPath.replace(/^\\/+/u, "");
|
|
2475
|
+
return new URL(relativePath, normalizedBaseUrl);
|
|
2476
|
+
}
|
|
2477
|
+
|
|
2478
|
+
async function assertJsonEndpoint(label, url) {
|
|
2479
|
+
const response = await fetch(url, {
|
|
2480
|
+
headers: {
|
|
2481
|
+
accept: "application/json",
|
|
2482
|
+
},
|
|
2483
|
+
});
|
|
2484
|
+
|
|
2485
|
+
if (!response.ok) {
|
|
2486
|
+
throw new Error(
|
|
2487
|
+
\`\${label} failed at \${url} with HTTP \${response.status}.\`,
|
|
2488
|
+
);
|
|
2489
|
+
}
|
|
2490
|
+
|
|
2491
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
2492
|
+
if (!contentType.includes("application/json")) {
|
|
2493
|
+
throw new Error(
|
|
2494
|
+
\`\${label} at \${url} did not return JSON (content-type: \${contentType || "missing"}).\`,
|
|
2495
|
+
);
|
|
2496
|
+
}
|
|
2497
|
+
|
|
2498
|
+
return response.json();
|
|
2499
|
+
}
|
|
2500
|
+
|
|
2501
|
+
const baseUrl = new URL(
|
|
2502
|
+
getEnv("WP_TYPIA_SMOKE_BASE_URL", "http://localhost:8888"),
|
|
2503
|
+
);
|
|
2504
|
+
const serviceUrl = getEnv("WP_TYPIA_SERVICE_URL", "").trim();
|
|
2505
|
+
|
|
2506
|
+
// Extend this starter with project-specific generated REST clients or schema
|
|
2507
|
+
// checks as the workspace grows. For example, read JSON schemas under
|
|
2508
|
+
// src/rest/<resource>/api-schemas or import TS clients through a tsx-powered
|
|
2509
|
+
// smoke runner when you need authenticated route coverage.
|
|
2510
|
+
|
|
2511
|
+
await assertJsonEndpoint(
|
|
2512
|
+
"WordPress REST index",
|
|
2513
|
+
resolveEndpointUrl(baseUrl, "wp-json/"),
|
|
2514
|
+
);
|
|
2515
|
+
|
|
2516
|
+
if (serviceUrl.length > 0) {
|
|
2517
|
+
await assertJsonEndpoint(
|
|
2518
|
+
"Local integration service healthcheck",
|
|
2519
|
+
resolveEndpointUrl(serviceUrl, "health"),
|
|
2520
|
+
);
|
|
2521
|
+
}
|
|
2522
|
+
|
|
2523
|
+
console.log("wp-typia integration smoke passed: ${integrationEnvSlug}");
|
|
2524
|
+
`;
|
|
2525
|
+
}
|
|
2526
|
+
function buildEnvExampleSource(service) {
|
|
2527
|
+
return [
|
|
2528
|
+
"# wp-typia integration smoke settings",
|
|
2529
|
+
"WP_TYPIA_SMOKE_BASE_URL=http://localhost:8888",
|
|
2530
|
+
"WP_TYPIA_SMOKE_USERNAME=admin",
|
|
2531
|
+
"WP_TYPIA_SMOKE_PASSWORD=password",
|
|
2532
|
+
...service === "docker-compose" ? [
|
|
2533
|
+
"",
|
|
2534
|
+
"# Optional docker-compose integration service starter.",
|
|
2535
|
+
"WP_TYPIA_SERVICE_URL=http://localhost:3000"
|
|
2536
|
+
] : [
|
|
2537
|
+
"",
|
|
2538
|
+
"# Set this when your smoke test needs a project-specific service.",
|
|
2539
|
+
"# WP_TYPIA_SERVICE_URL=http://localhost:3000"
|
|
2540
|
+
],
|
|
2541
|
+
""
|
|
2542
|
+
].join(`
|
|
2543
|
+
`);
|
|
2544
|
+
}
|
|
2545
|
+
function buildIntegrationEnvReadmeSource({
|
|
2546
|
+
integrationEnvSlug,
|
|
2547
|
+
service,
|
|
2548
|
+
withReleaseZip,
|
|
2549
|
+
withWpEnv
|
|
2550
|
+
}) {
|
|
2551
|
+
const title = toTitleCase(integrationEnvSlug);
|
|
2552
|
+
const setupSteps = [
|
|
2553
|
+
"Copy `.env.example` to `.env` and adjust the URLs or credentials for your local project.",
|
|
2554
|
+
...withWpEnv ? [
|
|
2555
|
+
"Run `npm run wp-env:start` to start the generated WordPress environment."
|
|
2556
|
+
] : [
|
|
2557
|
+
"Point `WP_TYPIA_SMOKE_BASE_URL` at the WordPress environment you already run locally."
|
|
2558
|
+
],
|
|
2559
|
+
...service === "docker-compose" ? [
|
|
2560
|
+
"Run `npm run service:start` if you want the placeholder docker-compose service available at `WP_TYPIA_SERVICE_URL`."
|
|
2561
|
+
] : [
|
|
2562
|
+
"Set `WP_TYPIA_SERVICE_URL` only when your integration smoke needs a local service dependency."
|
|
2563
|
+
],
|
|
2564
|
+
`Run \`npm run smoke:${integrationEnvSlug}\` to execute the starter smoke check.`,
|
|
2565
|
+
...withReleaseZip ? [
|
|
2566
|
+
"Run `npm run release:zip` after smoke checks pass to build a distributable plugin zip."
|
|
2567
|
+
] : []
|
|
2568
|
+
];
|
|
2569
|
+
return `# ${title} Integration Environment
|
|
2570
|
+
|
|
2571
|
+
This starter keeps local WordPress integration smoke checks opt-in and editable.
|
|
2572
|
+
It does not change default block scaffolds or require wp-env unless this add
|
|
2573
|
+
workflow was run with \`--wp-env\`.
|
|
2574
|
+
|
|
2575
|
+
## Setup
|
|
2576
|
+
|
|
2577
|
+
${setupSteps.map((step, index) => `${index + 1}. ${step}`).join(`
|
|
2578
|
+
`)}
|
|
2579
|
+
|
|
2580
|
+
## Adapting the Starter
|
|
2581
|
+
|
|
2582
|
+
- Extend \`scripts/integration-smoke/${integrationEnvSlug}.mjs\` with the REST,
|
|
2583
|
+
editor, or service assertions that matter for this project.
|
|
2584
|
+
- Keep secrets in \`.env\`; \`.env.example\` should document only safe defaults.
|
|
2585
|
+
- If your project uses a real service stack, replace the placeholder
|
|
2586
|
+
\`docker-compose.integration.yml\` service with your database, queue, API, or
|
|
2587
|
+
emulator containers.
|
|
2588
|
+
- Keep the smoke script focused on high-signal integration checks so CI and
|
|
2589
|
+
local debugging stay fast.
|
|
2590
|
+
${withReleaseZip ? "- Treat `release:zip:check` as a CI guard before packaging release artifacts.\n" : ""}
|
|
2591
|
+
`;
|
|
2592
|
+
}
|
|
2593
|
+
async function appendMissingLines(filePath, lines) {
|
|
2594
|
+
const current = await readOptionalUtf8File(filePath) ?? "";
|
|
2595
|
+
const missingLines = lines.filter((line) => !current.includes(`${line}
|
|
2596
|
+
`) && !current.endsWith(line));
|
|
2597
|
+
if (missingLines.length === 0) {
|
|
2598
|
+
return;
|
|
2599
|
+
}
|
|
2600
|
+
const separator = current.length === 0 || current.endsWith(`
|
|
2601
|
+
`) ? "" : `
|
|
2602
|
+
`;
|
|
2603
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2604
|
+
await fsp4.writeFile(filePath, `${current}${separator}${missingLines.join(`
|
|
2605
|
+
`)}
|
|
2606
|
+
`, "utf8");
|
|
2607
|
+
}
|
|
2608
|
+
async function writeFileIfAbsent({
|
|
2609
|
+
filePath,
|
|
2610
|
+
source,
|
|
2611
|
+
warnings
|
|
2612
|
+
}) {
|
|
2613
|
+
if (await pathExists(filePath)) {
|
|
2614
|
+
warnings.push(`Preserved existing ${path5.basename(filePath)}; review it manually if you need different local integration settings.`);
|
|
2615
|
+
return;
|
|
2616
|
+
}
|
|
2617
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2618
|
+
await fsp4.writeFile(filePath, source, "utf8");
|
|
2619
|
+
}
|
|
2620
|
+
async function writeNewScaffoldFile(filePath, source) {
|
|
2621
|
+
if (await pathExists(filePath)) {
|
|
2622
|
+
throw new Error(`An integration environment scaffold already exists at ${filePath}. Choose a different name.`);
|
|
2623
|
+
}
|
|
2624
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2625
|
+
await fsp4.writeFile(filePath, source, "utf8");
|
|
2626
|
+
}
|
|
2627
|
+
function addScriptIfMissing({
|
|
2628
|
+
scriptName,
|
|
2629
|
+
scripts,
|
|
2630
|
+
scriptValue,
|
|
2631
|
+
warnings
|
|
2632
|
+
}) {
|
|
2633
|
+
if (scripts[scriptName] === undefined) {
|
|
2634
|
+
scripts[scriptName] = scriptValue;
|
|
2635
|
+
return;
|
|
2636
|
+
}
|
|
2637
|
+
if (scripts[scriptName] !== scriptValue) {
|
|
2638
|
+
warnings.push(`Preserved existing package script "${scriptName}"; add "${scriptValue}" manually if you want the generated integration command.`);
|
|
2639
|
+
}
|
|
2640
|
+
}
|
|
2641
|
+
async function mutatePackageJson2(projectDir, mutate) {
|
|
2642
|
+
const packageJsonPath = path5.join(projectDir, "package.json");
|
|
2643
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
2644
|
+
context: "integration env package manifest"
|
|
2645
|
+
});
|
|
2646
|
+
mutate(packageJson);
|
|
2647
|
+
await fsp4.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
2648
|
+
`, "utf8");
|
|
2649
|
+
}
|
|
2650
|
+
function addIntegrationEnvPackageJsonEntries({
|
|
2651
|
+
integrationEnvSlug,
|
|
2652
|
+
packageManager,
|
|
2653
|
+
packageJson,
|
|
2654
|
+
withReleaseZip,
|
|
2655
|
+
service,
|
|
2656
|
+
warnings,
|
|
2657
|
+
withWpEnv
|
|
2658
|
+
}) {
|
|
2659
|
+
const devDependencies = {
|
|
2660
|
+
...packageJson.devDependencies ?? {}
|
|
2661
|
+
};
|
|
2662
|
+
if (withWpEnv && devDependencies["@wordpress/env"] === undefined) {
|
|
2663
|
+
devDependencies["@wordpress/env"] = WP_ENV_PACKAGE_VERSION;
|
|
2664
|
+
}
|
|
2665
|
+
packageJson.devDependencies = devDependencies;
|
|
2666
|
+
const scripts = {
|
|
2667
|
+
...packageJson.scripts ?? {}
|
|
2668
|
+
};
|
|
2669
|
+
addScriptIfMissing({
|
|
2670
|
+
scriptName: `smoke:${integrationEnvSlug}`,
|
|
2671
|
+
scriptValue: `node scripts/integration-smoke/${integrationEnvSlug}.mjs`,
|
|
2672
|
+
scripts,
|
|
2673
|
+
warnings
|
|
2674
|
+
});
|
|
2675
|
+
addScriptIfMissing({
|
|
2676
|
+
scriptName: "smoke:integration",
|
|
2677
|
+
scriptValue: formatRunScript(packageManager, `smoke:${integrationEnvSlug}`),
|
|
2678
|
+
scripts,
|
|
2679
|
+
warnings
|
|
2680
|
+
});
|
|
2681
|
+
if (withWpEnv) {
|
|
2682
|
+
addScriptIfMissing({
|
|
2683
|
+
scriptName: "wp-env:start",
|
|
2684
|
+
scriptValue: "wp-env start",
|
|
2685
|
+
scripts,
|
|
2686
|
+
warnings
|
|
2687
|
+
});
|
|
2688
|
+
addScriptIfMissing({
|
|
2689
|
+
scriptName: "wp-env:stop",
|
|
2690
|
+
scriptValue: "wp-env stop",
|
|
2691
|
+
scripts,
|
|
2692
|
+
warnings
|
|
2693
|
+
});
|
|
2694
|
+
addScriptIfMissing({
|
|
2695
|
+
scriptName: "wp-env:reset",
|
|
2696
|
+
scriptValue: "wp-env destroy all && wp-env start",
|
|
2697
|
+
scripts,
|
|
2698
|
+
warnings
|
|
2699
|
+
});
|
|
2700
|
+
}
|
|
2701
|
+
if (withReleaseZip) {
|
|
2702
|
+
addScriptIfMissing({
|
|
2703
|
+
scriptName: "release:zip",
|
|
2704
|
+
scriptValue: `${formatRunScript(packageManager, "sync-rest:package")} && ${formatRunScript(packageManager, "build")} && wp-scripts plugin-zip`,
|
|
2705
|
+
scripts,
|
|
2706
|
+
warnings
|
|
2707
|
+
});
|
|
2708
|
+
addScriptIfMissing({
|
|
2709
|
+
scriptName: "release:zip:check",
|
|
2710
|
+
scriptValue: `${formatRunScript(packageManager, "sync-rest:package:check")} && ${formatRunScript(packageManager, "build")}`,
|
|
2711
|
+
scripts,
|
|
2712
|
+
warnings
|
|
2713
|
+
});
|
|
2714
|
+
addScriptIfMissing({
|
|
2715
|
+
scriptName: "qa:check",
|
|
2716
|
+
scriptValue: `${formatRunScript(packageManager, "wp-typia:doctor:workspace")} && ${formatRunScript(packageManager, "release:zip:check")}`,
|
|
2717
|
+
scripts,
|
|
2718
|
+
warnings
|
|
2719
|
+
});
|
|
2720
|
+
}
|
|
2721
|
+
if (service === "docker-compose") {
|
|
2722
|
+
addScriptIfMissing({
|
|
2723
|
+
scriptName: "service:start",
|
|
2724
|
+
scriptValue: "docker compose -f docker-compose.integration.yml up -d",
|
|
2725
|
+
scripts,
|
|
2726
|
+
warnings
|
|
2727
|
+
});
|
|
2728
|
+
addScriptIfMissing({
|
|
2729
|
+
scriptName: "service:stop",
|
|
2730
|
+
scriptValue: "docker compose -f docker-compose.integration.yml down",
|
|
2731
|
+
scripts,
|
|
2732
|
+
warnings
|
|
2733
|
+
});
|
|
2734
|
+
}
|
|
2735
|
+
packageJson.scripts = scripts;
|
|
2736
|
+
}
|
|
2737
|
+
async function runAddIntegrationEnvCommand({
|
|
2738
|
+
cwd = process.cwd(),
|
|
2739
|
+
integrationEnvName,
|
|
2740
|
+
service,
|
|
2741
|
+
withReleaseZip = false,
|
|
2742
|
+
withWpEnv = false
|
|
2743
|
+
}) {
|
|
2744
|
+
const workspace = resolveWorkspaceProject(cwd);
|
|
2745
|
+
const integrationEnvSlug = assertValidGeneratedSlug("Integration environment name", normalizeBlockSlug(integrationEnvName), "wp-typia add integration-env <name> [--wp-env] [--release-zip]");
|
|
2746
|
+
const serviceId = assertValidIntegrationEnvService(service);
|
|
2747
|
+
const warnings = [];
|
|
2748
|
+
const packageJsonPath = path5.join(workspace.projectDir, "package.json");
|
|
2749
|
+
const gitignorePath = path5.join(workspace.projectDir, ".gitignore");
|
|
2750
|
+
const envExamplePath = path5.join(workspace.projectDir, ".env.example");
|
|
2751
|
+
const wpEnvPath = path5.join(workspace.projectDir, ".wp-env.json");
|
|
2752
|
+
const dockerComposePath = path5.join(workspace.projectDir, "docker-compose.integration.yml");
|
|
2753
|
+
const smokeDir = path5.join(workspace.projectDir, "scripts", "integration-smoke");
|
|
2754
|
+
const docsDir = path5.join(workspace.projectDir, "docs", "integration-env");
|
|
2755
|
+
const smokeScriptPath = path5.join(smokeDir, `${integrationEnvSlug}.mjs`);
|
|
2756
|
+
const docsPath = path5.join(docsDir, `${integrationEnvSlug}.md`);
|
|
2757
|
+
const shouldRemoveSmokeDirOnRollback = !await pathExists(smokeDir);
|
|
2758
|
+
const shouldRemoveDocsDirOnRollback = !await pathExists(docsDir);
|
|
2759
|
+
await executeWorkspaceMutationPlan({
|
|
2760
|
+
filePaths: [
|
|
2761
|
+
packageJsonPath,
|
|
2762
|
+
gitignorePath,
|
|
2763
|
+
envExamplePath,
|
|
2764
|
+
...withWpEnv ? [wpEnvPath] : [],
|
|
2765
|
+
...serviceId === "docker-compose" ? [dockerComposePath] : []
|
|
2766
|
+
],
|
|
2767
|
+
targetPaths: [
|
|
2768
|
+
smokeScriptPath,
|
|
2769
|
+
docsPath,
|
|
2770
|
+
...shouldRemoveSmokeDirOnRollback ? [smokeDir] : [],
|
|
2771
|
+
...shouldRemoveDocsDirOnRollback ? [docsDir] : []
|
|
2772
|
+
],
|
|
2773
|
+
run: async () => {
|
|
2774
|
+
await writeNewScaffoldFile(smokeScriptPath, buildIntegrationSmokeScriptSource(integrationEnvSlug));
|
|
2775
|
+
await writeNewScaffoldFile(docsPath, buildIntegrationEnvReadmeSource({
|
|
2776
|
+
integrationEnvSlug,
|
|
2777
|
+
service: serviceId,
|
|
2778
|
+
withReleaseZip,
|
|
2779
|
+
withWpEnv
|
|
2780
|
+
}));
|
|
2781
|
+
await appendMissingLines(envExamplePath, [
|
|
2782
|
+
...buildEnvExampleSource(serviceId).trimEnd().split(`
|
|
2783
|
+
`)
|
|
2784
|
+
]);
|
|
2785
|
+
await appendMissingLines(gitignorePath, [".env", ".env.local"]);
|
|
2786
|
+
if (withWpEnv) {
|
|
2787
|
+
await writeFileIfAbsent({
|
|
2788
|
+
filePath: wpEnvPath,
|
|
2789
|
+
source: buildWpEnvConfigSource(),
|
|
2790
|
+
warnings
|
|
2791
|
+
});
|
|
2792
|
+
}
|
|
2793
|
+
if (serviceId === "docker-compose") {
|
|
2794
|
+
await writeFileIfAbsent({
|
|
2795
|
+
filePath: dockerComposePath,
|
|
2796
|
+
source: buildDockerComposeSource(),
|
|
2797
|
+
warnings
|
|
2798
|
+
});
|
|
2799
|
+
}
|
|
2800
|
+
await mutatePackageJson2(workspace.projectDir, (packageJson) => addIntegrationEnvPackageJsonEntries({
|
|
2801
|
+
integrationEnvSlug,
|
|
2802
|
+
packageManager: workspace.packageManager,
|
|
2803
|
+
packageJson,
|
|
2804
|
+
service: serviceId,
|
|
2805
|
+
withReleaseZip,
|
|
2806
|
+
warnings,
|
|
2807
|
+
withWpEnv
|
|
2808
|
+
}));
|
|
2809
|
+
}
|
|
2810
|
+
});
|
|
2811
|
+
return {
|
|
2812
|
+
integrationEnvSlug,
|
|
2813
|
+
projectDir: workspace.projectDir,
|
|
2814
|
+
service: serviceId,
|
|
2815
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
2816
|
+
withReleaseZip,
|
|
2817
|
+
withWpEnv
|
|
2818
|
+
};
|
|
2819
|
+
}
|
|
2820
|
+
|
|
2291
2821
|
// ../wp-typia-project-tools/src/runtime/cli-validation.ts
|
|
2292
2822
|
import fs3 from "fs";
|
|
2293
|
-
import
|
|
2823
|
+
import path6 from "path";
|
|
2294
2824
|
function normalizeOptionalCliString(value) {
|
|
2295
2825
|
if (typeof value !== "string") {
|
|
2296
2826
|
return;
|
|
@@ -2299,14 +2829,14 @@ function normalizeOptionalCliString(value) {
|
|
|
2299
2829
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
2300
2830
|
}
|
|
2301
2831
|
function looksLikeLocalCliPath(value) {
|
|
2302
|
-
return
|
|
2832
|
+
return path6.isAbsolute(value) || value.startsWith("./") || value.startsWith("../") || value.startsWith(".\\") || value.startsWith("..\\");
|
|
2303
2833
|
}
|
|
2304
2834
|
function resolveLocalCliPathOption(options) {
|
|
2305
2835
|
const normalizedValue = normalizeOptionalCliString(options.value);
|
|
2306
2836
|
if (!normalizedValue || !looksLikeLocalCliPath(normalizedValue)) {
|
|
2307
2837
|
return normalizedValue;
|
|
2308
2838
|
}
|
|
2309
|
-
const resolvedPath =
|
|
2839
|
+
const resolvedPath = path6.resolve(options.cwd, normalizedValue);
|
|
2310
2840
|
if (!fs3.existsSync(resolvedPath)) {
|
|
2311
2841
|
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `\`${options.label}\` path does not exist: ${resolvedPath}. Check the path relative to ${options.cwd}.`);
|
|
2312
2842
|
}
|
|
@@ -2557,35 +3087,37 @@ async function collectScaffoldAnswers({
|
|
|
2557
3087
|
}
|
|
2558
3088
|
|
|
2559
3089
|
// ../wp-typia-project-tools/src/runtime/scaffold.ts
|
|
2560
|
-
import { promises as
|
|
2561
|
-
import
|
|
3090
|
+
import { promises as fsp13 } from "fs";
|
|
3091
|
+
import path18 from "path";
|
|
2562
3092
|
|
|
2563
3093
|
// ../wp-typia-project-tools/src/runtime/scaffold-apply-utils.ts
|
|
2564
|
-
import { promises as
|
|
2565
|
-
import
|
|
3094
|
+
import { promises as fsp7 } from "fs";
|
|
3095
|
+
import path10 from "path";
|
|
2566
3096
|
import { execSync as execSync3 } from "child_process";
|
|
2567
3097
|
import { fileURLToPath } from "url";
|
|
2568
3098
|
|
|
2569
3099
|
// ../wp-typia-project-tools/src/runtime/migration-ui-capability.ts
|
|
2570
|
-
import { promises as
|
|
2571
|
-
import
|
|
3100
|
+
import { promises as fsp5 } from "fs";
|
|
3101
|
+
import path7 from "path";
|
|
2572
3102
|
var INITIAL_MIGRATION_VERSION = "v1";
|
|
2573
3103
|
var BLOCK_METADATA_IMPORT_LINE = "import metadata from './block-metadata';";
|
|
2574
3104
|
var LEGACY_BLOCK_JSON_IMPORT_LINE = "import metadata from './block.json';";
|
|
2575
|
-
async function
|
|
2576
|
-
const packageJsonPath =
|
|
2577
|
-
const packageJson =
|
|
3105
|
+
async function mutatePackageJson3(projectDir, mutate) {
|
|
3106
|
+
const packageJsonPath = path7.join(projectDir, "package.json");
|
|
3107
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
3108
|
+
context: "migration UI package manifest"
|
|
3109
|
+
});
|
|
2578
3110
|
mutate(packageJson);
|
|
2579
|
-
await
|
|
3111
|
+
await fsp5.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
2580
3112
|
`, "utf8");
|
|
2581
3113
|
}
|
|
2582
3114
|
async function patchFile(filePath, transform) {
|
|
2583
|
-
const source = await
|
|
3115
|
+
const source = await fsp5.readFile(filePath, "utf8");
|
|
2584
3116
|
const nextSource = transform(source);
|
|
2585
3117
|
if (nextSource === source) {
|
|
2586
3118
|
throw new Error(`Unable to apply migration UI patch for ${filePath}`);
|
|
2587
3119
|
}
|
|
2588
|
-
await
|
|
3120
|
+
await fsp5.writeFile(filePath, nextSource, "utf8");
|
|
2589
3121
|
}
|
|
2590
3122
|
function injectAfter(source, needle, insertion) {
|
|
2591
3123
|
if (source.includes(insertion)) {
|
|
@@ -2647,8 +3179,8 @@ function buildMigrationBlocks(templateId, variables) {
|
|
|
2647
3179
|
];
|
|
2648
3180
|
}
|
|
2649
3181
|
async function applySingleBlockPatches(projectDir, variables) {
|
|
2650
|
-
const editPath =
|
|
2651
|
-
const indexPath =
|
|
3182
|
+
const editPath = path7.join(projectDir, "src", "edit.tsx");
|
|
3183
|
+
const indexPath = path7.join(projectDir, "src", "index.tsx");
|
|
2652
3184
|
const deprecatedImport = `import { deprecated } from './migrations/generated/${variables.slugKebabCase}/deprecated';`;
|
|
2653
3185
|
const deprecatedLine = " deprecated,";
|
|
2654
3186
|
const dashboardImport = `import { MigrationDashboard } from './admin/migration-dashboard';`;
|
|
@@ -2669,10 +3201,10 @@ async function applySingleBlockPatches(projectDir, variables) {
|
|
|
2669
3201
|
});
|
|
2670
3202
|
}
|
|
2671
3203
|
async function applyCompoundPatches(projectDir, variables) {
|
|
2672
|
-
const parentEditPath =
|
|
2673
|
-
const parentIndexPath =
|
|
2674
|
-
const childIndexPath =
|
|
2675
|
-
const addChildScriptPath =
|
|
3204
|
+
const parentEditPath = path7.join(projectDir, "src", "blocks", variables.slugKebabCase, "edit.tsx");
|
|
3205
|
+
const parentIndexPath = path7.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx");
|
|
3206
|
+
const childIndexPath = path7.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`, "index.tsx");
|
|
3207
|
+
const addChildScriptPath = path7.join(projectDir, "scripts", "add-compound-child.ts");
|
|
2676
3208
|
await patchFile(parentIndexPath, (source) => {
|
|
2677
3209
|
let nextSource = injectAfterBlockMetadataImport(source, `import { deprecated } from '../../migrations/generated/${variables.slugKebabCase}/deprecated';`);
|
|
2678
3210
|
nextSource = injectBefore(nextSource, "\tedit: Edit,", "\tdeprecated,");
|
|
@@ -2742,9 +3274,9 @@ async function applyMigrationUiCapability({
|
|
|
2742
3274
|
templateId,
|
|
2743
3275
|
variables
|
|
2744
3276
|
}) {
|
|
2745
|
-
const commonTemplateDir =
|
|
3277
|
+
const commonTemplateDir = path7.join(SHARED_MIGRATION_UI_TEMPLATE_ROOT, "common");
|
|
2746
3278
|
await copyInterpolatedDirectory(commonTemplateDir, projectDir, variables);
|
|
2747
|
-
await
|
|
3279
|
+
await mutatePackageJson3(projectDir, (packageJson) => {
|
|
2748
3280
|
const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
|
|
2749
3281
|
const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0" ? "wp-typia" : `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
|
|
2750
3282
|
const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
|
|
@@ -2996,9 +3528,9 @@ function mergeTextLines(primaryContent, existingContent) {
|
|
|
2996
3528
|
}
|
|
2997
3529
|
|
|
2998
3530
|
// ../wp-typia-project-tools/src/runtime/scaffold-package-manager-files.ts
|
|
2999
|
-
import { promises as
|
|
3531
|
+
import { promises as fsp6 } from "fs";
|
|
3000
3532
|
import { execSync as execSync2 } from "child_process";
|
|
3001
|
-
import
|
|
3533
|
+
import path8 from "path";
|
|
3002
3534
|
var LOCKFILES = {
|
|
3003
3535
|
bun: ["bun.lock", "bun.lockb"],
|
|
3004
3536
|
npm: ["package-lock.json"],
|
|
@@ -3006,22 +3538,25 @@ var LOCKFILES = {
|
|
|
3006
3538
|
yarn: ["yarn.lock"]
|
|
3007
3539
|
};
|
|
3008
3540
|
async function normalizePackageManagerFiles(targetDir, packageManagerId) {
|
|
3009
|
-
const yarnRcPath =
|
|
3541
|
+
const yarnRcPath = path8.join(targetDir, ".yarnrc.yml");
|
|
3010
3542
|
if (packageManagerId === "yarn") {
|
|
3011
|
-
await
|
|
3543
|
+
await fsp6.writeFile(yarnRcPath, `nodeLinker: node-modules
|
|
3012
3544
|
`, "utf8");
|
|
3013
3545
|
return;
|
|
3014
3546
|
}
|
|
3015
|
-
await
|
|
3547
|
+
await fsp6.rm(yarnRcPath, { force: true });
|
|
3016
3548
|
}
|
|
3017
3549
|
async function normalizePackageJson(targetDir, packageManagerId) {
|
|
3018
|
-
const packageJsonPath =
|
|
3550
|
+
const packageJsonPath = path8.join(targetDir, "package.json");
|
|
3019
3551
|
const packageJsonSource = await readOptionalUtf8File(packageJsonPath);
|
|
3020
3552
|
if (packageJsonSource === null) {
|
|
3021
3553
|
return;
|
|
3022
3554
|
}
|
|
3023
3555
|
const packageManager = getPackageManager(packageManagerId);
|
|
3024
|
-
const packageJson =
|
|
3556
|
+
const packageJson = safeJsonParse(packageJsonSource, {
|
|
3557
|
+
context: "generated package manifest",
|
|
3558
|
+
filePath: packageJsonPath
|
|
3559
|
+
});
|
|
3025
3560
|
if (packageManagerId === "npm") {
|
|
3026
3561
|
delete packageJson.packageManager;
|
|
3027
3562
|
} else {
|
|
@@ -3034,7 +3569,7 @@ async function normalizePackageJson(targetDir, packageManagerId) {
|
|
|
3034
3569
|
}
|
|
3035
3570
|
}
|
|
3036
3571
|
}
|
|
3037
|
-
await
|
|
3572
|
+
await fsp6.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
3038
3573
|
`, "utf8");
|
|
3039
3574
|
}
|
|
3040
3575
|
async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
|
|
@@ -3044,7 +3579,7 @@ async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
|
|
|
3044
3579
|
if (keep.has(filename)) {
|
|
3045
3580
|
return;
|
|
3046
3581
|
}
|
|
3047
|
-
await
|
|
3582
|
+
await fsp6.rm(path8.join(targetDir, filename), { force: true });
|
|
3048
3583
|
}));
|
|
3049
3584
|
}
|
|
3050
3585
|
async function defaultInstallDependencies({
|
|
@@ -3057,14 +3592,15 @@ async function defaultInstallDependencies({
|
|
|
3057
3592
|
});
|
|
3058
3593
|
}
|
|
3059
3594
|
// ../wp-typia-project-tools/src/runtime/scaffold-repository-reference.ts
|
|
3060
|
-
import fs4 from "fs";
|
|
3061
3595
|
import { createRequire } from "module";
|
|
3062
|
-
import
|
|
3596
|
+
import path9 from "path";
|
|
3063
3597
|
var require2 = createRequire(import.meta.url);
|
|
3064
3598
|
var DEFAULT_SCAFFOLD_REPOSITORY_REFERENCE = "imjlk/wp-typia";
|
|
3065
3599
|
function readRepositoryPackageManifest(packageJsonPath) {
|
|
3066
3600
|
try {
|
|
3067
|
-
return
|
|
3601
|
+
return readJsonFileSync(packageJsonPath, {
|
|
3602
|
+
context: "repository package manifest"
|
|
3603
|
+
});
|
|
3068
3604
|
} catch (error) {
|
|
3069
3605
|
if (getOptionalNodeErrorCode(error) === "ENOENT") {
|
|
3070
3606
|
return null;
|
|
@@ -3122,9 +3658,9 @@ function parseRepositoryReference(value) {
|
|
|
3122
3658
|
}
|
|
3123
3659
|
function getDefaultRepositoryManifestPaths() {
|
|
3124
3660
|
const candidatePaths = [
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3661
|
+
path9.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "package.json"),
|
|
3662
|
+
path9.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "wp-typia", "package.json"),
|
|
3663
|
+
path9.join(PROJECT_TOOLS_PACKAGE_ROOT, "package.json"),
|
|
3128
3664
|
resolveInstalledPackageManifestPath("wp-typia"),
|
|
3129
3665
|
resolveInstalledPackageManifestPath("@wp-typia/project-tools")
|
|
3130
3666
|
].filter((candidatePath) => Boolean(candidatePath));
|
|
@@ -3151,7 +3687,7 @@ async function reportScaffoldProgress(onProgress, event) {
|
|
|
3151
3687
|
await onProgress?.(event);
|
|
3152
3688
|
}
|
|
3153
3689
|
var EPHEMERAL_NODE_MODULES_LINK_TYPE2 = process.platform === "win32" ? "junction" : "dir";
|
|
3154
|
-
var __dirname2 =
|
|
3690
|
+
var __dirname2 = path10.dirname(fileURLToPath(import.meta.url));
|
|
3155
3691
|
var LOCKFILES2 = {
|
|
3156
3692
|
bun: ["bun.lock", "bun.lockb"],
|
|
3157
3693
|
npm: ["package-lock.json"],
|
|
@@ -3159,11 +3695,11 @@ var LOCKFILES2 = {
|
|
|
3159
3695
|
yarn: ["yarn.lock"]
|
|
3160
3696
|
};
|
|
3161
3697
|
async function ensureDirectory(targetDir, allowExisting = false) {
|
|
3162
|
-
await
|
|
3698
|
+
await fsp7.mkdir(targetDir, { recursive: true });
|
|
3163
3699
|
if (allowExisting) {
|
|
3164
3700
|
return;
|
|
3165
3701
|
}
|
|
3166
|
-
const entries = await
|
|
3702
|
+
const entries = await fsp7.readdir(targetDir);
|
|
3167
3703
|
if (entries.length > 0) {
|
|
3168
3704
|
throw new Error(formatNonEmptyTargetDirectoryError(targetDir));
|
|
3169
3705
|
}
|
|
@@ -3174,42 +3710,42 @@ async function writeStarterManifestFiles2(targetDir, templateId, variables, arti
|
|
|
3174
3710
|
relativePath: `${artifact.relativeDir}/typia.manifest.json`
|
|
3175
3711
|
})) : getStarterManifestFiles(templateId, variables);
|
|
3176
3712
|
for (const { document, relativePath } of manifests) {
|
|
3177
|
-
const destinationPath =
|
|
3178
|
-
await
|
|
3179
|
-
await
|
|
3713
|
+
const destinationPath = path10.join(targetDir, relativePath);
|
|
3714
|
+
await fsp7.mkdir(path10.dirname(destinationPath), { recursive: true });
|
|
3715
|
+
await fsp7.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
|
|
3180
3716
|
}
|
|
3181
3717
|
}
|
|
3182
3718
|
async function writeBuiltInStructuralArtifacts(targetDir, artifacts) {
|
|
3183
3719
|
for (const artifact of artifacts) {
|
|
3184
|
-
const destinationDir =
|
|
3185
|
-
await
|
|
3186
|
-
await
|
|
3187
|
-
await
|
|
3720
|
+
const destinationDir = path10.join(targetDir, artifact.relativeDir);
|
|
3721
|
+
await fsp7.mkdir(destinationDir, { recursive: true });
|
|
3722
|
+
await fsp7.writeFile(path10.join(destinationDir, "types.ts"), artifact.typesSource, "utf8");
|
|
3723
|
+
await fsp7.writeFile(path10.join(destinationDir, "block.json"), stringifyBuiltInBlockJsonDocument(artifact.blockJsonDocument), "utf8");
|
|
3188
3724
|
}
|
|
3189
3725
|
}
|
|
3190
3726
|
async function writeBuiltInCodeArtifacts(targetDir, codeArtifacts) {
|
|
3191
3727
|
for (const artifact of codeArtifacts) {
|
|
3192
|
-
const destinationPath =
|
|
3193
|
-
await
|
|
3194
|
-
await
|
|
3728
|
+
const destinationPath = path10.join(targetDir, artifact.relativePath);
|
|
3729
|
+
await fsp7.mkdir(path10.dirname(destinationPath), { recursive: true });
|
|
3730
|
+
await fsp7.writeFile(destinationPath, artifact.source, "utf8");
|
|
3195
3731
|
}
|
|
3196
3732
|
}
|
|
3197
3733
|
async function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
3198
|
-
const projectToolsPackageRoot =
|
|
3734
|
+
const projectToolsPackageRoot = path10.resolve(__dirname2, "..", "..");
|
|
3199
3735
|
const candidates = [
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3736
|
+
path10.join(projectToolsPackageRoot, "node_modules"),
|
|
3737
|
+
path10.resolve(projectToolsPackageRoot, "..", ".."),
|
|
3738
|
+
path10.resolve(projectToolsPackageRoot, "..", "..", "node_modules")
|
|
3203
3739
|
];
|
|
3204
3740
|
for (const candidate of candidates) {
|
|
3205
|
-
if (await pathExists(
|
|
3741
|
+
if (await pathExists(path10.join(candidate, "typia", "package.json"))) {
|
|
3206
3742
|
return candidate;
|
|
3207
3743
|
}
|
|
3208
3744
|
}
|
|
3209
3745
|
return null;
|
|
3210
3746
|
}
|
|
3211
3747
|
async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
|
|
3212
|
-
const targetNodeModulesPath =
|
|
3748
|
+
const targetNodeModulesPath = path10.join(targetDir, "node_modules");
|
|
3213
3749
|
if (await pathExists(targetNodeModulesPath)) {
|
|
3214
3750
|
await callback();
|
|
3215
3751
|
return;
|
|
@@ -3218,11 +3754,11 @@ async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
|
|
|
3218
3754
|
if (!sourceNodeModulesPath) {
|
|
3219
3755
|
throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
|
|
3220
3756
|
}
|
|
3221
|
-
await
|
|
3757
|
+
await fsp7.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE2);
|
|
3222
3758
|
try {
|
|
3223
3759
|
await callback();
|
|
3224
3760
|
} finally {
|
|
3225
|
-
await
|
|
3761
|
+
await fsp7.rm(targetNodeModulesPath, { force: true, recursive: true });
|
|
3226
3762
|
}
|
|
3227
3763
|
}
|
|
3228
3764
|
async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables) {
|
|
@@ -3233,7 +3769,7 @@ async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables
|
|
|
3233
3769
|
await withEphemeralScaffoldNodeModules2(targetDir, async () => {
|
|
3234
3770
|
if (templateId === "persistence") {
|
|
3235
3771
|
await syncPersistenceRestArtifacts({
|
|
3236
|
-
apiTypesFile:
|
|
3772
|
+
apiTypesFile: path10.join("src", "api-types.ts"),
|
|
3237
3773
|
outputDir: "src",
|
|
3238
3774
|
projectDir: targetDir,
|
|
3239
3775
|
variables
|
|
@@ -3241,27 +3777,27 @@ async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables
|
|
|
3241
3777
|
return;
|
|
3242
3778
|
}
|
|
3243
3779
|
await syncPersistenceRestArtifacts({
|
|
3244
|
-
apiTypesFile:
|
|
3245
|
-
outputDir:
|
|
3780
|
+
apiTypesFile: path10.join("src", "blocks", variables.slugKebabCase, "api-types.ts"),
|
|
3781
|
+
outputDir: path10.join("src", "blocks", variables.slugKebabCase),
|
|
3246
3782
|
projectDir: targetDir,
|
|
3247
3783
|
variables
|
|
3248
3784
|
});
|
|
3249
3785
|
});
|
|
3250
3786
|
}
|
|
3251
3787
|
async function normalizePackageManagerFiles2(targetDir, packageManagerId) {
|
|
3252
|
-
const yarnRcPath =
|
|
3788
|
+
const yarnRcPath = path10.join(targetDir, ".yarnrc.yml");
|
|
3253
3789
|
if (packageManagerId === "yarn") {
|
|
3254
|
-
await
|
|
3790
|
+
await fsp7.writeFile(yarnRcPath, `nodeLinker: node-modules
|
|
3255
3791
|
`, "utf8");
|
|
3256
3792
|
return;
|
|
3257
3793
|
}
|
|
3258
|
-
await
|
|
3794
|
+
await fsp7.rm(yarnRcPath, { force: true });
|
|
3259
3795
|
}
|
|
3260
3796
|
async function removeQueryLoopPlaceholderFiles(projectDir, templateId) {
|
|
3261
3797
|
if (templateId !== "query-loop") {
|
|
3262
3798
|
return;
|
|
3263
3799
|
}
|
|
3264
|
-
await
|
|
3800
|
+
await fsp7.rm(path10.join(projectDir, "src", "validator-toolkit.ts"), {
|
|
3265
3801
|
force: true
|
|
3266
3802
|
});
|
|
3267
3803
|
}
|
|
@@ -3272,7 +3808,7 @@ async function removeUnexpectedLockfiles2(targetDir, packageManagerId) {
|
|
|
3272
3808
|
if (keep.has(filename)) {
|
|
3273
3809
|
return;
|
|
3274
3810
|
}
|
|
3275
|
-
await
|
|
3811
|
+
await fsp7.rm(path10.join(targetDir, filename), { force: true });
|
|
3276
3812
|
}));
|
|
3277
3813
|
}
|
|
3278
3814
|
async function replaceTextRecursively(targetDir, packageManagerId, {
|
|
@@ -3295,21 +3831,21 @@ async function replaceTextRecursively(targetDir, packageManagerId, {
|
|
|
3295
3831
|
manifestPaths: repositoryManifestPaths
|
|
3296
3832
|
});
|
|
3297
3833
|
async function visit(currentPath) {
|
|
3298
|
-
const stats = await
|
|
3834
|
+
const stats = await fsp7.stat(currentPath);
|
|
3299
3835
|
if (stats.isDirectory()) {
|
|
3300
|
-
const entries = await
|
|
3836
|
+
const entries = await fsp7.readdir(currentPath);
|
|
3301
3837
|
for (const entry of entries) {
|
|
3302
|
-
await visit(
|
|
3838
|
+
await visit(path10.join(currentPath, entry));
|
|
3303
3839
|
}
|
|
3304
3840
|
return;
|
|
3305
3841
|
}
|
|
3306
|
-
if (
|
|
3842
|
+
if (path10.basename(currentPath) === "package.json" || !textExtensions.has(path10.extname(currentPath))) {
|
|
3307
3843
|
return;
|
|
3308
3844
|
}
|
|
3309
|
-
const content = await
|
|
3845
|
+
const content = await fsp7.readFile(currentPath, "utf8");
|
|
3310
3846
|
const nextContent = replaceRepositoryReferencePlaceholders(transformPackageManagerText(content, packageManagerId), resolvedRepositoryReference);
|
|
3311
3847
|
if (nextContent !== content) {
|
|
3312
|
-
await
|
|
3848
|
+
await fsp7.writeFile(currentPath, nextContent, "utf8");
|
|
3313
3849
|
}
|
|
3314
3850
|
}
|
|
3315
3851
|
await visit(targetDir);
|
|
@@ -3381,17 +3917,17 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
3381
3917
|
phase: "finalize-project",
|
|
3382
3918
|
title: "Finalizing scaffold output"
|
|
3383
3919
|
});
|
|
3384
|
-
const readmePath =
|
|
3920
|
+
const readmePath = path10.join(projectDir, "README.md");
|
|
3385
3921
|
if (!await pathExists(readmePath)) {
|
|
3386
|
-
await
|
|
3922
|
+
await fsp7.writeFile(readmePath, readmeContent ?? buildReadme(templateId, variables, packageManager, {
|
|
3387
3923
|
withMigrationUi,
|
|
3388
3924
|
withTestPreset,
|
|
3389
3925
|
withWpEnv
|
|
3390
3926
|
}), "utf8");
|
|
3391
3927
|
}
|
|
3392
|
-
const gitignorePath =
|
|
3928
|
+
const gitignorePath = path10.join(projectDir, ".gitignore");
|
|
3393
3929
|
const existingGitignore = await readOptionalUtf8File(gitignorePath) ?? "";
|
|
3394
|
-
await
|
|
3930
|
+
await fsp7.writeFile(gitignorePath, mergeTextLines(gitignoreContent ?? buildGitignore(), existingGitignore), "utf8");
|
|
3395
3931
|
await normalizePackageJson(projectDir, packageManager);
|
|
3396
3932
|
await applyGeneratedProjectDxPackageJson({
|
|
3397
3933
|
compoundPersistenceEnabled: isCompoundPersistenceEnabled(variables),
|
|
@@ -3422,31 +3958,31 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
3422
3958
|
}
|
|
3423
3959
|
|
|
3424
3960
|
// ../wp-typia-project-tools/src/runtime/template-source-normalization.ts
|
|
3425
|
-
import
|
|
3961
|
+
import path14 from "path";
|
|
3426
3962
|
|
|
3427
3963
|
// ../wp-typia-project-tools/src/runtime/template-layers.ts
|
|
3428
|
-
import
|
|
3429
|
-
import { promises as
|
|
3964
|
+
import path11 from "path";
|
|
3965
|
+
import { promises as fsp8 } from "fs";
|
|
3430
3966
|
var TEMPLATE_LAYER_MANIFEST_FILENAME = "wp-typia.layers.json";
|
|
3431
3967
|
var TEMPLATE_LAYER_MANIFEST_VERSION = 1;
|
|
3432
3968
|
function resolveLayerPath(sourceRoot, relativePath) {
|
|
3433
|
-
const targetPath =
|
|
3434
|
-
const relativeTarget =
|
|
3435
|
-
if (relativeTarget.startsWith("..") ||
|
|
3969
|
+
const targetPath = path11.resolve(sourceRoot, relativePath);
|
|
3970
|
+
const relativeTarget = path11.relative(sourceRoot, targetPath);
|
|
3971
|
+
if (relativeTarget.startsWith("..") || path11.isAbsolute(relativeTarget)) {
|
|
3436
3972
|
throw new Error(`Template layer path "${relativePath}" must stay within ${sourceRoot}.`);
|
|
3437
3973
|
}
|
|
3438
3974
|
return targetPath;
|
|
3439
3975
|
}
|
|
3440
3976
|
async function assertNoSymlinks(sourceDir) {
|
|
3441
|
-
const stats = await
|
|
3977
|
+
const stats = await fsp8.lstat(sourceDir);
|
|
3442
3978
|
if (stats.isSymbolicLink()) {
|
|
3443
3979
|
throw new Error(`Template layer packages may not include symbolic links: ${sourceDir}`);
|
|
3444
3980
|
}
|
|
3445
3981
|
if (!stats.isDirectory()) {
|
|
3446
3982
|
return;
|
|
3447
3983
|
}
|
|
3448
|
-
for (const entry of await
|
|
3449
|
-
await assertNoSymlinks(
|
|
3984
|
+
for (const entry of await fsp8.readdir(sourceDir)) {
|
|
3985
|
+
await assertNoSymlinks(path11.join(sourceDir, entry));
|
|
3450
3986
|
}
|
|
3451
3987
|
}
|
|
3452
3988
|
function parseLayerDefinition(layerId, value) {
|
|
@@ -3475,11 +4011,13 @@ function parseLayerDefinition(layerId, value) {
|
|
|
3475
4011
|
};
|
|
3476
4012
|
}
|
|
3477
4013
|
async function loadExternalTemplateLayerManifest(sourceRoot) {
|
|
3478
|
-
const manifestPath =
|
|
4014
|
+
const manifestPath = path11.join(sourceRoot, TEMPLATE_LAYER_MANIFEST_FILENAME);
|
|
3479
4015
|
if (!await pathExists(manifestPath)) {
|
|
3480
4016
|
return null;
|
|
3481
4017
|
}
|
|
3482
|
-
const raw =
|
|
4018
|
+
const raw = await readJsonFile(manifestPath, {
|
|
4019
|
+
context: "template layer manifest"
|
|
4020
|
+
});
|
|
3483
4021
|
if (!isPlainObject(raw)) {
|
|
3484
4022
|
throw new Error(`${TEMPLATE_LAYER_MANIFEST_FILENAME} must export a JSON object.`);
|
|
3485
4023
|
}
|
|
@@ -3573,7 +4111,7 @@ async function resolveExternalTemplateLayers({
|
|
|
3573
4111
|
return;
|
|
3574
4112
|
}
|
|
3575
4113
|
const layerDir = resolveLayerPath(sourceRoot, definition.path);
|
|
3576
|
-
const stats = await
|
|
4114
|
+
const stats = await fsp8.stat(layerDir).catch(() => null);
|
|
3577
4115
|
if (!stats || !stats.isDirectory()) {
|
|
3578
4116
|
throw new Error(`Layer "${layerId}" points to a missing directory: ${definition.path}`);
|
|
3579
4117
|
}
|
|
@@ -3611,12 +4149,12 @@ async function assertExternalTemplateLayersDoNotWriteProtectedOutputs({
|
|
|
3611
4149
|
}
|
|
3612
4150
|
|
|
3613
4151
|
// ../wp-typia-project-tools/src/runtime/template-source-external.ts
|
|
3614
|
-
import { promises as
|
|
3615
|
-
import
|
|
4152
|
+
import { promises as fsp9 } from "fs";
|
|
4153
|
+
import path12 from "path";
|
|
3616
4154
|
import { pathToFileURL } from "url";
|
|
3617
4155
|
|
|
3618
4156
|
// ../wp-typia-project-tools/src/runtime/external-template-guards.ts
|
|
3619
|
-
import
|
|
4157
|
+
import fs4 from "fs";
|
|
3620
4158
|
var TEMPLATE_SOURCE_TIMEOUT_CODE = "template-source-timeout";
|
|
3621
4159
|
var TEMPLATE_SOURCE_TOO_LARGE_CODE = "template-source-too-large";
|
|
3622
4160
|
var DEFAULT_EXTERNAL_TEMPLATE_TIMEOUT_MS = 20000;
|
|
@@ -3658,7 +4196,7 @@ function createExternalTemplateTooLargeError(label, maxBytes) {
|
|
|
3658
4196
|
return createTemplateGuardError(TEMPLATE_SOURCE_TOO_LARGE_CODE, `${label} exceeded the external template size limit (${maxBytes} bytes).`);
|
|
3659
4197
|
}
|
|
3660
4198
|
function assertExternalTemplateFileSize(filePath, options) {
|
|
3661
|
-
const stats =
|
|
4199
|
+
const stats = fs4.statSync(filePath);
|
|
3662
4200
|
if (stats.size > options.maxBytes) {
|
|
3663
4201
|
throw createExternalTemplateTooLargeError(options.label, options.maxBytes);
|
|
3664
4202
|
}
|
|
@@ -3734,11 +4272,9 @@ async function readResponseBodyWithLimit(response, options) {
|
|
|
3734
4272
|
}
|
|
3735
4273
|
async function readJsonResponseWithLimit(response, options) {
|
|
3736
4274
|
const buffer = await readResponseBodyWithLimit(response, options);
|
|
3737
|
-
|
|
3738
|
-
|
|
3739
|
-
}
|
|
3740
|
-
throw new Error(`Failed to parse ${options.label}: ${error instanceof Error ? error.message : String(error)}`);
|
|
3741
|
-
}
|
|
4275
|
+
return safeJsonParse(buffer.toString("utf8"), {
|
|
4276
|
+
context: options.label
|
|
4277
|
+
});
|
|
3742
4278
|
}
|
|
3743
4279
|
async function readBufferResponseWithLimit(response, options) {
|
|
3744
4280
|
return readResponseBodyWithLimit(response, options);
|
|
@@ -3756,16 +4292,16 @@ function getTemplateWarning(key) {
|
|
|
3756
4292
|
return `Ignoring external template config key "${key}": ${TEMPLATE_WARNING_MESSAGE}`;
|
|
3757
4293
|
}
|
|
3758
4294
|
function resolveSourceSubpath(sourceDir, relativePath) {
|
|
3759
|
-
const targetPath =
|
|
3760
|
-
const relativeTarget =
|
|
3761
|
-
if (relativeTarget.startsWith("..") ||
|
|
4295
|
+
const targetPath = path12.resolve(sourceDir, relativePath);
|
|
4296
|
+
const relativeTarget = path12.relative(sourceDir, targetPath);
|
|
4297
|
+
if (relativeTarget.startsWith("..") || path12.isAbsolute(relativeTarget)) {
|
|
3762
4298
|
throw new Error(`Template path "${relativePath}" must stay within ${sourceDir}.`);
|
|
3763
4299
|
}
|
|
3764
4300
|
return targetPath;
|
|
3765
4301
|
}
|
|
3766
4302
|
async function findExternalTemplateEntry(sourceDir) {
|
|
3767
4303
|
for (const filename of EXTERNAL_TEMPLATE_ENTRY_CANDIDATES) {
|
|
3768
|
-
const candidate =
|
|
4304
|
+
const candidate = path12.join(sourceDir, filename);
|
|
3769
4305
|
if (await pathExists(candidate)) {
|
|
3770
4306
|
return candidate;
|
|
3771
4307
|
}
|
|
@@ -3781,7 +4317,7 @@ async function loadExternalTemplateConfig(sourceDir) {
|
|
|
3781
4317
|
label: `External template config "${entryPath}"`,
|
|
3782
4318
|
maxBytes: getExternalTemplateConfigMaxBytes()
|
|
3783
4319
|
});
|
|
3784
|
-
const entryStats = await
|
|
4320
|
+
const entryStats = await fsp9.stat(entryPath);
|
|
3785
4321
|
const moduleUrl = `${pathToFileURL(entryPath).href}?mtime=${entryStats.mtimeMs}`;
|
|
3786
4322
|
const loadedModule = await withExternalTemplateTimeout(`loading external template config "${entryPath}"`, () => import(moduleUrl));
|
|
3787
4323
|
const loadedConfig = loadedModule.default ?? loadedModule;
|
|
@@ -3888,21 +4424,21 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
3888
4424
|
const { folderName, formatHint, templatePath } = resolveConfiguredTemplatePath(config, variantConfig);
|
|
3889
4425
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-create-block-external-");
|
|
3890
4426
|
try {
|
|
3891
|
-
const renderedRoot =
|
|
4427
|
+
const renderedRoot = path12.join(tempRoot, "rendered");
|
|
3892
4428
|
const blockDir = resolveSourceSubpath(renderedRoot, folderName);
|
|
3893
4429
|
const view = await buildExternalTemplateView(context, config, selectedVariant, variantConfig);
|
|
3894
4430
|
const blockTemplateDir = resolveSourceSubpath(sourceDir, templatePath);
|
|
3895
4431
|
await copyRenderedDirectory(blockTemplateDir, blockDir, view, {
|
|
3896
4432
|
filter: async (sourcePath, _destinationPath, entry) => {
|
|
3897
|
-
const mustacheVariantPath =
|
|
4433
|
+
const mustacheVariantPath = path12.join(path12.dirname(sourcePath), `${entry.name}.mustache`);
|
|
3898
4434
|
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && await pathExists(mustacheVariantPath));
|
|
3899
4435
|
}
|
|
3900
4436
|
});
|
|
3901
4437
|
const assetsPath = typeof variantConfig.assetsPath === "string" ? variantConfig.assetsPath : config.assetsPath;
|
|
3902
4438
|
if (typeof assetsPath === "string" && assetsPath.trim().length > 0) {
|
|
3903
|
-
await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath),
|
|
4439
|
+
await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath), path12.join(tempRoot, "assets"));
|
|
3904
4440
|
}
|
|
3905
|
-
const assetsDir =
|
|
4441
|
+
const assetsDir = path12.join(tempRoot, "assets");
|
|
3906
4442
|
return {
|
|
3907
4443
|
assetsDir: await pathExists(assetsDir) ? assetsDir : undefined,
|
|
3908
4444
|
blockDir,
|
|
@@ -3919,8 +4455,8 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
3919
4455
|
}
|
|
3920
4456
|
|
|
3921
4457
|
// ../wp-typia-project-tools/src/runtime/template-source-remote.ts
|
|
3922
|
-
import { promises as
|
|
3923
|
-
import
|
|
4458
|
+
import { promises as fsp10 } from "fs";
|
|
4459
|
+
import path13 from "path";
|
|
3924
4460
|
async function cleanupSeedRootPair(cleanup, seedCleanup) {
|
|
3925
4461
|
let cleanupError;
|
|
3926
4462
|
try {
|
|
@@ -3943,11 +4479,13 @@ function getDefaultCategoryFromBlockJson(blockJson) {
|
|
|
3943
4479
|
async function readRemoteBlockJsonAsync(blockDir) {
|
|
3944
4480
|
const sourceRoot = await getSeedSourceRoot(blockDir);
|
|
3945
4481
|
for (const candidate of [
|
|
3946
|
-
|
|
3947
|
-
|
|
4482
|
+
path13.join(blockDir, "block.json"),
|
|
4483
|
+
path13.join(sourceRoot, "block.json")
|
|
3948
4484
|
]) {
|
|
3949
4485
|
if (await pathExists(candidate)) {
|
|
3950
|
-
return
|
|
4486
|
+
return readJsonFile(candidate, {
|
|
4487
|
+
context: "remote block metadata"
|
|
4488
|
+
});
|
|
3951
4489
|
}
|
|
3952
4490
|
}
|
|
3953
4491
|
throw new Error(`Unable to locate block.json in ${blockDir}`);
|
|
@@ -3962,8 +4500,8 @@ async function getDefaultCategoryAsync(sourceDir) {
|
|
|
3962
4500
|
}
|
|
3963
4501
|
async function readTemplatePackageJsonAsync(sourceDir) {
|
|
3964
4502
|
for (const candidate of [
|
|
3965
|
-
|
|
3966
|
-
|
|
4503
|
+
path13.join(sourceDir, "package.json.mustache"),
|
|
4504
|
+
path13.join(sourceDir, "package.json")
|
|
3967
4505
|
]) {
|
|
3968
4506
|
if (!await pathExists(candidate)) {
|
|
3969
4507
|
continue;
|
|
@@ -3974,7 +4512,10 @@ async function readTemplatePackageJsonAsync(sourceDir) {
|
|
|
3974
4512
|
maxBytes: getExternalTemplatePackageJsonMaxBytes()
|
|
3975
4513
|
});
|
|
3976
4514
|
return {
|
|
3977
|
-
packageJson:
|
|
4515
|
+
packageJson: safeJsonParse(await fsp10.readFile(candidate, "utf8"), {
|
|
4516
|
+
context: "template metadata file",
|
|
4517
|
+
filePath: candidate
|
|
4518
|
+
}),
|
|
3978
4519
|
sourcePath: candidate
|
|
3979
4520
|
};
|
|
3980
4521
|
} catch (error) {
|
|
@@ -4000,16 +4541,16 @@ async function getTemplateProjectTypeAsync(sourceDir) {
|
|
|
4000
4541
|
}
|
|
4001
4542
|
async function normalizeWpTypiaTemplateSeed(seed) {
|
|
4002
4543
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
4003
|
-
const normalizedDir =
|
|
4544
|
+
const normalizedDir = path13.join(tempRoot, "template");
|
|
4004
4545
|
try {
|
|
4005
4546
|
await copyRawDirectory(seed.blockDir, normalizedDir, {
|
|
4006
4547
|
filter: async (sourcePath, _targetPath, entry) => {
|
|
4007
|
-
const mustacheVariantPath =
|
|
4548
|
+
const mustacheVariantPath = path13.join(path13.dirname(sourcePath), `${entry.name}.mustache`);
|
|
4008
4549
|
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && await pathExists(mustacheVariantPath));
|
|
4009
4550
|
}
|
|
4010
4551
|
});
|
|
4011
4552
|
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
4012
|
-
await
|
|
4553
|
+
await fsp10.cp(seed.assetsDir, path13.join(normalizedDir, "assets"), {
|
|
4013
4554
|
recursive: true,
|
|
4014
4555
|
force: true
|
|
4015
4556
|
});
|
|
@@ -4098,32 +4639,34 @@ function buildRemoteBlockJsonTemplate(blockJson) {
|
|
|
4098
4639
|
}
|
|
4099
4640
|
async function rewriteBlockJsonImports(directory) {
|
|
4100
4641
|
const textExtensions = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
4101
|
-
const targetBlockJsonPath =
|
|
4642
|
+
const targetBlockJsonPath = path13.join(directory, "block.json");
|
|
4102
4643
|
async function visit(currentPath) {
|
|
4103
|
-
const stats = await
|
|
4644
|
+
const stats = await fsp10.stat(currentPath);
|
|
4104
4645
|
if (stats.isDirectory()) {
|
|
4105
|
-
const entries = await
|
|
4646
|
+
const entries = await fsp10.readdir(currentPath);
|
|
4106
4647
|
for (const entry of entries) {
|
|
4107
|
-
await visit(
|
|
4648
|
+
await visit(path13.join(currentPath, entry));
|
|
4108
4649
|
}
|
|
4109
4650
|
return;
|
|
4110
4651
|
}
|
|
4111
|
-
if (!textExtensions.has(
|
|
4652
|
+
if (!textExtensions.has(path13.extname(currentPath))) {
|
|
4112
4653
|
return;
|
|
4113
4654
|
}
|
|
4114
|
-
const content = await
|
|
4115
|
-
const relativeSpecifier =
|
|
4655
|
+
const content = await fsp10.readFile(currentPath, "utf8");
|
|
4656
|
+
const relativeSpecifier = path13.relative(path13.dirname(currentPath), targetBlockJsonPath).replace(/\\/g, "/");
|
|
4116
4657
|
const normalizedSpecifier = relativeSpecifier.startsWith(".") ? relativeSpecifier : `./${relativeSpecifier}`;
|
|
4117
4658
|
const next = content.replace(/(['"])\.{1,2}\/[^'"]*block\.json\1/g, `$1${normalizedSpecifier}$1`);
|
|
4118
4659
|
if (next !== content) {
|
|
4119
|
-
await
|
|
4660
|
+
await fsp10.writeFile(currentPath, next, "utf8");
|
|
4120
4661
|
}
|
|
4121
4662
|
}
|
|
4122
4663
|
await visit(directory);
|
|
4123
4664
|
}
|
|
4124
4665
|
async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
4125
|
-
const packageJsonPath =
|
|
4126
|
-
const packageJson =
|
|
4666
|
+
const packageJsonPath = path13.join(templateDir, "package.json.mustache");
|
|
4667
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
4668
|
+
context: "remote package template manifest"
|
|
4669
|
+
});
|
|
4127
4670
|
const existingDependencies = { ...packageJson.dependencies ?? {} };
|
|
4128
4671
|
const existingDevDependencies = { ...packageJson.devDependencies ?? {} };
|
|
4129
4672
|
delete existingDependencies["@wp-typia/project-tools"];
|
|
@@ -4143,16 +4686,16 @@ async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
|
4143
4686
|
} else {
|
|
4144
4687
|
delete packageJson.dependencies;
|
|
4145
4688
|
}
|
|
4146
|
-
await
|
|
4689
|
+
await fsp10.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
4147
4690
|
`, "utf8");
|
|
4148
4691
|
}
|
|
4149
4692
|
async function getSeedSourceRoot(blockDir) {
|
|
4150
|
-
return await pathExists(
|
|
4693
|
+
return await pathExists(path13.join(blockDir, "src")) ? path13.join(blockDir, "src") : blockDir;
|
|
4151
4694
|
}
|
|
4152
4695
|
async function findSeedRenderPhp(seed) {
|
|
4153
4696
|
for (const candidate of [
|
|
4154
|
-
|
|
4155
|
-
|
|
4697
|
+
path13.join(seed.blockDir, "render.php"),
|
|
4698
|
+
path13.join(seed.rootDir, "render.php")
|
|
4156
4699
|
]) {
|
|
4157
4700
|
if (await pathExists(candidate)) {
|
|
4158
4701
|
return candidate;
|
|
@@ -4193,16 +4736,16 @@ async function removeSeedEntryConflicts(templateDir) {
|
|
|
4193
4736
|
"view.ts",
|
|
4194
4737
|
"view.tsx"
|
|
4195
4738
|
]) {
|
|
4196
|
-
await
|
|
4739
|
+
await fsp10.rm(path13.join(templateDir, "src", filename), { force: true });
|
|
4197
4740
|
}
|
|
4198
4741
|
}
|
|
4199
4742
|
async function normalizeCreateBlockSubset(seed, context) {
|
|
4200
4743
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-remote-template-");
|
|
4201
4744
|
try {
|
|
4202
|
-
const templateDir =
|
|
4745
|
+
const templateDir = path13.join(tempRoot, "template");
|
|
4203
4746
|
const blockJson = await readRemoteBlockJsonAsync(seed.blockDir);
|
|
4204
4747
|
const sourceRoot = await getSeedSourceRoot(seed.blockDir);
|
|
4205
|
-
await
|
|
4748
|
+
await fsp10.mkdir(templateDir, { recursive: true });
|
|
4206
4749
|
for (const layerDir of getBuiltInTemplateLayerDirs("basic")) {
|
|
4207
4750
|
if (!await pathExists(layerDir)) {
|
|
4208
4751
|
if (isOmittableBuiltInTemplateLayerDir("basic", layerDir)) {
|
|
@@ -4210,29 +4753,29 @@ async function normalizeCreateBlockSubset(seed, context) {
|
|
|
4210
4753
|
}
|
|
4211
4754
|
throw new Error(`Built-in template layer is missing: ${layerDir}`);
|
|
4212
4755
|
}
|
|
4213
|
-
await
|
|
4756
|
+
await fsp10.cp(layerDir, templateDir, {
|
|
4214
4757
|
recursive: true,
|
|
4215
4758
|
force: true
|
|
4216
4759
|
});
|
|
4217
4760
|
}
|
|
4218
4761
|
await removeSeedEntryConflicts(templateDir);
|
|
4219
|
-
await
|
|
4762
|
+
await fsp10.cp(sourceRoot, path13.join(templateDir, "src"), {
|
|
4220
4763
|
recursive: true,
|
|
4221
4764
|
force: true
|
|
4222
4765
|
});
|
|
4223
4766
|
const remoteRenderPath = await findSeedRenderPhp(seed);
|
|
4224
4767
|
if (remoteRenderPath) {
|
|
4225
|
-
await
|
|
4768
|
+
await fsp10.copyFile(remoteRenderPath, path13.join(templateDir, "render.php"));
|
|
4226
4769
|
}
|
|
4227
4770
|
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
4228
|
-
await
|
|
4771
|
+
await fsp10.cp(seed.assetsDir, path13.join(templateDir, "assets"), {
|
|
4229
4772
|
recursive: true,
|
|
4230
4773
|
force: true
|
|
4231
4774
|
});
|
|
4232
4775
|
}
|
|
4233
|
-
await
|
|
4234
|
-
await
|
|
4235
|
-
await rewriteBlockJsonImports(
|
|
4776
|
+
await fsp10.writeFile(path13.join(templateDir, "src", "types.ts"), buildRemoteTypesSource(blockJson, context), "utf8");
|
|
4777
|
+
await fsp10.writeFile(path13.join(templateDir, "src", "block.json"), buildRemoteBlockJsonTemplate(blockJson), "utf8");
|
|
4778
|
+
await rewriteBlockJsonImports(path13.join(templateDir, "src"));
|
|
4236
4779
|
const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" || (await Promise.all([
|
|
4237
4780
|
"view.js",
|
|
4238
4781
|
"view.jsx",
|
|
@@ -4240,7 +4783,7 @@ async function normalizeCreateBlockSubset(seed, context) {
|
|
|
4240
4783
|
"view.tsx",
|
|
4241
4784
|
"interactivity.js",
|
|
4242
4785
|
"interactivity.ts"
|
|
4243
|
-
].map((filename) => pathExists(
|
|
4786
|
+
].map((filename) => pathExists(path13.join(templateDir, "src", filename))))).some(Boolean);
|
|
4244
4787
|
await patchRemotePackageJson(templateDir, needsInteractivity);
|
|
4245
4788
|
return {
|
|
4246
4789
|
id: "remote:create-block-subset",
|
|
@@ -4270,7 +4813,8 @@ function getTemplateVariableContext(variables) {
|
|
|
4270
4813
|
blockRuntimePackageVersion,
|
|
4271
4814
|
blockTypesPackageVersion,
|
|
4272
4815
|
projectToolsPackageVersion,
|
|
4273
|
-
restPackageVersion
|
|
4816
|
+
restPackageVersion,
|
|
4817
|
+
wpTypiaPackageVersion
|
|
4274
4818
|
} = getPackageVersions();
|
|
4275
4819
|
return {
|
|
4276
4820
|
...variables,
|
|
@@ -4278,6 +4822,7 @@ function getTemplateVariableContext(variables) {
|
|
|
4278
4822
|
blockRuntimePackageVersion: variables.blockRuntimePackageVersion ?? blockRuntimePackageVersion,
|
|
4279
4823
|
blockTypesPackageVersion: variables.blockTypesPackageVersion ?? blockTypesPackageVersion,
|
|
4280
4824
|
projectToolsPackageVersion: variables.projectToolsPackageVersion ?? projectToolsPackageVersion,
|
|
4825
|
+
wpTypiaPackageVersion: variables.wpTypiaPackageVersion ?? wpTypiaPackageVersion,
|
|
4281
4826
|
description: variables.description,
|
|
4282
4827
|
keyword: variables.keyword,
|
|
4283
4828
|
namespace: variables.namespace,
|
|
@@ -4290,7 +4835,7 @@ function getTemplateVariableContext(variables) {
|
|
|
4290
4835
|
};
|
|
4291
4836
|
}
|
|
4292
4837
|
async function detectTemplateSourceFormat(sourceDir) {
|
|
4293
|
-
if (await pathExists(
|
|
4838
|
+
if (await pathExists(path14.join(sourceDir, "package.json.mustache"))) {
|
|
4294
4839
|
return "wp-typia";
|
|
4295
4840
|
}
|
|
4296
4841
|
if (await loadExternalTemplateLayerManifest(sourceDir)) {
|
|
@@ -4302,15 +4847,15 @@ async function detectTemplateSourceFormat(sourceDir) {
|
|
|
4302
4847
|
if (await getTemplateProjectTypeAsync(sourceDir) !== null) {
|
|
4303
4848
|
return "wp-typia";
|
|
4304
4849
|
}
|
|
4305
|
-
const sourceRoot = await pathExists(
|
|
4850
|
+
const sourceRoot = await pathExists(path14.join(sourceDir, "src")) ? path14.join(sourceDir, "src") : sourceDir;
|
|
4306
4851
|
const blockJsonCandidates = [
|
|
4307
|
-
|
|
4308
|
-
|
|
4852
|
+
path14.join(sourceDir, "block.json"),
|
|
4853
|
+
path14.join(sourceRoot, "block.json")
|
|
4309
4854
|
];
|
|
4310
4855
|
const hasBlockJson = (await Promise.all(blockJsonCandidates.map((candidate) => pathExists(candidate)))).some(Boolean);
|
|
4311
|
-
const hasIndexFile = (await Promise.all(["index.js", "index.jsx", "index.ts", "index.tsx"].map((filename) => pathExists(
|
|
4312
|
-
const hasEditFile = (await Promise.all(["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].map((filename) => pathExists(
|
|
4313
|
-
const hasSaveFile = (await Promise.all(["save.js", "save.jsx", "save.ts", "save.tsx"].map((filename) => pathExists(
|
|
4856
|
+
const hasIndexFile = (await Promise.all(["index.js", "index.jsx", "index.ts", "index.tsx"].map((filename) => pathExists(path14.join(sourceRoot, filename))))).some(Boolean);
|
|
4857
|
+
const hasEditFile = (await Promise.all(["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].map((filename) => pathExists(path14.join(sourceRoot, filename))))).some(Boolean);
|
|
4858
|
+
const hasSaveFile = (await Promise.all(["save.js", "save.jsx", "save.ts", "save.tsx"].map((filename) => pathExists(path14.join(sourceRoot, filename))))).some(Boolean);
|
|
4314
4859
|
if (hasBlockJson && hasIndexFile && hasEditFile && hasSaveFile) {
|
|
4315
4860
|
return "create-block-subset";
|
|
4316
4861
|
}
|
|
@@ -4319,10 +4864,10 @@ async function detectTemplateSourceFormat(sourceDir) {
|
|
|
4319
4864
|
|
|
4320
4865
|
// ../wp-typia-project-tools/src/runtime/template-source-seeds.ts
|
|
4321
4866
|
var import_semver = __toESM(require_semver(), 1);
|
|
4322
|
-
import
|
|
4323
|
-
import { promises as
|
|
4867
|
+
import fs6 from "fs";
|
|
4868
|
+
import { promises as fsp12 } from "fs";
|
|
4324
4869
|
import { createRequire as createRequire2 } from "module";
|
|
4325
|
-
import
|
|
4870
|
+
import path17 from "path";
|
|
4326
4871
|
import { spawnSync } from "child_process";
|
|
4327
4872
|
|
|
4328
4873
|
// ../../node_modules/.bun/tar@7.5.13/node_modules/tar/dist/esm/index.min.js
|
|
@@ -6595,7 +7140,7 @@ var Vn = 512 * 1024;
|
|
|
6595
7140
|
var $n = pr | ur | dr | mr;
|
|
6596
7141
|
var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
|
|
6597
7142
|
var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
|
|
6598
|
-
var
|
|
7143
|
+
var fs5 = (s3, t, e) => {
|
|
6599
7144
|
try {
|
|
6600
7145
|
return mi.lchownSync(s3, t, e);
|
|
6601
7146
|
} catch (i) {
|
|
@@ -6644,7 +7189,7 @@ var ds = (s3, t, e, i) => {
|
|
|
6644
7189
|
});
|
|
6645
7190
|
};
|
|
6646
7191
|
var qn = (s3, t, e, i) => {
|
|
6647
|
-
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i),
|
|
7192
|
+
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i), fs5(Ee.resolve(s3, t.name), e, i);
|
|
6648
7193
|
};
|
|
6649
7194
|
var us = (s3, t, e) => {
|
|
6650
7195
|
let i;
|
|
@@ -6655,12 +7200,12 @@ var us = (s3, t, e) => {
|
|
|
6655
7200
|
if (n?.code === "ENOENT")
|
|
6656
7201
|
return;
|
|
6657
7202
|
if (n?.code === "ENOTDIR" || n?.code === "ENOTSUP")
|
|
6658
|
-
return
|
|
7203
|
+
return fs5(s3, t, e);
|
|
6659
7204
|
throw n;
|
|
6660
7205
|
}
|
|
6661
7206
|
for (let r of i)
|
|
6662
7207
|
qn(s3, r, t, e);
|
|
6663
|
-
return
|
|
7208
|
+
return fs5(s3, t, e);
|
|
6664
7209
|
};
|
|
6665
7210
|
var we = class extends Error {
|
|
6666
7211
|
path;
|
|
@@ -7474,8 +8019,8 @@ var So = (s3) => {
|
|
|
7474
8019
|
|
|
7475
8020
|
// ../wp-typia-project-tools/src/runtime/template-source-cache.ts
|
|
7476
8021
|
import { createHash, randomUUID } from "crypto";
|
|
7477
|
-
import { promises as
|
|
7478
|
-
import
|
|
8022
|
+
import { promises as fsp11 } from "fs";
|
|
8023
|
+
import path16 from "path";
|
|
7479
8024
|
|
|
7480
8025
|
// ../wp-typia-project-tools/src/runtime/template-source-cache-markers.ts
|
|
7481
8026
|
var CACHE_MARKER_FILE = "wp-typia-template-cache.json";
|
|
@@ -7595,7 +8140,7 @@ function formatExternalTemplateCachePruneMarker({
|
|
|
7595
8140
|
|
|
7596
8141
|
// ../wp-typia-project-tools/src/runtime/template-source-cache-policy.ts
|
|
7597
8142
|
import os2 from "os";
|
|
7598
|
-
import
|
|
8143
|
+
import path15 from "path";
|
|
7599
8144
|
var EXTERNAL_TEMPLATE_CACHE_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE";
|
|
7600
8145
|
var EXTERNAL_TEMPLATE_CACHE_DIR_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_DIR";
|
|
7601
8146
|
var EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_TTL_DAYS";
|
|
@@ -7613,9 +8158,9 @@ function isExternalTemplateCacheEnabled(env = process.env) {
|
|
|
7613
8158
|
function getExternalTemplateCacheRoot(env = process.env) {
|
|
7614
8159
|
const configuredCacheDir = env[EXTERNAL_TEMPLATE_CACHE_DIR_ENV]?.trim();
|
|
7615
8160
|
if (configuredCacheDir) {
|
|
7616
|
-
return
|
|
8161
|
+
return path15.resolve(configuredCacheDir);
|
|
7617
8162
|
}
|
|
7618
|
-
return
|
|
8163
|
+
return path15.join(os2.tmpdir(), `wp-typia-template-source-cache-${getCurrentUserCacheSegment()}`);
|
|
7619
8164
|
}
|
|
7620
8165
|
function parseExternalTemplateCacheTtlDays(value) {
|
|
7621
8166
|
if (typeof value !== "string" && typeof value !== "number") {
|
|
@@ -7693,7 +8238,7 @@ function createExternalTemplateCacheKey(keyParts) {
|
|
|
7693
8238
|
}
|
|
7694
8239
|
async function isDirectoryPath(directory) {
|
|
7695
8240
|
try {
|
|
7696
|
-
const stats = await
|
|
8241
|
+
const stats = await fsp11.lstat(directory);
|
|
7697
8242
|
return stats.isDirectory() && !stats.isSymbolicLink();
|
|
7698
8243
|
} catch {
|
|
7699
8244
|
return false;
|
|
@@ -7701,7 +8246,7 @@ async function isDirectoryPath(directory) {
|
|
|
7701
8246
|
}
|
|
7702
8247
|
async function removeTemporaryCacheEntry(entryDir) {
|
|
7703
8248
|
try {
|
|
7704
|
-
await
|
|
8249
|
+
await fsp11.rm(entryDir, { force: true, recursive: true });
|
|
7705
8250
|
} catch {}
|
|
7706
8251
|
}
|
|
7707
8252
|
function getCurrentUid() {
|
|
@@ -7709,7 +8254,7 @@ function getCurrentUid() {
|
|
|
7709
8254
|
}
|
|
7710
8255
|
async function isPrivateCacheDirectory(directory) {
|
|
7711
8256
|
try {
|
|
7712
|
-
const stats = await
|
|
8257
|
+
const stats = await fsp11.lstat(directory);
|
|
7713
8258
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
7714
8259
|
return false;
|
|
7715
8260
|
}
|
|
@@ -7727,11 +8272,11 @@ async function isPrivateCacheDirectory(directory) {
|
|
|
7727
8272
|
}
|
|
7728
8273
|
async function ensurePrivateCacheDirectory(directory) {
|
|
7729
8274
|
try {
|
|
7730
|
-
await
|
|
8275
|
+
await fsp11.mkdir(directory, {
|
|
7731
8276
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
7732
8277
|
recursive: true
|
|
7733
8278
|
});
|
|
7734
|
-
const stats = await
|
|
8279
|
+
const stats = await fsp11.lstat(directory);
|
|
7735
8280
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
7736
8281
|
return false;
|
|
7737
8282
|
}
|
|
@@ -7741,7 +8286,7 @@ async function ensurePrivateCacheDirectory(directory) {
|
|
|
7741
8286
|
}
|
|
7742
8287
|
if (process.platform !== "win32") {
|
|
7743
8288
|
if ((stats.mode & 63) !== 0) {
|
|
7744
|
-
await
|
|
8289
|
+
await fsp11.chmod(directory, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
7745
8290
|
}
|
|
7746
8291
|
}
|
|
7747
8292
|
return isPrivateCacheDirectory(directory);
|
|
@@ -7753,9 +8298,9 @@ function resolveCacheNamespaceDir(cacheRoot, namespace) {
|
|
|
7753
8298
|
if (namespace === "." || namespace === ".." || !SAFE_CACHE_NAMESPACE_SEGMENT.test(namespace)) {
|
|
7754
8299
|
return null;
|
|
7755
8300
|
}
|
|
7756
|
-
const namespaceDir =
|
|
7757
|
-
const relativeNamespaceDir =
|
|
7758
|
-
if (relativeNamespaceDir.length === 0 || relativeNamespaceDir.startsWith("..") ||
|
|
8301
|
+
const namespaceDir = path16.join(cacheRoot, namespace);
|
|
8302
|
+
const relativeNamespaceDir = path16.relative(cacheRoot, namespaceDir);
|
|
8303
|
+
if (relativeNamespaceDir.length === 0 || relativeNamespaceDir.startsWith("..") || path16.isAbsolute(relativeNamespaceDir)) {
|
|
7759
8304
|
return null;
|
|
7760
8305
|
}
|
|
7761
8306
|
return namespaceDir;
|
|
@@ -7767,14 +8312,14 @@ function getCacheEntryPaths(descriptor) {
|
|
|
7767
8312
|
if (!namespaceDir) {
|
|
7768
8313
|
return null;
|
|
7769
8314
|
}
|
|
7770
|
-
const entryDir =
|
|
8315
|
+
const entryDir = path16.join(namespaceDir, cacheKey);
|
|
7771
8316
|
return {
|
|
7772
8317
|
cacheKey,
|
|
7773
8318
|
cacheRoot,
|
|
7774
8319
|
entryDir,
|
|
7775
|
-
markerPath:
|
|
8320
|
+
markerPath: path16.join(entryDir, CACHE_MARKER_FILE),
|
|
7776
8321
|
namespaceDir,
|
|
7777
|
-
sourceDir:
|
|
8322
|
+
sourceDir: path16.join(entryDir, "source")
|
|
7778
8323
|
};
|
|
7779
8324
|
}
|
|
7780
8325
|
async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
|
|
@@ -7782,7 +8327,7 @@ async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
|
|
|
7782
8327
|
}
|
|
7783
8328
|
async function readCacheEntryMarker(markerPath) {
|
|
7784
8329
|
try {
|
|
7785
|
-
return parseExternalTemplateCacheEntryMarker(await
|
|
8330
|
+
return parseExternalTemplateCacheEntryMarker(await fsp11.readFile(markerPath, "utf8"));
|
|
7786
8331
|
} catch {
|
|
7787
8332
|
return null;
|
|
7788
8333
|
}
|
|
@@ -7798,22 +8343,22 @@ async function isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs,
|
|
|
7798
8343
|
return marker !== null && isExternalTemplateCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs);
|
|
7799
8344
|
}
|
|
7800
8345
|
function isPathInsideDirectory(directory, candidatePath) {
|
|
7801
|
-
const relativePath =
|
|
7802
|
-
return relativePath.length > 0 && !relativePath.startsWith("..") && !
|
|
8346
|
+
const relativePath = path16.relative(directory, candidatePath);
|
|
8347
|
+
return relativePath.length > 0 && !relativePath.startsWith("..") && !path16.isAbsolute(relativePath);
|
|
7803
8348
|
}
|
|
7804
8349
|
async function removeCacheEntryWithinRoot(cacheRoot, entryDir) {
|
|
7805
8350
|
if (!isPathInsideDirectory(cacheRoot, entryDir)) {
|
|
7806
8351
|
return false;
|
|
7807
8352
|
}
|
|
7808
8353
|
try {
|
|
7809
|
-
await
|
|
8354
|
+
await fsp11.rm(entryDir, { force: true, recursive: true });
|
|
7810
8355
|
return true;
|
|
7811
8356
|
} catch {
|
|
7812
8357
|
return false;
|
|
7813
8358
|
}
|
|
7814
8359
|
}
|
|
7815
8360
|
function getCachePruneMarkerPath(cacheRoot) {
|
|
7816
|
-
return
|
|
8361
|
+
return path16.join(cacheRoot, CACHE_PRUNE_MARKER_FILE);
|
|
7817
8362
|
}
|
|
7818
8363
|
async function shouldSkipExternalTemplateCachePrune({
|
|
7819
8364
|
cacheRoot,
|
|
@@ -7827,7 +8372,7 @@ async function shouldSkipExternalTemplateCachePrune({
|
|
|
7827
8372
|
}
|
|
7828
8373
|
let markerText;
|
|
7829
8374
|
try {
|
|
7830
|
-
markerText = await
|
|
8375
|
+
markerText = await fsp11.readFile(getCachePruneMarkerPath(cacheRoot), "utf8");
|
|
7831
8376
|
} catch {
|
|
7832
8377
|
return false;
|
|
7833
8378
|
}
|
|
@@ -7845,7 +8390,7 @@ async function writeExternalTemplateCachePruneMarker({
|
|
|
7845
8390
|
ttlMs
|
|
7846
8391
|
}) {
|
|
7847
8392
|
try {
|
|
7848
|
-
await
|
|
8393
|
+
await fsp11.writeFile(getCachePruneMarkerPath(cacheRoot), formatExternalTemplateCachePruneMarker({
|
|
7849
8394
|
nowMs,
|
|
7850
8395
|
pruneIntervalMs,
|
|
7851
8396
|
ttlMs
|
|
@@ -7887,7 +8432,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7887
8432
|
}
|
|
7888
8433
|
let namespaceEntries;
|
|
7889
8434
|
try {
|
|
7890
|
-
namespaceEntries = await
|
|
8435
|
+
namespaceEntries = await fsp11.readdir(cacheRoot, { withFileTypes: true });
|
|
7891
8436
|
} catch {
|
|
7892
8437
|
return result;
|
|
7893
8438
|
}
|
|
@@ -7903,7 +8448,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7903
8448
|
}
|
|
7904
8449
|
let cacheEntries;
|
|
7905
8450
|
try {
|
|
7906
|
-
cacheEntries = await
|
|
8451
|
+
cacheEntries = await fsp11.readdir(namespaceDir, { withFileTypes: true });
|
|
7907
8452
|
} catch {
|
|
7908
8453
|
result.skippedEntries += 1;
|
|
7909
8454
|
continue;
|
|
@@ -7916,14 +8461,14 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7916
8461
|
result.skippedEntries += 1;
|
|
7917
8462
|
continue;
|
|
7918
8463
|
}
|
|
7919
|
-
const entryDir =
|
|
8464
|
+
const entryDir = path16.join(namespaceDir, cacheEntry.name);
|
|
7920
8465
|
result.scannedEntries += 1;
|
|
7921
8466
|
if (!isPathInsideDirectory(cacheRoot, entryDir)) {
|
|
7922
8467
|
result.skippedEntries += 1;
|
|
7923
8468
|
continue;
|
|
7924
8469
|
}
|
|
7925
|
-
const markerPath =
|
|
7926
|
-
const sourceDir =
|
|
8470
|
+
const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
|
|
8471
|
+
const sourceDir = path16.join(entryDir, "source");
|
|
7927
8472
|
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
7928
8473
|
if (!marker) {
|
|
7929
8474
|
result.skippedEntries += 1;
|
|
@@ -7963,7 +8508,7 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
7963
8508
|
await pruneExternalTemplateCache();
|
|
7964
8509
|
let entries;
|
|
7965
8510
|
try {
|
|
7966
|
-
entries = await
|
|
8511
|
+
entries = await fsp11.readdir(namespaceDir, { withFileTypes: true });
|
|
7967
8512
|
} catch {
|
|
7968
8513
|
return null;
|
|
7969
8514
|
}
|
|
@@ -7972,9 +8517,9 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
7972
8517
|
if (!entry.isDirectory()) {
|
|
7973
8518
|
continue;
|
|
7974
8519
|
}
|
|
7975
|
-
const entryDir =
|
|
7976
|
-
const markerPath =
|
|
7977
|
-
const sourceDir =
|
|
8520
|
+
const entryDir = path16.join(namespaceDir, entry.name);
|
|
8521
|
+
const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
|
|
8522
|
+
const sourceDir = path16.join(entryDir, "source");
|
|
7978
8523
|
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
7979
8524
|
if (!marker || !isExternalTemplateCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs) || !externalTemplateCacheMetadataMatches(marker.metadata, descriptor.metadata)) {
|
|
7980
8525
|
continue;
|
|
@@ -8016,16 +8561,16 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
8016
8561
|
if (existingMarker) {
|
|
8017
8562
|
await removeCacheEntryWithinRoot(cacheRoot, entryDir);
|
|
8018
8563
|
}
|
|
8019
|
-
const temporaryEntryDir =
|
|
8020
|
-
const temporarySourceDir =
|
|
8564
|
+
const temporaryEntryDir = path16.join(namespaceDir, createTemporaryCacheEntryDirName(cacheKey));
|
|
8565
|
+
const temporarySourceDir = path16.join(temporaryEntryDir, "source");
|
|
8021
8566
|
let populateFailed = false;
|
|
8022
8567
|
try {
|
|
8023
|
-
await
|
|
8568
|
+
await fsp11.mkdir(temporarySourceDir, {
|
|
8024
8569
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
8025
8570
|
recursive: true
|
|
8026
8571
|
});
|
|
8027
8572
|
if (process.platform !== "win32") {
|
|
8028
|
-
await
|
|
8573
|
+
await fsp11.chmod(temporaryEntryDir, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
8029
8574
|
}
|
|
8030
8575
|
try {
|
|
8031
8576
|
await populateSourceDir(temporarySourceDir);
|
|
@@ -8033,13 +8578,13 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
8033
8578
|
populateFailed = true;
|
|
8034
8579
|
throw error;
|
|
8035
8580
|
}
|
|
8036
|
-
await
|
|
8581
|
+
await fsp11.writeFile(path16.join(temporaryEntryDir, CACHE_MARKER_FILE), formatExternalTemplateCacheEntryMarker({
|
|
8037
8582
|
cacheKey,
|
|
8038
8583
|
createdAt: new Date,
|
|
8039
8584
|
metadata: descriptor.metadata,
|
|
8040
8585
|
namespace: descriptor.namespace
|
|
8041
8586
|
}), "utf8");
|
|
8042
|
-
await
|
|
8587
|
+
await fsp11.rename(temporaryEntryDir, entryDir);
|
|
8043
8588
|
return {
|
|
8044
8589
|
cacheHit: false,
|
|
8045
8590
|
sourceDir
|
|
@@ -8110,9 +8655,9 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
8110
8655
|
if (!tarballResponse.ok) {
|
|
8111
8656
|
throw new Error(`Failed to download npm template tarball for ${locator.raw}: ${tarballResponse.status}`);
|
|
8112
8657
|
}
|
|
8113
|
-
const tarballPath =
|
|
8114
|
-
await
|
|
8115
|
-
await
|
|
8658
|
+
const tarballPath = path17.join(path17.dirname(unpackDir), "template.tgz");
|
|
8659
|
+
await fsp12.mkdir(unpackDir, { recursive: true });
|
|
8660
|
+
await fsp12.writeFile(tarballPath, await readBufferResponseWithLimit(tarballResponse, {
|
|
8116
8661
|
label: `npm template tarball for ${locator.raw}@${resolvedVersion}`,
|
|
8117
8662
|
maxBytes: getExternalTemplateTarballMaxBytes()
|
|
8118
8663
|
}));
|
|
@@ -8121,7 +8666,7 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
8121
8666
|
file: tarballPath,
|
|
8122
8667
|
strip: 1
|
|
8123
8668
|
});
|
|
8124
|
-
await
|
|
8669
|
+
await fsp12.rm(tarballPath, { force: true });
|
|
8125
8670
|
await assertNoSymlinks2(unpackDir);
|
|
8126
8671
|
}
|
|
8127
8672
|
function selectRegistryVersion(metadata, locator) {
|
|
@@ -8216,7 +8761,7 @@ async function fetchNpmTemplateSource(locator) {
|
|
|
8216
8761
|
}
|
|
8217
8762
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
8218
8763
|
try {
|
|
8219
|
-
const unpackDir =
|
|
8764
|
+
const unpackDir = path17.join(tempRoot, "source");
|
|
8220
8765
|
await downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl, unpackDir);
|
|
8221
8766
|
return {
|
|
8222
8767
|
blockDir: unpackDir,
|
|
@@ -8232,20 +8777,22 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8232
8777
|
if (locator.rawSpec !== "" && locator.rawSpec !== "*") {
|
|
8233
8778
|
return null;
|
|
8234
8779
|
}
|
|
8235
|
-
const workspacePackagesRoot =
|
|
8236
|
-
if (
|
|
8237
|
-
for (const entry of
|
|
8780
|
+
const workspacePackagesRoot = path17.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..");
|
|
8781
|
+
if (fs6.existsSync(workspacePackagesRoot)) {
|
|
8782
|
+
for (const entry of fs6.readdirSync(workspacePackagesRoot, {
|
|
8238
8783
|
withFileTypes: true
|
|
8239
8784
|
})) {
|
|
8240
8785
|
if (!entry.isDirectory()) {
|
|
8241
8786
|
continue;
|
|
8242
8787
|
}
|
|
8243
|
-
const packageDir =
|
|
8244
|
-
const packageJsonPath =
|
|
8245
|
-
if (!
|
|
8788
|
+
const packageDir = path17.join(workspacePackagesRoot, entry.name);
|
|
8789
|
+
const packageJsonPath = path17.join(packageDir, "package.json");
|
|
8790
|
+
if (!fs6.existsSync(packageJsonPath)) {
|
|
8246
8791
|
continue;
|
|
8247
8792
|
}
|
|
8248
|
-
const manifest =
|
|
8793
|
+
const manifest = readJsonFileSync(packageJsonPath, {
|
|
8794
|
+
context: "workspace template package manifest"
|
|
8795
|
+
});
|
|
8249
8796
|
if (manifest.name === locator.name) {
|
|
8250
8797
|
return {
|
|
8251
8798
|
blockDir: packageDir,
|
|
@@ -8254,10 +8801,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8254
8801
|
}
|
|
8255
8802
|
}
|
|
8256
8803
|
}
|
|
8257
|
-
const workspaceRequire = createRequire2(
|
|
8804
|
+
const workspaceRequire = createRequire2(path17.join(path17.resolve(cwd), "__wp_typia_template_resolver__.cjs"));
|
|
8258
8805
|
try {
|
|
8259
|
-
const packageJsonPath =
|
|
8260
|
-
const sourceDir =
|
|
8806
|
+
const packageJsonPath = fs6.realpathSync(workspaceRequire.resolve(`${locator.name}/package.json`));
|
|
8807
|
+
const sourceDir = path17.dirname(packageJsonPath);
|
|
8261
8808
|
return {
|
|
8262
8809
|
blockDir: sourceDir,
|
|
8263
8810
|
rootDir: sourceDir
|
|
@@ -8266,11 +8813,11 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8266
8813
|
const errorCode = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
8267
8814
|
if (errorCode === "MODULE_NOT_FOUND" || errorCode === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
8268
8815
|
for (const basePath of workspaceRequire.resolve.paths(locator.name) ?? []) {
|
|
8269
|
-
const packageJsonPath =
|
|
8270
|
-
if (!
|
|
8816
|
+
const packageJsonPath = path17.join(basePath, locator.name, "package.json");
|
|
8817
|
+
if (!fs6.existsSync(packageJsonPath)) {
|
|
8271
8818
|
continue;
|
|
8272
8819
|
}
|
|
8273
|
-
const sourceDir =
|
|
8820
|
+
const sourceDir = path17.dirname(fs6.realpathSync(packageJsonPath));
|
|
8274
8821
|
return {
|
|
8275
8822
|
blockDir: sourceDir,
|
|
8276
8823
|
rootDir: sourceDir
|
|
@@ -8282,27 +8829,29 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8282
8829
|
}
|
|
8283
8830
|
}
|
|
8284
8831
|
async function isOfficialWorkspaceTemplateSeedAsync(seed) {
|
|
8285
|
-
const packageJsonPath =
|
|
8832
|
+
const packageJsonPath = path17.join(seed.rootDir, "package.json");
|
|
8286
8833
|
if (!await pathExists(packageJsonPath)) {
|
|
8287
8834
|
return false;
|
|
8288
8835
|
}
|
|
8289
8836
|
try {
|
|
8290
|
-
const packageJson =
|
|
8837
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
8838
|
+
context: "workspace template seed manifest"
|
|
8839
|
+
});
|
|
8291
8840
|
return packageJson.name === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE;
|
|
8292
8841
|
} catch {
|
|
8293
8842
|
return false;
|
|
8294
8843
|
}
|
|
8295
8844
|
}
|
|
8296
8845
|
async function assertNoSymlinks2(sourceDir) {
|
|
8297
|
-
const stats = await
|
|
8846
|
+
const stats = await fsp12.lstat(sourceDir);
|
|
8298
8847
|
if (stats.isSymbolicLink()) {
|
|
8299
8848
|
throw new Error(`Template sources may not include symbolic links: ${sourceDir}`);
|
|
8300
8849
|
}
|
|
8301
8850
|
if (!stats.isDirectory()) {
|
|
8302
8851
|
return;
|
|
8303
8852
|
}
|
|
8304
|
-
for (const entry of await
|
|
8305
|
-
await assertNoSymlinks2(
|
|
8853
|
+
for (const entry of await fsp12.readdir(sourceDir)) {
|
|
8854
|
+
await assertNoSymlinks2(path17.join(sourceDir, entry));
|
|
8306
8855
|
}
|
|
8307
8856
|
}
|
|
8308
8857
|
function runGitTemplateCommand(args, label, options = {}) {
|
|
@@ -8331,9 +8880,9 @@ function getGitHubTemplateRepositoryUrl(locator) {
|
|
|
8331
8880
|
return `https://github.com/${locator.owner}/${locator.repo}.git`;
|
|
8332
8881
|
}
|
|
8333
8882
|
async function resolveGitHubTemplateDirectory(checkoutDir, locator) {
|
|
8334
|
-
const sourceDir =
|
|
8335
|
-
const relativeSourceDir =
|
|
8336
|
-
if (relativeSourceDir.startsWith("..") ||
|
|
8883
|
+
const sourceDir = path17.resolve(checkoutDir, locator.sourcePath);
|
|
8884
|
+
const relativeSourceDir = path17.relative(checkoutDir, sourceDir);
|
|
8885
|
+
if (relativeSourceDir.startsWith("..") || path17.isAbsolute(relativeSourceDir)) {
|
|
8337
8886
|
throw new Error("GitHub template path must stay within the cloned repository.");
|
|
8338
8887
|
}
|
|
8339
8888
|
if (!await pathExists(sourceDir)) {
|
|
@@ -8522,7 +9071,7 @@ async function resolveGitHubTemplateSource(locator) {
|
|
|
8522
9071
|
}
|
|
8523
9072
|
}
|
|
8524
9073
|
const { path: remoteRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
8525
|
-
const checkoutDir =
|
|
9074
|
+
const checkoutDir = path17.join(remoteRoot, "source");
|
|
8526
9075
|
try {
|
|
8527
9076
|
cloneGitHubTemplateSource(locator, checkoutDir);
|
|
8528
9077
|
const sourceDir = await resolveGitHubTemplateDirectory(checkoutDir, locator);
|
|
@@ -8539,7 +9088,7 @@ async function resolveGitHubTemplateSource(locator) {
|
|
|
8539
9088
|
}
|
|
8540
9089
|
async function resolveTemplateSeed(locator, cwd) {
|
|
8541
9090
|
if (locator.kind === "path") {
|
|
8542
|
-
const sourceDir =
|
|
9091
|
+
const sourceDir = path17.resolve(cwd, locator.templatePath);
|
|
8543
9092
|
if (!await pathExists(sourceDir)) {
|
|
8544
9093
|
throw new Error(`Template path does not exist: ${sourceDir}`);
|
|
8545
9094
|
}
|
|
@@ -9073,7 +9622,8 @@ function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
9073
9622
|
blockRuntimePackageVersion,
|
|
9074
9623
|
blockTypesPackageVersion,
|
|
9075
9624
|
projectToolsPackageVersion,
|
|
9076
|
-
restPackageVersion
|
|
9625
|
+
restPackageVersion,
|
|
9626
|
+
wpTypiaPackageVersion
|
|
9077
9627
|
} = getPackageVersions();
|
|
9078
9628
|
const slug = spec.block.slug;
|
|
9079
9629
|
const slugSnakeCase = toSnakeCase(slug);
|
|
@@ -9129,6 +9679,7 @@ function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
9129
9679
|
requiresPhp: compatibility.pluginHeader.requiresPhp,
|
|
9130
9680
|
testedUpTo: compatibility.pluginHeader.testedUpTo,
|
|
9131
9681
|
projectToolsPackageVersion,
|
|
9682
|
+
wpTypiaPackageVersion,
|
|
9132
9683
|
cssClassName,
|
|
9133
9684
|
dashCase: slug,
|
|
9134
9685
|
dataStorageMode,
|
|
@@ -13642,7 +14193,8 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13642
14193
|
blockRuntimePackageVersion,
|
|
13643
14194
|
blockTypesPackageVersion,
|
|
13644
14195
|
projectToolsPackageVersion,
|
|
13645
|
-
restPackageVersion
|
|
14196
|
+
restPackageVersion,
|
|
14197
|
+
wpTypiaPackageVersion
|
|
13646
14198
|
} = getPackageVersions();
|
|
13647
14199
|
const template = isBuiltInTemplateId(templateId) ? getTemplateById(templateId) : null;
|
|
13648
14200
|
const metadataDefaults = isBuiltInTemplateId(templateId) ? getBuiltInTemplateMetadataDefaults(templateId) : null;
|
|
@@ -13698,6 +14250,7 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13698
14250
|
hasAlternatePlainTextRenderTarget: "false",
|
|
13699
14251
|
hasAlternateRenderTargets: "false",
|
|
13700
14252
|
projectToolsPackageVersion,
|
|
14253
|
+
wpTypiaPackageVersion,
|
|
13701
14254
|
requiresAtLeast: compatibility.pluginHeader.requiresAtLeast,
|
|
13702
14255
|
requiresPhp: compatibility.pluginHeader.requiresPhp,
|
|
13703
14256
|
cssClassName,
|
|
@@ -13801,15 +14354,55 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13801
14354
|
// ../wp-typia-project-tools/src/runtime/scaffold.ts
|
|
13802
14355
|
var DATA_STORAGE_MODES = ["post-meta", "custom-table"];
|
|
13803
14356
|
var PERSISTENCE_POLICIES = ["authenticated", "public"];
|
|
14357
|
+
var CREATE_PROFILE_IDS = ["plugin-qa"];
|
|
13804
14358
|
function isDataStorageMode(value) {
|
|
13805
14359
|
return DATA_STORAGE_MODES.includes(value);
|
|
13806
14360
|
}
|
|
13807
14361
|
function isPersistencePolicy(value) {
|
|
13808
14362
|
return PERSISTENCE_POLICIES.includes(value);
|
|
13809
14363
|
}
|
|
14364
|
+
function isCreateProfileId(value) {
|
|
14365
|
+
return CREATE_PROFILE_IDS.includes(value);
|
|
14366
|
+
}
|
|
14367
|
+
function resolveCreateProfileId(profile) {
|
|
14368
|
+
if (profile === undefined || profile.trim().length === 0) {
|
|
14369
|
+
return;
|
|
14370
|
+
}
|
|
14371
|
+
const normalizedProfile = profile.trim();
|
|
14372
|
+
if (isCreateProfileId(normalizedProfile)) {
|
|
14373
|
+
return normalizedProfile;
|
|
14374
|
+
}
|
|
14375
|
+
throw new Error(`Unknown create profile "${profile}". Expected one of: ${CREATE_PROFILE_IDS.join(", ")}.`);
|
|
14376
|
+
}
|
|
13810
14377
|
function normalizeTemplateSelection(templateId) {
|
|
13811
14378
|
return normalizeTemplateLookupId(templateId);
|
|
13812
14379
|
}
|
|
14380
|
+
function assertCreateProfileTemplateCompatibility({
|
|
14381
|
+
profile,
|
|
14382
|
+
templateId
|
|
14383
|
+
}) {
|
|
14384
|
+
if (!profile) {
|
|
14385
|
+
return;
|
|
14386
|
+
}
|
|
14387
|
+
if (profile === "plugin-qa" && templateId !== OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
|
|
14388
|
+
throw new Error("`--profile plugin-qa` currently supports only the official workspace template. Use `--template workspace` or add QA files later with `wp-typia add integration-env <name> --wp-env --release-zip`.");
|
|
14389
|
+
}
|
|
14390
|
+
}
|
|
14391
|
+
async function applyCreateProfile({
|
|
14392
|
+
profile,
|
|
14393
|
+
projectDir
|
|
14394
|
+
}) {
|
|
14395
|
+
if (profile !== "plugin-qa") {
|
|
14396
|
+
return;
|
|
14397
|
+
}
|
|
14398
|
+
await runAddIntegrationEnvCommand({
|
|
14399
|
+
cwd: projectDir,
|
|
14400
|
+
integrationEnvName: "local-smoke",
|
|
14401
|
+
service: "none",
|
|
14402
|
+
withReleaseZip: true,
|
|
14403
|
+
withWpEnv: true
|
|
14404
|
+
});
|
|
14405
|
+
}
|
|
13813
14406
|
async function reportScaffoldProgress2(onProgress, event) {
|
|
13814
14407
|
await onProgress?.(event);
|
|
13815
14408
|
}
|
|
@@ -13824,6 +14417,7 @@ async function scaffoldProject({
|
|
|
13824
14417
|
externalLayerId,
|
|
13825
14418
|
externalLayerSource,
|
|
13826
14419
|
externalLayerSourceLabel,
|
|
14420
|
+
profile,
|
|
13827
14421
|
repositoryReference,
|
|
13828
14422
|
cwd = process.cwd(),
|
|
13829
14423
|
allowExistingDir = false,
|
|
@@ -13838,6 +14432,10 @@ async function scaffoldProject({
|
|
|
13838
14432
|
const resolvedTemplateId = normalizeTemplateSelection(templateId);
|
|
13839
14433
|
const resolvedPackageManager = getPackageManager(packageManager).id;
|
|
13840
14434
|
const isBuiltInTemplate = isBuiltInTemplateId(resolvedTemplateId);
|
|
14435
|
+
assertCreateProfileTemplateCompatibility({
|
|
14436
|
+
profile,
|
|
14437
|
+
templateId: resolvedTemplateId
|
|
14438
|
+
});
|
|
13841
14439
|
assertExternalLayerCompositionOptions({
|
|
13842
14440
|
externalLayerId,
|
|
13843
14441
|
externalLayerSource
|
|
@@ -13946,17 +14544,17 @@ async function scaffoldProject({
|
|
|
13946
14544
|
phase: "finalize-project",
|
|
13947
14545
|
title: "Finalizing scaffold output"
|
|
13948
14546
|
});
|
|
13949
|
-
const readmePath =
|
|
14547
|
+
const readmePath = path18.join(projectDir, "README.md");
|
|
13950
14548
|
if (!await pathExists(readmePath)) {
|
|
13951
|
-
await
|
|
14549
|
+
await fsp13.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
|
|
13952
14550
|
withMigrationUi: isBuiltInTemplate || isWorkspace ? withMigrationUi : false,
|
|
13953
14551
|
withTestPreset: isBuiltInTemplate ? withTestPreset : false,
|
|
13954
14552
|
withWpEnv: isBuiltInTemplate ? withWpEnv : false
|
|
13955
14553
|
}), "utf8");
|
|
13956
14554
|
}
|
|
13957
|
-
const gitignorePath =
|
|
13958
|
-
const existingGitignore = await pathExists(gitignorePath) ? await
|
|
13959
|
-
await
|
|
14555
|
+
const gitignorePath = path18.join(projectDir, ".gitignore");
|
|
14556
|
+
const existingGitignore = await pathExists(gitignorePath) ? await fsp13.readFile(gitignorePath, "utf8") : "";
|
|
14557
|
+
await fsp13.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
|
|
13960
14558
|
await normalizePackageJson(projectDir, resolvedPackageManager);
|
|
13961
14559
|
if (isBuiltInTemplate) {
|
|
13962
14560
|
const variableGroups = getScaffoldTemplateVariableGroups(variables);
|
|
@@ -13969,6 +14567,10 @@ async function scaffoldProject({
|
|
|
13969
14567
|
withWpEnv
|
|
13970
14568
|
});
|
|
13971
14569
|
}
|
|
14570
|
+
await applyCreateProfile({
|
|
14571
|
+
profile,
|
|
14572
|
+
projectDir
|
|
14573
|
+
});
|
|
13972
14574
|
await normalizePackageManagerFiles(projectDir, resolvedPackageManager);
|
|
13973
14575
|
await removeUnexpectedLockfiles(projectDir, resolvedPackageManager);
|
|
13974
14576
|
await replaceTextRecursively(projectDir, resolvedPackageManager, {
|
|
@@ -14036,6 +14638,6 @@ async function resolveOptionalInteractiveExternalLayerId({
|
|
|
14036
14638
|
}
|
|
14037
14639
|
}
|
|
14038
14640
|
|
|
14039
|
-
export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, isCompoundPersistenceEnabled, formatNonEmptyTargetDirectoryError, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, createScaffoldCompatibilityConfig, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
|
|
14641
|
+
export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, isCompoundPersistenceEnabled, formatNonEmptyTargetDirectoryError, executeWorkspaceMutationPlan, insertPhpSnippetBeforeWorkspaceAnchors, appendPhpSnippetBeforeClosingTag, runAddIntegrationEnvCommand, resolveExternalTemplateLayers, resolveTemplateSeed, normalizeOptionalCliString, resolveLocalCliPathOption, assertExternalLayerCompositionOptions, assertBuiltInTemplateVariantAllowed, parseAlternateRenderTargets, parseCompoundInnerBlocksPreset, OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY, REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY, resolveScaffoldCompatibilityPolicy, createScaffoldCompatibilityConfig, renderScaffoldCompatibilityConfig, updatePluginHeaderCompatibility, getDefaultAnswers, resolveTemplateId, resolvePackageManagerId, collectScaffoldAnswers, DATA_STORAGE_MODES, PERSISTENCE_POLICIES, isDataStorageMode, isPersistencePolicy, resolveCreateProfileId, scaffoldProject, resolveOptionalInteractiveExternalLayerId };
|
|
14040
14642
|
|
|
14041
|
-
//# debugId=
|
|
14643
|
+
//# debugId=5D116D118BFF7F2764756E2164756E21
|