wp-typia 0.23.0 → 0.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/bin/routing-metadata.generated.js +11 -0
- package/dist-bunli/.bunli/commands.gen.js +11884 -9017
- package/dist-bunli/{cli-9npd9was.js → cli-0v407aag.js} +12 -10
- package/dist-bunli/{cli-hhp1d348.js → cli-1170yyve.js} +8 -7
- package/dist-bunli/{cli-1meywwsy.js → cli-74y6z3yx.js} +1455 -819
- 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-nmdraf20.js} +8542 -7667
- package/dist-bunli/{cli-52ke0ptp.js → cli-am5x7tb4.js} +8 -2
- package/dist-bunli/{cli-43mx1vfb.js → cli-bajwv85z.js} +2 -1
- package/dist-bunli/cli-ccax7s0s.js +34 -0
- package/dist-bunli/{cli-z5qkx2pn.js → cli-cwjdzq6n.js} +79 -13
- package/dist-bunli/{cli-diagnostics-5dvztm7q.js → cli-diagnostics-10drxh34.js} +1 -1
- package/dist-bunli/{cli-doctor-wy2yjsge.js → cli-doctor-pcss6ecx.js} +688 -459
- package/dist-bunli/{cli-2rqf6t0b.js → cli-e4bwd81c.js} +8 -11
- package/dist-bunli/{cli-init-xnsbxncv.js → cli-init-he7vm7kc.js} +15 -11
- 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-an2k0fnm.js} +28 -16
- package/dist-bunli/{cli-c2acv5dv.js → cli-sw06c521.js} +2 -2
- 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-ts9thts5.js → cli-v0nnagb3.js} +1513 -1053
- package/dist-bunli/{cli-agywa5n6.js → cli-y0a8nztv.js} +15 -6
- package/dist-bunli/cli-z48frc8t.js +229 -0
- package/dist-bunli/cli.js +5 -5
- package/dist-bunli/{command-list-aqrkx021.js → command-list-xaw5agks.js} +241 -64
- package/dist-bunli/{create-template-validation-rtec5sng.js → create-template-validation-4fr851vg.js} +5 -4
- package/dist-bunli/{migrations-bx0yvc2v.js → migrations-z7f4kxba.js} +10 -9
- package/dist-bunli/node-cli.js +661 -389
- package/dist-bunli/{workspace-project-csnnggz6.js → workspace-project-gmv2a71z.js} +4 -3
- package/package.json +2 -2
- package/dist-bunli/cli-j8et6jvr.js +0 -123
|
@@ -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,11 @@ import {
|
|
|
14
14
|
isOmittableBuiltInTemplateLayerDir,
|
|
15
15
|
resolveBuiltInTemplateSource,
|
|
16
16
|
resolveBuiltInTemplateSourceFromLayerDirs
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-sw06c521.js";
|
|
18
18
|
import {
|
|
19
|
+
DEFAULT_WORDPRESS_ENV_VERSION,
|
|
19
20
|
getPackageVersions
|
|
20
|
-
} from "./cli-
|
|
21
|
+
} from "./cli-y0a8nztv.js";
|
|
21
22
|
import {
|
|
22
23
|
BUILTIN_BLOCK_METADATA_VERSION,
|
|
23
24
|
COMPOUND_CHILD_BLOCK_METADATA_DEFAULTS,
|
|
@@ -32,18 +33,20 @@ import {
|
|
|
32
33
|
getTemplateById,
|
|
33
34
|
isBuiltInTemplateId,
|
|
34
35
|
normalizeTemplateLookupId
|
|
35
|
-
} from "./cli-
|
|
36
|
+
} from "./cli-8hxf9qw6.js";
|
|
36
37
|
import {
|
|
37
38
|
seedProjectMigrations
|
|
38
|
-
} from "./cli-
|
|
39
|
+
} from "./cli-0v407aag.js";
|
|
39
40
|
import {
|
|
40
41
|
ensureMigrationDirectories,
|
|
41
42
|
isPlainObject,
|
|
42
43
|
stableJsonStringify,
|
|
43
44
|
writeInitialMigrationScaffold,
|
|
44
45
|
writeMigrationConfig
|
|
45
|
-
} from "./cli-
|
|
46
|
+
} from "./cli-e4bwd81c.js";
|
|
46
47
|
import {
|
|
48
|
+
assertValidGeneratedSlug,
|
|
49
|
+
assertValidIntegrationEnvService,
|
|
47
50
|
buildBlockCssClassName,
|
|
48
51
|
buildFrontendCssClassName,
|
|
49
52
|
getNodeErrorCode,
|
|
@@ -52,20 +55,25 @@ import {
|
|
|
52
55
|
pathExists,
|
|
53
56
|
readOptionalUtf8File,
|
|
54
57
|
resolveScaffoldIdentifiers,
|
|
58
|
+
rollbackWorkspaceMutation,
|
|
59
|
+
snapshotWorkspaceFiles,
|
|
55
60
|
toPascalCase,
|
|
56
61
|
toSegmentPascalCase,
|
|
57
62
|
toSnakeCase,
|
|
58
63
|
toTitleCase,
|
|
59
64
|
validateBlockSlug,
|
|
60
65
|
validateNamespace
|
|
61
|
-
} from "./cli-
|
|
66
|
+
} from "./cli-v0nnagb3.js";
|
|
62
67
|
import {
|
|
63
68
|
createManagedTempRoot
|
|
64
69
|
} from "./cli-t73q5aqz.js";
|
|
65
70
|
import {
|
|
66
71
|
CLI_DIAGNOSTIC_CODES,
|
|
67
72
|
createCliDiagnosticCodeError
|
|
68
|
-
} from "./cli-
|
|
73
|
+
} from "./cli-tq730sqt.js";
|
|
74
|
+
import {
|
|
75
|
+
resolveWorkspaceProject
|
|
76
|
+
} from "./cli-1170yyve.js";
|
|
69
77
|
import {
|
|
70
78
|
PACKAGE_MANAGER_IDS,
|
|
71
79
|
formatInstallCommand,
|
|
@@ -73,7 +81,12 @@ import {
|
|
|
73
81
|
formatRunScript,
|
|
74
82
|
getPackageManager,
|
|
75
83
|
transformPackageManagerText
|
|
76
|
-
} from "./cli-
|
|
84
|
+
} from "./cli-am5x7tb4.js";
|
|
85
|
+
import {
|
|
86
|
+
readJsonFile,
|
|
87
|
+
readJsonFileSync,
|
|
88
|
+
safeJsonParse
|
|
89
|
+
} from "./cli-ccax7s0s.js";
|
|
77
90
|
import {
|
|
78
91
|
__toESM
|
|
79
92
|
} from "./cli-xnn9xjcy.js";
|
|
@@ -754,7 +767,9 @@ function getDevScript(packageManager, compoundPersistenceEnabled, templateId) {
|
|
|
754
767
|
}
|
|
755
768
|
async function mutatePackageJson(projectDir, mutate) {
|
|
756
769
|
const packageJsonPath = path2.join(projectDir, "package.json");
|
|
757
|
-
const packageJson =
|
|
770
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
771
|
+
context: "local dev package manifest"
|
|
772
|
+
});
|
|
758
773
|
mutate(packageJson);
|
|
759
774
|
await fsp2.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
760
775
|
`, "utf8");
|
|
@@ -810,7 +825,7 @@ async function applyGeneratedProjectDxPackageJson({
|
|
|
810
825
|
} : {}
|
|
811
826
|
};
|
|
812
827
|
if (withWpEnv || withTestPreset) {
|
|
813
|
-
packageJson.devDependencies["@wordpress/env"] =
|
|
828
|
+
packageJson.devDependencies["@wordpress/env"] = DEFAULT_WORDPRESS_ENV_VERSION;
|
|
814
829
|
}
|
|
815
830
|
if (withTestPreset) {
|
|
816
831
|
packageJson.devDependencies["@playwright/test"] = "^1.54.2";
|
|
@@ -2189,7 +2204,9 @@ function readGeneratedPackageJson(projectDir) {
|
|
|
2189
2204
|
if (!fs2.existsSync(packageJsonPath)) {
|
|
2190
2205
|
return null;
|
|
2191
2206
|
}
|
|
2192
|
-
return
|
|
2207
|
+
return readJsonFileSync(packageJsonPath, {
|
|
2208
|
+
context: "generated package manifest"
|
|
2209
|
+
});
|
|
2193
2210
|
}
|
|
2194
2211
|
function formatNonEmptyTargetDirectoryError(targetDir) {
|
|
2195
2212
|
return `Target directory is not empty: ${targetDir}. Choose a new project directory, or empty this directory before rerunning the scaffold.`;
|
|
@@ -2231,7 +2248,9 @@ function isWorkspaceProject(projectDir) {
|
|
|
2231
2248
|
}
|
|
2232
2249
|
async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
|
|
2233
2250
|
const packageJsonPath = path4.join(projectDir, "package.json");
|
|
2234
|
-
const packageJson =
|
|
2251
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
2252
|
+
context: "workspace package manifest"
|
|
2253
|
+
});
|
|
2235
2254
|
const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
|
|
2236
2255
|
const canonicalCliSpecifier = wpTypiaPackageVersion === "^0.0.0" ? "wp-typia" : `wp-typia@${wpTypiaPackageVersion.replace(/^[~^]/u, "")}`;
|
|
2237
2256
|
const migrationCli = (args) => formatPackageExecCommand(packageManager, canonicalCliSpecifier, `migrate ${args}`);
|
|
@@ -2288,9 +2307,548 @@ async function withEphemeralScaffoldNodeModules(targetDir, callback) {
|
|
|
2288
2307
|
}
|
|
2289
2308
|
}
|
|
2290
2309
|
|
|
2310
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env.ts
|
|
2311
|
+
import path7 from "path";
|
|
2312
|
+
|
|
2313
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env-files.ts
|
|
2314
|
+
import { promises as fsp4 } from "fs";
|
|
2315
|
+
import path5 from "path";
|
|
2316
|
+
async function appendMissingLines(filePath, lines) {
|
|
2317
|
+
const current = await readOptionalUtf8File(filePath) ?? "";
|
|
2318
|
+
const existingLines = new Set(current.split(/\r?\n/u));
|
|
2319
|
+
const missingLines = lines.filter((line) => !existingLines.has(line));
|
|
2320
|
+
if (missingLines.length === 0) {
|
|
2321
|
+
return;
|
|
2322
|
+
}
|
|
2323
|
+
const separator = current.length === 0 || current.endsWith(`
|
|
2324
|
+
`) ? "" : `
|
|
2325
|
+
`;
|
|
2326
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2327
|
+
await fsp4.writeFile(filePath, `${current}${separator}${missingLines.join(`
|
|
2328
|
+
`)}
|
|
2329
|
+
`, "utf8");
|
|
2330
|
+
}
|
|
2331
|
+
async function writeFileIfAbsent({
|
|
2332
|
+
filePath,
|
|
2333
|
+
source,
|
|
2334
|
+
warnings
|
|
2335
|
+
}) {
|
|
2336
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2337
|
+
try {
|
|
2338
|
+
await fsp4.writeFile(filePath, source, { encoding: "utf8", flag: "wx" });
|
|
2339
|
+
} catch (error) {
|
|
2340
|
+
if (error.code === "EEXIST") {
|
|
2341
|
+
warnings.push(`Preserved existing ${path5.basename(filePath)}; review it manually if you need different local integration settings.`);
|
|
2342
|
+
return;
|
|
2343
|
+
}
|
|
2344
|
+
throw error;
|
|
2345
|
+
}
|
|
2346
|
+
}
|
|
2347
|
+
async function writeNewScaffoldFile(filePath, source) {
|
|
2348
|
+
await fsp4.mkdir(path5.dirname(filePath), { recursive: true });
|
|
2349
|
+
try {
|
|
2350
|
+
await fsp4.writeFile(filePath, source, { encoding: "utf8", flag: "wx" });
|
|
2351
|
+
} catch (error) {
|
|
2352
|
+
if (error.code === "EEXIST") {
|
|
2353
|
+
throw new Error(`An integration environment scaffold already exists at ${filePath}. Choose a different name.`);
|
|
2354
|
+
}
|
|
2355
|
+
throw error;
|
|
2356
|
+
}
|
|
2357
|
+
}
|
|
2358
|
+
|
|
2359
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env-package-json.ts
|
|
2360
|
+
import { promises as fsp5 } from "fs";
|
|
2361
|
+
import path6 from "path";
|
|
2362
|
+
function addScriptIfMissing({
|
|
2363
|
+
scriptName,
|
|
2364
|
+
scripts,
|
|
2365
|
+
scriptValue,
|
|
2366
|
+
warnings
|
|
2367
|
+
}) {
|
|
2368
|
+
if (scripts[scriptName] === undefined) {
|
|
2369
|
+
scripts[scriptName] = scriptValue;
|
|
2370
|
+
return;
|
|
2371
|
+
}
|
|
2372
|
+
if (scripts[scriptName] !== scriptValue) {
|
|
2373
|
+
warnings.push(`Preserved existing package script "${scriptName}"; add "${scriptValue}" manually if you want the generated integration command.`);
|
|
2374
|
+
}
|
|
2375
|
+
}
|
|
2376
|
+
async function mutateIntegrationEnvPackageJson(projectDir, mutate) {
|
|
2377
|
+
const packageJsonPath = path6.join(projectDir, "package.json");
|
|
2378
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
2379
|
+
context: "integration env package manifest"
|
|
2380
|
+
});
|
|
2381
|
+
mutate(packageJson);
|
|
2382
|
+
await fsp5.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
2383
|
+
`, "utf8");
|
|
2384
|
+
}
|
|
2385
|
+
function addIntegrationEnvPackageJsonEntries({
|
|
2386
|
+
integrationEnvSlug,
|
|
2387
|
+
packageManager,
|
|
2388
|
+
packageJson,
|
|
2389
|
+
withReleaseZip,
|
|
2390
|
+
service,
|
|
2391
|
+
warnings,
|
|
2392
|
+
withWpEnv
|
|
2393
|
+
}) {
|
|
2394
|
+
const devDependencies = {
|
|
2395
|
+
...packageJson.devDependencies ?? {}
|
|
2396
|
+
};
|
|
2397
|
+
if (withWpEnv && devDependencies["@wordpress/env"] === undefined) {
|
|
2398
|
+
devDependencies["@wordpress/env"] = DEFAULT_WORDPRESS_ENV_VERSION;
|
|
2399
|
+
}
|
|
2400
|
+
packageJson.devDependencies = devDependencies;
|
|
2401
|
+
const scripts = {
|
|
2402
|
+
...packageJson.scripts ?? {}
|
|
2403
|
+
};
|
|
2404
|
+
addScriptIfMissing({
|
|
2405
|
+
scriptName: `smoke:${integrationEnvSlug}`,
|
|
2406
|
+
scriptValue: `node scripts/integration-smoke/${integrationEnvSlug}.mjs`,
|
|
2407
|
+
scripts,
|
|
2408
|
+
warnings
|
|
2409
|
+
});
|
|
2410
|
+
addScriptIfMissing({
|
|
2411
|
+
scriptName: "smoke:integration",
|
|
2412
|
+
scriptValue: formatRunScript(packageManager, `smoke:${integrationEnvSlug}`),
|
|
2413
|
+
scripts,
|
|
2414
|
+
warnings
|
|
2415
|
+
});
|
|
2416
|
+
if (withWpEnv) {
|
|
2417
|
+
addScriptIfMissing({
|
|
2418
|
+
scriptName: "wp-env:start",
|
|
2419
|
+
scriptValue: "wp-env start",
|
|
2420
|
+
scripts,
|
|
2421
|
+
warnings
|
|
2422
|
+
});
|
|
2423
|
+
addScriptIfMissing({
|
|
2424
|
+
scriptName: "wp-env:stop",
|
|
2425
|
+
scriptValue: "wp-env stop",
|
|
2426
|
+
scripts,
|
|
2427
|
+
warnings
|
|
2428
|
+
});
|
|
2429
|
+
addScriptIfMissing({
|
|
2430
|
+
scriptName: "wp-env:reset",
|
|
2431
|
+
scriptValue: "wp-env destroy all && wp-env start",
|
|
2432
|
+
scripts,
|
|
2433
|
+
warnings
|
|
2434
|
+
});
|
|
2435
|
+
}
|
|
2436
|
+
if (withReleaseZip) {
|
|
2437
|
+
addScriptIfMissing({
|
|
2438
|
+
scriptName: "release:zip",
|
|
2439
|
+
scriptValue: `${formatRunScript(packageManager, "sync-rest:package")} && ${formatRunScript(packageManager, "build")} && wp-scripts plugin-zip`,
|
|
2440
|
+
scripts,
|
|
2441
|
+
warnings
|
|
2442
|
+
});
|
|
2443
|
+
addScriptIfMissing({
|
|
2444
|
+
scriptName: "release:zip:check",
|
|
2445
|
+
scriptValue: `${formatRunScript(packageManager, "sync-rest:package:check")} && ${formatRunScript(packageManager, "build")}`,
|
|
2446
|
+
scripts,
|
|
2447
|
+
warnings
|
|
2448
|
+
});
|
|
2449
|
+
addScriptIfMissing({
|
|
2450
|
+
scriptName: "qa:check",
|
|
2451
|
+
scriptValue: `${formatRunScript(packageManager, "wp-typia:doctor:workspace")} && ${formatRunScript(packageManager, "release:zip:check")}`,
|
|
2452
|
+
scripts,
|
|
2453
|
+
warnings
|
|
2454
|
+
});
|
|
2455
|
+
}
|
|
2456
|
+
if (service === "docker-compose") {
|
|
2457
|
+
addScriptIfMissing({
|
|
2458
|
+
scriptName: "service:start",
|
|
2459
|
+
scriptValue: "docker compose -f docker-compose.integration.yml up -d",
|
|
2460
|
+
scripts,
|
|
2461
|
+
warnings
|
|
2462
|
+
});
|
|
2463
|
+
addScriptIfMissing({
|
|
2464
|
+
scriptName: "service:stop",
|
|
2465
|
+
scriptValue: "docker compose -f docker-compose.integration.yml down",
|
|
2466
|
+
scripts,
|
|
2467
|
+
warnings
|
|
2468
|
+
});
|
|
2469
|
+
}
|
|
2470
|
+
packageJson.scripts = scripts;
|
|
2471
|
+
}
|
|
2472
|
+
|
|
2473
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env-source-emitters.ts
|
|
2474
|
+
function buildWpEnvConfigSource() {
|
|
2475
|
+
return `${JSON.stringify({
|
|
2476
|
+
$schema: "https://schemas.wp.org/trunk/wp-env.json",
|
|
2477
|
+
core: null,
|
|
2478
|
+
port: 8888,
|
|
2479
|
+
testsEnvironment: false,
|
|
2480
|
+
plugins: ["."],
|
|
2481
|
+
config: {
|
|
2482
|
+
WP_DEBUG: true,
|
|
2483
|
+
WP_DEBUG_LOG: true,
|
|
2484
|
+
WP_DEBUG_DISPLAY: false,
|
|
2485
|
+
SCRIPT_DEBUG: true,
|
|
2486
|
+
WP_ENVIRONMENT_TYPE: "local"
|
|
2487
|
+
}
|
|
2488
|
+
}, null, 2)}
|
|
2489
|
+
`;
|
|
2490
|
+
}
|
|
2491
|
+
function buildDockerComposeSource() {
|
|
2492
|
+
return `services:
|
|
2493
|
+
integration-service:
|
|
2494
|
+
image: node:22-alpine
|
|
2495
|
+
working_dir: /workspace
|
|
2496
|
+
volumes:
|
|
2497
|
+
- .:/workspace
|
|
2498
|
+
command: >
|
|
2499
|
+
node -e "require('node:http').createServer((request, response) => {
|
|
2500
|
+
response.writeHead(request.url === '/health' ? 200 : 404, {
|
|
2501
|
+
'content-type': 'application/json'
|
|
2502
|
+
});
|
|
2503
|
+
response.end(JSON.stringify({
|
|
2504
|
+
ok: request.url === '/health',
|
|
2505
|
+
service: 'wp-typia-integration-starter'
|
|
2506
|
+
}));
|
|
2507
|
+
}).listen(3000, '0.0.0.0')"
|
|
2508
|
+
ports:
|
|
2509
|
+
- "3000:3000"
|
|
2510
|
+
`;
|
|
2511
|
+
}
|
|
2512
|
+
function buildIntegrationSmokeScriptSource(integrationEnvSlug) {
|
|
2513
|
+
return `import fs from "node:fs";
|
|
2514
|
+
import path from "node:path";
|
|
2515
|
+
import { fileURLToPath } from "node:url";
|
|
2516
|
+
|
|
2517
|
+
const ROOT_DIR = path.resolve(
|
|
2518
|
+
fileURLToPath(new URL("../..", import.meta.url)),
|
|
2519
|
+
);
|
|
2520
|
+
const ENV_FILE = path.join(ROOT_DIR, ".env");
|
|
2521
|
+
|
|
2522
|
+
function parseEnvValue(value) {
|
|
2523
|
+
const trimmed = value.trim();
|
|
2524
|
+
if (
|
|
2525
|
+
(trimmed.startsWith('"') && trimmed.endsWith('"')) ||
|
|
2526
|
+
(trimmed.startsWith("'") && trimmed.endsWith("'"))
|
|
2527
|
+
) {
|
|
2528
|
+
return trimmed.slice(1, -1);
|
|
2529
|
+
}
|
|
2530
|
+
|
|
2531
|
+
return trimmed;
|
|
2532
|
+
}
|
|
2533
|
+
|
|
2534
|
+
function readEnvFile(filePath) {
|
|
2535
|
+
if (!fs.existsSync(filePath)) {
|
|
2536
|
+
return {};
|
|
2537
|
+
}
|
|
2538
|
+
|
|
2539
|
+
return Object.fromEntries(
|
|
2540
|
+
fs
|
|
2541
|
+
.readFileSync(filePath, "utf8")
|
|
2542
|
+
.split(/\\r?\\n/u)
|
|
2543
|
+
.map((line) => line.trim())
|
|
2544
|
+
.filter((line) => line.length > 0 && !line.startsWith("#"))
|
|
2545
|
+
.map((line) => {
|
|
2546
|
+
const separatorIndex = line.indexOf("=");
|
|
2547
|
+
if (separatorIndex === -1) {
|
|
2548
|
+
return null;
|
|
2549
|
+
}
|
|
2550
|
+
|
|
2551
|
+
return [
|
|
2552
|
+
line.slice(0, separatorIndex).trim(),
|
|
2553
|
+
parseEnvValue(line.slice(separatorIndex + 1)),
|
|
2554
|
+
];
|
|
2555
|
+
})
|
|
2556
|
+
.filter(Boolean),
|
|
2557
|
+
);
|
|
2558
|
+
}
|
|
2559
|
+
|
|
2560
|
+
const envFile = readEnvFile(ENV_FILE);
|
|
2561
|
+
|
|
2562
|
+
function getEnv(name, fallback) {
|
|
2563
|
+
return process.env[name] ?? envFile[name] ?? fallback;
|
|
2564
|
+
}
|
|
2565
|
+
|
|
2566
|
+
function getPositiveIntegerEnv(name, fallback) {
|
|
2567
|
+
const value = Number.parseInt(getEnv(name, String(fallback)), 10);
|
|
2568
|
+
return Number.isFinite(value) && value > 0 ? value : fallback;
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
function resolveEndpointUrl(baseUrl, endpointPath) {
|
|
2572
|
+
const normalizedBaseUrl = new URL(baseUrl);
|
|
2573
|
+
if (!normalizedBaseUrl.pathname.endsWith("/")) {
|
|
2574
|
+
normalizedBaseUrl.pathname = \`\${normalizedBaseUrl.pathname}/\`;
|
|
2575
|
+
}
|
|
2576
|
+
|
|
2577
|
+
const relativePath = endpointPath.replace(/^\\/+/u, "");
|
|
2578
|
+
return new URL(relativePath, normalizedBaseUrl);
|
|
2579
|
+
}
|
|
2580
|
+
|
|
2581
|
+
async function assertJsonEndpoint(label, url) {
|
|
2582
|
+
const requestTimeoutMs = getPositiveIntegerEnv(
|
|
2583
|
+
"WP_TYPIA_SMOKE_TIMEOUT_MS",
|
|
2584
|
+
30_000,
|
|
2585
|
+
);
|
|
2586
|
+
const response = await fetch(url, {
|
|
2587
|
+
headers: {
|
|
2588
|
+
accept: "application/json",
|
|
2589
|
+
},
|
|
2590
|
+
signal: AbortSignal.timeout(requestTimeoutMs),
|
|
2591
|
+
});
|
|
2592
|
+
|
|
2593
|
+
if (!response.ok) {
|
|
2594
|
+
throw new Error(
|
|
2595
|
+
\`\${label} failed at \${url} with HTTP \${response.status}.\`,
|
|
2596
|
+
);
|
|
2597
|
+
}
|
|
2598
|
+
|
|
2599
|
+
const contentType = response.headers.get("content-type") ?? "";
|
|
2600
|
+
if (!contentType.includes("application/json")) {
|
|
2601
|
+
throw new Error(
|
|
2602
|
+
\`\${label} at \${url} did not return JSON (content-type: \${contentType || "missing"}).\`,
|
|
2603
|
+
);
|
|
2604
|
+
}
|
|
2605
|
+
|
|
2606
|
+
return response.json();
|
|
2607
|
+
}
|
|
2608
|
+
|
|
2609
|
+
const baseUrl = new URL(
|
|
2610
|
+
getEnv("WP_TYPIA_SMOKE_BASE_URL", "http://localhost:8888"),
|
|
2611
|
+
);
|
|
2612
|
+
const serviceUrl = getEnv("WP_TYPIA_SERVICE_URL", "").trim();
|
|
2613
|
+
|
|
2614
|
+
// Extend this starter with project-specific generated REST clients or schema
|
|
2615
|
+
// checks as the workspace grows. For example, read JSON schemas under
|
|
2616
|
+
// src/rest/<resource>/api-schemas or import TS clients through a tsx-powered
|
|
2617
|
+
// smoke runner when you need authenticated route coverage.
|
|
2618
|
+
|
|
2619
|
+
await assertJsonEndpoint(
|
|
2620
|
+
"WordPress REST index",
|
|
2621
|
+
resolveEndpointUrl(baseUrl, "wp-json/"),
|
|
2622
|
+
);
|
|
2623
|
+
|
|
2624
|
+
if (serviceUrl.length > 0) {
|
|
2625
|
+
await assertJsonEndpoint(
|
|
2626
|
+
"Local integration service healthcheck",
|
|
2627
|
+
resolveEndpointUrl(serviceUrl, "health"),
|
|
2628
|
+
);
|
|
2629
|
+
}
|
|
2630
|
+
|
|
2631
|
+
console.log("wp-typia integration smoke passed: ${integrationEnvSlug}");
|
|
2632
|
+
`;
|
|
2633
|
+
}
|
|
2634
|
+
function buildEnvExampleSource(service) {
|
|
2635
|
+
return [
|
|
2636
|
+
"# wp-typia integration smoke settings",
|
|
2637
|
+
"WP_TYPIA_SMOKE_BASE_URL=http://localhost:8888",
|
|
2638
|
+
"WP_TYPIA_SMOKE_USERNAME=admin",
|
|
2639
|
+
"WP_TYPIA_SMOKE_PASSWORD=password",
|
|
2640
|
+
"WP_TYPIA_SMOKE_TIMEOUT_MS=30000",
|
|
2641
|
+
...service === "docker-compose" ? [
|
|
2642
|
+
"",
|
|
2643
|
+
"# Optional docker-compose integration service starter.",
|
|
2644
|
+
"WP_TYPIA_SERVICE_URL=http://localhost:3000"
|
|
2645
|
+
] : [
|
|
2646
|
+
"",
|
|
2647
|
+
"# Set this when your smoke test needs a project-specific service.",
|
|
2648
|
+
"# WP_TYPIA_SERVICE_URL=http://localhost:3000"
|
|
2649
|
+
],
|
|
2650
|
+
""
|
|
2651
|
+
].join(`
|
|
2652
|
+
`);
|
|
2653
|
+
}
|
|
2654
|
+
function buildIntegrationEnvReadmeSource({
|
|
2655
|
+
integrationEnvSlug,
|
|
2656
|
+
service,
|
|
2657
|
+
withReleaseZip,
|
|
2658
|
+
withWpEnv
|
|
2659
|
+
}) {
|
|
2660
|
+
const title = toTitleCase(integrationEnvSlug);
|
|
2661
|
+
const setupSteps = [
|
|
2662
|
+
"Copy `.env.example` to `.env` and adjust the URLs or credentials for your local project.",
|
|
2663
|
+
...withWpEnv ? [
|
|
2664
|
+
"Run `npm run wp-env:start` to start the generated WordPress environment."
|
|
2665
|
+
] : [
|
|
2666
|
+
"Point `WP_TYPIA_SMOKE_BASE_URL` at the WordPress environment you already run locally."
|
|
2667
|
+
],
|
|
2668
|
+
...service === "docker-compose" ? [
|
|
2669
|
+
"Run `npm run service:start` if you want the placeholder docker-compose service available at `WP_TYPIA_SERVICE_URL`."
|
|
2670
|
+
] : [
|
|
2671
|
+
"Set `WP_TYPIA_SERVICE_URL` only when your integration smoke needs a local service dependency."
|
|
2672
|
+
],
|
|
2673
|
+
`Run \`npm run smoke:${integrationEnvSlug}\` to execute the starter smoke check.`,
|
|
2674
|
+
...withReleaseZip ? [
|
|
2675
|
+
"Run `npm run release:zip` after smoke checks pass to build a distributable plugin zip."
|
|
2676
|
+
] : []
|
|
2677
|
+
];
|
|
2678
|
+
return `# ${title} Integration Environment
|
|
2679
|
+
|
|
2680
|
+
This starter keeps local WordPress integration smoke checks opt-in and editable.
|
|
2681
|
+
It does not change default block scaffolds or require wp-env unless this add
|
|
2682
|
+
workflow was run with \`--wp-env\`.
|
|
2683
|
+
|
|
2684
|
+
## Setup
|
|
2685
|
+
|
|
2686
|
+
${setupSteps.map((step, index) => `${index + 1}. ${step}`).join(`
|
|
2687
|
+
`)}
|
|
2688
|
+
|
|
2689
|
+
## Adapting the Starter
|
|
2690
|
+
|
|
2691
|
+
- Extend \`scripts/integration-smoke/${integrationEnvSlug}.mjs\` with the REST,
|
|
2692
|
+
editor, or service assertions that matter for this project.
|
|
2693
|
+
- Keep secrets in \`.env\`; \`.env.example\` should document only safe defaults.
|
|
2694
|
+
- If your project uses a real service stack, replace the placeholder
|
|
2695
|
+
\`docker-compose.integration.yml\` service with your database, queue, API, or
|
|
2696
|
+
emulator containers.
|
|
2697
|
+
- Keep the smoke script focused on high-signal integration checks so CI and
|
|
2698
|
+
local debugging stay fast.
|
|
2699
|
+
${withReleaseZip ? "- Treat `release:zip:check` as a CI guard before packaging release artifacts.\n" : ""}
|
|
2700
|
+
`;
|
|
2701
|
+
}
|
|
2702
|
+
|
|
2703
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-mutation.ts
|
|
2704
|
+
var DEFAULT_PHP_SNIPPET_INSERTION_ANCHORS = [
|
|
2705
|
+
/add_action\(\s*["']init["']\s*,\s*["'][^"']+_load_textdomain["']\s*\);\s*\n/u,
|
|
2706
|
+
/\?>\s*$/u
|
|
2707
|
+
];
|
|
2708
|
+
|
|
2709
|
+
class WorkspaceMutationRollbackError extends Error {
|
|
2710
|
+
mutationError;
|
|
2711
|
+
rollbackError;
|
|
2712
|
+
constructor(mutationError, rollbackError) {
|
|
2713
|
+
super("Workspace mutation failed and rollback also failed.");
|
|
2714
|
+
this.name = "WorkspaceMutationRollbackError";
|
|
2715
|
+
this.mutationError = mutationError;
|
|
2716
|
+
this.rollbackError = rollbackError;
|
|
2717
|
+
}
|
|
2718
|
+
}
|
|
2719
|
+
async function executeWorkspaceMutationPlan({
|
|
2720
|
+
filePaths,
|
|
2721
|
+
run,
|
|
2722
|
+
snapshotDirs = [],
|
|
2723
|
+
targetPaths = []
|
|
2724
|
+
}) {
|
|
2725
|
+
const mutationSnapshot = {
|
|
2726
|
+
fileSources: await snapshotWorkspaceFiles(filePaths),
|
|
2727
|
+
snapshotDirs: [...snapshotDirs],
|
|
2728
|
+
targetPaths: [...targetPaths]
|
|
2729
|
+
};
|
|
2730
|
+
try {
|
|
2731
|
+
return await run();
|
|
2732
|
+
} catch (error) {
|
|
2733
|
+
try {
|
|
2734
|
+
await rollbackWorkspaceMutation(mutationSnapshot);
|
|
2735
|
+
} catch (rollbackError) {
|
|
2736
|
+
throw new WorkspaceMutationRollbackError(error, rollbackError);
|
|
2737
|
+
}
|
|
2738
|
+
throw error;
|
|
2739
|
+
}
|
|
2740
|
+
}
|
|
2741
|
+
function insertPhpSnippetBeforeWorkspaceAnchors(source, snippet) {
|
|
2742
|
+
for (const anchor of DEFAULT_PHP_SNIPPET_INSERTION_ANCHORS) {
|
|
2743
|
+
const candidate = source.replace(anchor, (match) => `${snippet}
|
|
2744
|
+
${match}`);
|
|
2745
|
+
if (candidate !== source) {
|
|
2746
|
+
return candidate;
|
|
2747
|
+
}
|
|
2748
|
+
}
|
|
2749
|
+
return `${source.trimEnd()}
|
|
2750
|
+
${snippet}
|
|
2751
|
+
`;
|
|
2752
|
+
}
|
|
2753
|
+
function appendPhpSnippetBeforeClosingTag(source, snippet) {
|
|
2754
|
+
const closingTagPattern = /\?>\s*$/u;
|
|
2755
|
+
if (closingTagPattern.test(source)) {
|
|
2756
|
+
return source.replace(closingTagPattern, `${snippet}
|
|
2757
|
+
?>`);
|
|
2758
|
+
}
|
|
2759
|
+
return `${source.trimEnd()}
|
|
2760
|
+
${snippet}
|
|
2761
|
+
`;
|
|
2762
|
+
}
|
|
2763
|
+
|
|
2764
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-integration-env.ts
|
|
2765
|
+
async function runAddIntegrationEnvCommand({
|
|
2766
|
+
cwd = process.cwd(),
|
|
2767
|
+
integrationEnvName,
|
|
2768
|
+
service,
|
|
2769
|
+
withReleaseZip = false,
|
|
2770
|
+
withWpEnv = false
|
|
2771
|
+
}) {
|
|
2772
|
+
const workspace = resolveWorkspaceProject(cwd);
|
|
2773
|
+
const integrationEnvSlug = assertValidGeneratedSlug("Integration environment name", normalizeBlockSlug(integrationEnvName), "wp-typia add integration-env <name> [--wp-env] [--release-zip]");
|
|
2774
|
+
const serviceId = assertValidIntegrationEnvService(service);
|
|
2775
|
+
const warnings = [];
|
|
2776
|
+
const packageJsonPath = path7.join(workspace.projectDir, "package.json");
|
|
2777
|
+
const gitignorePath = path7.join(workspace.projectDir, ".gitignore");
|
|
2778
|
+
const envExamplePath = path7.join(workspace.projectDir, ".env.example");
|
|
2779
|
+
const wpEnvPath = path7.join(workspace.projectDir, ".wp-env.json");
|
|
2780
|
+
const dockerComposePath = path7.join(workspace.projectDir, "docker-compose.integration.yml");
|
|
2781
|
+
const smokeDir = path7.join(workspace.projectDir, "scripts", "integration-smoke");
|
|
2782
|
+
const docsDir = path7.join(workspace.projectDir, "docs", "integration-env");
|
|
2783
|
+
const smokeScriptPath = path7.join(smokeDir, `${integrationEnvSlug}.mjs`);
|
|
2784
|
+
const docsPath = path7.join(docsDir, `${integrationEnvSlug}.md`);
|
|
2785
|
+
const shouldRemoveSmokeDirOnRollback = !await pathExists(smokeDir);
|
|
2786
|
+
const shouldRemoveDocsDirOnRollback = !await pathExists(docsDir);
|
|
2787
|
+
await executeWorkspaceMutationPlan({
|
|
2788
|
+
filePaths: [
|
|
2789
|
+
packageJsonPath,
|
|
2790
|
+
gitignorePath,
|
|
2791
|
+
envExamplePath,
|
|
2792
|
+
...withWpEnv ? [wpEnvPath] : [],
|
|
2793
|
+
...serviceId === "docker-compose" ? [dockerComposePath] : []
|
|
2794
|
+
],
|
|
2795
|
+
targetPaths: [
|
|
2796
|
+
smokeScriptPath,
|
|
2797
|
+
docsPath,
|
|
2798
|
+
...shouldRemoveSmokeDirOnRollback ? [smokeDir] : [],
|
|
2799
|
+
...shouldRemoveDocsDirOnRollback ? [docsDir] : []
|
|
2800
|
+
],
|
|
2801
|
+
run: async () => {
|
|
2802
|
+
await writeNewScaffoldFile(smokeScriptPath, buildIntegrationSmokeScriptSource(integrationEnvSlug));
|
|
2803
|
+
await writeNewScaffoldFile(docsPath, buildIntegrationEnvReadmeSource({
|
|
2804
|
+
integrationEnvSlug,
|
|
2805
|
+
service: serviceId,
|
|
2806
|
+
withReleaseZip,
|
|
2807
|
+
withWpEnv
|
|
2808
|
+
}));
|
|
2809
|
+
await appendMissingLines(envExamplePath, [
|
|
2810
|
+
...buildEnvExampleSource(serviceId).trimEnd().split(`
|
|
2811
|
+
`)
|
|
2812
|
+
]);
|
|
2813
|
+
await appendMissingLines(gitignorePath, [".env", ".env.local"]);
|
|
2814
|
+
if (withWpEnv) {
|
|
2815
|
+
await writeFileIfAbsent({
|
|
2816
|
+
filePath: wpEnvPath,
|
|
2817
|
+
source: buildWpEnvConfigSource(),
|
|
2818
|
+
warnings
|
|
2819
|
+
});
|
|
2820
|
+
}
|
|
2821
|
+
if (serviceId === "docker-compose") {
|
|
2822
|
+
await writeFileIfAbsent({
|
|
2823
|
+
filePath: dockerComposePath,
|
|
2824
|
+
source: buildDockerComposeSource(),
|
|
2825
|
+
warnings
|
|
2826
|
+
});
|
|
2827
|
+
}
|
|
2828
|
+
await mutateIntegrationEnvPackageJson(workspace.projectDir, (packageJson) => addIntegrationEnvPackageJsonEntries({
|
|
2829
|
+
integrationEnvSlug,
|
|
2830
|
+
packageManager: workspace.packageManager,
|
|
2831
|
+
packageJson,
|
|
2832
|
+
service: serviceId,
|
|
2833
|
+
withReleaseZip,
|
|
2834
|
+
warnings,
|
|
2835
|
+
withWpEnv
|
|
2836
|
+
}));
|
|
2837
|
+
}
|
|
2838
|
+
});
|
|
2839
|
+
return {
|
|
2840
|
+
integrationEnvSlug,
|
|
2841
|
+
projectDir: workspace.projectDir,
|
|
2842
|
+
service: serviceId,
|
|
2843
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
2844
|
+
withReleaseZip,
|
|
2845
|
+
withWpEnv
|
|
2846
|
+
};
|
|
2847
|
+
}
|
|
2848
|
+
|
|
2291
2849
|
// ../wp-typia-project-tools/src/runtime/cli-validation.ts
|
|
2292
2850
|
import fs3 from "fs";
|
|
2293
|
-
import
|
|
2851
|
+
import path8 from "path";
|
|
2294
2852
|
function normalizeOptionalCliString(value) {
|
|
2295
2853
|
if (typeof value !== "string") {
|
|
2296
2854
|
return;
|
|
@@ -2299,14 +2857,14 @@ function normalizeOptionalCliString(value) {
|
|
|
2299
2857
|
return trimmed.length > 0 ? trimmed : undefined;
|
|
2300
2858
|
}
|
|
2301
2859
|
function looksLikeLocalCliPath(value) {
|
|
2302
|
-
return
|
|
2860
|
+
return path8.isAbsolute(value) || value.startsWith("./") || value.startsWith("../") || value.startsWith(".\\") || value.startsWith("..\\");
|
|
2303
2861
|
}
|
|
2304
2862
|
function resolveLocalCliPathOption(options) {
|
|
2305
2863
|
const normalizedValue = normalizeOptionalCliString(options.value);
|
|
2306
2864
|
if (!normalizedValue || !looksLikeLocalCliPath(normalizedValue)) {
|
|
2307
2865
|
return normalizedValue;
|
|
2308
2866
|
}
|
|
2309
|
-
const resolvedPath =
|
|
2867
|
+
const resolvedPath = path8.resolve(options.cwd, normalizedValue);
|
|
2310
2868
|
if (!fs3.existsSync(resolvedPath)) {
|
|
2311
2869
|
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, `\`${options.label}\` path does not exist: ${resolvedPath}. Check the path relative to ${options.cwd}.`);
|
|
2312
2870
|
}
|
|
@@ -2557,35 +3115,37 @@ async function collectScaffoldAnswers({
|
|
|
2557
3115
|
}
|
|
2558
3116
|
|
|
2559
3117
|
// ../wp-typia-project-tools/src/runtime/scaffold.ts
|
|
2560
|
-
import { promises as
|
|
2561
|
-
import
|
|
3118
|
+
import { promises as fsp14 } from "fs";
|
|
3119
|
+
import path20 from "path";
|
|
2562
3120
|
|
|
2563
3121
|
// ../wp-typia-project-tools/src/runtime/scaffold-apply-utils.ts
|
|
2564
|
-
import { promises as
|
|
2565
|
-
import
|
|
3122
|
+
import { promises as fsp8 } from "fs";
|
|
3123
|
+
import path12 from "path";
|
|
2566
3124
|
import { execSync as execSync3 } from "child_process";
|
|
2567
3125
|
import { fileURLToPath } from "url";
|
|
2568
3126
|
|
|
2569
3127
|
// ../wp-typia-project-tools/src/runtime/migration-ui-capability.ts
|
|
2570
|
-
import { promises as
|
|
2571
|
-
import
|
|
3128
|
+
import { promises as fsp6 } from "fs";
|
|
3129
|
+
import path9 from "path";
|
|
2572
3130
|
var INITIAL_MIGRATION_VERSION = "v1";
|
|
2573
3131
|
var BLOCK_METADATA_IMPORT_LINE = "import metadata from './block-metadata';";
|
|
2574
3132
|
var LEGACY_BLOCK_JSON_IMPORT_LINE = "import metadata from './block.json';";
|
|
2575
3133
|
async function mutatePackageJson2(projectDir, mutate) {
|
|
2576
|
-
const packageJsonPath =
|
|
2577
|
-
const packageJson =
|
|
3134
|
+
const packageJsonPath = path9.join(projectDir, "package.json");
|
|
3135
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
3136
|
+
context: "migration UI package manifest"
|
|
3137
|
+
});
|
|
2578
3138
|
mutate(packageJson);
|
|
2579
|
-
await
|
|
3139
|
+
await fsp6.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
2580
3140
|
`, "utf8");
|
|
2581
3141
|
}
|
|
2582
3142
|
async function patchFile(filePath, transform) {
|
|
2583
|
-
const source = await
|
|
3143
|
+
const source = await fsp6.readFile(filePath, "utf8");
|
|
2584
3144
|
const nextSource = transform(source);
|
|
2585
3145
|
if (nextSource === source) {
|
|
2586
3146
|
throw new Error(`Unable to apply migration UI patch for ${filePath}`);
|
|
2587
3147
|
}
|
|
2588
|
-
await
|
|
3148
|
+
await fsp6.writeFile(filePath, nextSource, "utf8");
|
|
2589
3149
|
}
|
|
2590
3150
|
function injectAfter(source, needle, insertion) {
|
|
2591
3151
|
if (source.includes(insertion)) {
|
|
@@ -2647,8 +3207,8 @@ function buildMigrationBlocks(templateId, variables) {
|
|
|
2647
3207
|
];
|
|
2648
3208
|
}
|
|
2649
3209
|
async function applySingleBlockPatches(projectDir, variables) {
|
|
2650
|
-
const editPath =
|
|
2651
|
-
const indexPath =
|
|
3210
|
+
const editPath = path9.join(projectDir, "src", "edit.tsx");
|
|
3211
|
+
const indexPath = path9.join(projectDir, "src", "index.tsx");
|
|
2652
3212
|
const deprecatedImport = `import { deprecated } from './migrations/generated/${variables.slugKebabCase}/deprecated';`;
|
|
2653
3213
|
const deprecatedLine = " deprecated,";
|
|
2654
3214
|
const dashboardImport = `import { MigrationDashboard } from './admin/migration-dashboard';`;
|
|
@@ -2669,10 +3229,10 @@ async function applySingleBlockPatches(projectDir, variables) {
|
|
|
2669
3229
|
});
|
|
2670
3230
|
}
|
|
2671
3231
|
async function applyCompoundPatches(projectDir, variables) {
|
|
2672
|
-
const parentEditPath =
|
|
2673
|
-
const parentIndexPath =
|
|
2674
|
-
const childIndexPath =
|
|
2675
|
-
const addChildScriptPath =
|
|
3232
|
+
const parentEditPath = path9.join(projectDir, "src", "blocks", variables.slugKebabCase, "edit.tsx");
|
|
3233
|
+
const parentIndexPath = path9.join(projectDir, "src", "blocks", variables.slugKebabCase, "index.tsx");
|
|
3234
|
+
const childIndexPath = path9.join(projectDir, "src", "blocks", `${variables.slugKebabCase}-item`, "index.tsx");
|
|
3235
|
+
const addChildScriptPath = path9.join(projectDir, "scripts", "add-compound-child.ts");
|
|
2676
3236
|
await patchFile(parentIndexPath, (source) => {
|
|
2677
3237
|
let nextSource = injectAfterBlockMetadataImport(source, `import { deprecated } from '../../migrations/generated/${variables.slugKebabCase}/deprecated';`);
|
|
2678
3238
|
nextSource = injectBefore(nextSource, "\tedit: Edit,", "\tdeprecated,");
|
|
@@ -2742,7 +3302,7 @@ async function applyMigrationUiCapability({
|
|
|
2742
3302
|
templateId,
|
|
2743
3303
|
variables
|
|
2744
3304
|
}) {
|
|
2745
|
-
const commonTemplateDir =
|
|
3305
|
+
const commonTemplateDir = path9.join(SHARED_MIGRATION_UI_TEMPLATE_ROOT, "common");
|
|
2746
3306
|
await copyInterpolatedDirectory(commonTemplateDir, projectDir, variables);
|
|
2747
3307
|
await mutatePackageJson2(projectDir, (packageJson) => {
|
|
2748
3308
|
const wpTypiaPackageVersion = getPackageVersions().wpTypiaPackageVersion;
|
|
@@ -2996,9 +3556,9 @@ function mergeTextLines(primaryContent, existingContent) {
|
|
|
2996
3556
|
}
|
|
2997
3557
|
|
|
2998
3558
|
// ../wp-typia-project-tools/src/runtime/scaffold-package-manager-files.ts
|
|
2999
|
-
import { promises as
|
|
3559
|
+
import { promises as fsp7 } from "fs";
|
|
3000
3560
|
import { execSync as execSync2 } from "child_process";
|
|
3001
|
-
import
|
|
3561
|
+
import path10 from "path";
|
|
3002
3562
|
var LOCKFILES = {
|
|
3003
3563
|
bun: ["bun.lock", "bun.lockb"],
|
|
3004
3564
|
npm: ["package-lock.json"],
|
|
@@ -3006,22 +3566,25 @@ var LOCKFILES = {
|
|
|
3006
3566
|
yarn: ["yarn.lock"]
|
|
3007
3567
|
};
|
|
3008
3568
|
async function normalizePackageManagerFiles(targetDir, packageManagerId) {
|
|
3009
|
-
const yarnRcPath =
|
|
3569
|
+
const yarnRcPath = path10.join(targetDir, ".yarnrc.yml");
|
|
3010
3570
|
if (packageManagerId === "yarn") {
|
|
3011
|
-
await
|
|
3571
|
+
await fsp7.writeFile(yarnRcPath, `nodeLinker: node-modules
|
|
3012
3572
|
`, "utf8");
|
|
3013
3573
|
return;
|
|
3014
3574
|
}
|
|
3015
|
-
await
|
|
3575
|
+
await fsp7.rm(yarnRcPath, { force: true });
|
|
3016
3576
|
}
|
|
3017
3577
|
async function normalizePackageJson(targetDir, packageManagerId) {
|
|
3018
|
-
const packageJsonPath =
|
|
3578
|
+
const packageJsonPath = path10.join(targetDir, "package.json");
|
|
3019
3579
|
const packageJsonSource = await readOptionalUtf8File(packageJsonPath);
|
|
3020
3580
|
if (packageJsonSource === null) {
|
|
3021
3581
|
return;
|
|
3022
3582
|
}
|
|
3023
3583
|
const packageManager = getPackageManager(packageManagerId);
|
|
3024
|
-
const packageJson =
|
|
3584
|
+
const packageJson = safeJsonParse(packageJsonSource, {
|
|
3585
|
+
context: "generated package manifest",
|
|
3586
|
+
filePath: packageJsonPath
|
|
3587
|
+
});
|
|
3025
3588
|
if (packageManagerId === "npm") {
|
|
3026
3589
|
delete packageJson.packageManager;
|
|
3027
3590
|
} else {
|
|
@@ -3034,7 +3597,7 @@ async function normalizePackageJson(targetDir, packageManagerId) {
|
|
|
3034
3597
|
}
|
|
3035
3598
|
}
|
|
3036
3599
|
}
|
|
3037
|
-
await
|
|
3600
|
+
await fsp7.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}
|
|
3038
3601
|
`, "utf8");
|
|
3039
3602
|
}
|
|
3040
3603
|
async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
|
|
@@ -3044,7 +3607,7 @@ async function removeUnexpectedLockfiles(targetDir, packageManagerId) {
|
|
|
3044
3607
|
if (keep.has(filename)) {
|
|
3045
3608
|
return;
|
|
3046
3609
|
}
|
|
3047
|
-
await
|
|
3610
|
+
await fsp7.rm(path10.join(targetDir, filename), { force: true });
|
|
3048
3611
|
}));
|
|
3049
3612
|
}
|
|
3050
3613
|
async function defaultInstallDependencies({
|
|
@@ -3057,14 +3620,15 @@ async function defaultInstallDependencies({
|
|
|
3057
3620
|
});
|
|
3058
3621
|
}
|
|
3059
3622
|
// ../wp-typia-project-tools/src/runtime/scaffold-repository-reference.ts
|
|
3060
|
-
import fs4 from "fs";
|
|
3061
3623
|
import { createRequire } from "module";
|
|
3062
|
-
import
|
|
3624
|
+
import path11 from "path";
|
|
3063
3625
|
var require2 = createRequire(import.meta.url);
|
|
3064
3626
|
var DEFAULT_SCAFFOLD_REPOSITORY_REFERENCE = "imjlk/wp-typia";
|
|
3065
3627
|
function readRepositoryPackageManifest(packageJsonPath) {
|
|
3066
3628
|
try {
|
|
3067
|
-
return
|
|
3629
|
+
return readJsonFileSync(packageJsonPath, {
|
|
3630
|
+
context: "repository package manifest"
|
|
3631
|
+
});
|
|
3068
3632
|
} catch (error) {
|
|
3069
3633
|
if (getOptionalNodeErrorCode(error) === "ENOENT") {
|
|
3070
3634
|
return null;
|
|
@@ -3122,9 +3686,9 @@ function parseRepositoryReference(value) {
|
|
|
3122
3686
|
}
|
|
3123
3687
|
function getDefaultRepositoryManifestPaths() {
|
|
3124
3688
|
const candidatePaths = [
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3689
|
+
path11.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "package.json"),
|
|
3690
|
+
path11.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "wp-typia", "package.json"),
|
|
3691
|
+
path11.join(PROJECT_TOOLS_PACKAGE_ROOT, "package.json"),
|
|
3128
3692
|
resolveInstalledPackageManifestPath("wp-typia"),
|
|
3129
3693
|
resolveInstalledPackageManifestPath("@wp-typia/project-tools")
|
|
3130
3694
|
].filter((candidatePath) => Boolean(candidatePath));
|
|
@@ -3151,7 +3715,7 @@ async function reportScaffoldProgress(onProgress, event) {
|
|
|
3151
3715
|
await onProgress?.(event);
|
|
3152
3716
|
}
|
|
3153
3717
|
var EPHEMERAL_NODE_MODULES_LINK_TYPE2 = process.platform === "win32" ? "junction" : "dir";
|
|
3154
|
-
var __dirname2 =
|
|
3718
|
+
var __dirname2 = path12.dirname(fileURLToPath(import.meta.url));
|
|
3155
3719
|
var LOCKFILES2 = {
|
|
3156
3720
|
bun: ["bun.lock", "bun.lockb"],
|
|
3157
3721
|
npm: ["package-lock.json"],
|
|
@@ -3159,11 +3723,11 @@ var LOCKFILES2 = {
|
|
|
3159
3723
|
yarn: ["yarn.lock"]
|
|
3160
3724
|
};
|
|
3161
3725
|
async function ensureDirectory(targetDir, allowExisting = false) {
|
|
3162
|
-
await
|
|
3726
|
+
await fsp8.mkdir(targetDir, { recursive: true });
|
|
3163
3727
|
if (allowExisting) {
|
|
3164
3728
|
return;
|
|
3165
3729
|
}
|
|
3166
|
-
const entries = await
|
|
3730
|
+
const entries = await fsp8.readdir(targetDir);
|
|
3167
3731
|
if (entries.length > 0) {
|
|
3168
3732
|
throw new Error(formatNonEmptyTargetDirectoryError(targetDir));
|
|
3169
3733
|
}
|
|
@@ -3174,42 +3738,42 @@ async function writeStarterManifestFiles2(targetDir, templateId, variables, arti
|
|
|
3174
3738
|
relativePath: `${artifact.relativeDir}/typia.manifest.json`
|
|
3175
3739
|
})) : getStarterManifestFiles(templateId, variables);
|
|
3176
3740
|
for (const { document, relativePath } of manifests) {
|
|
3177
|
-
const destinationPath =
|
|
3178
|
-
await
|
|
3179
|
-
await
|
|
3741
|
+
const destinationPath = path12.join(targetDir, relativePath);
|
|
3742
|
+
await fsp8.mkdir(path12.dirname(destinationPath), { recursive: true });
|
|
3743
|
+
await fsp8.writeFile(destinationPath, stringifyStarterManifest(document), "utf8");
|
|
3180
3744
|
}
|
|
3181
3745
|
}
|
|
3182
3746
|
async function writeBuiltInStructuralArtifacts(targetDir, artifacts) {
|
|
3183
3747
|
for (const artifact of artifacts) {
|
|
3184
|
-
const destinationDir =
|
|
3185
|
-
await
|
|
3186
|
-
await
|
|
3187
|
-
await
|
|
3748
|
+
const destinationDir = path12.join(targetDir, artifact.relativeDir);
|
|
3749
|
+
await fsp8.mkdir(destinationDir, { recursive: true });
|
|
3750
|
+
await fsp8.writeFile(path12.join(destinationDir, "types.ts"), artifact.typesSource, "utf8");
|
|
3751
|
+
await fsp8.writeFile(path12.join(destinationDir, "block.json"), stringifyBuiltInBlockJsonDocument(artifact.blockJsonDocument), "utf8");
|
|
3188
3752
|
}
|
|
3189
3753
|
}
|
|
3190
3754
|
async function writeBuiltInCodeArtifacts(targetDir, codeArtifacts) {
|
|
3191
3755
|
for (const artifact of codeArtifacts) {
|
|
3192
|
-
const destinationPath =
|
|
3193
|
-
await
|
|
3194
|
-
await
|
|
3756
|
+
const destinationPath = path12.join(targetDir, artifact.relativePath);
|
|
3757
|
+
await fsp8.mkdir(path12.dirname(destinationPath), { recursive: true });
|
|
3758
|
+
await fsp8.writeFile(destinationPath, artifact.source, "utf8");
|
|
3195
3759
|
}
|
|
3196
3760
|
}
|
|
3197
3761
|
async function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
3198
|
-
const projectToolsPackageRoot =
|
|
3762
|
+
const projectToolsPackageRoot = path12.resolve(__dirname2, "..", "..");
|
|
3199
3763
|
const candidates = [
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3764
|
+
path12.join(projectToolsPackageRoot, "node_modules"),
|
|
3765
|
+
path12.resolve(projectToolsPackageRoot, "..", ".."),
|
|
3766
|
+
path12.resolve(projectToolsPackageRoot, "..", "..", "node_modules")
|
|
3203
3767
|
];
|
|
3204
3768
|
for (const candidate of candidates) {
|
|
3205
|
-
if (await pathExists(
|
|
3769
|
+
if (await pathExists(path12.join(candidate, "typia", "package.json"))) {
|
|
3206
3770
|
return candidate;
|
|
3207
3771
|
}
|
|
3208
3772
|
}
|
|
3209
3773
|
return null;
|
|
3210
3774
|
}
|
|
3211
3775
|
async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
|
|
3212
|
-
const targetNodeModulesPath =
|
|
3776
|
+
const targetNodeModulesPath = path12.join(targetDir, "node_modules");
|
|
3213
3777
|
if (await pathExists(targetNodeModulesPath)) {
|
|
3214
3778
|
await callback();
|
|
3215
3779
|
return;
|
|
@@ -3218,11 +3782,11 @@ async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
|
|
|
3218
3782
|
if (!sourceNodeModulesPath) {
|
|
3219
3783
|
throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
|
|
3220
3784
|
}
|
|
3221
|
-
await
|
|
3785
|
+
await fsp8.symlink(sourceNodeModulesPath, targetNodeModulesPath, EPHEMERAL_NODE_MODULES_LINK_TYPE2);
|
|
3222
3786
|
try {
|
|
3223
3787
|
await callback();
|
|
3224
3788
|
} finally {
|
|
3225
|
-
await
|
|
3789
|
+
await fsp8.rm(targetNodeModulesPath, { force: true, recursive: true });
|
|
3226
3790
|
}
|
|
3227
3791
|
}
|
|
3228
3792
|
async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables) {
|
|
@@ -3233,7 +3797,7 @@ async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables
|
|
|
3233
3797
|
await withEphemeralScaffoldNodeModules2(targetDir, async () => {
|
|
3234
3798
|
if (templateId === "persistence") {
|
|
3235
3799
|
await syncPersistenceRestArtifacts({
|
|
3236
|
-
apiTypesFile:
|
|
3800
|
+
apiTypesFile: path12.join("src", "api-types.ts"),
|
|
3237
3801
|
outputDir: "src",
|
|
3238
3802
|
projectDir: targetDir,
|
|
3239
3803
|
variables
|
|
@@ -3241,27 +3805,27 @@ async function seedBuiltInPersistenceArtifacts2(targetDir, templateId, variables
|
|
|
3241
3805
|
return;
|
|
3242
3806
|
}
|
|
3243
3807
|
await syncPersistenceRestArtifacts({
|
|
3244
|
-
apiTypesFile:
|
|
3245
|
-
outputDir:
|
|
3808
|
+
apiTypesFile: path12.join("src", "blocks", variables.slugKebabCase, "api-types.ts"),
|
|
3809
|
+
outputDir: path12.join("src", "blocks", variables.slugKebabCase),
|
|
3246
3810
|
projectDir: targetDir,
|
|
3247
3811
|
variables
|
|
3248
3812
|
});
|
|
3249
3813
|
});
|
|
3250
3814
|
}
|
|
3251
3815
|
async function normalizePackageManagerFiles2(targetDir, packageManagerId) {
|
|
3252
|
-
const yarnRcPath =
|
|
3816
|
+
const yarnRcPath = path12.join(targetDir, ".yarnrc.yml");
|
|
3253
3817
|
if (packageManagerId === "yarn") {
|
|
3254
|
-
await
|
|
3818
|
+
await fsp8.writeFile(yarnRcPath, `nodeLinker: node-modules
|
|
3255
3819
|
`, "utf8");
|
|
3256
3820
|
return;
|
|
3257
3821
|
}
|
|
3258
|
-
await
|
|
3822
|
+
await fsp8.rm(yarnRcPath, { force: true });
|
|
3259
3823
|
}
|
|
3260
3824
|
async function removeQueryLoopPlaceholderFiles(projectDir, templateId) {
|
|
3261
3825
|
if (templateId !== "query-loop") {
|
|
3262
3826
|
return;
|
|
3263
3827
|
}
|
|
3264
|
-
await
|
|
3828
|
+
await fsp8.rm(path12.join(projectDir, "src", "validator-toolkit.ts"), {
|
|
3265
3829
|
force: true
|
|
3266
3830
|
});
|
|
3267
3831
|
}
|
|
@@ -3272,7 +3836,7 @@ async function removeUnexpectedLockfiles2(targetDir, packageManagerId) {
|
|
|
3272
3836
|
if (keep.has(filename)) {
|
|
3273
3837
|
return;
|
|
3274
3838
|
}
|
|
3275
|
-
await
|
|
3839
|
+
await fsp8.rm(path12.join(targetDir, filename), { force: true });
|
|
3276
3840
|
}));
|
|
3277
3841
|
}
|
|
3278
3842
|
async function replaceTextRecursively(targetDir, packageManagerId, {
|
|
@@ -3295,21 +3859,21 @@ async function replaceTextRecursively(targetDir, packageManagerId, {
|
|
|
3295
3859
|
manifestPaths: repositoryManifestPaths
|
|
3296
3860
|
});
|
|
3297
3861
|
async function visit(currentPath) {
|
|
3298
|
-
const stats = await
|
|
3862
|
+
const stats = await fsp8.stat(currentPath);
|
|
3299
3863
|
if (stats.isDirectory()) {
|
|
3300
|
-
const entries = await
|
|
3864
|
+
const entries = await fsp8.readdir(currentPath);
|
|
3301
3865
|
for (const entry of entries) {
|
|
3302
|
-
await visit(
|
|
3866
|
+
await visit(path12.join(currentPath, entry));
|
|
3303
3867
|
}
|
|
3304
3868
|
return;
|
|
3305
3869
|
}
|
|
3306
|
-
if (
|
|
3870
|
+
if (path12.basename(currentPath) === "package.json" || !textExtensions.has(path12.extname(currentPath))) {
|
|
3307
3871
|
return;
|
|
3308
3872
|
}
|
|
3309
|
-
const content = await
|
|
3873
|
+
const content = await fsp8.readFile(currentPath, "utf8");
|
|
3310
3874
|
const nextContent = replaceRepositoryReferencePlaceholders(transformPackageManagerText(content, packageManagerId), resolvedRepositoryReference);
|
|
3311
3875
|
if (nextContent !== content) {
|
|
3312
|
-
await
|
|
3876
|
+
await fsp8.writeFile(currentPath, nextContent, "utf8");
|
|
3313
3877
|
}
|
|
3314
3878
|
}
|
|
3315
3879
|
await visit(targetDir);
|
|
@@ -3381,17 +3945,17 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
3381
3945
|
phase: "finalize-project",
|
|
3382
3946
|
title: "Finalizing scaffold output"
|
|
3383
3947
|
});
|
|
3384
|
-
const readmePath =
|
|
3948
|
+
const readmePath = path12.join(projectDir, "README.md");
|
|
3385
3949
|
if (!await pathExists(readmePath)) {
|
|
3386
|
-
await
|
|
3950
|
+
await fsp8.writeFile(readmePath, readmeContent ?? buildReadme(templateId, variables, packageManager, {
|
|
3387
3951
|
withMigrationUi,
|
|
3388
3952
|
withTestPreset,
|
|
3389
3953
|
withWpEnv
|
|
3390
3954
|
}), "utf8");
|
|
3391
3955
|
}
|
|
3392
|
-
const gitignorePath =
|
|
3956
|
+
const gitignorePath = path12.join(projectDir, ".gitignore");
|
|
3393
3957
|
const existingGitignore = await readOptionalUtf8File(gitignorePath) ?? "";
|
|
3394
|
-
await
|
|
3958
|
+
await fsp8.writeFile(gitignorePath, mergeTextLines(gitignoreContent ?? buildGitignore(), existingGitignore), "utf8");
|
|
3395
3959
|
await normalizePackageJson(projectDir, packageManager);
|
|
3396
3960
|
await applyGeneratedProjectDxPackageJson({
|
|
3397
3961
|
compoundPersistenceEnabled: isCompoundPersistenceEnabled(variables),
|
|
@@ -3422,31 +3986,31 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
3422
3986
|
}
|
|
3423
3987
|
|
|
3424
3988
|
// ../wp-typia-project-tools/src/runtime/template-source-normalization.ts
|
|
3425
|
-
import
|
|
3989
|
+
import path16 from "path";
|
|
3426
3990
|
|
|
3427
3991
|
// ../wp-typia-project-tools/src/runtime/template-layers.ts
|
|
3428
|
-
import
|
|
3429
|
-
import { promises as
|
|
3992
|
+
import path13 from "path";
|
|
3993
|
+
import { promises as fsp9 } from "fs";
|
|
3430
3994
|
var TEMPLATE_LAYER_MANIFEST_FILENAME = "wp-typia.layers.json";
|
|
3431
3995
|
var TEMPLATE_LAYER_MANIFEST_VERSION = 1;
|
|
3432
3996
|
function resolveLayerPath(sourceRoot, relativePath) {
|
|
3433
|
-
const targetPath =
|
|
3434
|
-
const relativeTarget =
|
|
3435
|
-
if (relativeTarget.startsWith("..") ||
|
|
3997
|
+
const targetPath = path13.resolve(sourceRoot, relativePath);
|
|
3998
|
+
const relativeTarget = path13.relative(sourceRoot, targetPath);
|
|
3999
|
+
if (relativeTarget.startsWith("..") || path13.isAbsolute(relativeTarget)) {
|
|
3436
4000
|
throw new Error(`Template layer path "${relativePath}" must stay within ${sourceRoot}.`);
|
|
3437
4001
|
}
|
|
3438
4002
|
return targetPath;
|
|
3439
4003
|
}
|
|
3440
4004
|
async function assertNoSymlinks(sourceDir) {
|
|
3441
|
-
const stats = await
|
|
4005
|
+
const stats = await fsp9.lstat(sourceDir);
|
|
3442
4006
|
if (stats.isSymbolicLink()) {
|
|
3443
4007
|
throw new Error(`Template layer packages may not include symbolic links: ${sourceDir}`);
|
|
3444
4008
|
}
|
|
3445
4009
|
if (!stats.isDirectory()) {
|
|
3446
4010
|
return;
|
|
3447
4011
|
}
|
|
3448
|
-
for (const entry of await
|
|
3449
|
-
await assertNoSymlinks(
|
|
4012
|
+
for (const entry of await fsp9.readdir(sourceDir)) {
|
|
4013
|
+
await assertNoSymlinks(path13.join(sourceDir, entry));
|
|
3450
4014
|
}
|
|
3451
4015
|
}
|
|
3452
4016
|
function parseLayerDefinition(layerId, value) {
|
|
@@ -3475,11 +4039,13 @@ function parseLayerDefinition(layerId, value) {
|
|
|
3475
4039
|
};
|
|
3476
4040
|
}
|
|
3477
4041
|
async function loadExternalTemplateLayerManifest(sourceRoot) {
|
|
3478
|
-
const manifestPath =
|
|
4042
|
+
const manifestPath = path13.join(sourceRoot, TEMPLATE_LAYER_MANIFEST_FILENAME);
|
|
3479
4043
|
if (!await pathExists(manifestPath)) {
|
|
3480
4044
|
return null;
|
|
3481
4045
|
}
|
|
3482
|
-
const raw =
|
|
4046
|
+
const raw = await readJsonFile(manifestPath, {
|
|
4047
|
+
context: "template layer manifest"
|
|
4048
|
+
});
|
|
3483
4049
|
if (!isPlainObject(raw)) {
|
|
3484
4050
|
throw new Error(`${TEMPLATE_LAYER_MANIFEST_FILENAME} must export a JSON object.`);
|
|
3485
4051
|
}
|
|
@@ -3573,7 +4139,7 @@ async function resolveExternalTemplateLayers({
|
|
|
3573
4139
|
return;
|
|
3574
4140
|
}
|
|
3575
4141
|
const layerDir = resolveLayerPath(sourceRoot, definition.path);
|
|
3576
|
-
const stats = await
|
|
4142
|
+
const stats = await fsp9.stat(layerDir).catch(() => null);
|
|
3577
4143
|
if (!stats || !stats.isDirectory()) {
|
|
3578
4144
|
throw new Error(`Layer "${layerId}" points to a missing directory: ${definition.path}`);
|
|
3579
4145
|
}
|
|
@@ -3611,12 +4177,12 @@ async function assertExternalTemplateLayersDoNotWriteProtectedOutputs({
|
|
|
3611
4177
|
}
|
|
3612
4178
|
|
|
3613
4179
|
// ../wp-typia-project-tools/src/runtime/template-source-external.ts
|
|
3614
|
-
import { promises as
|
|
3615
|
-
import
|
|
4180
|
+
import { promises as fsp10 } from "fs";
|
|
4181
|
+
import path14 from "path";
|
|
3616
4182
|
import { pathToFileURL } from "url";
|
|
3617
4183
|
|
|
3618
4184
|
// ../wp-typia-project-tools/src/runtime/external-template-guards.ts
|
|
3619
|
-
import
|
|
4185
|
+
import fs4 from "fs";
|
|
3620
4186
|
var TEMPLATE_SOURCE_TIMEOUT_CODE = "template-source-timeout";
|
|
3621
4187
|
var TEMPLATE_SOURCE_TOO_LARGE_CODE = "template-source-too-large";
|
|
3622
4188
|
var DEFAULT_EXTERNAL_TEMPLATE_TIMEOUT_MS = 20000;
|
|
@@ -3658,7 +4224,7 @@ function createExternalTemplateTooLargeError(label, maxBytes) {
|
|
|
3658
4224
|
return createTemplateGuardError(TEMPLATE_SOURCE_TOO_LARGE_CODE, `${label} exceeded the external template size limit (${maxBytes} bytes).`);
|
|
3659
4225
|
}
|
|
3660
4226
|
function assertExternalTemplateFileSize(filePath, options) {
|
|
3661
|
-
const stats =
|
|
4227
|
+
const stats = fs4.statSync(filePath);
|
|
3662
4228
|
if (stats.size > options.maxBytes) {
|
|
3663
4229
|
throw createExternalTemplateTooLargeError(options.label, options.maxBytes);
|
|
3664
4230
|
}
|
|
@@ -3734,11 +4300,9 @@ async function readResponseBodyWithLimit(response, options) {
|
|
|
3734
4300
|
}
|
|
3735
4301
|
async function readJsonResponseWithLimit(response, options) {
|
|
3736
4302
|
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
|
-
}
|
|
4303
|
+
return safeJsonParse(buffer.toString("utf8"), {
|
|
4304
|
+
context: options.label
|
|
4305
|
+
});
|
|
3742
4306
|
}
|
|
3743
4307
|
async function readBufferResponseWithLimit(response, options) {
|
|
3744
4308
|
return readResponseBodyWithLimit(response, options);
|
|
@@ -3756,16 +4320,16 @@ function getTemplateWarning(key) {
|
|
|
3756
4320
|
return `Ignoring external template config key "${key}": ${TEMPLATE_WARNING_MESSAGE}`;
|
|
3757
4321
|
}
|
|
3758
4322
|
function resolveSourceSubpath(sourceDir, relativePath) {
|
|
3759
|
-
const targetPath =
|
|
3760
|
-
const relativeTarget =
|
|
3761
|
-
if (relativeTarget.startsWith("..") ||
|
|
4323
|
+
const targetPath = path14.resolve(sourceDir, relativePath);
|
|
4324
|
+
const relativeTarget = path14.relative(sourceDir, targetPath);
|
|
4325
|
+
if (relativeTarget.startsWith("..") || path14.isAbsolute(relativeTarget)) {
|
|
3762
4326
|
throw new Error(`Template path "${relativePath}" must stay within ${sourceDir}.`);
|
|
3763
4327
|
}
|
|
3764
4328
|
return targetPath;
|
|
3765
4329
|
}
|
|
3766
4330
|
async function findExternalTemplateEntry(sourceDir) {
|
|
3767
4331
|
for (const filename of EXTERNAL_TEMPLATE_ENTRY_CANDIDATES) {
|
|
3768
|
-
const candidate =
|
|
4332
|
+
const candidate = path14.join(sourceDir, filename);
|
|
3769
4333
|
if (await pathExists(candidate)) {
|
|
3770
4334
|
return candidate;
|
|
3771
4335
|
}
|
|
@@ -3781,7 +4345,7 @@ async function loadExternalTemplateConfig(sourceDir) {
|
|
|
3781
4345
|
label: `External template config "${entryPath}"`,
|
|
3782
4346
|
maxBytes: getExternalTemplateConfigMaxBytes()
|
|
3783
4347
|
});
|
|
3784
|
-
const entryStats = await
|
|
4348
|
+
const entryStats = await fsp10.stat(entryPath);
|
|
3785
4349
|
const moduleUrl = `${pathToFileURL(entryPath).href}?mtime=${entryStats.mtimeMs}`;
|
|
3786
4350
|
const loadedModule = await withExternalTemplateTimeout(`loading external template config "${entryPath}"`, () => import(moduleUrl));
|
|
3787
4351
|
const loadedConfig = loadedModule.default ?? loadedModule;
|
|
@@ -3888,21 +4452,21 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
3888
4452
|
const { folderName, formatHint, templatePath } = resolveConfiguredTemplatePath(config, variantConfig);
|
|
3889
4453
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-create-block-external-");
|
|
3890
4454
|
try {
|
|
3891
|
-
const renderedRoot =
|
|
4455
|
+
const renderedRoot = path14.join(tempRoot, "rendered");
|
|
3892
4456
|
const blockDir = resolveSourceSubpath(renderedRoot, folderName);
|
|
3893
4457
|
const view = await buildExternalTemplateView(context, config, selectedVariant, variantConfig);
|
|
3894
4458
|
const blockTemplateDir = resolveSourceSubpath(sourceDir, templatePath);
|
|
3895
4459
|
await copyRenderedDirectory(blockTemplateDir, blockDir, view, {
|
|
3896
4460
|
filter: async (sourcePath, _destinationPath, entry) => {
|
|
3897
|
-
const mustacheVariantPath =
|
|
4461
|
+
const mustacheVariantPath = path14.join(path14.dirname(sourcePath), `${entry.name}.mustache`);
|
|
3898
4462
|
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && await pathExists(mustacheVariantPath));
|
|
3899
4463
|
}
|
|
3900
4464
|
});
|
|
3901
4465
|
const assetsPath = typeof variantConfig.assetsPath === "string" ? variantConfig.assetsPath : config.assetsPath;
|
|
3902
4466
|
if (typeof assetsPath === "string" && assetsPath.trim().length > 0) {
|
|
3903
|
-
await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath),
|
|
4467
|
+
await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath), path14.join(tempRoot, "assets"));
|
|
3904
4468
|
}
|
|
3905
|
-
const assetsDir =
|
|
4469
|
+
const assetsDir = path14.join(tempRoot, "assets");
|
|
3906
4470
|
return {
|
|
3907
4471
|
assetsDir: await pathExists(assetsDir) ? assetsDir : undefined,
|
|
3908
4472
|
blockDir,
|
|
@@ -3919,8 +4483,8 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
3919
4483
|
}
|
|
3920
4484
|
|
|
3921
4485
|
// ../wp-typia-project-tools/src/runtime/template-source-remote.ts
|
|
3922
|
-
import { promises as
|
|
3923
|
-
import
|
|
4486
|
+
import { promises as fsp11 } from "fs";
|
|
4487
|
+
import path15 from "path";
|
|
3924
4488
|
async function cleanupSeedRootPair(cleanup, seedCleanup) {
|
|
3925
4489
|
let cleanupError;
|
|
3926
4490
|
try {
|
|
@@ -3943,11 +4507,13 @@ function getDefaultCategoryFromBlockJson(blockJson) {
|
|
|
3943
4507
|
async function readRemoteBlockJsonAsync(blockDir) {
|
|
3944
4508
|
const sourceRoot = await getSeedSourceRoot(blockDir);
|
|
3945
4509
|
for (const candidate of [
|
|
3946
|
-
|
|
3947
|
-
|
|
4510
|
+
path15.join(blockDir, "block.json"),
|
|
4511
|
+
path15.join(sourceRoot, "block.json")
|
|
3948
4512
|
]) {
|
|
3949
4513
|
if (await pathExists(candidate)) {
|
|
3950
|
-
return
|
|
4514
|
+
return readJsonFile(candidate, {
|
|
4515
|
+
context: "remote block metadata"
|
|
4516
|
+
});
|
|
3951
4517
|
}
|
|
3952
4518
|
}
|
|
3953
4519
|
throw new Error(`Unable to locate block.json in ${blockDir}`);
|
|
@@ -3962,8 +4528,8 @@ async function getDefaultCategoryAsync(sourceDir) {
|
|
|
3962
4528
|
}
|
|
3963
4529
|
async function readTemplatePackageJsonAsync(sourceDir) {
|
|
3964
4530
|
for (const candidate of [
|
|
3965
|
-
|
|
3966
|
-
|
|
4531
|
+
path15.join(sourceDir, "package.json.mustache"),
|
|
4532
|
+
path15.join(sourceDir, "package.json")
|
|
3967
4533
|
]) {
|
|
3968
4534
|
if (!await pathExists(candidate)) {
|
|
3969
4535
|
continue;
|
|
@@ -3974,7 +4540,10 @@ async function readTemplatePackageJsonAsync(sourceDir) {
|
|
|
3974
4540
|
maxBytes: getExternalTemplatePackageJsonMaxBytes()
|
|
3975
4541
|
});
|
|
3976
4542
|
return {
|
|
3977
|
-
packageJson:
|
|
4543
|
+
packageJson: safeJsonParse(await fsp11.readFile(candidate, "utf8"), {
|
|
4544
|
+
context: "template metadata file",
|
|
4545
|
+
filePath: candidate
|
|
4546
|
+
}),
|
|
3978
4547
|
sourcePath: candidate
|
|
3979
4548
|
};
|
|
3980
4549
|
} catch (error) {
|
|
@@ -4000,16 +4569,16 @@ async function getTemplateProjectTypeAsync(sourceDir) {
|
|
|
4000
4569
|
}
|
|
4001
4570
|
async function normalizeWpTypiaTemplateSeed(seed) {
|
|
4002
4571
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
4003
|
-
const normalizedDir =
|
|
4572
|
+
const normalizedDir = path15.join(tempRoot, "template");
|
|
4004
4573
|
try {
|
|
4005
4574
|
await copyRawDirectory(seed.blockDir, normalizedDir, {
|
|
4006
4575
|
filter: async (sourcePath, _targetPath, entry) => {
|
|
4007
|
-
const mustacheVariantPath =
|
|
4576
|
+
const mustacheVariantPath = path15.join(path15.dirname(sourcePath), `${entry.name}.mustache`);
|
|
4008
4577
|
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && await pathExists(mustacheVariantPath));
|
|
4009
4578
|
}
|
|
4010
4579
|
});
|
|
4011
4580
|
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
4012
|
-
await
|
|
4581
|
+
await fsp11.cp(seed.assetsDir, path15.join(normalizedDir, "assets"), {
|
|
4013
4582
|
recursive: true,
|
|
4014
4583
|
force: true
|
|
4015
4584
|
});
|
|
@@ -4098,32 +4667,34 @@ function buildRemoteBlockJsonTemplate(blockJson) {
|
|
|
4098
4667
|
}
|
|
4099
4668
|
async function rewriteBlockJsonImports(directory) {
|
|
4100
4669
|
const textExtensions = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
4101
|
-
const targetBlockJsonPath =
|
|
4670
|
+
const targetBlockJsonPath = path15.join(directory, "block.json");
|
|
4102
4671
|
async function visit(currentPath) {
|
|
4103
|
-
const stats = await
|
|
4672
|
+
const stats = await fsp11.stat(currentPath);
|
|
4104
4673
|
if (stats.isDirectory()) {
|
|
4105
|
-
const entries = await
|
|
4674
|
+
const entries = await fsp11.readdir(currentPath);
|
|
4106
4675
|
for (const entry of entries) {
|
|
4107
|
-
await visit(
|
|
4676
|
+
await visit(path15.join(currentPath, entry));
|
|
4108
4677
|
}
|
|
4109
4678
|
return;
|
|
4110
4679
|
}
|
|
4111
|
-
if (!textExtensions.has(
|
|
4680
|
+
if (!textExtensions.has(path15.extname(currentPath))) {
|
|
4112
4681
|
return;
|
|
4113
4682
|
}
|
|
4114
|
-
const content = await
|
|
4115
|
-
const relativeSpecifier =
|
|
4683
|
+
const content = await fsp11.readFile(currentPath, "utf8");
|
|
4684
|
+
const relativeSpecifier = path15.relative(path15.dirname(currentPath), targetBlockJsonPath).replace(/\\/g, "/");
|
|
4116
4685
|
const normalizedSpecifier = relativeSpecifier.startsWith(".") ? relativeSpecifier : `./${relativeSpecifier}`;
|
|
4117
4686
|
const next = content.replace(/(['"])\.{1,2}\/[^'"]*block\.json\1/g, `$1${normalizedSpecifier}$1`);
|
|
4118
4687
|
if (next !== content) {
|
|
4119
|
-
await
|
|
4688
|
+
await fsp11.writeFile(currentPath, next, "utf8");
|
|
4120
4689
|
}
|
|
4121
4690
|
}
|
|
4122
4691
|
await visit(directory);
|
|
4123
4692
|
}
|
|
4124
4693
|
async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
4125
|
-
const packageJsonPath =
|
|
4126
|
-
const packageJson =
|
|
4694
|
+
const packageJsonPath = path15.join(templateDir, "package.json.mustache");
|
|
4695
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
4696
|
+
context: "remote package template manifest"
|
|
4697
|
+
});
|
|
4127
4698
|
const existingDependencies = { ...packageJson.dependencies ?? {} };
|
|
4128
4699
|
const existingDevDependencies = { ...packageJson.devDependencies ?? {} };
|
|
4129
4700
|
delete existingDependencies["@wp-typia/project-tools"];
|
|
@@ -4143,16 +4714,16 @@ async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
|
4143
4714
|
} else {
|
|
4144
4715
|
delete packageJson.dependencies;
|
|
4145
4716
|
}
|
|
4146
|
-
await
|
|
4717
|
+
await fsp11.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
4147
4718
|
`, "utf8");
|
|
4148
4719
|
}
|
|
4149
4720
|
async function getSeedSourceRoot(blockDir) {
|
|
4150
|
-
return await pathExists(
|
|
4721
|
+
return await pathExists(path15.join(blockDir, "src")) ? path15.join(blockDir, "src") : blockDir;
|
|
4151
4722
|
}
|
|
4152
4723
|
async function findSeedRenderPhp(seed) {
|
|
4153
4724
|
for (const candidate of [
|
|
4154
|
-
|
|
4155
|
-
|
|
4725
|
+
path15.join(seed.blockDir, "render.php"),
|
|
4726
|
+
path15.join(seed.rootDir, "render.php")
|
|
4156
4727
|
]) {
|
|
4157
4728
|
if (await pathExists(candidate)) {
|
|
4158
4729
|
return candidate;
|
|
@@ -4193,16 +4764,16 @@ async function removeSeedEntryConflicts(templateDir) {
|
|
|
4193
4764
|
"view.ts",
|
|
4194
4765
|
"view.tsx"
|
|
4195
4766
|
]) {
|
|
4196
|
-
await
|
|
4767
|
+
await fsp11.rm(path15.join(templateDir, "src", filename), { force: true });
|
|
4197
4768
|
}
|
|
4198
4769
|
}
|
|
4199
4770
|
async function normalizeCreateBlockSubset(seed, context) {
|
|
4200
4771
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-remote-template-");
|
|
4201
4772
|
try {
|
|
4202
|
-
const templateDir =
|
|
4773
|
+
const templateDir = path15.join(tempRoot, "template");
|
|
4203
4774
|
const blockJson = await readRemoteBlockJsonAsync(seed.blockDir);
|
|
4204
4775
|
const sourceRoot = await getSeedSourceRoot(seed.blockDir);
|
|
4205
|
-
await
|
|
4776
|
+
await fsp11.mkdir(templateDir, { recursive: true });
|
|
4206
4777
|
for (const layerDir of getBuiltInTemplateLayerDirs("basic")) {
|
|
4207
4778
|
if (!await pathExists(layerDir)) {
|
|
4208
4779
|
if (isOmittableBuiltInTemplateLayerDir("basic", layerDir)) {
|
|
@@ -4210,29 +4781,29 @@ async function normalizeCreateBlockSubset(seed, context) {
|
|
|
4210
4781
|
}
|
|
4211
4782
|
throw new Error(`Built-in template layer is missing: ${layerDir}`);
|
|
4212
4783
|
}
|
|
4213
|
-
await
|
|
4784
|
+
await fsp11.cp(layerDir, templateDir, {
|
|
4214
4785
|
recursive: true,
|
|
4215
4786
|
force: true
|
|
4216
4787
|
});
|
|
4217
4788
|
}
|
|
4218
4789
|
await removeSeedEntryConflicts(templateDir);
|
|
4219
|
-
await
|
|
4790
|
+
await fsp11.cp(sourceRoot, path15.join(templateDir, "src"), {
|
|
4220
4791
|
recursive: true,
|
|
4221
4792
|
force: true
|
|
4222
4793
|
});
|
|
4223
4794
|
const remoteRenderPath = await findSeedRenderPhp(seed);
|
|
4224
4795
|
if (remoteRenderPath) {
|
|
4225
|
-
await
|
|
4796
|
+
await fsp11.copyFile(remoteRenderPath, path15.join(templateDir, "render.php"));
|
|
4226
4797
|
}
|
|
4227
4798
|
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
4228
|
-
await
|
|
4799
|
+
await fsp11.cp(seed.assetsDir, path15.join(templateDir, "assets"), {
|
|
4229
4800
|
recursive: true,
|
|
4230
4801
|
force: true
|
|
4231
4802
|
});
|
|
4232
4803
|
}
|
|
4233
|
-
await
|
|
4234
|
-
await
|
|
4235
|
-
await rewriteBlockJsonImports(
|
|
4804
|
+
await fsp11.writeFile(path15.join(templateDir, "src", "types.ts"), buildRemoteTypesSource(blockJson, context), "utf8");
|
|
4805
|
+
await fsp11.writeFile(path15.join(templateDir, "src", "block.json"), buildRemoteBlockJsonTemplate(blockJson), "utf8");
|
|
4806
|
+
await rewriteBlockJsonImports(path15.join(templateDir, "src"));
|
|
4236
4807
|
const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" || (await Promise.all([
|
|
4237
4808
|
"view.js",
|
|
4238
4809
|
"view.jsx",
|
|
@@ -4240,7 +4811,7 @@ async function normalizeCreateBlockSubset(seed, context) {
|
|
|
4240
4811
|
"view.tsx",
|
|
4241
4812
|
"interactivity.js",
|
|
4242
4813
|
"interactivity.ts"
|
|
4243
|
-
].map((filename) => pathExists(
|
|
4814
|
+
].map((filename) => pathExists(path15.join(templateDir, "src", filename))))).some(Boolean);
|
|
4244
4815
|
await patchRemotePackageJson(templateDir, needsInteractivity);
|
|
4245
4816
|
return {
|
|
4246
4817
|
id: "remote:create-block-subset",
|
|
@@ -4270,7 +4841,8 @@ function getTemplateVariableContext(variables) {
|
|
|
4270
4841
|
blockRuntimePackageVersion,
|
|
4271
4842
|
blockTypesPackageVersion,
|
|
4272
4843
|
projectToolsPackageVersion,
|
|
4273
|
-
restPackageVersion
|
|
4844
|
+
restPackageVersion,
|
|
4845
|
+
wpTypiaPackageVersion
|
|
4274
4846
|
} = getPackageVersions();
|
|
4275
4847
|
return {
|
|
4276
4848
|
...variables,
|
|
@@ -4278,6 +4850,7 @@ function getTemplateVariableContext(variables) {
|
|
|
4278
4850
|
blockRuntimePackageVersion: variables.blockRuntimePackageVersion ?? blockRuntimePackageVersion,
|
|
4279
4851
|
blockTypesPackageVersion: variables.blockTypesPackageVersion ?? blockTypesPackageVersion,
|
|
4280
4852
|
projectToolsPackageVersion: variables.projectToolsPackageVersion ?? projectToolsPackageVersion,
|
|
4853
|
+
wpTypiaPackageVersion: variables.wpTypiaPackageVersion ?? wpTypiaPackageVersion,
|
|
4281
4854
|
description: variables.description,
|
|
4282
4855
|
keyword: variables.keyword,
|
|
4283
4856
|
namespace: variables.namespace,
|
|
@@ -4290,7 +4863,7 @@ function getTemplateVariableContext(variables) {
|
|
|
4290
4863
|
};
|
|
4291
4864
|
}
|
|
4292
4865
|
async function detectTemplateSourceFormat(sourceDir) {
|
|
4293
|
-
if (await pathExists(
|
|
4866
|
+
if (await pathExists(path16.join(sourceDir, "package.json.mustache"))) {
|
|
4294
4867
|
return "wp-typia";
|
|
4295
4868
|
}
|
|
4296
4869
|
if (await loadExternalTemplateLayerManifest(sourceDir)) {
|
|
@@ -4302,15 +4875,15 @@ async function detectTemplateSourceFormat(sourceDir) {
|
|
|
4302
4875
|
if (await getTemplateProjectTypeAsync(sourceDir) !== null) {
|
|
4303
4876
|
return "wp-typia";
|
|
4304
4877
|
}
|
|
4305
|
-
const sourceRoot = await pathExists(
|
|
4878
|
+
const sourceRoot = await pathExists(path16.join(sourceDir, "src")) ? path16.join(sourceDir, "src") : sourceDir;
|
|
4306
4879
|
const blockJsonCandidates = [
|
|
4307
|
-
|
|
4308
|
-
|
|
4880
|
+
path16.join(sourceDir, "block.json"),
|
|
4881
|
+
path16.join(sourceRoot, "block.json")
|
|
4309
4882
|
];
|
|
4310
4883
|
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(
|
|
4884
|
+
const hasIndexFile = (await Promise.all(["index.js", "index.jsx", "index.ts", "index.tsx"].map((filename) => pathExists(path16.join(sourceRoot, filename))))).some(Boolean);
|
|
4885
|
+
const hasEditFile = (await Promise.all(["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].map((filename) => pathExists(path16.join(sourceRoot, filename))))).some(Boolean);
|
|
4886
|
+
const hasSaveFile = (await Promise.all(["save.js", "save.jsx", "save.ts", "save.tsx"].map((filename) => pathExists(path16.join(sourceRoot, filename))))).some(Boolean);
|
|
4314
4887
|
if (hasBlockJson && hasIndexFile && hasEditFile && hasSaveFile) {
|
|
4315
4888
|
return "create-block-subset";
|
|
4316
4889
|
}
|
|
@@ -4319,10 +4892,10 @@ async function detectTemplateSourceFormat(sourceDir) {
|
|
|
4319
4892
|
|
|
4320
4893
|
// ../wp-typia-project-tools/src/runtime/template-source-seeds.ts
|
|
4321
4894
|
var import_semver = __toESM(require_semver(), 1);
|
|
4322
|
-
import
|
|
4323
|
-
import { promises as
|
|
4895
|
+
import fs6 from "fs";
|
|
4896
|
+
import { promises as fsp13 } from "fs";
|
|
4324
4897
|
import { createRequire as createRequire2 } from "module";
|
|
4325
|
-
import
|
|
4898
|
+
import path19 from "path";
|
|
4326
4899
|
import { spawnSync } from "child_process";
|
|
4327
4900
|
|
|
4328
4901
|
// ../../node_modules/.bun/tar@7.5.13/node_modules/tar/dist/esm/index.min.js
|
|
@@ -6595,7 +7168,7 @@ var Vn = 512 * 1024;
|
|
|
6595
7168
|
var $n = pr | ur | dr | mr;
|
|
6596
7169
|
var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
|
|
6597
7170
|
var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
|
|
6598
|
-
var
|
|
7171
|
+
var fs5 = (s3, t, e) => {
|
|
6599
7172
|
try {
|
|
6600
7173
|
return mi.lchownSync(s3, t, e);
|
|
6601
7174
|
} catch (i) {
|
|
@@ -6644,7 +7217,7 @@ var ds = (s3, t, e, i) => {
|
|
|
6644
7217
|
});
|
|
6645
7218
|
};
|
|
6646
7219
|
var qn = (s3, t, e, i) => {
|
|
6647
|
-
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i),
|
|
7220
|
+
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i), fs5(Ee.resolve(s3, t.name), e, i);
|
|
6648
7221
|
};
|
|
6649
7222
|
var us = (s3, t, e) => {
|
|
6650
7223
|
let i;
|
|
@@ -6655,12 +7228,12 @@ var us = (s3, t, e) => {
|
|
|
6655
7228
|
if (n?.code === "ENOENT")
|
|
6656
7229
|
return;
|
|
6657
7230
|
if (n?.code === "ENOTDIR" || n?.code === "ENOTSUP")
|
|
6658
|
-
return
|
|
7231
|
+
return fs5(s3, t, e);
|
|
6659
7232
|
throw n;
|
|
6660
7233
|
}
|
|
6661
7234
|
for (let r of i)
|
|
6662
7235
|
qn(s3, r, t, e);
|
|
6663
|
-
return
|
|
7236
|
+
return fs5(s3, t, e);
|
|
6664
7237
|
};
|
|
6665
7238
|
var we = class extends Error {
|
|
6666
7239
|
path;
|
|
@@ -7474,8 +8047,8 @@ var So = (s3) => {
|
|
|
7474
8047
|
|
|
7475
8048
|
// ../wp-typia-project-tools/src/runtime/template-source-cache.ts
|
|
7476
8049
|
import { createHash, randomUUID } from "crypto";
|
|
7477
|
-
import { promises as
|
|
7478
|
-
import
|
|
8050
|
+
import { promises as fsp12 } from "fs";
|
|
8051
|
+
import path18 from "path";
|
|
7479
8052
|
|
|
7480
8053
|
// ../wp-typia-project-tools/src/runtime/template-source-cache-markers.ts
|
|
7481
8054
|
var CACHE_MARKER_FILE = "wp-typia-template-cache.json";
|
|
@@ -7595,7 +8168,7 @@ function formatExternalTemplateCachePruneMarker({
|
|
|
7595
8168
|
|
|
7596
8169
|
// ../wp-typia-project-tools/src/runtime/template-source-cache-policy.ts
|
|
7597
8170
|
import os2 from "os";
|
|
7598
|
-
import
|
|
8171
|
+
import path17 from "path";
|
|
7599
8172
|
var EXTERNAL_TEMPLATE_CACHE_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE";
|
|
7600
8173
|
var EXTERNAL_TEMPLATE_CACHE_DIR_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_DIR";
|
|
7601
8174
|
var EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_TTL_DAYS";
|
|
@@ -7613,9 +8186,9 @@ function isExternalTemplateCacheEnabled(env = process.env) {
|
|
|
7613
8186
|
function getExternalTemplateCacheRoot(env = process.env) {
|
|
7614
8187
|
const configuredCacheDir = env[EXTERNAL_TEMPLATE_CACHE_DIR_ENV]?.trim();
|
|
7615
8188
|
if (configuredCacheDir) {
|
|
7616
|
-
return
|
|
8189
|
+
return path17.resolve(configuredCacheDir);
|
|
7617
8190
|
}
|
|
7618
|
-
return
|
|
8191
|
+
return path17.join(os2.tmpdir(), `wp-typia-template-source-cache-${getCurrentUserCacheSegment()}`);
|
|
7619
8192
|
}
|
|
7620
8193
|
function parseExternalTemplateCacheTtlDays(value) {
|
|
7621
8194
|
if (typeof value !== "string" && typeof value !== "number") {
|
|
@@ -7693,7 +8266,7 @@ function createExternalTemplateCacheKey(keyParts) {
|
|
|
7693
8266
|
}
|
|
7694
8267
|
async function isDirectoryPath(directory) {
|
|
7695
8268
|
try {
|
|
7696
|
-
const stats = await
|
|
8269
|
+
const stats = await fsp12.lstat(directory);
|
|
7697
8270
|
return stats.isDirectory() && !stats.isSymbolicLink();
|
|
7698
8271
|
} catch {
|
|
7699
8272
|
return false;
|
|
@@ -7701,7 +8274,7 @@ async function isDirectoryPath(directory) {
|
|
|
7701
8274
|
}
|
|
7702
8275
|
async function removeTemporaryCacheEntry(entryDir) {
|
|
7703
8276
|
try {
|
|
7704
|
-
await
|
|
8277
|
+
await fsp12.rm(entryDir, { force: true, recursive: true });
|
|
7705
8278
|
} catch {}
|
|
7706
8279
|
}
|
|
7707
8280
|
function getCurrentUid() {
|
|
@@ -7709,7 +8282,7 @@ function getCurrentUid() {
|
|
|
7709
8282
|
}
|
|
7710
8283
|
async function isPrivateCacheDirectory(directory) {
|
|
7711
8284
|
try {
|
|
7712
|
-
const stats = await
|
|
8285
|
+
const stats = await fsp12.lstat(directory);
|
|
7713
8286
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
7714
8287
|
return false;
|
|
7715
8288
|
}
|
|
@@ -7727,11 +8300,11 @@ async function isPrivateCacheDirectory(directory) {
|
|
|
7727
8300
|
}
|
|
7728
8301
|
async function ensurePrivateCacheDirectory(directory) {
|
|
7729
8302
|
try {
|
|
7730
|
-
await
|
|
8303
|
+
await fsp12.mkdir(directory, {
|
|
7731
8304
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
7732
8305
|
recursive: true
|
|
7733
8306
|
});
|
|
7734
|
-
const stats = await
|
|
8307
|
+
const stats = await fsp12.lstat(directory);
|
|
7735
8308
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
7736
8309
|
return false;
|
|
7737
8310
|
}
|
|
@@ -7741,7 +8314,7 @@ async function ensurePrivateCacheDirectory(directory) {
|
|
|
7741
8314
|
}
|
|
7742
8315
|
if (process.platform !== "win32") {
|
|
7743
8316
|
if ((stats.mode & 63) !== 0) {
|
|
7744
|
-
await
|
|
8317
|
+
await fsp12.chmod(directory, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
7745
8318
|
}
|
|
7746
8319
|
}
|
|
7747
8320
|
return isPrivateCacheDirectory(directory);
|
|
@@ -7753,9 +8326,9 @@ function resolveCacheNamespaceDir(cacheRoot, namespace) {
|
|
|
7753
8326
|
if (namespace === "." || namespace === ".." || !SAFE_CACHE_NAMESPACE_SEGMENT.test(namespace)) {
|
|
7754
8327
|
return null;
|
|
7755
8328
|
}
|
|
7756
|
-
const namespaceDir =
|
|
7757
|
-
const relativeNamespaceDir =
|
|
7758
|
-
if (relativeNamespaceDir.length === 0 || relativeNamespaceDir.startsWith("..") ||
|
|
8329
|
+
const namespaceDir = path18.join(cacheRoot, namespace);
|
|
8330
|
+
const relativeNamespaceDir = path18.relative(cacheRoot, namespaceDir);
|
|
8331
|
+
if (relativeNamespaceDir.length === 0 || relativeNamespaceDir.startsWith("..") || path18.isAbsolute(relativeNamespaceDir)) {
|
|
7759
8332
|
return null;
|
|
7760
8333
|
}
|
|
7761
8334
|
return namespaceDir;
|
|
@@ -7767,14 +8340,14 @@ function getCacheEntryPaths(descriptor) {
|
|
|
7767
8340
|
if (!namespaceDir) {
|
|
7768
8341
|
return null;
|
|
7769
8342
|
}
|
|
7770
|
-
const entryDir =
|
|
8343
|
+
const entryDir = path18.join(namespaceDir, cacheKey);
|
|
7771
8344
|
return {
|
|
7772
8345
|
cacheKey,
|
|
7773
8346
|
cacheRoot,
|
|
7774
8347
|
entryDir,
|
|
7775
|
-
markerPath:
|
|
8348
|
+
markerPath: path18.join(entryDir, CACHE_MARKER_FILE),
|
|
7776
8349
|
namespaceDir,
|
|
7777
|
-
sourceDir:
|
|
8350
|
+
sourceDir: path18.join(entryDir, "source")
|
|
7778
8351
|
};
|
|
7779
8352
|
}
|
|
7780
8353
|
async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
|
|
@@ -7782,7 +8355,7 @@ async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
|
|
|
7782
8355
|
}
|
|
7783
8356
|
async function readCacheEntryMarker(markerPath) {
|
|
7784
8357
|
try {
|
|
7785
|
-
return parseExternalTemplateCacheEntryMarker(await
|
|
8358
|
+
return parseExternalTemplateCacheEntryMarker(await fsp12.readFile(markerPath, "utf8"));
|
|
7786
8359
|
} catch {
|
|
7787
8360
|
return null;
|
|
7788
8361
|
}
|
|
@@ -7798,22 +8371,22 @@ async function isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs,
|
|
|
7798
8371
|
return marker !== null && isExternalTemplateCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs);
|
|
7799
8372
|
}
|
|
7800
8373
|
function isPathInsideDirectory(directory, candidatePath) {
|
|
7801
|
-
const relativePath =
|
|
7802
|
-
return relativePath.length > 0 && !relativePath.startsWith("..") && !
|
|
8374
|
+
const relativePath = path18.relative(directory, candidatePath);
|
|
8375
|
+
return relativePath.length > 0 && !relativePath.startsWith("..") && !path18.isAbsolute(relativePath);
|
|
7803
8376
|
}
|
|
7804
8377
|
async function removeCacheEntryWithinRoot(cacheRoot, entryDir) {
|
|
7805
8378
|
if (!isPathInsideDirectory(cacheRoot, entryDir)) {
|
|
7806
8379
|
return false;
|
|
7807
8380
|
}
|
|
7808
8381
|
try {
|
|
7809
|
-
await
|
|
8382
|
+
await fsp12.rm(entryDir, { force: true, recursive: true });
|
|
7810
8383
|
return true;
|
|
7811
8384
|
} catch {
|
|
7812
8385
|
return false;
|
|
7813
8386
|
}
|
|
7814
8387
|
}
|
|
7815
8388
|
function getCachePruneMarkerPath(cacheRoot) {
|
|
7816
|
-
return
|
|
8389
|
+
return path18.join(cacheRoot, CACHE_PRUNE_MARKER_FILE);
|
|
7817
8390
|
}
|
|
7818
8391
|
async function shouldSkipExternalTemplateCachePrune({
|
|
7819
8392
|
cacheRoot,
|
|
@@ -7827,7 +8400,7 @@ async function shouldSkipExternalTemplateCachePrune({
|
|
|
7827
8400
|
}
|
|
7828
8401
|
let markerText;
|
|
7829
8402
|
try {
|
|
7830
|
-
markerText = await
|
|
8403
|
+
markerText = await fsp12.readFile(getCachePruneMarkerPath(cacheRoot), "utf8");
|
|
7831
8404
|
} catch {
|
|
7832
8405
|
return false;
|
|
7833
8406
|
}
|
|
@@ -7845,7 +8418,7 @@ async function writeExternalTemplateCachePruneMarker({
|
|
|
7845
8418
|
ttlMs
|
|
7846
8419
|
}) {
|
|
7847
8420
|
try {
|
|
7848
|
-
await
|
|
8421
|
+
await fsp12.writeFile(getCachePruneMarkerPath(cacheRoot), formatExternalTemplateCachePruneMarker({
|
|
7849
8422
|
nowMs,
|
|
7850
8423
|
pruneIntervalMs,
|
|
7851
8424
|
ttlMs
|
|
@@ -7887,7 +8460,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7887
8460
|
}
|
|
7888
8461
|
let namespaceEntries;
|
|
7889
8462
|
try {
|
|
7890
|
-
namespaceEntries = await
|
|
8463
|
+
namespaceEntries = await fsp12.readdir(cacheRoot, { withFileTypes: true });
|
|
7891
8464
|
} catch {
|
|
7892
8465
|
return result;
|
|
7893
8466
|
}
|
|
@@ -7903,7 +8476,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7903
8476
|
}
|
|
7904
8477
|
let cacheEntries;
|
|
7905
8478
|
try {
|
|
7906
|
-
cacheEntries = await
|
|
8479
|
+
cacheEntries = await fsp12.readdir(namespaceDir, { withFileTypes: true });
|
|
7907
8480
|
} catch {
|
|
7908
8481
|
result.skippedEntries += 1;
|
|
7909
8482
|
continue;
|
|
@@ -7916,14 +8489,14 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
7916
8489
|
result.skippedEntries += 1;
|
|
7917
8490
|
continue;
|
|
7918
8491
|
}
|
|
7919
|
-
const entryDir =
|
|
8492
|
+
const entryDir = path18.join(namespaceDir, cacheEntry.name);
|
|
7920
8493
|
result.scannedEntries += 1;
|
|
7921
8494
|
if (!isPathInsideDirectory(cacheRoot, entryDir)) {
|
|
7922
8495
|
result.skippedEntries += 1;
|
|
7923
8496
|
continue;
|
|
7924
8497
|
}
|
|
7925
|
-
const markerPath =
|
|
7926
|
-
const sourceDir =
|
|
8498
|
+
const markerPath = path18.join(entryDir, CACHE_MARKER_FILE);
|
|
8499
|
+
const sourceDir = path18.join(entryDir, "source");
|
|
7927
8500
|
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
7928
8501
|
if (!marker) {
|
|
7929
8502
|
result.skippedEntries += 1;
|
|
@@ -7963,7 +8536,7 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
7963
8536
|
await pruneExternalTemplateCache();
|
|
7964
8537
|
let entries;
|
|
7965
8538
|
try {
|
|
7966
|
-
entries = await
|
|
8539
|
+
entries = await fsp12.readdir(namespaceDir, { withFileTypes: true });
|
|
7967
8540
|
} catch {
|
|
7968
8541
|
return null;
|
|
7969
8542
|
}
|
|
@@ -7972,9 +8545,9 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
7972
8545
|
if (!entry.isDirectory()) {
|
|
7973
8546
|
continue;
|
|
7974
8547
|
}
|
|
7975
|
-
const entryDir =
|
|
7976
|
-
const markerPath =
|
|
7977
|
-
const sourceDir =
|
|
8548
|
+
const entryDir = path18.join(namespaceDir, entry.name);
|
|
8549
|
+
const markerPath = path18.join(entryDir, CACHE_MARKER_FILE);
|
|
8550
|
+
const sourceDir = path18.join(entryDir, "source");
|
|
7978
8551
|
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
7979
8552
|
if (!marker || !isExternalTemplateCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs) || !externalTemplateCacheMetadataMatches(marker.metadata, descriptor.metadata)) {
|
|
7980
8553
|
continue;
|
|
@@ -8016,16 +8589,16 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
8016
8589
|
if (existingMarker) {
|
|
8017
8590
|
await removeCacheEntryWithinRoot(cacheRoot, entryDir);
|
|
8018
8591
|
}
|
|
8019
|
-
const temporaryEntryDir =
|
|
8020
|
-
const temporarySourceDir =
|
|
8592
|
+
const temporaryEntryDir = path18.join(namespaceDir, createTemporaryCacheEntryDirName(cacheKey));
|
|
8593
|
+
const temporarySourceDir = path18.join(temporaryEntryDir, "source");
|
|
8021
8594
|
let populateFailed = false;
|
|
8022
8595
|
try {
|
|
8023
|
-
await
|
|
8596
|
+
await fsp12.mkdir(temporarySourceDir, {
|
|
8024
8597
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
8025
8598
|
recursive: true
|
|
8026
8599
|
});
|
|
8027
8600
|
if (process.platform !== "win32") {
|
|
8028
|
-
await
|
|
8601
|
+
await fsp12.chmod(temporaryEntryDir, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
8029
8602
|
}
|
|
8030
8603
|
try {
|
|
8031
8604
|
await populateSourceDir(temporarySourceDir);
|
|
@@ -8033,13 +8606,13 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
8033
8606
|
populateFailed = true;
|
|
8034
8607
|
throw error;
|
|
8035
8608
|
}
|
|
8036
|
-
await
|
|
8609
|
+
await fsp12.writeFile(path18.join(temporaryEntryDir, CACHE_MARKER_FILE), formatExternalTemplateCacheEntryMarker({
|
|
8037
8610
|
cacheKey,
|
|
8038
8611
|
createdAt: new Date,
|
|
8039
8612
|
metadata: descriptor.metadata,
|
|
8040
8613
|
namespace: descriptor.namespace
|
|
8041
8614
|
}), "utf8");
|
|
8042
|
-
await
|
|
8615
|
+
await fsp12.rename(temporaryEntryDir, entryDir);
|
|
8043
8616
|
return {
|
|
8044
8617
|
cacheHit: false,
|
|
8045
8618
|
sourceDir
|
|
@@ -8110,9 +8683,9 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
8110
8683
|
if (!tarballResponse.ok) {
|
|
8111
8684
|
throw new Error(`Failed to download npm template tarball for ${locator.raw}: ${tarballResponse.status}`);
|
|
8112
8685
|
}
|
|
8113
|
-
const tarballPath =
|
|
8114
|
-
await
|
|
8115
|
-
await
|
|
8686
|
+
const tarballPath = path19.join(path19.dirname(unpackDir), "template.tgz");
|
|
8687
|
+
await fsp13.mkdir(unpackDir, { recursive: true });
|
|
8688
|
+
await fsp13.writeFile(tarballPath, await readBufferResponseWithLimit(tarballResponse, {
|
|
8116
8689
|
label: `npm template tarball for ${locator.raw}@${resolvedVersion}`,
|
|
8117
8690
|
maxBytes: getExternalTemplateTarballMaxBytes()
|
|
8118
8691
|
}));
|
|
@@ -8121,7 +8694,7 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
8121
8694
|
file: tarballPath,
|
|
8122
8695
|
strip: 1
|
|
8123
8696
|
});
|
|
8124
|
-
await
|
|
8697
|
+
await fsp13.rm(tarballPath, { force: true });
|
|
8125
8698
|
await assertNoSymlinks2(unpackDir);
|
|
8126
8699
|
}
|
|
8127
8700
|
function selectRegistryVersion(metadata, locator) {
|
|
@@ -8216,7 +8789,7 @@ async function fetchNpmTemplateSource(locator) {
|
|
|
8216
8789
|
}
|
|
8217
8790
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
8218
8791
|
try {
|
|
8219
|
-
const unpackDir =
|
|
8792
|
+
const unpackDir = path19.join(tempRoot, "source");
|
|
8220
8793
|
await downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl, unpackDir);
|
|
8221
8794
|
return {
|
|
8222
8795
|
blockDir: unpackDir,
|
|
@@ -8232,20 +8805,22 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8232
8805
|
if (locator.rawSpec !== "" && locator.rawSpec !== "*") {
|
|
8233
8806
|
return null;
|
|
8234
8807
|
}
|
|
8235
|
-
const workspacePackagesRoot =
|
|
8236
|
-
if (
|
|
8237
|
-
for (const entry of
|
|
8808
|
+
const workspacePackagesRoot = path19.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..");
|
|
8809
|
+
if (fs6.existsSync(workspacePackagesRoot)) {
|
|
8810
|
+
for (const entry of fs6.readdirSync(workspacePackagesRoot, {
|
|
8238
8811
|
withFileTypes: true
|
|
8239
8812
|
})) {
|
|
8240
8813
|
if (!entry.isDirectory()) {
|
|
8241
8814
|
continue;
|
|
8242
8815
|
}
|
|
8243
|
-
const packageDir =
|
|
8244
|
-
const packageJsonPath =
|
|
8245
|
-
if (!
|
|
8816
|
+
const packageDir = path19.join(workspacePackagesRoot, entry.name);
|
|
8817
|
+
const packageJsonPath = path19.join(packageDir, "package.json");
|
|
8818
|
+
if (!fs6.existsSync(packageJsonPath)) {
|
|
8246
8819
|
continue;
|
|
8247
8820
|
}
|
|
8248
|
-
const manifest =
|
|
8821
|
+
const manifest = readJsonFileSync(packageJsonPath, {
|
|
8822
|
+
context: "workspace template package manifest"
|
|
8823
|
+
});
|
|
8249
8824
|
if (manifest.name === locator.name) {
|
|
8250
8825
|
return {
|
|
8251
8826
|
blockDir: packageDir,
|
|
@@ -8254,10 +8829,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8254
8829
|
}
|
|
8255
8830
|
}
|
|
8256
8831
|
}
|
|
8257
|
-
const workspaceRequire = createRequire2(
|
|
8832
|
+
const workspaceRequire = createRequire2(path19.join(path19.resolve(cwd), "__wp_typia_template_resolver__.cjs"));
|
|
8258
8833
|
try {
|
|
8259
|
-
const packageJsonPath =
|
|
8260
|
-
const sourceDir =
|
|
8834
|
+
const packageJsonPath = fs6.realpathSync(workspaceRequire.resolve(`${locator.name}/package.json`));
|
|
8835
|
+
const sourceDir = path19.dirname(packageJsonPath);
|
|
8261
8836
|
return {
|
|
8262
8837
|
blockDir: sourceDir,
|
|
8263
8838
|
rootDir: sourceDir
|
|
@@ -8266,11 +8841,11 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8266
8841
|
const errorCode = typeof error === "object" && error !== null && "code" in error ? String(error.code) : "";
|
|
8267
8842
|
if (errorCode === "MODULE_NOT_FOUND" || errorCode === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
8268
8843
|
for (const basePath of workspaceRequire.resolve.paths(locator.name) ?? []) {
|
|
8269
|
-
const packageJsonPath =
|
|
8270
|
-
if (!
|
|
8844
|
+
const packageJsonPath = path19.join(basePath, locator.name, "package.json");
|
|
8845
|
+
if (!fs6.existsSync(packageJsonPath)) {
|
|
8271
8846
|
continue;
|
|
8272
8847
|
}
|
|
8273
|
-
const sourceDir =
|
|
8848
|
+
const sourceDir = path19.dirname(fs6.realpathSync(packageJsonPath));
|
|
8274
8849
|
return {
|
|
8275
8850
|
blockDir: sourceDir,
|
|
8276
8851
|
rootDir: sourceDir
|
|
@@ -8282,27 +8857,29 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
8282
8857
|
}
|
|
8283
8858
|
}
|
|
8284
8859
|
async function isOfficialWorkspaceTemplateSeedAsync(seed) {
|
|
8285
|
-
const packageJsonPath =
|
|
8860
|
+
const packageJsonPath = path19.join(seed.rootDir, "package.json");
|
|
8286
8861
|
if (!await pathExists(packageJsonPath)) {
|
|
8287
8862
|
return false;
|
|
8288
8863
|
}
|
|
8289
8864
|
try {
|
|
8290
|
-
const packageJson =
|
|
8865
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
8866
|
+
context: "workspace template seed manifest"
|
|
8867
|
+
});
|
|
8291
8868
|
return packageJson.name === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE;
|
|
8292
8869
|
} catch {
|
|
8293
8870
|
return false;
|
|
8294
8871
|
}
|
|
8295
8872
|
}
|
|
8296
8873
|
async function assertNoSymlinks2(sourceDir) {
|
|
8297
|
-
const stats = await
|
|
8874
|
+
const stats = await fsp13.lstat(sourceDir);
|
|
8298
8875
|
if (stats.isSymbolicLink()) {
|
|
8299
8876
|
throw new Error(`Template sources may not include symbolic links: ${sourceDir}`);
|
|
8300
8877
|
}
|
|
8301
8878
|
if (!stats.isDirectory()) {
|
|
8302
8879
|
return;
|
|
8303
8880
|
}
|
|
8304
|
-
for (const entry of await
|
|
8305
|
-
await assertNoSymlinks2(
|
|
8881
|
+
for (const entry of await fsp13.readdir(sourceDir)) {
|
|
8882
|
+
await assertNoSymlinks2(path19.join(sourceDir, entry));
|
|
8306
8883
|
}
|
|
8307
8884
|
}
|
|
8308
8885
|
function runGitTemplateCommand(args, label, options = {}) {
|
|
@@ -8331,9 +8908,9 @@ function getGitHubTemplateRepositoryUrl(locator) {
|
|
|
8331
8908
|
return `https://github.com/${locator.owner}/${locator.repo}.git`;
|
|
8332
8909
|
}
|
|
8333
8910
|
async function resolveGitHubTemplateDirectory(checkoutDir, locator) {
|
|
8334
|
-
const sourceDir =
|
|
8335
|
-
const relativeSourceDir =
|
|
8336
|
-
if (relativeSourceDir.startsWith("..") ||
|
|
8911
|
+
const sourceDir = path19.resolve(checkoutDir, locator.sourcePath);
|
|
8912
|
+
const relativeSourceDir = path19.relative(checkoutDir, sourceDir);
|
|
8913
|
+
if (relativeSourceDir.startsWith("..") || path19.isAbsolute(relativeSourceDir)) {
|
|
8337
8914
|
throw new Error("GitHub template path must stay within the cloned repository.");
|
|
8338
8915
|
}
|
|
8339
8916
|
if (!await pathExists(sourceDir)) {
|
|
@@ -8522,7 +9099,7 @@ async function resolveGitHubTemplateSource(locator) {
|
|
|
8522
9099
|
}
|
|
8523
9100
|
}
|
|
8524
9101
|
const { path: remoteRoot, cleanup } = await createManagedTempRoot("wp-typia-template-source-");
|
|
8525
|
-
const checkoutDir =
|
|
9102
|
+
const checkoutDir = path19.join(remoteRoot, "source");
|
|
8526
9103
|
try {
|
|
8527
9104
|
cloneGitHubTemplateSource(locator, checkoutDir);
|
|
8528
9105
|
const sourceDir = await resolveGitHubTemplateDirectory(checkoutDir, locator);
|
|
@@ -8539,7 +9116,7 @@ async function resolveGitHubTemplateSource(locator) {
|
|
|
8539
9116
|
}
|
|
8540
9117
|
async function resolveTemplateSeed(locator, cwd) {
|
|
8541
9118
|
if (locator.kind === "path") {
|
|
8542
|
-
const sourceDir =
|
|
9119
|
+
const sourceDir = path19.resolve(cwd, locator.templatePath);
|
|
8543
9120
|
if (!await pathExists(sourceDir)) {
|
|
8544
9121
|
throw new Error(`Template path does not exist: ${sourceDir}`);
|
|
8545
9122
|
}
|
|
@@ -9073,7 +9650,8 @@ function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
9073
9650
|
blockRuntimePackageVersion,
|
|
9074
9651
|
blockTypesPackageVersion,
|
|
9075
9652
|
projectToolsPackageVersion,
|
|
9076
|
-
restPackageVersion
|
|
9653
|
+
restPackageVersion,
|
|
9654
|
+
wpTypiaPackageVersion
|
|
9077
9655
|
} = getPackageVersions();
|
|
9078
9656
|
const slug = spec.block.slug;
|
|
9079
9657
|
const slugSnakeCase = toSnakeCase(slug);
|
|
@@ -9129,6 +9707,7 @@ function buildTemplateVariablesFromBlockSpec(spec) {
|
|
|
9129
9707
|
requiresPhp: compatibility.pluginHeader.requiresPhp,
|
|
9130
9708
|
testedUpTo: compatibility.pluginHeader.testedUpTo,
|
|
9131
9709
|
projectToolsPackageVersion,
|
|
9710
|
+
wpTypiaPackageVersion,
|
|
9132
9711
|
cssClassName,
|
|
9133
9712
|
dashCase: slug,
|
|
9134
9713
|
dataStorageMode,
|
|
@@ -9426,7 +10005,7 @@ function toPhpSingleQuotedString(value) {
|
|
|
9426
10005
|
return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
9427
10006
|
}
|
|
9428
10007
|
|
|
9429
|
-
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-
|
|
10008
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-basic-artifacts.ts
|
|
9430
10009
|
var BASIC_STYLE_TEMPLATE = `/**
|
|
9431
10010
|
* {{title}} Block Styles
|
|
9432
10011
|
*/
|
|
@@ -9497,14 +10076,485 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|
|
9497
10076
|
<?php esc_html_e( 'Server render placeholder.', '{{textDomain}}' ); ?>
|
|
9498
10077
|
</div>
|
|
9499
10078
|
`;
|
|
9500
|
-
|
|
9501
|
-
|
|
9502
|
-
|
|
9503
|
-
|
|
9504
|
-
|
|
9505
|
-
|
|
9506
|
-
|
|
9507
|
-
|
|
10079
|
+
function buildBasicArtifacts(variables) {
|
|
10080
|
+
return [
|
|
10081
|
+
renderArtifact("src/editor.scss", BASIC_EDITOR_STYLE_TEMPLATE, variables),
|
|
10082
|
+
renderArtifact("src/style.scss", BASIC_STYLE_TEMPLATE, variables),
|
|
10083
|
+
renderArtifact("src/render.php", BASIC_RENDER_TEMPLATE, variables)
|
|
10084
|
+
];
|
|
10085
|
+
}
|
|
10086
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-compound-templates.ts
|
|
10087
|
+
var COMPOUND_PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
|
|
10088
|
+
/**
|
|
10089
|
+
* Alternate render target helpers for the {{title}} compound parent block.
|
|
10090
|
+
*
|
|
10091
|
+
* @package {{pascalCase}}
|
|
10092
|
+
*/
|
|
10093
|
+
|
|
10094
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
10095
|
+
exit;
|
|
10096
|
+
}
|
|
10097
|
+
|
|
10098
|
+
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {
|
|
10099
|
+
function {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {
|
|
10100
|
+
$validator_path = __DIR__ . '/typia-validator.php';
|
|
10101
|
+
if ( ! file_exists( $validator_path ) ) {
|
|
10102
|
+
return null;
|
|
10103
|
+
}
|
|
10104
|
+
|
|
10105
|
+
$validator = require $validator_path;
|
|
10106
|
+
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
10107
|
+
return null;
|
|
10108
|
+
}
|
|
10109
|
+
|
|
10110
|
+
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
10111
|
+
$validation = $validator->validate( $normalized );
|
|
10112
|
+
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
10113
|
+
$heading = isset( $normalized['heading'] ) ? (string) $normalized['heading'] : {{titlePhpLiteral}};
|
|
10114
|
+
$intro = isset( $normalized['intro'] ) ? (string) $normalized['intro'] : '';
|
|
10115
|
+
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
10116
|
+
$show_count = ! empty( $normalized['showCount'] );
|
|
10117
|
+
$show_dividers = ! empty( $normalized['showDividers'] );
|
|
10118
|
+
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
10119
|
+
? (int) $block->context['postId']
|
|
10120
|
+
: (int) get_queried_object_id();
|
|
10121
|
+
$storage_mode = '{{dataStorageMode}}';
|
|
10122
|
+
$persistence_policy = '{{persistencePolicy}}';
|
|
10123
|
+
|
|
10124
|
+
$notice_message = 'authenticated' === $persistence_policy
|
|
10125
|
+
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
10126
|
+
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
10127
|
+
|
|
10128
|
+
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
10129
|
+
return null;
|
|
10130
|
+
}
|
|
10131
|
+
|
|
10132
|
+
{{phpPrefix}}_record_rendered_block_instance(
|
|
10133
|
+
(int) $post_id,
|
|
10134
|
+
'{{namespace}}/{{slugKebabCase}}',
|
|
10135
|
+
$resource_key
|
|
10136
|
+
);
|
|
10137
|
+
|
|
10138
|
+
$web_context = array(
|
|
10139
|
+
'bootstrapReady' => false,
|
|
10140
|
+
'buttonLabel' => $button_label,
|
|
10141
|
+
'canWrite' => false,
|
|
10142
|
+
'client' => array(
|
|
10143
|
+
'writeExpiry' => 0,
|
|
10144
|
+
'writeNonce' => '',
|
|
10145
|
+
'writeToken' => '',
|
|
10146
|
+
),
|
|
10147
|
+
'count' => 0,
|
|
10148
|
+
'error' => '',
|
|
10149
|
+
'isBootstrapping' => false,
|
|
10150
|
+
'isLoading' => false,
|
|
10151
|
+
'isSaving' => false,
|
|
10152
|
+
'persistencePolicy' => $persistence_policy,
|
|
10153
|
+
'postId' => (int) $post_id,
|
|
10154
|
+
'resourceKey' => $resource_key,
|
|
10155
|
+
'showCount' => $show_count,
|
|
10156
|
+
'storage' => $storage_mode,
|
|
10157
|
+
);
|
|
10158
|
+
|
|
10159
|
+
$allowed_inner_html = wp_kses_allowed_html( 'post' );
|
|
10160
|
+
|
|
10161
|
+
foreach ( $allowed_inner_html as &$allowed_attributes ) {
|
|
10162
|
+
if ( ! is_array( $allowed_attributes ) ) {
|
|
10163
|
+
continue;
|
|
10164
|
+
}
|
|
10165
|
+
|
|
10166
|
+
$allowed_attributes['data-wp-bind--disabled'] = true;
|
|
10167
|
+
$allowed_attributes['data-wp-bind--hidden'] = true;
|
|
10168
|
+
$allowed_attributes['data-wp-bind--value'] = true;
|
|
10169
|
+
$allowed_attributes['data-wp-class'] = true;
|
|
10170
|
+
$allowed_attributes['data-wp-class--active'] = true;
|
|
10171
|
+
$allowed_attributes['data-wp-context'] = true;
|
|
10172
|
+
$allowed_attributes['data-wp-init'] = true;
|
|
10173
|
+
$allowed_attributes['data-wp-interactive'] = true;
|
|
10174
|
+
$allowed_attributes['data-wp-on--click'] = true;
|
|
10175
|
+
$allowed_attributes['data-wp-on--mouseenter'] = true;
|
|
10176
|
+
$allowed_attributes['data-wp-on--mouseleave'] = true;
|
|
10177
|
+
$allowed_attributes['data-wp-run--mounted'] = true;
|
|
10178
|
+
$allowed_attributes['data-wp-style--width'] = true;
|
|
10179
|
+
$allowed_attributes['data-wp-text'] = true;
|
|
10180
|
+
}
|
|
10181
|
+
unset( $allowed_attributes );
|
|
10182
|
+
|
|
10183
|
+
return array(
|
|
10184
|
+
'buttonLabel' => $button_label,
|
|
10185
|
+
'frontendClassName' => '{{cssClassName}}',
|
|
10186
|
+
'heading' => $heading,
|
|
10187
|
+
'intro' => $intro,
|
|
10188
|
+
'isVisible' => true,
|
|
10189
|
+
'normalized' => $normalized,
|
|
10190
|
+
'noticeMessage' => $notice_message,
|
|
10191
|
+
'postId' => (int) $post_id,
|
|
10192
|
+
'resourceKey' => $resource_key,
|
|
10193
|
+
'sanitizedContent' => wp_kses( $content, $allowed_inner_html ),
|
|
10194
|
+
'showCount' => $show_count,
|
|
10195
|
+
'showDividers' => $show_dividers,
|
|
10196
|
+
'title' => {{titleJson}},
|
|
10197
|
+
'webContext' => $web_context,
|
|
10198
|
+
);
|
|
10199
|
+
}
|
|
10200
|
+
}
|
|
10201
|
+
|
|
10202
|
+
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
10203
|
+
function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
|
|
10204
|
+
$context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
|
|
10205
|
+
if ( null === $context ) {
|
|
10206
|
+
return '';
|
|
10207
|
+
}
|
|
10208
|
+
|
|
10209
|
+
$target_context = apply_filters(
|
|
10210
|
+
'{{phpPrefix}}_{{slugSnakeCase}}_render_target_context',
|
|
10211
|
+
$context,
|
|
10212
|
+
$target,
|
|
10213
|
+
$attributes,
|
|
10214
|
+
$block
|
|
10215
|
+
);
|
|
10216
|
+
|
|
10217
|
+
$markup = '';
|
|
10218
|
+
switch ( $target ) {
|
|
10219
|
+
case 'email':
|
|
10220
|
+
$parts = array(
|
|
10221
|
+
'<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
|
|
10222
|
+
'<h3>' . esc_html( $target_context['heading'] ) . '</h3>',
|
|
10223
|
+
);
|
|
10224
|
+
if ( '' !== $target_context['intro'] ) {
|
|
10225
|
+
$parts[] = '<p>' . esc_html( $target_context['intro'] ) . '</p>';
|
|
10226
|
+
}
|
|
10227
|
+
if ( ! empty( $target_context['showCount'] ) ) {
|
|
10228
|
+
$parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
|
|
10229
|
+
}
|
|
10230
|
+
$parts[] = wp_kses_post( $target_context['sanitizedContent'] );
|
|
10231
|
+
$parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
|
|
10232
|
+
$parts[] = '</div>';
|
|
10233
|
+
$markup = implode( '', $parts );
|
|
10234
|
+
break;
|
|
10235
|
+
case 'mjml':
|
|
10236
|
+
$markup = '<mjml><mj-body><mj-section><mj-column><mj-text font-weight="700">' . esc_html( $target_context['heading'] ) . '</mj-text>';
|
|
10237
|
+
if ( '' !== $target_context['intro'] ) {
|
|
10238
|
+
$markup .= '<mj-text>' . esc_html( $target_context['intro'] ) . '</mj-text>';
|
|
10239
|
+
}
|
|
10240
|
+
if ( ! empty( $target_context['showCount'] ) ) {
|
|
10241
|
+
$markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
|
|
10242
|
+
}
|
|
10243
|
+
$markup .= '<mj-text>' . esc_html( wp_strip_all_tags( $target_context['sanitizedContent'] ) ) . '</mj-text>';
|
|
10244
|
+
$markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
|
|
10245
|
+
break;
|
|
10246
|
+
case 'plain-text':
|
|
10247
|
+
$markup = implode(
|
|
10248
|
+
"\\n",
|
|
10249
|
+
array_filter(
|
|
10250
|
+
array(
|
|
10251
|
+
$target_context['heading'],
|
|
10252
|
+
$target_context['intro'],
|
|
10253
|
+
wp_strip_all_tags( $target_context['sanitizedContent'] ),
|
|
10254
|
+
! empty( $target_context['showCount'] )
|
|
10255
|
+
? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
|
|
10256
|
+
: null,
|
|
10257
|
+
$target_context['noticeMessage'],
|
|
10258
|
+
),
|
|
10259
|
+
static fn( $value ) => is_string( $value ) && '' !== $value
|
|
10260
|
+
)
|
|
10261
|
+
);
|
|
10262
|
+
break;
|
|
10263
|
+
case 'web':
|
|
10264
|
+
default:
|
|
10265
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
10266
|
+
array(
|
|
10267
|
+
'class' => '{{cssClassName}}',
|
|
10268
|
+
'data-show-dividers' => $target_context['showDividers'] ? 'true' : 'false',
|
|
10269
|
+
'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
|
|
10270
|
+
'data-wp-init' => 'callbacks.init',
|
|
10271
|
+
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
10272
|
+
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
10273
|
+
)
|
|
10274
|
+
);
|
|
10275
|
+
ob_start();
|
|
10276
|
+
?>
|
|
10277
|
+
<div <?php echo $wrapper_attributes; ?>>
|
|
10278
|
+
<h3 class="{{cssClassName}}__heading"><?php echo esc_html( $target_context['heading'] ); ?></h3>
|
|
10279
|
+
<?php if ( '' !== $target_context['intro'] ) : ?>
|
|
10280
|
+
<p class="{{cssClassName}}__intro"><?php echo esc_html( $target_context['intro'] ); ?></p>
|
|
10281
|
+
<?php endif; ?>
|
|
10282
|
+
<p
|
|
10283
|
+
class="{{cssClassName}}__notice"
|
|
10284
|
+
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
10285
|
+
hidden
|
|
10286
|
+
>
|
|
10287
|
+
<?php echo esc_html( $target_context['noticeMessage'] ); ?>
|
|
10288
|
+
</p>
|
|
10289
|
+
<p
|
|
10290
|
+
class="{{cssClassName}}__error"
|
|
10291
|
+
role="status"
|
|
10292
|
+
aria-live="polite"
|
|
10293
|
+
aria-atomic="true"
|
|
10294
|
+
data-wp-bind--hidden="!context.error"
|
|
10295
|
+
data-wp-text="context.error"
|
|
10296
|
+
hidden
|
|
10297
|
+
></p>
|
|
10298
|
+
<?php if ( ! empty( $target_context['showCount'] ) ) : ?>
|
|
10299
|
+
<div class="{{cssClassName}}__counter">
|
|
10300
|
+
<span
|
|
10301
|
+
class="{{cssClassName}}__count"
|
|
10302
|
+
role="status"
|
|
10303
|
+
aria-live="polite"
|
|
10304
|
+
aria-atomic="true"
|
|
10305
|
+
data-wp-text="context.count"
|
|
10306
|
+
>0</span>
|
|
10307
|
+
<button
|
|
10308
|
+
type="button"
|
|
10309
|
+
disabled
|
|
10310
|
+
data-wp-bind--disabled="!context.canWrite"
|
|
10311
|
+
data-wp-on--click="actions.increment"
|
|
10312
|
+
>
|
|
10313
|
+
<?php echo esc_html( $target_context['buttonLabel'] ); ?>
|
|
10314
|
+
</button>
|
|
10315
|
+
</div>
|
|
10316
|
+
<?php endif; ?>
|
|
10317
|
+
<div class="{{cssClassName}}__items">
|
|
10318
|
+
<?php echo wp_kses_post( $target_context['sanitizedContent'] ); ?>
|
|
10319
|
+
</div>
|
|
10320
|
+
</div>
|
|
10321
|
+
<?php
|
|
10322
|
+
$markup = (string) ob_get_clean();
|
|
10323
|
+
break;
|
|
10324
|
+
}
|
|
10325
|
+
|
|
10326
|
+
return apply_filters(
|
|
10327
|
+
'{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',
|
|
10328
|
+
$markup,
|
|
10329
|
+
$target,
|
|
10330
|
+
$target_context
|
|
10331
|
+
);
|
|
10332
|
+
}
|
|
10333
|
+
}
|
|
10334
|
+
`;
|
|
10335
|
+
var COMPOUND_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
10336
|
+
border: 1px solid #dcdcde;
|
|
10337
|
+
border-radius: 12px;
|
|
10338
|
+
padding: 1.25rem;
|
|
10339
|
+
background: #fff;
|
|
10340
|
+
}
|
|
10341
|
+
|
|
10342
|
+
.{{cssClassName}}__heading {
|
|
10343
|
+
margin: 0 0 0.5rem;
|
|
10344
|
+
font-size: 1.2rem;
|
|
10345
|
+
}
|
|
10346
|
+
|
|
10347
|
+
.{{cssClassName}}__intro {
|
|
10348
|
+
margin: 0 0 1rem;
|
|
10349
|
+
color: #50575e;
|
|
10350
|
+
}
|
|
10351
|
+
|
|
10352
|
+
.{{cssClassName}}__items {
|
|
10353
|
+
display: grid;
|
|
10354
|
+
gap: 0.75rem;
|
|
10355
|
+
}
|
|
10356
|
+
|
|
10357
|
+
.{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}} {
|
|
10358
|
+
border-top: 1px solid #dcdcde;
|
|
10359
|
+
padding-top: 0.75rem;
|
|
10360
|
+
}
|
|
10361
|
+
|
|
10362
|
+
.{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}}:first-child {
|
|
10363
|
+
border-top: 0;
|
|
10364
|
+
padding-top: 0;
|
|
10365
|
+
}
|
|
10366
|
+
`;
|
|
10367
|
+
var COMPOUND_PERSISTENCE_RENDER_TEMPLATE = `<?php
|
|
10368
|
+
/**
|
|
10369
|
+
* Dynamic render entry for the {{title}} compound parent block.
|
|
10370
|
+
*
|
|
10371
|
+
* @package {{pascalCase}}
|
|
10372
|
+
*/
|
|
10373
|
+
|
|
10374
|
+
if ( ! defined( 'ABSPATH' ) ) {
|
|
10375
|
+
exit;
|
|
10376
|
+
}
|
|
10377
|
+
|
|
10378
|
+
$validator_path = __DIR__ . '/typia-validator.php';
|
|
10379
|
+
if ( ! file_exists( $validator_path ) ) {
|
|
10380
|
+
return '';
|
|
10381
|
+
}
|
|
10382
|
+
|
|
10383
|
+
$validator = require $validator_path;
|
|
10384
|
+
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
10385
|
+
return '';
|
|
10386
|
+
}
|
|
10387
|
+
|
|
10388
|
+
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
10389
|
+
$validation = $validator->validate( $normalized );
|
|
10390
|
+
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
10391
|
+
$heading = isset( $normalized['heading'] ) ? (string) $normalized['heading'] : {{titlePhpLiteral}};
|
|
10392
|
+
$intro = isset( $normalized['intro'] ) ? (string) $normalized['intro'] : '';
|
|
10393
|
+
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
10394
|
+
$show_count = ! empty( $normalized['showCount'] );
|
|
10395
|
+
$show_dividers = ! empty( $normalized['showDividers'] );
|
|
10396
|
+
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
10397
|
+
? (int) $block->context['postId']
|
|
10398
|
+
: (int) get_queried_object_id();
|
|
10399
|
+
$storage_mode = '{{dataStorageMode}}';
|
|
10400
|
+
$persistence_policy = '{{persistencePolicy}}';
|
|
10401
|
+
|
|
10402
|
+
$notice_message = 'authenticated' === $persistence_policy
|
|
10403
|
+
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
10404
|
+
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
10405
|
+
|
|
10406
|
+
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
10407
|
+
return '';
|
|
10408
|
+
}
|
|
10409
|
+
|
|
10410
|
+
{{phpPrefix}}_record_rendered_block_instance(
|
|
10411
|
+
(int) $post_id,
|
|
10412
|
+
'{{namespace}}/{{slugKebabCase}}',
|
|
10413
|
+
$resource_key
|
|
10414
|
+
);
|
|
10415
|
+
|
|
10416
|
+
$context = array(
|
|
10417
|
+
'bootstrapReady' => false,
|
|
10418
|
+
'buttonLabel' => $button_label,
|
|
10419
|
+
'canWrite' => false,
|
|
10420
|
+
'client' => array(
|
|
10421
|
+
'writeExpiry' => 0,
|
|
10422
|
+
'writeNonce' => '',
|
|
10423
|
+
'writeToken' => '',
|
|
10424
|
+
),
|
|
10425
|
+
'count' => 0,
|
|
10426
|
+
'error' => '',
|
|
10427
|
+
'isBootstrapping' => false,
|
|
10428
|
+
'isLoading' => false,
|
|
10429
|
+
'isSaving' => false,
|
|
10430
|
+
'persistencePolicy' => $persistence_policy,
|
|
10431
|
+
'postId' => (int) $post_id,
|
|
10432
|
+
'resourceKey' => $resource_key,
|
|
10433
|
+
'showCount' => $show_count,
|
|
10434
|
+
'storage' => $storage_mode,
|
|
10435
|
+
);
|
|
10436
|
+
|
|
10437
|
+
$allowed_inner_html = wp_kses_allowed_html( 'post' );
|
|
10438
|
+
|
|
10439
|
+
foreach ( $allowed_inner_html as &$allowed_attributes ) {
|
|
10440
|
+
if ( ! is_array( $allowed_attributes ) ) {
|
|
10441
|
+
continue;
|
|
10442
|
+
}
|
|
10443
|
+
|
|
10444
|
+
$allowed_attributes['data-wp-bind--disabled'] = true;
|
|
10445
|
+
$allowed_attributes['data-wp-bind--hidden'] = true;
|
|
10446
|
+
$allowed_attributes['data-wp-bind--value'] = true;
|
|
10447
|
+
$allowed_attributes['data-wp-class'] = true;
|
|
10448
|
+
$allowed_attributes['data-wp-class--active'] = true;
|
|
10449
|
+
$allowed_attributes['data-wp-context'] = true;
|
|
10450
|
+
$allowed_attributes['data-wp-init'] = true;
|
|
10451
|
+
$allowed_attributes['data-wp-interactive'] = true;
|
|
10452
|
+
$allowed_attributes['data-wp-on--click'] = true;
|
|
10453
|
+
$allowed_attributes['data-wp-on--mouseenter'] = true;
|
|
10454
|
+
$allowed_attributes['data-wp-on--mouseleave'] = true;
|
|
10455
|
+
$allowed_attributes['data-wp-run--mounted'] = true;
|
|
10456
|
+
$allowed_attributes['data-wp-style--width'] = true;
|
|
10457
|
+
$allowed_attributes['data-wp-text'] = true;
|
|
10458
|
+
}
|
|
10459
|
+
unset( $allowed_attributes );
|
|
10460
|
+
|
|
10461
|
+
$sanitized_content = wp_kses( $content, $allowed_inner_html );
|
|
10462
|
+
|
|
10463
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
10464
|
+
array(
|
|
10465
|
+
'class' => '{{cssClassName}}',
|
|
10466
|
+
'data-show-dividers' => $show_dividers ? 'true' : 'false',
|
|
10467
|
+
'data-wp-context' => wp_json_encode( $context ),
|
|
10468
|
+
'data-wp-init' => 'callbacks.init',
|
|
10469
|
+
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
10470
|
+
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
10471
|
+
)
|
|
10472
|
+
);
|
|
10473
|
+
?>
|
|
10474
|
+
|
|
10475
|
+
<div <?php echo $wrapper_attributes; ?>>
|
|
10476
|
+
<h3 class="{{cssClassName}}__heading"><?php echo esc_html( $heading ); ?></h3>
|
|
10477
|
+
<?php if ( '' !== $intro ) : ?>
|
|
10478
|
+
<p class="{{cssClassName}}__intro"><?php echo esc_html( $intro ); ?></p>
|
|
10479
|
+
<?php endif; ?>
|
|
10480
|
+
<p
|
|
10481
|
+
class="{{cssClassName}}__notice"
|
|
10482
|
+
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
10483
|
+
hidden
|
|
10484
|
+
>
|
|
10485
|
+
<?php echo esc_html( $notice_message ); ?>
|
|
10486
|
+
</p>
|
|
10487
|
+
<p
|
|
10488
|
+
class="{{cssClassName}}__error"
|
|
10489
|
+
role="status"
|
|
10490
|
+
aria-live="polite"
|
|
10491
|
+
aria-atomic="true"
|
|
10492
|
+
data-wp-bind--hidden="!context.error"
|
|
10493
|
+
data-wp-text="context.error"
|
|
10494
|
+
hidden
|
|
10495
|
+
></p>
|
|
10496
|
+
<?php if ( $show_count ) : ?>
|
|
10497
|
+
<div class="{{cssClassName}}__counter">
|
|
10498
|
+
<span
|
|
10499
|
+
class="{{cssClassName}}__count"
|
|
10500
|
+
role="status"
|
|
10501
|
+
aria-live="polite"
|
|
10502
|
+
aria-atomic="true"
|
|
10503
|
+
data-wp-text="context.count"
|
|
10504
|
+
>0</span>
|
|
10505
|
+
<button
|
|
10506
|
+
type="button"
|
|
10507
|
+
disabled
|
|
10508
|
+
data-wp-bind--disabled="!context.canWrite"
|
|
10509
|
+
data-wp-on--click="actions.increment"
|
|
10510
|
+
>
|
|
10511
|
+
<?php echo esc_html( $button_label ); ?>
|
|
10512
|
+
</button>
|
|
10513
|
+
</div>
|
|
10514
|
+
<?php endif; ?>
|
|
10515
|
+
<div class="{{cssClassName}}__items">
|
|
10516
|
+
<?php echo $sanitized_content; ?>
|
|
10517
|
+
</div>
|
|
10518
|
+
</div>
|
|
10519
|
+
`;
|
|
10520
|
+
|
|
10521
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-compound-artifacts.ts
|
|
10522
|
+
function buildCompoundArtifacts(variables) {
|
|
10523
|
+
const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
|
|
10524
|
+
const artifacts = [
|
|
10525
|
+
renderArtifact(`src/blocks/${variables.slugKebabCase}/style.scss`, COMPOUND_STYLE_TEMPLATE, variables)
|
|
10526
|
+
];
|
|
10527
|
+
if (isCompoundPersistenceEnabled(variables)) {
|
|
10528
|
+
const renderView = {
|
|
10529
|
+
...variables,
|
|
10530
|
+
titlePhpLiteral: toPhpSingleQuotedString(variables.title)
|
|
10531
|
+
};
|
|
10532
|
+
if (alternateRenderTargets.enabled) {
|
|
10533
|
+
artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render-targets.php`, COMPOUND_PERSISTENCE_RENDER_TARGETS_TEMPLATE, renderView), buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, "web", variables));
|
|
10534
|
+
if (alternateRenderTargets.hasEmail) {
|
|
10535
|
+
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-email.php`, "email", variables));
|
|
10536
|
+
}
|
|
10537
|
+
if (alternateRenderTargets.hasMjml) {
|
|
10538
|
+
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-mjml.php`, "mjml", variables));
|
|
10539
|
+
}
|
|
10540
|
+
if (alternateRenderTargets.hasPlainText) {
|
|
10541
|
+
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-text.php`, "plain-text", variables));
|
|
10542
|
+
}
|
|
10543
|
+
return artifacts;
|
|
10544
|
+
}
|
|
10545
|
+
artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, COMPOUND_PERSISTENCE_RENDER_TEMPLATE, renderView));
|
|
10546
|
+
}
|
|
10547
|
+
return artifacts;
|
|
10548
|
+
}
|
|
10549
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-interactivity-artifacts.ts
|
|
10550
|
+
var INTERACTIVITY_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
10551
|
+
position: relative;
|
|
10552
|
+
padding: 1rem;
|
|
10553
|
+
border: 1px solid #dcdcde;
|
|
10554
|
+
border-radius: 0.75rem;
|
|
10555
|
+
background: #fff;
|
|
10556
|
+
|
|
10557
|
+
&__content {
|
|
9508
10558
|
display: grid;
|
|
9509
10559
|
gap: 0.75rem;
|
|
9510
10560
|
}
|
|
@@ -9567,6 +10617,13 @@ var INTERACTIVITY_EDITOR_STYLE_TEMPLATE = `/**
|
|
|
9567
10617
|
outline-offset: -1px;
|
|
9568
10618
|
}
|
|
9569
10619
|
`;
|
|
10620
|
+
function buildInteractivityArtifacts(variables) {
|
|
10621
|
+
return [
|
|
10622
|
+
renderArtifact("src/editor.scss", INTERACTIVITY_EDITOR_STYLE_TEMPLATE, variables),
|
|
10623
|
+
renderArtifact("src/style.scss", INTERACTIVITY_STYLE_TEMPLATE, variables)
|
|
10624
|
+
];
|
|
10625
|
+
}
|
|
10626
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-persistence-templates.ts
|
|
9570
10627
|
var PERSISTENCE_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
9571
10628
|
border: 1px solid #dcdcde;
|
|
9572
10629
|
border-radius: 12px;
|
|
@@ -9665,238 +10722,44 @@ $context = array(
|
|
|
9665
10722
|
'bootstrapReady' => false,
|
|
9666
10723
|
'buttonLabel' => $button_label,
|
|
9667
10724
|
'canWrite' => false,
|
|
9668
|
-
'client' => array(
|
|
9669
|
-
'writeExpiry' => 0,
|
|
9670
|
-
'writeNonce' => '',
|
|
9671
|
-
'writeToken' => '',
|
|
9672
|
-
),
|
|
9673
|
-
'count' => 0,
|
|
9674
|
-
'error' => '',
|
|
9675
|
-
'isBootstrapping' => false,
|
|
9676
|
-
'isLoading' => false,
|
|
9677
|
-
'isSaving' => false,
|
|
9678
|
-
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
9679
|
-
'persistencePolicy' => $persistence_policy,
|
|
9680
|
-
'postId' => (int) $post_id,
|
|
9681
|
-
'resourceKey' => $resource_key,
|
|
9682
|
-
'storage' => $storage_mode,
|
|
9683
|
-
);
|
|
9684
|
-
|
|
9685
|
-
$wrapper_attributes = get_block_wrapper_attributes(
|
|
9686
|
-
array(
|
|
9687
|
-
'data-wp-context' => wp_json_encode( $context ),
|
|
9688
|
-
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
9689
|
-
'data-wp-init' => 'callbacks.init',
|
|
9690
|
-
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
9691
|
-
)
|
|
9692
|
-
);
|
|
9693
|
-
?>
|
|
9694
|
-
|
|
9695
|
-
<div <?php echo $wrapper_attributes; ?>>
|
|
9696
|
-
<div class="{{frontendCssClassName}}">
|
|
9697
|
-
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $alignment ); ?>">
|
|
9698
|
-
<?php echo esc_html( $content ); ?>
|
|
9699
|
-
</p>
|
|
9700
|
-
<p
|
|
9701
|
-
class="{{frontendCssClassName}}__notice"
|
|
9702
|
-
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
9703
|
-
hidden
|
|
9704
|
-
>
|
|
9705
|
-
<?php echo esc_html( $notice_message ); ?>
|
|
9706
|
-
</p>
|
|
9707
|
-
<p
|
|
9708
|
-
class="{{frontendCssClassName}}__error"
|
|
9709
|
-
role="status"
|
|
9710
|
-
aria-live="polite"
|
|
9711
|
-
aria-atomic="true"
|
|
9712
|
-
data-wp-bind--hidden="!context.error"
|
|
9713
|
-
data-wp-text="context.error"
|
|
9714
|
-
hidden
|
|
9715
|
-
></p>
|
|
9716
|
-
<?php if ( ! empty( $normalized['showCount'] ) ) : ?>
|
|
9717
|
-
<span
|
|
9718
|
-
class="{{frontendCssClassName}}__count"
|
|
9719
|
-
role="status"
|
|
9720
|
-
aria-live="polite"
|
|
9721
|
-
aria-atomic="true"
|
|
9722
|
-
data-wp-text="context.count"
|
|
9723
|
-
>
|
|
9724
|
-
0
|
|
9725
|
-
</span>
|
|
9726
|
-
<?php endif; ?>
|
|
9727
|
-
<button
|
|
9728
|
-
type="button"
|
|
9729
|
-
disabled
|
|
9730
|
-
data-wp-bind--disabled="!context.canWrite"
|
|
9731
|
-
data-wp-on--click="actions.increment"
|
|
9732
|
-
>
|
|
9733
|
-
<?php echo esc_html( $button_label ); ?>
|
|
9734
|
-
</button>
|
|
9735
|
-
</div>
|
|
9736
|
-
</div>
|
|
9737
|
-
`;
|
|
9738
|
-
var PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
|
|
9739
|
-
/**
|
|
9740
|
-
* Alternate render target helpers for the {{title}} block.
|
|
9741
|
-
*
|
|
9742
|
-
* @package {{pascalCase}}
|
|
9743
|
-
*/
|
|
9744
|
-
|
|
9745
|
-
if ( ! defined( 'ABSPATH' ) ) {
|
|
9746
|
-
exit;
|
|
9747
|
-
}
|
|
9748
|
-
|
|
9749
|
-
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' ) ) {
|
|
9750
|
-
function {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block ) {
|
|
9751
|
-
$validator_path = __DIR__ . '/typia-validator.php';
|
|
9752
|
-
if ( ! file_exists( $validator_path ) ) {
|
|
9753
|
-
return null;
|
|
9754
|
-
}
|
|
9755
|
-
|
|
9756
|
-
$validator = require $validator_path;
|
|
9757
|
-
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
9758
|
-
return null;
|
|
9759
|
-
}
|
|
9760
|
-
|
|
9761
|
-
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
9762
|
-
$validation = $validator->validate( $normalized );
|
|
9763
|
-
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
9764
|
-
|
|
9765
|
-
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
9766
|
-
return null;
|
|
9767
|
-
}
|
|
9768
|
-
|
|
9769
|
-
$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
|
|
9770
|
-
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
9771
|
-
$rendered_content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
|
|
9772
|
-
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
9773
|
-
? (int) $block->context['postId']
|
|
9774
|
-
: (int) get_queried_object_id();
|
|
9775
|
-
$storage_mode = '{{dataStorageMode}}';
|
|
9776
|
-
$persistence_policy = '{{persistencePolicy}}';
|
|
9777
|
-
|
|
9778
|
-
{{phpPrefix}}_record_rendered_block_instance(
|
|
9779
|
-
(int) $post_id,
|
|
9780
|
-
'{{namespace}}/{{slugKebabCase}}',
|
|
9781
|
-
$resource_key
|
|
9782
|
-
);
|
|
9783
|
-
|
|
9784
|
-
$notice_message = 'authenticated' === $persistence_policy
|
|
9785
|
-
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
9786
|
-
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
9787
|
-
$web_context = array(
|
|
9788
|
-
'bootstrapReady' => false,
|
|
9789
|
-
'buttonLabel' => $button_label,
|
|
9790
|
-
'canWrite' => false,
|
|
9791
|
-
'client' => array(
|
|
9792
|
-
'writeExpiry' => 0,
|
|
9793
|
-
'writeNonce' => '',
|
|
9794
|
-
'writeToken' => '',
|
|
9795
|
-
),
|
|
9796
|
-
'count' => 0,
|
|
9797
|
-
'error' => '',
|
|
9798
|
-
'isBootstrapping' => false,
|
|
9799
|
-
'isLoading' => false,
|
|
9800
|
-
'isSaving' => false,
|
|
9801
|
-
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
9802
|
-
'persistencePolicy' => $persistence_policy,
|
|
9803
|
-
'postId' => (int) $post_id,
|
|
9804
|
-
'resourceKey' => $resource_key,
|
|
9805
|
-
'storage' => $storage_mode,
|
|
9806
|
-
);
|
|
9807
|
-
|
|
9808
|
-
return array(
|
|
9809
|
-
'alignment' => $alignment,
|
|
9810
|
-
'buttonLabel' => $button_label,
|
|
9811
|
-
'content' => $rendered_content,
|
|
9812
|
-
'frontendClassName' => '{{frontendCssClassName}}',
|
|
9813
|
-
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
9814
|
-
'normalized' => $normalized,
|
|
9815
|
-
'noticeMessage' => $notice_message,
|
|
9816
|
-
'postId' => (int) $post_id,
|
|
9817
|
-
'resourceKey' => $resource_key,
|
|
9818
|
-
'showCount' => ! empty( $normalized['showCount'] ),
|
|
9819
|
-
'title' => {{titleJson}},
|
|
9820
|
-
'webContext' => $web_context,
|
|
9821
|
-
);
|
|
9822
|
-
}
|
|
9823
|
-
}
|
|
9824
|
-
|
|
9825
|
-
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
9826
|
-
function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
|
|
9827
|
-
$context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
|
|
9828
|
-
if ( null === $context || empty( $context['isVisible'] ) ) {
|
|
9829
|
-
return '';
|
|
9830
|
-
}
|
|
10725
|
+
'client' => array(
|
|
10726
|
+
'writeExpiry' => 0,
|
|
10727
|
+
'writeNonce' => '',
|
|
10728
|
+
'writeToken' => '',
|
|
10729
|
+
),
|
|
10730
|
+
'count' => 0,
|
|
10731
|
+
'error' => '',
|
|
10732
|
+
'isBootstrapping' => false,
|
|
10733
|
+
'isLoading' => false,
|
|
10734
|
+
'isSaving' => false,
|
|
10735
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
10736
|
+
'persistencePolicy' => $persistence_policy,
|
|
10737
|
+
'postId' => (int) $post_id,
|
|
10738
|
+
'resourceKey' => $resource_key,
|
|
10739
|
+
'storage' => $storage_mode,
|
|
10740
|
+
);
|
|
9831
10741
|
|
|
9832
|
-
|
|
9833
|
-
|
|
9834
|
-
|
|
9835
|
-
|
|
9836
|
-
|
|
9837
|
-
|
|
9838
|
-
|
|
10742
|
+
$wrapper_attributes = get_block_wrapper_attributes(
|
|
10743
|
+
array(
|
|
10744
|
+
'data-wp-context' => wp_json_encode( $context ),
|
|
10745
|
+
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
10746
|
+
'data-wp-init' => 'callbacks.init',
|
|
10747
|
+
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
10748
|
+
)
|
|
10749
|
+
);
|
|
10750
|
+
?>
|
|
9839
10751
|
|
|
9840
|
-
$markup = '';
|
|
9841
|
-
switch ( $target ) {
|
|
9842
|
-
case 'email':
|
|
9843
|
-
$parts = array(
|
|
9844
|
-
'<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
|
|
9845
|
-
'<p style="text-align:' . esc_attr( $target_context['alignment'] ) . ';">' . esc_html( $target_context['content'] ) . '</p>',
|
|
9846
|
-
);
|
|
9847
|
-
if ( ! empty( $target_context['showCount'] ) ) {
|
|
9848
|
-
$parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
|
|
9849
|
-
}
|
|
9850
|
-
$parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
|
|
9851
|
-
$parts[] = '</div>';
|
|
9852
|
-
$markup = implode( '', $parts );
|
|
9853
|
-
break;
|
|
9854
|
-
case 'mjml':
|
|
9855
|
-
$markup = '<mjml><mj-body><mj-section><mj-column><mj-text align="' . esc_attr( $target_context['alignment'] ) . '">' . esc_html( $target_context['content'] ) . '</mj-text>';
|
|
9856
|
-
if ( ! empty( $target_context['showCount'] ) ) {
|
|
9857
|
-
$markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
|
|
9858
|
-
}
|
|
9859
|
-
$markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
|
|
9860
|
-
break;
|
|
9861
|
-
case 'plain-text':
|
|
9862
|
-
$markup = implode(
|
|
9863
|
-
"\\n",
|
|
9864
|
-
array_filter(
|
|
9865
|
-
array(
|
|
9866
|
-
$target_context['title'],
|
|
9867
|
-
$target_context['content'],
|
|
9868
|
-
! empty( $target_context['showCount'] )
|
|
9869
|
-
? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
|
|
9870
|
-
: null,
|
|
9871
|
-
$target_context['noticeMessage'],
|
|
9872
|
-
),
|
|
9873
|
-
static fn( $value ) => is_string( $value ) && '' !== $value
|
|
9874
|
-
)
|
|
9875
|
-
);
|
|
9876
|
-
break;
|
|
9877
|
-
case 'web':
|
|
9878
|
-
default:
|
|
9879
|
-
$wrapper_attributes = get_block_wrapper_attributes(
|
|
9880
|
-
array(
|
|
9881
|
-
'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
|
|
9882
|
-
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
9883
|
-
'data-wp-init' => 'callbacks.init',
|
|
9884
|
-
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
9885
|
-
)
|
|
9886
|
-
);
|
|
9887
|
-
ob_start();
|
|
9888
|
-
?>
|
|
9889
10752
|
<div <?php echo $wrapper_attributes; ?>>
|
|
9890
10753
|
<div class="{{frontendCssClassName}}">
|
|
9891
|
-
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $
|
|
9892
|
-
<?php echo esc_html( $
|
|
10754
|
+
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $alignment ); ?>">
|
|
10755
|
+
<?php echo esc_html( $content ); ?>
|
|
9893
10756
|
</p>
|
|
9894
10757
|
<p
|
|
9895
10758
|
class="{{frontendCssClassName}}__notice"
|
|
9896
10759
|
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
9897
10760
|
hidden
|
|
9898
10761
|
>
|
|
9899
|
-
<?php echo esc_html( $
|
|
10762
|
+
<?php echo esc_html( $notice_message ); ?>
|
|
9900
10763
|
</p>
|
|
9901
10764
|
<p
|
|
9902
10765
|
class="{{frontendCssClassName}}__error"
|
|
@@ -9907,7 +10770,7 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
9907
10770
|
data-wp-text="context.error"
|
|
9908
10771
|
hidden
|
|
9909
10772
|
></p>
|
|
9910
|
-
<?php if ( ! empty( $
|
|
10773
|
+
<?php if ( ! empty( $normalized['showCount'] ) ) : ?>
|
|
9911
10774
|
<span
|
|
9912
10775
|
class="{{frontendCssClassName}}__count"
|
|
9913
10776
|
role="status"
|
|
@@ -9924,27 +10787,14 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
9924
10787
|
data-wp-bind--disabled="!context.canWrite"
|
|
9925
10788
|
data-wp-on--click="actions.increment"
|
|
9926
10789
|
>
|
|
9927
|
-
<?php echo esc_html( $
|
|
10790
|
+
<?php echo esc_html( $button_label ); ?>
|
|
9928
10791
|
</button>
|
|
9929
10792
|
</div>
|
|
9930
10793
|
</div>
|
|
9931
|
-
<?php
|
|
9932
|
-
$markup = (string) ob_get_clean();
|
|
9933
|
-
break;
|
|
9934
|
-
}
|
|
9935
|
-
|
|
9936
|
-
return apply_filters(
|
|
9937
|
-
'{{phpPrefix}}_{{slugSnakeCase}}_render_target_markup',
|
|
9938
|
-
$markup,
|
|
9939
|
-
$target,
|
|
9940
|
-
$target_context
|
|
9941
|
-
);
|
|
9942
|
-
}
|
|
9943
|
-
}
|
|
9944
10794
|
`;
|
|
9945
|
-
var
|
|
10795
|
+
var PERSISTENCE_RENDER_TARGETS_TEMPLATE = `<?php
|
|
9946
10796
|
/**
|
|
9947
|
-
* Alternate render target helpers for the {{title}}
|
|
10797
|
+
* Alternate render target helpers for the {{title}} block.
|
|
9948
10798
|
*
|
|
9949
10799
|
* @package {{pascalCase}}
|
|
9950
10800
|
*/
|
|
@@ -9965,34 +10815,32 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' )
|
|
|
9965
10815
|
return null;
|
|
9966
10816
|
}
|
|
9967
10817
|
|
|
9968
|
-
$normalized
|
|
9969
|
-
$validation
|
|
9970
|
-
$resource_key
|
|
9971
|
-
|
|
9972
|
-
|
|
10818
|
+
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
10819
|
+
$validation = $validator->validate( $normalized );
|
|
10820
|
+
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
10821
|
+
|
|
10822
|
+
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
10823
|
+
return null;
|
|
10824
|
+
}
|
|
10825
|
+
|
|
10826
|
+
$alignment = isset( $normalized['alignment'] ) ? (string) $normalized['alignment'] : 'left';
|
|
9973
10827
|
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
9974
|
-
$
|
|
9975
|
-
$show_dividers = ! empty( $normalized['showDividers'] );
|
|
10828
|
+
$rendered_content = isset( $normalized['content'] ) ? (string) $normalized['content'] : '';
|
|
9976
10829
|
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
9977
10830
|
? (int) $block->context['postId']
|
|
9978
10831
|
: (int) get_queried_object_id();
|
|
9979
10832
|
$storage_mode = '{{dataStorageMode}}';
|
|
9980
10833
|
$persistence_policy = '{{persistencePolicy}}';
|
|
9981
10834
|
|
|
9982
|
-
$notice_message = 'authenticated' === $persistence_policy
|
|
9983
|
-
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
9984
|
-
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
9985
|
-
|
|
9986
|
-
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
9987
|
-
return null;
|
|
9988
|
-
}
|
|
9989
|
-
|
|
9990
10835
|
{{phpPrefix}}_record_rendered_block_instance(
|
|
9991
10836
|
(int) $post_id,
|
|
9992
10837
|
'{{namespace}}/{{slugKebabCase}}',
|
|
9993
10838
|
$resource_key
|
|
9994
10839
|
);
|
|
9995
10840
|
|
|
10841
|
+
$notice_message = 'authenticated' === $persistence_policy
|
|
10842
|
+
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
10843
|
+
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
9996
10844
|
$web_context = array(
|
|
9997
10845
|
'bootstrapReady' => false,
|
|
9998
10846
|
'buttonLabel' => $button_label,
|
|
@@ -10007,50 +10855,24 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' )
|
|
|
10007
10855
|
'isBootstrapping' => false,
|
|
10008
10856
|
'isLoading' => false,
|
|
10009
10857
|
'isSaving' => false,
|
|
10858
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
10010
10859
|
'persistencePolicy' => $persistence_policy,
|
|
10011
10860
|
'postId' => (int) $post_id,
|
|
10012
10861
|
'resourceKey' => $resource_key,
|
|
10013
|
-
'showCount' => $show_count,
|
|
10014
10862
|
'storage' => $storage_mode,
|
|
10015
10863
|
);
|
|
10016
10864
|
|
|
10017
|
-
$allowed_inner_html = wp_kses_allowed_html( 'post' );
|
|
10018
|
-
|
|
10019
|
-
foreach ( $allowed_inner_html as &$allowed_attributes ) {
|
|
10020
|
-
if ( ! is_array( $allowed_attributes ) ) {
|
|
10021
|
-
continue;
|
|
10022
|
-
}
|
|
10023
|
-
|
|
10024
|
-
$allowed_attributes['data-wp-bind--disabled'] = true;
|
|
10025
|
-
$allowed_attributes['data-wp-bind--hidden'] = true;
|
|
10026
|
-
$allowed_attributes['data-wp-bind--value'] = true;
|
|
10027
|
-
$allowed_attributes['data-wp-class'] = true;
|
|
10028
|
-
$allowed_attributes['data-wp-class--active'] = true;
|
|
10029
|
-
$allowed_attributes['data-wp-context'] = true;
|
|
10030
|
-
$allowed_attributes['data-wp-init'] = true;
|
|
10031
|
-
$allowed_attributes['data-wp-interactive'] = true;
|
|
10032
|
-
$allowed_attributes['data-wp-on--click'] = true;
|
|
10033
|
-
$allowed_attributes['data-wp-on--mouseenter'] = true;
|
|
10034
|
-
$allowed_attributes['data-wp-on--mouseleave'] = true;
|
|
10035
|
-
$allowed_attributes['data-wp-run--mounted'] = true;
|
|
10036
|
-
$allowed_attributes['data-wp-style--width'] = true;
|
|
10037
|
-
$allowed_attributes['data-wp-text'] = true;
|
|
10038
|
-
}
|
|
10039
|
-
unset( $allowed_attributes );
|
|
10040
|
-
|
|
10041
10865
|
return array(
|
|
10866
|
+
'alignment' => $alignment,
|
|
10042
10867
|
'buttonLabel' => $button_label,
|
|
10043
|
-
'
|
|
10044
|
-
'
|
|
10045
|
-
'
|
|
10046
|
-
'isVisible' => true,
|
|
10868
|
+
'content' => $rendered_content,
|
|
10869
|
+
'frontendClassName' => '{{frontendCssClassName}}',
|
|
10870
|
+
'isVisible' => ! empty( $normalized['isVisible'] ),
|
|
10047
10871
|
'normalized' => $normalized,
|
|
10048
10872
|
'noticeMessage' => $notice_message,
|
|
10049
10873
|
'postId' => (int) $post_id,
|
|
10050
10874
|
'resourceKey' => $resource_key,
|
|
10051
|
-
'
|
|
10052
|
-
'showCount' => $show_count,
|
|
10053
|
-
'showDividers' => $show_dividers,
|
|
10875
|
+
'showCount' => ! empty( $normalized['showCount'] ),
|
|
10054
10876
|
'title' => {{titleJson}},
|
|
10055
10877
|
'webContext' => $web_context,
|
|
10056
10878
|
);
|
|
@@ -10060,7 +10882,7 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_build_render_context' )
|
|
|
10060
10882
|
if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
10061
10883
|
function {{phpPrefix}}_{{slugSnakeCase}}_render_target( string $target, $attributes, $content = '', $block = null ): string {
|
|
10062
10884
|
$context = {{phpPrefix}}_{{slugSnakeCase}}_build_render_context( $attributes, $content, $block );
|
|
10063
|
-
if ( null === $context ) {
|
|
10885
|
+
if ( null === $context || empty( $context['isVisible'] ) ) {
|
|
10064
10886
|
return '';
|
|
10065
10887
|
}
|
|
10066
10888
|
|
|
@@ -10077,28 +10899,20 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
10077
10899
|
case 'email':
|
|
10078
10900
|
$parts = array(
|
|
10079
10901
|
'<div class="' . esc_attr( $target_context['frontendClassName'] ) . '-email">',
|
|
10080
|
-
'<
|
|
10902
|
+
'<p style="text-align:' . esc_attr( $target_context['alignment'] ) . ';">' . esc_html( $target_context['content'] ) . '</p>',
|
|
10081
10903
|
);
|
|
10082
|
-
if ( '' !== $target_context['intro'] ) {
|
|
10083
|
-
$parts[] = '<p>' . esc_html( $target_context['intro'] ) . '</p>';
|
|
10084
|
-
}
|
|
10085
10904
|
if ( ! empty( $target_context['showCount'] ) ) {
|
|
10086
10905
|
$parts[] = '<p><strong>' . esc_html__( 'Count', '{{textDomain}}' ) . ':</strong> ' . esc_html( (string) $target_context['webContext']['count'] ) . '</p>';
|
|
10087
10906
|
}
|
|
10088
|
-
$parts[] = wp_kses_post( $target_context['sanitizedContent'] );
|
|
10089
10907
|
$parts[] = '<p>' . esc_html( $target_context['noticeMessage'] ) . '</p>';
|
|
10090
10908
|
$parts[] = '</div>';
|
|
10091
10909
|
$markup = implode( '', $parts );
|
|
10092
10910
|
break;
|
|
10093
10911
|
case 'mjml':
|
|
10094
|
-
$markup = '<mjml><mj-body><mj-section><mj-column><mj-text
|
|
10095
|
-
if ( '' !== $target_context['intro'] ) {
|
|
10096
|
-
$markup .= '<mj-text>' . esc_html( $target_context['intro'] ) . '</mj-text>';
|
|
10097
|
-
}
|
|
10912
|
+
$markup = '<mjml><mj-body><mj-section><mj-column><mj-text align="' . esc_attr( $target_context['alignment'] ) . '">' . esc_html( $target_context['content'] ) . '</mj-text>';
|
|
10098
10913
|
if ( ! empty( $target_context['showCount'] ) ) {
|
|
10099
10914
|
$markup .= '<mj-text>' . esc_html__( 'Count', '{{textDomain}}' ) . ': ' . esc_html( (string) $target_context['webContext']['count'] ) . '</mj-text>';
|
|
10100
10915
|
}
|
|
10101
|
-
$markup .= '<mj-text>' . esc_html( wp_strip_all_tags( $target_context['sanitizedContent'] ) ) . '</mj-text>';
|
|
10102
10916
|
$markup .= '<mj-text>' . esc_html( $target_context['noticeMessage'] ) . '</mj-text></mj-column></mj-section></mj-body></mjml>';
|
|
10103
10917
|
break;
|
|
10104
10918
|
case 'plain-text':
|
|
@@ -10106,9 +10920,8 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
10106
10920
|
"\\n",
|
|
10107
10921
|
array_filter(
|
|
10108
10922
|
array(
|
|
10109
|
-
$target_context['
|
|
10110
|
-
$target_context['
|
|
10111
|
-
wp_strip_all_tags( $target_context['sanitizedContent'] ),
|
|
10923
|
+
$target_context['title'],
|
|
10924
|
+
$target_context['content'],
|
|
10112
10925
|
! empty( $target_context['showCount'] )
|
|
10113
10926
|
? sprintf( '%s: %s', __( 'Count', '{{textDomain}}' ), (string) $target_context['webContext']['count'] )
|
|
10114
10927
|
: null,
|
|
@@ -10122,58 +10935,54 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
10122
10935
|
default:
|
|
10123
10936
|
$wrapper_attributes = get_block_wrapper_attributes(
|
|
10124
10937
|
array(
|
|
10125
|
-
'class' => '{{cssClassName}}',
|
|
10126
|
-
'data-show-dividers' => $target_context['showDividers'] ? 'true' : 'false',
|
|
10127
10938
|
'data-wp-context' => wp_json_encode( $target_context['webContext'] ),
|
|
10128
|
-
'data-wp-init' => 'callbacks.init',
|
|
10129
10939
|
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
10940
|
+
'data-wp-init' => 'callbacks.init',
|
|
10130
10941
|
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
10131
10942
|
)
|
|
10132
10943
|
);
|
|
10133
10944
|
ob_start();
|
|
10134
10945
|
?>
|
|
10135
10946
|
<div <?php echo $wrapper_attributes; ?>>
|
|
10136
|
-
<
|
|
10137
|
-
|
|
10138
|
-
|
|
10139
|
-
|
|
10140
|
-
|
|
10141
|
-
|
|
10142
|
-
|
|
10143
|
-
|
|
10144
|
-
|
|
10145
|
-
|
|
10146
|
-
|
|
10147
|
-
|
|
10148
|
-
|
|
10149
|
-
|
|
10150
|
-
|
|
10151
|
-
|
|
10152
|
-
|
|
10153
|
-
|
|
10154
|
-
|
|
10155
|
-
|
|
10156
|
-
|
|
10157
|
-
<div class="{{cssClassName}}__counter">
|
|
10947
|
+
<div class="{{frontendCssClassName}}">
|
|
10948
|
+
<p class="{{frontendCssClassName}}__content" style="<?php echo esc_attr( 'text-align:' . $target_context['alignment'] ); ?>">
|
|
10949
|
+
<?php echo esc_html( $target_context['content'] ); ?>
|
|
10950
|
+
</p>
|
|
10951
|
+
<p
|
|
10952
|
+
class="{{frontendCssClassName}}__notice"
|
|
10953
|
+
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
10954
|
+
hidden
|
|
10955
|
+
>
|
|
10956
|
+
<?php echo esc_html( $target_context['noticeMessage'] ); ?>
|
|
10957
|
+
</p>
|
|
10958
|
+
<p
|
|
10959
|
+
class="{{frontendCssClassName}}__error"
|
|
10960
|
+
role="status"
|
|
10961
|
+
aria-live="polite"
|
|
10962
|
+
aria-atomic="true"
|
|
10963
|
+
data-wp-bind--hidden="!context.error"
|
|
10964
|
+
data-wp-text="context.error"
|
|
10965
|
+
hidden
|
|
10966
|
+
></p>
|
|
10967
|
+
<?php if ( ! empty( $target_context['showCount'] ) ) : ?>
|
|
10158
10968
|
<span
|
|
10159
|
-
class="{{
|
|
10969
|
+
class="{{frontendCssClassName}}__count"
|
|
10160
10970
|
role="status"
|
|
10161
10971
|
aria-live="polite"
|
|
10162
10972
|
aria-atomic="true"
|
|
10163
|
-
data-wp-text="context.count"
|
|
10164
|
-
>
|
|
10165
|
-
|
|
10166
|
-
|
|
10167
|
-
|
|
10168
|
-
|
|
10169
|
-
|
|
10170
|
-
|
|
10171
|
-
|
|
10172
|
-
|
|
10173
|
-
|
|
10174
|
-
|
|
10175
|
-
|
|
10176
|
-
<?php echo wp_kses_post( $target_context['sanitizedContent'] ); ?>
|
|
10973
|
+
data-wp-text="context.count"
|
|
10974
|
+
>
|
|
10975
|
+
0
|
|
10976
|
+
</span>
|
|
10977
|
+
<?php endif; ?>
|
|
10978
|
+
<button
|
|
10979
|
+
type="button"
|
|
10980
|
+
disabled
|
|
10981
|
+
data-wp-bind--disabled="!context.canWrite"
|
|
10982
|
+
data-wp-on--click="actions.increment"
|
|
10983
|
+
>
|
|
10984
|
+
<?php echo esc_html( $target_context['buttonLabel'] ); ?>
|
|
10985
|
+
</button>
|
|
10177
10986
|
</div>
|
|
10178
10987
|
</div>
|
|
10179
10988
|
<?php
|
|
@@ -10190,51 +10999,8 @@ if ( ! function_exists( '{{phpPrefix}}_{{slugSnakeCase}}_render_target' ) ) {
|
|
|
10190
10999
|
}
|
|
10191
11000
|
}
|
|
10192
11001
|
`;
|
|
10193
|
-
var COMPOUND_STYLE_TEMPLATE = `.{{cssClassName}} {
|
|
10194
|
-
border: 1px solid #dcdcde;
|
|
10195
|
-
border-radius: 12px;
|
|
10196
|
-
padding: 1.25rem;
|
|
10197
|
-
background: #fff;
|
|
10198
|
-
}
|
|
10199
|
-
|
|
10200
|
-
.{{cssClassName}}__heading {
|
|
10201
|
-
margin: 0 0 0.5rem;
|
|
10202
|
-
font-size: 1.2rem;
|
|
10203
|
-
}
|
|
10204
|
-
|
|
10205
|
-
.{{cssClassName}}__intro {
|
|
10206
|
-
margin: 0 0 1rem;
|
|
10207
|
-
color: #50575e;
|
|
10208
|
-
}
|
|
10209
|
-
|
|
10210
|
-
.{{cssClassName}}__items {
|
|
10211
|
-
display: grid;
|
|
10212
|
-
gap: 0.75rem;
|
|
10213
|
-
}
|
|
10214
|
-
|
|
10215
|
-
.{{cssClassName}}[data-show-dividers='true'] .{{compoundChildCssClassName}} {
|
|
10216
|
-
border-top: 1px solid #dcdcde;
|
|
10217
|
-
padding-top: 0.75rem;
|
|
10218
|
-
}
|
|
10219
11002
|
|
|
10220
|
-
|
|
10221
|
-
border-top: 0;
|
|
10222
|
-
padding-top: 0;
|
|
10223
|
-
}
|
|
10224
|
-
`;
|
|
10225
|
-
function buildBasicArtifacts(variables) {
|
|
10226
|
-
return [
|
|
10227
|
-
renderArtifact("src/editor.scss", BASIC_EDITOR_STYLE_TEMPLATE, variables),
|
|
10228
|
-
renderArtifact("src/style.scss", BASIC_STYLE_TEMPLATE, variables),
|
|
10229
|
-
renderArtifact("src/render.php", BASIC_RENDER_TEMPLATE, variables)
|
|
10230
|
-
];
|
|
10231
|
-
}
|
|
10232
|
-
function buildInteractivityArtifacts(variables) {
|
|
10233
|
-
return [
|
|
10234
|
-
renderArtifact("src/editor.scss", INTERACTIVITY_EDITOR_STYLE_TEMPLATE, variables),
|
|
10235
|
-
renderArtifact("src/style.scss", INTERACTIVITY_STYLE_TEMPLATE, variables)
|
|
10236
|
-
];
|
|
10237
|
-
}
|
|
11003
|
+
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-persistence-artifacts.ts
|
|
10238
11004
|
function buildPersistenceArtifacts(variables) {
|
|
10239
11005
|
const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
|
|
10240
11006
|
if (!alternateRenderTargets.enabled) {
|
|
@@ -10259,187 +11025,6 @@ function buildPersistenceArtifacts(variables) {
|
|
|
10259
11025
|
}
|
|
10260
11026
|
return artifacts;
|
|
10261
11027
|
}
|
|
10262
|
-
function buildCompoundArtifacts(variables) {
|
|
10263
|
-
const alternateRenderTargets = getScaffoldAlternateRenderTargets(variables);
|
|
10264
|
-
const artifacts = [
|
|
10265
|
-
renderArtifact(`src/blocks/${variables.slugKebabCase}/style.scss`, COMPOUND_STYLE_TEMPLATE, variables)
|
|
10266
|
-
];
|
|
10267
|
-
if (isCompoundPersistenceEnabled(variables)) {
|
|
10268
|
-
const renderView = {
|
|
10269
|
-
...variables,
|
|
10270
|
-
titlePhpLiteral: toPhpSingleQuotedString(variables.title)
|
|
10271
|
-
};
|
|
10272
|
-
if (alternateRenderTargets.enabled) {
|
|
10273
|
-
artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render-targets.php`, COMPOUND_PERSISTENCE_RENDER_TARGETS_TEMPLATE, renderView), buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, "web", variables));
|
|
10274
|
-
if (alternateRenderTargets.hasEmail) {
|
|
10275
|
-
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-email.php`, "email", variables));
|
|
10276
|
-
}
|
|
10277
|
-
if (alternateRenderTargets.hasMjml) {
|
|
10278
|
-
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-mjml.php`, "mjml", variables));
|
|
10279
|
-
}
|
|
10280
|
-
if (alternateRenderTargets.hasPlainText) {
|
|
10281
|
-
artifacts.push(buildAlternateRenderEntryArtifact(`src/blocks/${variables.slugKebabCase}/render-text.php`, "plain-text", variables));
|
|
10282
|
-
}
|
|
10283
|
-
return artifacts;
|
|
10284
|
-
}
|
|
10285
|
-
const renderSource = `<?php
|
|
10286
|
-
/**
|
|
10287
|
-
* Dynamic render entry for the {{title}} compound parent block.
|
|
10288
|
-
*
|
|
10289
|
-
* @package {{pascalCase}}
|
|
10290
|
-
*/
|
|
10291
|
-
|
|
10292
|
-
if ( ! defined( 'ABSPATH' ) ) {
|
|
10293
|
-
exit;
|
|
10294
|
-
}
|
|
10295
|
-
|
|
10296
|
-
$validator_path = __DIR__ . '/typia-validator.php';
|
|
10297
|
-
if ( ! file_exists( $validator_path ) ) {
|
|
10298
|
-
return '';
|
|
10299
|
-
}
|
|
10300
|
-
|
|
10301
|
-
$validator = require $validator_path;
|
|
10302
|
-
if ( ! is_object( $validator ) || ! method_exists( $validator, 'apply_defaults' ) || ! method_exists( $validator, 'validate' ) ) {
|
|
10303
|
-
return '';
|
|
10304
|
-
}
|
|
10305
|
-
|
|
10306
|
-
$normalized = $validator->apply_defaults( is_array( $attributes ) ? $attributes : array() );
|
|
10307
|
-
$validation = $validator->validate( $normalized );
|
|
10308
|
-
$resource_key = isset( $normalized['resourceKey'] ) ? (string) $normalized['resourceKey'] : '';
|
|
10309
|
-
$heading = isset( $normalized['heading'] ) ? (string) $normalized['heading'] : {{titlePhpLiteral}};
|
|
10310
|
-
$intro = isset( $normalized['intro'] ) ? (string) $normalized['intro'] : '';
|
|
10311
|
-
$button_label = isset( $normalized['buttonLabel'] ) ? (string) $normalized['buttonLabel'] : 'Persist Count';
|
|
10312
|
-
$show_count = ! empty( $normalized['showCount'] );
|
|
10313
|
-
$show_dividers = ! empty( $normalized['showDividers'] );
|
|
10314
|
-
$post_id = is_object( $block ) && isset( $block->context['postId'] )
|
|
10315
|
-
? (int) $block->context['postId']
|
|
10316
|
-
: (int) get_queried_object_id();
|
|
10317
|
-
$storage_mode = '{{dataStorageMode}}';
|
|
10318
|
-
$persistence_policy = '{{persistencePolicy}}';
|
|
10319
|
-
|
|
10320
|
-
$notice_message = 'authenticated' === $persistence_policy
|
|
10321
|
-
? __( 'Sign in to persist this counter.', '{{textDomain}}' )
|
|
10322
|
-
: __( 'Public writes are temporarily unavailable.', '{{textDomain}}' );
|
|
10323
|
-
|
|
10324
|
-
if ( empty( $validation['valid'] ) || '' === $resource_key ) {
|
|
10325
|
-
return '';
|
|
10326
|
-
}
|
|
10327
|
-
|
|
10328
|
-
{{phpPrefix}}_record_rendered_block_instance(
|
|
10329
|
-
(int) $post_id,
|
|
10330
|
-
'{{namespace}}/{{slugKebabCase}}',
|
|
10331
|
-
$resource_key
|
|
10332
|
-
);
|
|
10333
|
-
|
|
10334
|
-
$context = array(
|
|
10335
|
-
'bootstrapReady' => false,
|
|
10336
|
-
'buttonLabel' => $button_label,
|
|
10337
|
-
'canWrite' => false,
|
|
10338
|
-
'client' => array(
|
|
10339
|
-
'writeExpiry' => 0,
|
|
10340
|
-
'writeNonce' => '',
|
|
10341
|
-
'writeToken' => '',
|
|
10342
|
-
),
|
|
10343
|
-
'count' => 0,
|
|
10344
|
-
'error' => '',
|
|
10345
|
-
'isBootstrapping' => false,
|
|
10346
|
-
'isLoading' => false,
|
|
10347
|
-
'isSaving' => false,
|
|
10348
|
-
'persistencePolicy' => $persistence_policy,
|
|
10349
|
-
'postId' => (int) $post_id,
|
|
10350
|
-
'resourceKey' => $resource_key,
|
|
10351
|
-
'showCount' => $show_count,
|
|
10352
|
-
'storage' => $storage_mode,
|
|
10353
|
-
);
|
|
10354
|
-
|
|
10355
|
-
$allowed_inner_html = wp_kses_allowed_html( 'post' );
|
|
10356
|
-
|
|
10357
|
-
foreach ( $allowed_inner_html as &$allowed_attributes ) {
|
|
10358
|
-
if ( ! is_array( $allowed_attributes ) ) {
|
|
10359
|
-
continue;
|
|
10360
|
-
}
|
|
10361
|
-
|
|
10362
|
-
$allowed_attributes['data-wp-bind--disabled'] = true;
|
|
10363
|
-
$allowed_attributes['data-wp-bind--hidden'] = true;
|
|
10364
|
-
$allowed_attributes['data-wp-bind--value'] = true;
|
|
10365
|
-
$allowed_attributes['data-wp-class'] = true;
|
|
10366
|
-
$allowed_attributes['data-wp-class--active'] = true;
|
|
10367
|
-
$allowed_attributes['data-wp-context'] = true;
|
|
10368
|
-
$allowed_attributes['data-wp-init'] = true;
|
|
10369
|
-
$allowed_attributes['data-wp-interactive'] = true;
|
|
10370
|
-
$allowed_attributes['data-wp-on--click'] = true;
|
|
10371
|
-
$allowed_attributes['data-wp-on--mouseenter'] = true;
|
|
10372
|
-
$allowed_attributes['data-wp-on--mouseleave'] = true;
|
|
10373
|
-
$allowed_attributes['data-wp-run--mounted'] = true;
|
|
10374
|
-
$allowed_attributes['data-wp-style--width'] = true;
|
|
10375
|
-
$allowed_attributes['data-wp-text'] = true;
|
|
10376
|
-
}
|
|
10377
|
-
unset( $allowed_attributes );
|
|
10378
|
-
|
|
10379
|
-
$sanitized_content = wp_kses( $content, $allowed_inner_html );
|
|
10380
|
-
|
|
10381
|
-
$wrapper_attributes = get_block_wrapper_attributes(
|
|
10382
|
-
array(
|
|
10383
|
-
'class' => '{{cssClassName}}',
|
|
10384
|
-
'data-show-dividers' => $show_dividers ? 'true' : 'false',
|
|
10385
|
-
'data-wp-context' => wp_json_encode( $context ),
|
|
10386
|
-
'data-wp-init' => 'callbacks.init',
|
|
10387
|
-
'data-wp-interactive' => '{{slugKebabCase}}',
|
|
10388
|
-
'data-wp-run--mounted' => 'callbacks.mounted',
|
|
10389
|
-
)
|
|
10390
|
-
);
|
|
10391
|
-
?>
|
|
10392
|
-
|
|
10393
|
-
<div <?php echo $wrapper_attributes; ?>>
|
|
10394
|
-
<h3 class="{{cssClassName}}__heading"><?php echo esc_html( $heading ); ?></h3>
|
|
10395
|
-
<?php if ( '' !== $intro ) : ?>
|
|
10396
|
-
<p class="{{cssClassName}}__intro"><?php echo esc_html( $intro ); ?></p>
|
|
10397
|
-
<?php endif; ?>
|
|
10398
|
-
<p
|
|
10399
|
-
class="{{cssClassName}}__notice"
|
|
10400
|
-
data-wp-bind--hidden="!context.bootstrapReady || context.canWrite"
|
|
10401
|
-
hidden
|
|
10402
|
-
>
|
|
10403
|
-
<?php echo esc_html( $notice_message ); ?>
|
|
10404
|
-
</p>
|
|
10405
|
-
<p
|
|
10406
|
-
class="{{cssClassName}}__error"
|
|
10407
|
-
role="status"
|
|
10408
|
-
aria-live="polite"
|
|
10409
|
-
aria-atomic="true"
|
|
10410
|
-
data-wp-bind--hidden="!context.error"
|
|
10411
|
-
data-wp-text="context.error"
|
|
10412
|
-
hidden
|
|
10413
|
-
></p>
|
|
10414
|
-
<?php if ( $show_count ) : ?>
|
|
10415
|
-
<div class="{{cssClassName}}__counter">
|
|
10416
|
-
<span
|
|
10417
|
-
class="{{cssClassName}}__count"
|
|
10418
|
-
role="status"
|
|
10419
|
-
aria-live="polite"
|
|
10420
|
-
aria-atomic="true"
|
|
10421
|
-
data-wp-text="context.count"
|
|
10422
|
-
>0</span>
|
|
10423
|
-
<button
|
|
10424
|
-
type="button"
|
|
10425
|
-
disabled
|
|
10426
|
-
data-wp-bind--disabled="!context.canWrite"
|
|
10427
|
-
data-wp-on--click="actions.increment"
|
|
10428
|
-
>
|
|
10429
|
-
<?php echo esc_html( $button_label ); ?>
|
|
10430
|
-
</button>
|
|
10431
|
-
</div>
|
|
10432
|
-
<?php endif; ?>
|
|
10433
|
-
<div class="{{cssClassName}}__items">
|
|
10434
|
-
<?php echo $sanitized_content; ?>
|
|
10435
|
-
</div>
|
|
10436
|
-
</div>
|
|
10437
|
-
`;
|
|
10438
|
-
artifacts.push(renderArtifact(`src/blocks/${variables.slugKebabCase}/render.php`, renderSource, renderView));
|
|
10439
|
-
}
|
|
10440
|
-
return artifacts;
|
|
10441
|
-
}
|
|
10442
|
-
|
|
10443
11028
|
// ../wp-typia-project-tools/src/runtime/built-in-block-non-ts-artifacts.ts
|
|
10444
11029
|
function buildBuiltInNonTsArtifacts({
|
|
10445
11030
|
templateId,
|
|
@@ -13642,7 +14227,8 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13642
14227
|
blockRuntimePackageVersion,
|
|
13643
14228
|
blockTypesPackageVersion,
|
|
13644
14229
|
projectToolsPackageVersion,
|
|
13645
|
-
restPackageVersion
|
|
14230
|
+
restPackageVersion,
|
|
14231
|
+
wpTypiaPackageVersion
|
|
13646
14232
|
} = getPackageVersions();
|
|
13647
14233
|
const template = isBuiltInTemplateId(templateId) ? getTemplateById(templateId) : null;
|
|
13648
14234
|
const metadataDefaults = isBuiltInTemplateId(templateId) ? getBuiltInTemplateMetadataDefaults(templateId) : null;
|
|
@@ -13698,6 +14284,7 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13698
14284
|
hasAlternatePlainTextRenderTarget: "false",
|
|
13699
14285
|
hasAlternateRenderTargets: "false",
|
|
13700
14286
|
projectToolsPackageVersion,
|
|
14287
|
+
wpTypiaPackageVersion,
|
|
13701
14288
|
requiresAtLeast: compatibility.pluginHeader.requiresAtLeast,
|
|
13702
14289
|
requiresPhp: compatibility.pluginHeader.requiresPhp,
|
|
13703
14290
|
cssClassName,
|
|
@@ -13801,15 +14388,55 @@ function getTemplateVariables(templateId, answers) {
|
|
|
13801
14388
|
// ../wp-typia-project-tools/src/runtime/scaffold.ts
|
|
13802
14389
|
var DATA_STORAGE_MODES = ["post-meta", "custom-table"];
|
|
13803
14390
|
var PERSISTENCE_POLICIES = ["authenticated", "public"];
|
|
14391
|
+
var CREATE_PROFILE_IDS = ["plugin-qa"];
|
|
13804
14392
|
function isDataStorageMode(value) {
|
|
13805
14393
|
return DATA_STORAGE_MODES.includes(value);
|
|
13806
14394
|
}
|
|
13807
14395
|
function isPersistencePolicy(value) {
|
|
13808
14396
|
return PERSISTENCE_POLICIES.includes(value);
|
|
13809
14397
|
}
|
|
14398
|
+
function isCreateProfileId(value) {
|
|
14399
|
+
return CREATE_PROFILE_IDS.includes(value);
|
|
14400
|
+
}
|
|
14401
|
+
function resolveCreateProfileId(profile) {
|
|
14402
|
+
if (profile === undefined || profile.trim().length === 0) {
|
|
14403
|
+
return;
|
|
14404
|
+
}
|
|
14405
|
+
const normalizedProfile = profile.trim();
|
|
14406
|
+
if (isCreateProfileId(normalizedProfile)) {
|
|
14407
|
+
return normalizedProfile;
|
|
14408
|
+
}
|
|
14409
|
+
throw new Error(`Unknown create profile "${profile}". Expected one of: ${CREATE_PROFILE_IDS.join(", ")}.`);
|
|
14410
|
+
}
|
|
13810
14411
|
function normalizeTemplateSelection(templateId) {
|
|
13811
14412
|
return normalizeTemplateLookupId(templateId);
|
|
13812
14413
|
}
|
|
14414
|
+
function assertCreateProfileTemplateCompatibility({
|
|
14415
|
+
profile,
|
|
14416
|
+
templateId
|
|
14417
|
+
}) {
|
|
14418
|
+
if (!profile) {
|
|
14419
|
+
return;
|
|
14420
|
+
}
|
|
14421
|
+
if (profile === "plugin-qa" && templateId !== OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE) {
|
|
14422
|
+
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`.");
|
|
14423
|
+
}
|
|
14424
|
+
}
|
|
14425
|
+
async function applyCreateProfile({
|
|
14426
|
+
profile,
|
|
14427
|
+
projectDir
|
|
14428
|
+
}) {
|
|
14429
|
+
if (profile !== "plugin-qa") {
|
|
14430
|
+
return;
|
|
14431
|
+
}
|
|
14432
|
+
await runAddIntegrationEnvCommand({
|
|
14433
|
+
cwd: projectDir,
|
|
14434
|
+
integrationEnvName: "local-smoke",
|
|
14435
|
+
service: "none",
|
|
14436
|
+
withReleaseZip: true,
|
|
14437
|
+
withWpEnv: true
|
|
14438
|
+
});
|
|
14439
|
+
}
|
|
13813
14440
|
async function reportScaffoldProgress2(onProgress, event) {
|
|
13814
14441
|
await onProgress?.(event);
|
|
13815
14442
|
}
|
|
@@ -13824,6 +14451,7 @@ async function scaffoldProject({
|
|
|
13824
14451
|
externalLayerId,
|
|
13825
14452
|
externalLayerSource,
|
|
13826
14453
|
externalLayerSourceLabel,
|
|
14454
|
+
profile,
|
|
13827
14455
|
repositoryReference,
|
|
13828
14456
|
cwd = process.cwd(),
|
|
13829
14457
|
allowExistingDir = false,
|
|
@@ -13838,6 +14466,10 @@ async function scaffoldProject({
|
|
|
13838
14466
|
const resolvedTemplateId = normalizeTemplateSelection(templateId);
|
|
13839
14467
|
const resolvedPackageManager = getPackageManager(packageManager).id;
|
|
13840
14468
|
const isBuiltInTemplate = isBuiltInTemplateId(resolvedTemplateId);
|
|
14469
|
+
assertCreateProfileTemplateCompatibility({
|
|
14470
|
+
profile,
|
|
14471
|
+
templateId: resolvedTemplateId
|
|
14472
|
+
});
|
|
13841
14473
|
assertExternalLayerCompositionOptions({
|
|
13842
14474
|
externalLayerId,
|
|
13843
14475
|
externalLayerSource
|
|
@@ -13946,17 +14578,17 @@ async function scaffoldProject({
|
|
|
13946
14578
|
phase: "finalize-project",
|
|
13947
14579
|
title: "Finalizing scaffold output"
|
|
13948
14580
|
});
|
|
13949
|
-
const readmePath =
|
|
14581
|
+
const readmePath = path20.join(projectDir, "README.md");
|
|
13950
14582
|
if (!await pathExists(readmePath)) {
|
|
13951
|
-
await
|
|
14583
|
+
await fsp14.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
|
|
13952
14584
|
withMigrationUi: isBuiltInTemplate || isWorkspace ? withMigrationUi : false,
|
|
13953
14585
|
withTestPreset: isBuiltInTemplate ? withTestPreset : false,
|
|
13954
14586
|
withWpEnv: isBuiltInTemplate ? withWpEnv : false
|
|
13955
14587
|
}), "utf8");
|
|
13956
14588
|
}
|
|
13957
|
-
const gitignorePath =
|
|
13958
|
-
const existingGitignore = await pathExists(gitignorePath) ? await
|
|
13959
|
-
await
|
|
14589
|
+
const gitignorePath = path20.join(projectDir, ".gitignore");
|
|
14590
|
+
const existingGitignore = await pathExists(gitignorePath) ? await fsp14.readFile(gitignorePath, "utf8") : "";
|
|
14591
|
+
await fsp14.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
|
|
13960
14592
|
await normalizePackageJson(projectDir, resolvedPackageManager);
|
|
13961
14593
|
if (isBuiltInTemplate) {
|
|
13962
14594
|
const variableGroups = getScaffoldTemplateVariableGroups(variables);
|
|
@@ -13969,6 +14601,10 @@ async function scaffoldProject({
|
|
|
13969
14601
|
withWpEnv
|
|
13970
14602
|
});
|
|
13971
14603
|
}
|
|
14604
|
+
await applyCreateProfile({
|
|
14605
|
+
profile,
|
|
14606
|
+
projectDir
|
|
14607
|
+
});
|
|
13972
14608
|
await normalizePackageManagerFiles(projectDir, resolvedPackageManager);
|
|
13973
14609
|
await removeUnexpectedLockfiles(projectDir, resolvedPackageManager);
|
|
13974
14610
|
await replaceTextRecursively(projectDir, resolvedPackageManager, {
|
|
@@ -14036,6 +14672,6 @@ async function resolveOptionalInteractiveExternalLayerId({
|
|
|
14036
14672
|
}
|
|
14037
14673
|
}
|
|
14038
14674
|
|
|
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 };
|
|
14675
|
+
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
14676
|
|
|
14041
|
-
//# debugId=
|
|
14677
|
+
//# debugId=5D6C751C245E365E64756E2164756E21
|