wp-typia 0.22.5 → 0.22.7
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 +7 -0
- package/bin/wp-typia.js +83 -0
- package/dist-bunli/.bunli/commands.gen.js +2000 -1256
- package/dist-bunli/{cli-xbzfx7qz.js → cli-27v2qpjg.js} +4 -4
- package/dist-bunli/{cli-1sm60g1z.js → cli-2hsp17nd.js} +2 -2
- package/dist-bunli/{cli-hb9vpsev.js → cli-2rqf6t0b.js} +1 -1
- package/dist-bunli/{cli-6bhfzq5e.js → cli-52ke0ptp.js} +2 -2
- package/dist-bunli/{cli-ctddkm3n.js → cli-8snabymq.js} +405 -204
- package/dist-bunli/{cli-add-1gqgshf0.js → cli-add-8jpdnz1r.js} +85 -64
- package/dist-bunli/{cli-nzwpmw4y.js → cli-cjygr56g.js} +98 -32
- package/dist-bunli/{cli-doctor-w35s8y9w.js → cli-doctor-h5tq4ztr.js} +15 -18
- package/dist-bunli/cli-fys8vm2t.js +20 -0
- package/dist-bunli/{cli-btbpt84c.js → cli-hhp1d348.js} +1 -1
- package/dist-bunli/{cli-init-z8sjmkvc.js → cli-init-w9p558th.js} +414 -393
- package/dist-bunli/{cli-scaffold-ad3bd555.js → cli-scaffold-qve8rqja.js} +9 -8
- package/dist-bunli/{cli-j30rk466.js → cli-ta3y0hp2.js} +697 -298
- package/dist-bunli/cli.js +8 -6
- package/dist-bunli/{command-list-scd6zqp8.js → command-list-6zr1tj96.js} +16 -12
- package/dist-bunli/{migrations-skkzdvhm.js → migrations-v0avgyg6.js} +7 -6
- package/dist-bunli/node-cli.js +253 -97
- package/dist-bunli/{workspace-project-7826tewa.js → workspace-project-csnnggz6.js} +2 -2
- package/package.json +2 -2
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
// @bun
|
|
2
2
|
import {
|
|
3
3
|
getPackageVersions
|
|
4
|
-
} from "./cli-
|
|
4
|
+
} from "./cli-2hsp17nd.js";
|
|
5
5
|
import {
|
|
6
6
|
seedProjectMigrations
|
|
7
|
-
} from "./cli-
|
|
7
|
+
} from "./cli-27v2qpjg.js";
|
|
8
8
|
import {
|
|
9
9
|
ensureMigrationDirectories,
|
|
10
10
|
isPlainObject,
|
|
11
11
|
stableJsonStringify,
|
|
12
12
|
writeInitialMigrationScaffold,
|
|
13
13
|
writeMigrationConfig
|
|
14
|
-
} from "./cli-
|
|
14
|
+
} from "./cli-2rqf6t0b.js";
|
|
15
15
|
import {
|
|
16
16
|
getBuiltInSharedTemplateLayerDir,
|
|
17
17
|
getBuiltInTemplateLayerDirs,
|
|
@@ -44,6 +44,8 @@ import {
|
|
|
44
44
|
buildBlockCssClassName,
|
|
45
45
|
buildFrontendCssClassName,
|
|
46
46
|
normalizeBlockSlug,
|
|
47
|
+
pathExists,
|
|
48
|
+
readOptionalUtf8File,
|
|
47
49
|
resolveScaffoldIdentifiers,
|
|
48
50
|
toPascalCase,
|
|
49
51
|
toSegmentPascalCase,
|
|
@@ -51,7 +53,7 @@ import {
|
|
|
51
53
|
toTitleCase,
|
|
52
54
|
validateBlockSlug,
|
|
53
55
|
validateNamespace
|
|
54
|
-
} from "./cli-
|
|
56
|
+
} from "./cli-ta3y0hp2.js";
|
|
55
57
|
import {
|
|
56
58
|
createManagedTempRoot
|
|
57
59
|
} from "./cli-t73q5aqz.js";
|
|
@@ -66,7 +68,7 @@ import {
|
|
|
66
68
|
formatRunScript,
|
|
67
69
|
getPackageManager,
|
|
68
70
|
transformPackageManagerText
|
|
69
|
-
} from "./cli-
|
|
71
|
+
} from "./cli-52ke0ptp.js";
|
|
70
72
|
import {
|
|
71
73
|
__commonJS,
|
|
72
74
|
__require,
|
|
@@ -5682,10 +5684,7 @@ function stringifyStarterManifest(document) {
|
|
|
5682
5684
|
// ../wp-typia-project-tools/src/runtime/scaffold-bootstrap.ts
|
|
5683
5685
|
var EPHEMERAL_NODE_MODULES_LINK_TYPE = process.platform === "win32" ? "junction" : "dir";
|
|
5684
5686
|
async function ensureScaffoldDirectory(targetDir, allowExisting = false) {
|
|
5685
|
-
|
|
5686
|
-
await fsp3.mkdir(targetDir, { recursive: true });
|
|
5687
|
-
return;
|
|
5688
|
-
}
|
|
5687
|
+
await fsp3.mkdir(targetDir, { recursive: true });
|
|
5689
5688
|
if (allowExisting) {
|
|
5690
5689
|
return;
|
|
5691
5690
|
}
|
|
@@ -5767,14 +5766,14 @@ async function applyWorkspaceMigrationCapability(projectDir, packageManager) {
|
|
|
5767
5766
|
ensureMigrationDirectories(projectDir, []);
|
|
5768
5767
|
writeInitialMigrationScaffold(projectDir, "v1", []);
|
|
5769
5768
|
}
|
|
5770
|
-
function resolveScaffoldGeneratorNodeModulesPath() {
|
|
5769
|
+
async function resolveScaffoldGeneratorNodeModulesPath() {
|
|
5771
5770
|
const candidates = [
|
|
5772
5771
|
path4.join(PROJECT_TOOLS_PACKAGE_ROOT, "node_modules"),
|
|
5773
5772
|
path4.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", ".."),
|
|
5774
5773
|
path4.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..", "..", "node_modules")
|
|
5775
5774
|
];
|
|
5776
5775
|
for (const candidate of candidates) {
|
|
5777
|
-
if (
|
|
5776
|
+
if (await pathExists(path4.join(candidate, "typia", "package.json"))) {
|
|
5778
5777
|
return candidate;
|
|
5779
5778
|
}
|
|
5780
5779
|
}
|
|
@@ -5782,11 +5781,11 @@ function resolveScaffoldGeneratorNodeModulesPath() {
|
|
|
5782
5781
|
}
|
|
5783
5782
|
async function withEphemeralScaffoldNodeModules(targetDir, callback) {
|
|
5784
5783
|
const targetNodeModulesPath = path4.join(targetDir, "node_modules");
|
|
5785
|
-
if (
|
|
5784
|
+
if (await pathExists(targetNodeModulesPath)) {
|
|
5786
5785
|
await callback();
|
|
5787
5786
|
return;
|
|
5788
5787
|
}
|
|
5789
|
-
const sourceNodeModulesPath = resolveScaffoldGeneratorNodeModulesPath();
|
|
5788
|
+
const sourceNodeModulesPath = await resolveScaffoldGeneratorNodeModulesPath();
|
|
5790
5789
|
if (!sourceNodeModulesPath) {
|
|
5791
5790
|
throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
|
|
5792
5791
|
}
|
|
@@ -6219,12 +6218,11 @@ async function collectScaffoldAnswers({
|
|
|
6219
6218
|
}
|
|
6220
6219
|
|
|
6221
6220
|
// ../wp-typia-project-tools/src/runtime/scaffold.ts
|
|
6222
|
-
import
|
|
6223
|
-
import { promises as
|
|
6221
|
+
import fs12 from "fs";
|
|
6222
|
+
import { promises as fsp12 } from "fs";
|
|
6224
6223
|
import path18 from "path";
|
|
6225
6224
|
|
|
6226
6225
|
// ../wp-typia-project-tools/src/runtime/scaffold-apply-utils.ts
|
|
6227
|
-
import fs6 from "fs";
|
|
6228
6226
|
import { promises as fsp6 } from "fs";
|
|
6229
6227
|
import path11 from "path";
|
|
6230
6228
|
import { execSync as execSync3 } from "child_process";
|
|
@@ -6458,6 +6456,18 @@ function formatReadmeTemplateIdentity(templateId) {
|
|
|
6458
6456
|
return [`- Template id: ${templateId}`, "- Type: custom or external scaffold"].join(`
|
|
6459
6457
|
`);
|
|
6460
6458
|
}
|
|
6459
|
+
function getPackageManagerInstallGuidance(packageManager) {
|
|
6460
|
+
if (packageManager !== "npm") {
|
|
6461
|
+
return "";
|
|
6462
|
+
}
|
|
6463
|
+
const installCommand = formatInstallCommand(packageManager);
|
|
6464
|
+
return [
|
|
6465
|
+
"",
|
|
6466
|
+
`> npm note: the scaffold uses \`${installCommand}\` for the first install so npm does not spend the initial create flow in the audit resolver. Run \`npm audit\` separately when you want npm vulnerability output.`,
|
|
6467
|
+
"> If npm prints React peer dependency noise from WordPress block-editor packages, validate with `npm run typecheck` and `npm run build` before changing WordPress package ranges."
|
|
6468
|
+
].join(`
|
|
6469
|
+
`);
|
|
6470
|
+
}
|
|
6461
6471
|
function buildReadme(templateId, variables, packageManager, {
|
|
6462
6472
|
withMigrationUi = false,
|
|
6463
6473
|
withTestPreset = false,
|
|
@@ -6552,6 +6562,7 @@ ${formatReadmeTemplateIdentity(templateId)}
|
|
|
6552
6562
|
${formatInstallCommand(packageManager)}
|
|
6553
6563
|
${formatRunScript(packageManager, developmentScript)}
|
|
6554
6564
|
\`\`\`
|
|
6565
|
+
${getPackageManagerInstallGuidance(packageManager)}
|
|
6555
6566
|
|
|
6556
6567
|
${getQuickStartWorkflowNote(packageManager, templateId, {
|
|
6557
6568
|
compoundPersistenceEnabled
|
|
@@ -6647,7 +6658,6 @@ function mergeTextLines(primaryContent, existingContent) {
|
|
|
6647
6658
|
}
|
|
6648
6659
|
|
|
6649
6660
|
// ../wp-typia-project-tools/src/runtime/scaffold-package-manager-files.ts
|
|
6650
|
-
import fs4 from "fs";
|
|
6651
6661
|
import { promises as fsp5 } from "fs";
|
|
6652
6662
|
import { execSync as execSync2 } from "child_process";
|
|
6653
6663
|
import path9 from "path";
|
|
@@ -6668,11 +6678,12 @@ async function normalizePackageManagerFiles(targetDir, packageManagerId) {
|
|
|
6668
6678
|
}
|
|
6669
6679
|
async function normalizePackageJson(targetDir, packageManagerId) {
|
|
6670
6680
|
const packageJsonPath = path9.join(targetDir, "package.json");
|
|
6671
|
-
|
|
6681
|
+
const packageJsonSource = await readOptionalUtf8File(packageJsonPath);
|
|
6682
|
+
if (packageJsonSource === null) {
|
|
6672
6683
|
return;
|
|
6673
6684
|
}
|
|
6674
6685
|
const packageManager = getPackageManager(packageManagerId);
|
|
6675
|
-
const packageJson = JSON.parse(
|
|
6686
|
+
const packageJson = JSON.parse(packageJsonSource);
|
|
6676
6687
|
if (packageManagerId === "npm") {
|
|
6677
6688
|
delete packageJson.packageManager;
|
|
6678
6689
|
} else {
|
|
@@ -6708,7 +6719,7 @@ async function defaultInstallDependencies({
|
|
|
6708
6719
|
});
|
|
6709
6720
|
}
|
|
6710
6721
|
// ../wp-typia-project-tools/src/runtime/scaffold-repository-reference.ts
|
|
6711
|
-
import
|
|
6722
|
+
import fs4 from "fs";
|
|
6712
6723
|
import { createRequire } from "module";
|
|
6713
6724
|
import path10 from "path";
|
|
6714
6725
|
var require2 = createRequire(import.meta.url);
|
|
@@ -6718,7 +6729,7 @@ function getErrorCode(error) {
|
|
|
6718
6729
|
}
|
|
6719
6730
|
function readRepositoryPackageManifest(packageJsonPath) {
|
|
6720
6731
|
try {
|
|
6721
|
-
return JSON.parse(
|
|
6732
|
+
return JSON.parse(fs4.readFileSync(packageJsonPath, "utf8"));
|
|
6722
6733
|
} catch (error) {
|
|
6723
6734
|
if (getErrorCode(error) === "ENOENT") {
|
|
6724
6735
|
return null;
|
|
@@ -6813,10 +6824,7 @@ var LOCKFILES2 = {
|
|
|
6813
6824
|
yarn: ["yarn.lock"]
|
|
6814
6825
|
};
|
|
6815
6826
|
async function ensureDirectory(targetDir, allowExisting = false) {
|
|
6816
|
-
|
|
6817
|
-
await fsp6.mkdir(targetDir, { recursive: true });
|
|
6818
|
-
return;
|
|
6819
|
-
}
|
|
6827
|
+
await fsp6.mkdir(targetDir, { recursive: true });
|
|
6820
6828
|
if (allowExisting) {
|
|
6821
6829
|
return;
|
|
6822
6830
|
}
|
|
@@ -6851,7 +6859,7 @@ async function writeBuiltInCodeArtifacts(targetDir, codeArtifacts) {
|
|
|
6851
6859
|
await fsp6.writeFile(destinationPath, artifact.source, "utf8");
|
|
6852
6860
|
}
|
|
6853
6861
|
}
|
|
6854
|
-
function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
6862
|
+
async function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
6855
6863
|
const projectToolsPackageRoot = path11.resolve(__dirname2, "..", "..");
|
|
6856
6864
|
const candidates = [
|
|
6857
6865
|
path11.join(projectToolsPackageRoot, "node_modules"),
|
|
@@ -6859,7 +6867,7 @@ function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
|
6859
6867
|
path11.resolve(projectToolsPackageRoot, "..", "..", "node_modules")
|
|
6860
6868
|
];
|
|
6861
6869
|
for (const candidate of candidates) {
|
|
6862
|
-
if (
|
|
6870
|
+
if (await pathExists(path11.join(candidate, "typia", "package.json"))) {
|
|
6863
6871
|
return candidate;
|
|
6864
6872
|
}
|
|
6865
6873
|
}
|
|
@@ -6867,11 +6875,11 @@ function resolveScaffoldGeneratorNodeModulesPath2() {
|
|
|
6867
6875
|
}
|
|
6868
6876
|
async function withEphemeralScaffoldNodeModules2(targetDir, callback) {
|
|
6869
6877
|
const targetNodeModulesPath = path11.join(targetDir, "node_modules");
|
|
6870
|
-
if (
|
|
6878
|
+
if (await pathExists(targetNodeModulesPath)) {
|
|
6871
6879
|
await callback();
|
|
6872
6880
|
return;
|
|
6873
6881
|
}
|
|
6874
|
-
const sourceNodeModulesPath = resolveScaffoldGeneratorNodeModulesPath2();
|
|
6882
|
+
const sourceNodeModulesPath = await resolveScaffoldGeneratorNodeModulesPath2();
|
|
6875
6883
|
if (!sourceNodeModulesPath) {
|
|
6876
6884
|
throw new Error("Unable to resolve a node_modules directory with typia for scaffold-time REST artifact generation.");
|
|
6877
6885
|
}
|
|
@@ -6912,9 +6920,7 @@ async function normalizePackageManagerFiles2(targetDir, packageManagerId) {
|
|
|
6912
6920
|
`, "utf8");
|
|
6913
6921
|
return;
|
|
6914
6922
|
}
|
|
6915
|
-
|
|
6916
|
-
await fsp6.rm(yarnRcPath, { force: true });
|
|
6917
|
-
}
|
|
6923
|
+
await fsp6.rm(yarnRcPath, { force: true });
|
|
6918
6924
|
}
|
|
6919
6925
|
async function removeQueryLoopPlaceholderFiles(projectDir, templateId) {
|
|
6920
6926
|
if (templateId !== "query-loop") {
|
|
@@ -6931,10 +6937,7 @@ async function removeUnexpectedLockfiles2(targetDir, packageManagerId) {
|
|
|
6931
6937
|
if (keep.has(filename)) {
|
|
6932
6938
|
return;
|
|
6933
6939
|
}
|
|
6934
|
-
|
|
6935
|
-
if (fs6.existsSync(filePath)) {
|
|
6936
|
-
await fsp6.rm(filePath, { force: true });
|
|
6937
|
-
}
|
|
6940
|
+
await fsp6.rm(path11.join(targetDir, filename), { force: true });
|
|
6938
6941
|
}));
|
|
6939
6942
|
}
|
|
6940
6943
|
async function replaceTextRecursively(targetDir, packageManagerId, {
|
|
@@ -7044,7 +7047,7 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
7044
7047
|
title: "Finalizing scaffold output"
|
|
7045
7048
|
});
|
|
7046
7049
|
const readmePath = path11.join(projectDir, "README.md");
|
|
7047
|
-
if (!
|
|
7050
|
+
if (!await pathExists(readmePath)) {
|
|
7048
7051
|
await fsp6.writeFile(readmePath, readmeContent ?? buildReadme(templateId, variables, packageManager, {
|
|
7049
7052
|
withMigrationUi,
|
|
7050
7053
|
withTestPreset,
|
|
@@ -7052,7 +7055,7 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
7052
7055
|
}), "utf8");
|
|
7053
7056
|
}
|
|
7054
7057
|
const gitignorePath = path11.join(projectDir, ".gitignore");
|
|
7055
|
-
const existingGitignore =
|
|
7058
|
+
const existingGitignore = await readOptionalUtf8File(gitignorePath) ?? "";
|
|
7056
7059
|
await fsp6.writeFile(gitignorePath, mergeTextLines(gitignoreContent ?? buildGitignore(), existingGitignore), "utf8");
|
|
7057
7060
|
await normalizePackageJson(projectDir, packageManager);
|
|
7058
7061
|
await applyGeneratedProjectDxPackageJson({
|
|
@@ -7084,11 +7087,10 @@ async function applyBuiltInScaffoldProjectFiles({
|
|
|
7084
7087
|
}
|
|
7085
7088
|
|
|
7086
7089
|
// ../wp-typia-project-tools/src/runtime/template-source-normalization.ts
|
|
7087
|
-
import fs11 from "fs";
|
|
7088
7090
|
import path15 from "path";
|
|
7089
7091
|
|
|
7090
7092
|
// ../wp-typia-project-tools/src/runtime/template-layers.ts
|
|
7091
|
-
import
|
|
7093
|
+
import fs5 from "fs";
|
|
7092
7094
|
import path12 from "path";
|
|
7093
7095
|
import { promises as fsp7 } from "fs";
|
|
7094
7096
|
var TEMPLATE_LAYER_MANIFEST_FILENAME = "wp-typia.layers.json";
|
|
@@ -7140,7 +7142,7 @@ function parseLayerDefinition(layerId, value) {
|
|
|
7140
7142
|
}
|
|
7141
7143
|
async function loadExternalTemplateLayerManifest(sourceRoot) {
|
|
7142
7144
|
const manifestPath = path12.join(sourceRoot, TEMPLATE_LAYER_MANIFEST_FILENAME);
|
|
7143
|
-
if (!
|
|
7145
|
+
if (!fs5.existsSync(manifestPath)) {
|
|
7144
7146
|
return null;
|
|
7145
7147
|
}
|
|
7146
7148
|
const raw = JSON.parse(await fsp7.readFile(manifestPath, "utf8"));
|
|
@@ -7275,12 +7277,13 @@ async function assertExternalTemplateLayersDoNotWriteProtectedOutputs({
|
|
|
7275
7277
|
}
|
|
7276
7278
|
|
|
7277
7279
|
// ../wp-typia-project-tools/src/runtime/template-source-external.ts
|
|
7278
|
-
import
|
|
7280
|
+
import fs7 from "fs";
|
|
7281
|
+
import { promises as fsp8 } from "fs";
|
|
7279
7282
|
import path13 from "path";
|
|
7280
7283
|
import { pathToFileURL } from "url";
|
|
7281
7284
|
|
|
7282
7285
|
// ../wp-typia-project-tools/src/runtime/external-template-guards.ts
|
|
7283
|
-
import
|
|
7286
|
+
import fs6 from "fs";
|
|
7284
7287
|
var TEMPLATE_SOURCE_TIMEOUT_CODE = "template-source-timeout";
|
|
7285
7288
|
var TEMPLATE_SOURCE_TOO_LARGE_CODE = "template-source-too-large";
|
|
7286
7289
|
var DEFAULT_EXTERNAL_TEMPLATE_TIMEOUT_MS = 20000;
|
|
@@ -7322,7 +7325,7 @@ function createExternalTemplateTooLargeError(label, maxBytes) {
|
|
|
7322
7325
|
return createTemplateGuardError(TEMPLATE_SOURCE_TOO_LARGE_CODE, `${label} exceeded the external template size limit (${maxBytes} bytes).`);
|
|
7323
7326
|
}
|
|
7324
7327
|
function assertExternalTemplateFileSize(filePath, options) {
|
|
7325
|
-
const stats =
|
|
7328
|
+
const stats = fs6.statSync(filePath);
|
|
7326
7329
|
if (stats.size > options.maxBytes) {
|
|
7327
7330
|
throw createExternalTemplateTooLargeError(options.label, options.maxBytes);
|
|
7328
7331
|
}
|
|
@@ -7427,17 +7430,17 @@ function resolveSourceSubpath(sourceDir, relativePath) {
|
|
|
7427
7430
|
}
|
|
7428
7431
|
return targetPath;
|
|
7429
7432
|
}
|
|
7430
|
-
function
|
|
7433
|
+
async function findExternalTemplateEntry(sourceDir) {
|
|
7431
7434
|
for (const filename of EXTERNAL_TEMPLATE_ENTRY_CANDIDATES) {
|
|
7432
7435
|
const candidate = path13.join(sourceDir, filename);
|
|
7433
|
-
if (
|
|
7436
|
+
if (await pathExists(candidate)) {
|
|
7434
7437
|
return candidate;
|
|
7435
7438
|
}
|
|
7436
7439
|
}
|
|
7437
7440
|
return null;
|
|
7438
7441
|
}
|
|
7439
7442
|
async function loadExternalTemplateConfig(sourceDir) {
|
|
7440
|
-
const entryPath =
|
|
7443
|
+
const entryPath = await findExternalTemplateEntry(sourceDir);
|
|
7441
7444
|
if (!entryPath) {
|
|
7442
7445
|
throw new Error(`No external template config entry found in ${sourceDir}.`);
|
|
7443
7446
|
}
|
|
@@ -7445,7 +7448,8 @@ async function loadExternalTemplateConfig(sourceDir) {
|
|
|
7445
7448
|
label: `External template config "${entryPath}"`,
|
|
7446
7449
|
maxBytes: getExternalTemplateConfigMaxBytes()
|
|
7447
7450
|
});
|
|
7448
|
-
const
|
|
7451
|
+
const entryStats = await fsp8.stat(entryPath);
|
|
7452
|
+
const moduleUrl = `${pathToFileURL(entryPath).href}?mtime=${entryStats.mtimeMs}`;
|
|
7449
7453
|
const loadedModule = await withExternalTemplateTimeout(`loading external template config "${entryPath}"`, () => import(moduleUrl));
|
|
7450
7454
|
const loadedConfig = loadedModule.default ?? loadedModule;
|
|
7451
7455
|
if (!isPlainObject(loadedConfig)) {
|
|
@@ -7558,15 +7562,16 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
7558
7562
|
await copyRenderedDirectory(blockTemplateDir, blockDir, view, {
|
|
7559
7563
|
filter: (sourcePath, _destinationPath, entry) => {
|
|
7560
7564
|
const mustacheVariantPath = path13.join(path13.dirname(sourcePath), `${entry.name}.mustache`);
|
|
7561
|
-
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") &&
|
|
7565
|
+
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs7.existsSync(mustacheVariantPath));
|
|
7562
7566
|
}
|
|
7563
7567
|
});
|
|
7564
7568
|
const assetsPath = typeof variantConfig.assetsPath === "string" ? variantConfig.assetsPath : config.assetsPath;
|
|
7565
7569
|
if (typeof assetsPath === "string" && assetsPath.trim().length > 0) {
|
|
7566
7570
|
await copyRawDirectory(resolveSourceSubpath(sourceDir, assetsPath), path13.join(tempRoot, "assets"));
|
|
7567
7571
|
}
|
|
7572
|
+
const assetsDir = path13.join(tempRoot, "assets");
|
|
7568
7573
|
return {
|
|
7569
|
-
assetsDir:
|
|
7574
|
+
assetsDir: await pathExists(assetsDir) ? assetsDir : undefined,
|
|
7570
7575
|
blockDir,
|
|
7571
7576
|
cleanup,
|
|
7572
7577
|
formatHint,
|
|
@@ -7581,8 +7586,8 @@ async function renderCreateBlockExternalTemplate(sourceDir, context, requestedVa
|
|
|
7581
7586
|
}
|
|
7582
7587
|
|
|
7583
7588
|
// ../wp-typia-project-tools/src/runtime/template-source-remote.ts
|
|
7584
|
-
import
|
|
7585
|
-
import { promises as
|
|
7589
|
+
import fs8 from "fs";
|
|
7590
|
+
import { promises as fsp9 } from "fs";
|
|
7586
7591
|
import path14 from "path";
|
|
7587
7592
|
async function cleanupSeedRootPair(cleanup, seedCleanup) {
|
|
7588
7593
|
let cleanupError;
|
|
@@ -7603,32 +7608,32 @@ async function cleanupSeedRootPair(cleanup, seedCleanup) {
|
|
|
7603
7608
|
function getDefaultCategoryFromBlockJson(blockJson) {
|
|
7604
7609
|
return typeof blockJson.category === "string" && blockJson.category.trim().length > 0 ? blockJson.category.trim() : "widgets";
|
|
7605
7610
|
}
|
|
7606
|
-
function
|
|
7607
|
-
const sourceRoot =
|
|
7611
|
+
async function readRemoteBlockJsonAsync(blockDir) {
|
|
7612
|
+
const sourceRoot = await getSeedSourceRoot(blockDir);
|
|
7608
7613
|
for (const candidate of [
|
|
7609
7614
|
path14.join(blockDir, "block.json"),
|
|
7610
7615
|
path14.join(sourceRoot, "block.json")
|
|
7611
7616
|
]) {
|
|
7612
|
-
if (
|
|
7613
|
-
return JSON.parse(
|
|
7617
|
+
if (await pathExists(candidate)) {
|
|
7618
|
+
return JSON.parse(await fsp9.readFile(candidate, "utf8"));
|
|
7614
7619
|
}
|
|
7615
7620
|
}
|
|
7616
7621
|
throw new Error(`Unable to locate block.json in ${blockDir}`);
|
|
7617
7622
|
}
|
|
7618
|
-
function
|
|
7623
|
+
async function getDefaultCategoryAsync(sourceDir) {
|
|
7619
7624
|
try {
|
|
7620
|
-
const blockJson =
|
|
7625
|
+
const blockJson = await readRemoteBlockJsonAsync(sourceDir);
|
|
7621
7626
|
return getDefaultCategoryFromBlockJson(blockJson);
|
|
7622
7627
|
} catch {
|
|
7623
7628
|
return "widgets";
|
|
7624
7629
|
}
|
|
7625
7630
|
}
|
|
7626
|
-
function
|
|
7631
|
+
async function readTemplatePackageJsonAsync(sourceDir) {
|
|
7627
7632
|
for (const candidate of [
|
|
7628
7633
|
path14.join(sourceDir, "package.json.mustache"),
|
|
7629
7634
|
path14.join(sourceDir, "package.json")
|
|
7630
7635
|
]) {
|
|
7631
|
-
if (!
|
|
7636
|
+
if (!await pathExists(candidate)) {
|
|
7632
7637
|
continue;
|
|
7633
7638
|
}
|
|
7634
7639
|
try {
|
|
@@ -7637,7 +7642,7 @@ function readTemplatePackageJson(sourceDir) {
|
|
|
7637
7642
|
maxBytes: getExternalTemplatePackageJsonMaxBytes()
|
|
7638
7643
|
});
|
|
7639
7644
|
return {
|
|
7640
|
-
packageJson: JSON.parse(
|
|
7645
|
+
packageJson: JSON.parse(await fsp9.readFile(candidate, "utf8")),
|
|
7641
7646
|
sourcePath: candidate
|
|
7642
7647
|
};
|
|
7643
7648
|
} catch (error) {
|
|
@@ -7647,8 +7652,8 @@ function readTemplatePackageJson(sourceDir) {
|
|
|
7647
7652
|
}
|
|
7648
7653
|
return null;
|
|
7649
7654
|
}
|
|
7650
|
-
function
|
|
7651
|
-
const packageJsonEntry =
|
|
7655
|
+
async function getTemplateProjectTypeAsync(sourceDir) {
|
|
7656
|
+
const packageJsonEntry = await readTemplatePackageJsonAsync(sourceDir);
|
|
7652
7657
|
if (!packageJsonEntry) {
|
|
7653
7658
|
return null;
|
|
7654
7659
|
}
|
|
@@ -7668,11 +7673,11 @@ async function normalizeWpTypiaTemplateSeed(seed) {
|
|
|
7668
7673
|
await copyRawDirectory(seed.blockDir, normalizedDir, {
|
|
7669
7674
|
filter: (sourcePath, _targetPath, entry) => {
|
|
7670
7675
|
const mustacheVariantPath = path14.join(path14.dirname(sourcePath), `${entry.name}.mustache`);
|
|
7671
|
-
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") &&
|
|
7676
|
+
return !(entry.isFile() && (entry.name === "package.json" || entry.name === "README.md") && fs8.existsSync(mustacheVariantPath));
|
|
7672
7677
|
}
|
|
7673
7678
|
});
|
|
7674
|
-
if (seed.assetsDir &&
|
|
7675
|
-
await
|
|
7679
|
+
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
7680
|
+
await fsp9.cp(seed.assetsDir, path14.join(normalizedDir, "assets"), {
|
|
7676
7681
|
recursive: true,
|
|
7677
7682
|
force: true
|
|
7678
7683
|
});
|
|
@@ -7763,9 +7768,9 @@ async function rewriteBlockJsonImports(directory) {
|
|
|
7763
7768
|
const textExtensions = new Set([".js", ".jsx", ".ts", ".tsx"]);
|
|
7764
7769
|
const targetBlockJsonPath = path14.join(directory, "block.json");
|
|
7765
7770
|
async function visit(currentPath) {
|
|
7766
|
-
const stats = await
|
|
7771
|
+
const stats = await fsp9.stat(currentPath);
|
|
7767
7772
|
if (stats.isDirectory()) {
|
|
7768
|
-
const entries = await
|
|
7773
|
+
const entries = await fsp9.readdir(currentPath);
|
|
7769
7774
|
for (const entry of entries) {
|
|
7770
7775
|
await visit(path14.join(currentPath, entry));
|
|
7771
7776
|
}
|
|
@@ -7774,19 +7779,19 @@ async function rewriteBlockJsonImports(directory) {
|
|
|
7774
7779
|
if (!textExtensions.has(path14.extname(currentPath))) {
|
|
7775
7780
|
return;
|
|
7776
7781
|
}
|
|
7777
|
-
const content = await
|
|
7782
|
+
const content = await fsp9.readFile(currentPath, "utf8");
|
|
7778
7783
|
const relativeSpecifier = path14.relative(path14.dirname(currentPath), targetBlockJsonPath).replace(/\\/g, "/");
|
|
7779
7784
|
const normalizedSpecifier = relativeSpecifier.startsWith(".") ? relativeSpecifier : `./${relativeSpecifier}`;
|
|
7780
7785
|
const next = content.replace(/(['"])\.{1,2}\/[^'"]*block\.json\1/g, `$1${normalizedSpecifier}$1`);
|
|
7781
7786
|
if (next !== content) {
|
|
7782
|
-
await
|
|
7787
|
+
await fsp9.writeFile(currentPath, next, "utf8");
|
|
7783
7788
|
}
|
|
7784
7789
|
}
|
|
7785
7790
|
await visit(directory);
|
|
7786
7791
|
}
|
|
7787
7792
|
async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
7788
7793
|
const packageJsonPath = path14.join(templateDir, "package.json.mustache");
|
|
7789
|
-
const packageJson = JSON.parse(await
|
|
7794
|
+
const packageJson = JSON.parse(await fsp9.readFile(packageJsonPath, "utf8"));
|
|
7790
7795
|
const existingDependencies = { ...packageJson.dependencies ?? {} };
|
|
7791
7796
|
const existingDevDependencies = { ...packageJson.devDependencies ?? {} };
|
|
7792
7797
|
delete existingDependencies["@wp-typia/project-tools"];
|
|
@@ -7806,18 +7811,18 @@ async function patchRemotePackageJson(templateDir, needsInteractivity) {
|
|
|
7806
7811
|
} else {
|
|
7807
7812
|
delete packageJson.dependencies;
|
|
7808
7813
|
}
|
|
7809
|
-
await
|
|
7814
|
+
await fsp9.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, 2)}
|
|
7810
7815
|
`, "utf8");
|
|
7811
7816
|
}
|
|
7812
|
-
function getSeedSourceRoot(blockDir) {
|
|
7813
|
-
return
|
|
7817
|
+
async function getSeedSourceRoot(blockDir) {
|
|
7818
|
+
return await pathExists(path14.join(blockDir, "src")) ? path14.join(blockDir, "src") : blockDir;
|
|
7814
7819
|
}
|
|
7815
|
-
function findSeedRenderPhp(seed) {
|
|
7820
|
+
async function findSeedRenderPhp(seed) {
|
|
7816
7821
|
for (const candidate of [
|
|
7817
7822
|
path14.join(seed.blockDir, "render.php"),
|
|
7818
7823
|
path14.join(seed.rootDir, "render.php")
|
|
7819
7824
|
]) {
|
|
7820
|
-
if (
|
|
7825
|
+
if (await pathExists(candidate)) {
|
|
7821
7826
|
return candidate;
|
|
7822
7827
|
}
|
|
7823
7828
|
}
|
|
@@ -7856,47 +7861,54 @@ async function removeSeedEntryConflicts(templateDir) {
|
|
|
7856
7861
|
"view.ts",
|
|
7857
7862
|
"view.tsx"
|
|
7858
7863
|
]) {
|
|
7859
|
-
await
|
|
7864
|
+
await fsp9.rm(path14.join(templateDir, "src", filename), { force: true });
|
|
7860
7865
|
}
|
|
7861
7866
|
}
|
|
7862
7867
|
async function normalizeCreateBlockSubset(seed, context) {
|
|
7863
7868
|
const { path: tempRoot, cleanup } = await createManagedTempRoot("wp-typia-remote-template-");
|
|
7864
7869
|
try {
|
|
7865
7870
|
const templateDir = path14.join(tempRoot, "template");
|
|
7866
|
-
const blockJson =
|
|
7867
|
-
const sourceRoot = getSeedSourceRoot(seed.blockDir);
|
|
7868
|
-
await
|
|
7871
|
+
const blockJson = await readRemoteBlockJsonAsync(seed.blockDir);
|
|
7872
|
+
const sourceRoot = await getSeedSourceRoot(seed.blockDir);
|
|
7873
|
+
await fsp9.mkdir(templateDir, { recursive: true });
|
|
7869
7874
|
for (const layerDir of getBuiltInTemplateLayerDirs("basic")) {
|
|
7870
|
-
if (!
|
|
7875
|
+
if (!await pathExists(layerDir)) {
|
|
7871
7876
|
if (isOmittableBuiltInTemplateLayerDir("basic", layerDir)) {
|
|
7872
7877
|
continue;
|
|
7873
7878
|
}
|
|
7874
7879
|
throw new Error(`Built-in template layer is missing: ${layerDir}`);
|
|
7875
7880
|
}
|
|
7876
|
-
await
|
|
7881
|
+
await fsp9.cp(layerDir, templateDir, {
|
|
7877
7882
|
recursive: true,
|
|
7878
7883
|
force: true
|
|
7879
7884
|
});
|
|
7880
7885
|
}
|
|
7881
7886
|
await removeSeedEntryConflicts(templateDir);
|
|
7882
|
-
await
|
|
7887
|
+
await fsp9.cp(sourceRoot, path14.join(templateDir, "src"), {
|
|
7883
7888
|
recursive: true,
|
|
7884
7889
|
force: true
|
|
7885
7890
|
});
|
|
7886
|
-
const remoteRenderPath = findSeedRenderPhp(seed);
|
|
7891
|
+
const remoteRenderPath = await findSeedRenderPhp(seed);
|
|
7887
7892
|
if (remoteRenderPath) {
|
|
7888
|
-
await
|
|
7893
|
+
await fsp9.copyFile(remoteRenderPath, path14.join(templateDir, "render.php"));
|
|
7889
7894
|
}
|
|
7890
|
-
if (seed.assetsDir &&
|
|
7891
|
-
await
|
|
7895
|
+
if (seed.assetsDir && await pathExists(seed.assetsDir)) {
|
|
7896
|
+
await fsp9.cp(seed.assetsDir, path14.join(templateDir, "assets"), {
|
|
7892
7897
|
recursive: true,
|
|
7893
7898
|
force: true
|
|
7894
7899
|
});
|
|
7895
7900
|
}
|
|
7896
|
-
await
|
|
7897
|
-
await
|
|
7901
|
+
await fsp9.writeFile(path14.join(templateDir, "src", "types.ts"), buildRemoteTypesSource(blockJson, context), "utf8");
|
|
7902
|
+
await fsp9.writeFile(path14.join(templateDir, "src", "block.json"), buildRemoteBlockJsonTemplate(blockJson), "utf8");
|
|
7898
7903
|
await rewriteBlockJsonImports(path14.join(templateDir, "src"));
|
|
7899
|
-
const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" ||
|
|
7904
|
+
const needsInteractivity = typeof blockJson.viewScriptModule === "string" || typeof blockJson.viewScript === "string" || (await Promise.all([
|
|
7905
|
+
"view.js",
|
|
7906
|
+
"view.jsx",
|
|
7907
|
+
"view.ts",
|
|
7908
|
+
"view.tsx",
|
|
7909
|
+
"interactivity.js",
|
|
7910
|
+
"interactivity.ts"
|
|
7911
|
+
].map((filename) => pathExists(path14.join(templateDir, "src", filename))))).some(Boolean);
|
|
7900
7912
|
await patchRemotePackageJson(templateDir, needsInteractivity);
|
|
7901
7913
|
return {
|
|
7902
7914
|
id: "remote:create-block-subset",
|
|
@@ -7946,27 +7958,27 @@ function getTemplateVariableContext(variables) {
|
|
|
7946
7958
|
};
|
|
7947
7959
|
}
|
|
7948
7960
|
async function detectTemplateSourceFormat(sourceDir) {
|
|
7949
|
-
if (
|
|
7961
|
+
if (await pathExists(path15.join(sourceDir, "package.json.mustache"))) {
|
|
7950
7962
|
return "wp-typia";
|
|
7951
7963
|
}
|
|
7952
7964
|
if (await loadExternalTemplateLayerManifest(sourceDir)) {
|
|
7953
7965
|
throw new Error(`Template source at ${sourceDir} is an external layer package. External layers currently compose only through built-in scaffolds via the runtime API, not as standalone template ids.`);
|
|
7954
7966
|
}
|
|
7955
|
-
if (
|
|
7967
|
+
if (await findExternalTemplateEntry(sourceDir)) {
|
|
7956
7968
|
return "create-block-external";
|
|
7957
7969
|
}
|
|
7958
|
-
if (
|
|
7970
|
+
if (await getTemplateProjectTypeAsync(sourceDir) !== null) {
|
|
7959
7971
|
return "wp-typia";
|
|
7960
7972
|
}
|
|
7961
|
-
const sourceRoot =
|
|
7973
|
+
const sourceRoot = await pathExists(path15.join(sourceDir, "src")) ? path15.join(sourceDir, "src") : sourceDir;
|
|
7962
7974
|
const blockJsonCandidates = [
|
|
7963
7975
|
path15.join(sourceDir, "block.json"),
|
|
7964
7976
|
path15.join(sourceRoot, "block.json")
|
|
7965
7977
|
];
|
|
7966
|
-
const hasBlockJson = blockJsonCandidates.
|
|
7967
|
-
const hasIndexFile = ["index.js", "index.jsx", "index.ts", "index.tsx"].
|
|
7968
|
-
const hasEditFile = ["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].
|
|
7969
|
-
const hasSaveFile = ["save.js", "save.jsx", "save.ts", "save.tsx"].
|
|
7978
|
+
const hasBlockJson = (await Promise.all(blockJsonCandidates.map((candidate) => pathExists(candidate)))).some(Boolean);
|
|
7979
|
+
const hasIndexFile = (await Promise.all(["index.js", "index.jsx", "index.ts", "index.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
|
|
7980
|
+
const hasEditFile = (await Promise.all(["edit.js", "edit.jsx", "edit.ts", "edit.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
|
|
7981
|
+
const hasSaveFile = (await Promise.all(["save.js", "save.jsx", "save.ts", "save.tsx"].map((filename) => pathExists(path15.join(sourceRoot, filename))))).some(Boolean);
|
|
7970
7982
|
if (hasBlockJson && hasIndexFile && hasEditFile && hasSaveFile) {
|
|
7971
7983
|
return "create-block-subset";
|
|
7972
7984
|
}
|
|
@@ -7975,8 +7987,8 @@ async function detectTemplateSourceFormat(sourceDir) {
|
|
|
7975
7987
|
|
|
7976
7988
|
// ../wp-typia-project-tools/src/runtime/template-source-seeds.ts
|
|
7977
7989
|
var import_semver = __toESM(require_semver2(), 1);
|
|
7978
|
-
import
|
|
7979
|
-
import { promises as
|
|
7990
|
+
import fs11 from "fs";
|
|
7991
|
+
import { promises as fsp11 } from "fs";
|
|
7980
7992
|
import { createRequire as createRequire2 } from "module";
|
|
7981
7993
|
import path17 from "path";
|
|
7982
7994
|
import { spawnSync } from "child_process";
|
|
@@ -10251,7 +10263,7 @@ var Vn = 512 * 1024;
|
|
|
10251
10263
|
var $n = pr | ur | dr | mr;
|
|
10252
10264
|
var lr = !fr && typeof ar == "number" ? ar | ur | dr | mr : null;
|
|
10253
10265
|
var cs = lr !== null ? () => lr : Kn ? (s3) => s3 < Vn ? $n : "w" : () => "w";
|
|
10254
|
-
var
|
|
10266
|
+
var fs9 = (s3, t, e) => {
|
|
10255
10267
|
try {
|
|
10256
10268
|
return mi.lchownSync(s3, t, e);
|
|
10257
10269
|
} catch (i) {
|
|
@@ -10300,7 +10312,7 @@ var ds = (s3, t, e, i) => {
|
|
|
10300
10312
|
});
|
|
10301
10313
|
};
|
|
10302
10314
|
var qn = (s3, t, e, i) => {
|
|
10303
|
-
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i),
|
|
10315
|
+
t.isDirectory() && us(Ee.resolve(s3, t.name), e, i), fs9(Ee.resolve(s3, t.name), e, i);
|
|
10304
10316
|
};
|
|
10305
10317
|
var us = (s3, t, e) => {
|
|
10306
10318
|
let i;
|
|
@@ -10311,12 +10323,12 @@ var us = (s3, t, e) => {
|
|
|
10311
10323
|
if (n?.code === "ENOENT")
|
|
10312
10324
|
return;
|
|
10313
10325
|
if (n?.code === "ENOTDIR" || n?.code === "ENOTSUP")
|
|
10314
|
-
return
|
|
10326
|
+
return fs9(s3, t, e);
|
|
10315
10327
|
throw n;
|
|
10316
10328
|
}
|
|
10317
10329
|
for (let r of i)
|
|
10318
10330
|
qn(s3, r, t, e);
|
|
10319
|
-
return
|
|
10331
|
+
return fs9(s3, t, e);
|
|
10320
10332
|
};
|
|
10321
10333
|
var we = class extends Error {
|
|
10322
10334
|
path;
|
|
@@ -11130,15 +11142,18 @@ var So = (s3) => {
|
|
|
11130
11142
|
|
|
11131
11143
|
// ../wp-typia-project-tools/src/runtime/template-source-cache.ts
|
|
11132
11144
|
import { createHash } from "crypto";
|
|
11133
|
-
import
|
|
11134
|
-
import { promises as
|
|
11145
|
+
import fs10 from "fs";
|
|
11146
|
+
import { promises as fsp10 } from "fs";
|
|
11135
11147
|
import os2 from "os";
|
|
11136
11148
|
import path16 from "path";
|
|
11137
11149
|
var EXTERNAL_TEMPLATE_CACHE_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE";
|
|
11138
11150
|
var EXTERNAL_TEMPLATE_CACHE_DIR_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_DIR";
|
|
11139
11151
|
var EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_TTL_DAYS";
|
|
11152
|
+
var EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS_ENV = "WP_TYPIA_EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS";
|
|
11140
11153
|
var CACHE_MARKER_FILE = "wp-typia-template-cache.json";
|
|
11154
|
+
var CACHE_PRUNE_MARKER_FILE = "wp-typia-template-cache-prune.json";
|
|
11141
11155
|
var MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;
|
|
11156
|
+
var DEFAULT_CACHE_PRUNE_INTERVAL_MS = 60 * 60 * 1000;
|
|
11142
11157
|
var PRIVATE_CACHE_DIRECTORY_MODE = 448;
|
|
11143
11158
|
var REDACTED_CACHE_METADATA_VALUE = "[redacted]";
|
|
11144
11159
|
var DISABLED_CACHE_VALUES = new Set(["0", "false", "no", "off"]);
|
|
@@ -11186,12 +11201,33 @@ function resolveExternalTemplateCacheTtlMs(options = {}) {
|
|
|
11186
11201
|
const ttlMs = ttlDays * MILLISECONDS_PER_DAY;
|
|
11187
11202
|
return Number.isFinite(ttlMs) ? ttlMs : null;
|
|
11188
11203
|
}
|
|
11204
|
+
function parseExternalTemplateCachePruneIntervalMs(value) {
|
|
11205
|
+
if (typeof value !== "string" && typeof value !== "number") {
|
|
11206
|
+
return null;
|
|
11207
|
+
}
|
|
11208
|
+
const intervalMs = typeof value === "number" ? value : Number(value.trim());
|
|
11209
|
+
if (!Number.isFinite(intervalMs) || intervalMs <= 0) {
|
|
11210
|
+
return null;
|
|
11211
|
+
}
|
|
11212
|
+
return intervalMs;
|
|
11213
|
+
}
|
|
11214
|
+
function resolveExternalTemplateCachePruneIntervalMs(options = {}) {
|
|
11215
|
+
if (options.pruneIntervalMs !== undefined) {
|
|
11216
|
+
return parseExternalTemplateCachePruneIntervalMs(options.pruneIntervalMs);
|
|
11217
|
+
}
|
|
11218
|
+
const env = options.env ?? process.env;
|
|
11219
|
+
const envValue = env[EXTERNAL_TEMPLATE_CACHE_PRUNE_INTERVAL_MS_ENV];
|
|
11220
|
+
if (envValue === undefined) {
|
|
11221
|
+
return DEFAULT_CACHE_PRUNE_INTERVAL_MS;
|
|
11222
|
+
}
|
|
11223
|
+
return parseExternalTemplateCachePruneIntervalMs(envValue);
|
|
11224
|
+
}
|
|
11189
11225
|
function createExternalTemplateCacheKey(keyParts) {
|
|
11190
11226
|
return createHash("sha256").update(JSON.stringify(keyParts)).digest("hex");
|
|
11191
11227
|
}
|
|
11192
|
-
async function
|
|
11228
|
+
async function pathExists2(filePath) {
|
|
11193
11229
|
try {
|
|
11194
|
-
await
|
|
11230
|
+
await fsp10.access(filePath, fs10.constants.F_OK);
|
|
11195
11231
|
return true;
|
|
11196
11232
|
} catch {
|
|
11197
11233
|
return false;
|
|
@@ -11199,7 +11235,7 @@ async function pathExists(filePath) {
|
|
|
11199
11235
|
}
|
|
11200
11236
|
async function isDirectoryPath(directory) {
|
|
11201
11237
|
try {
|
|
11202
|
-
const stats = await
|
|
11238
|
+
const stats = await fsp10.lstat(directory);
|
|
11203
11239
|
return stats.isDirectory() && !stats.isSymbolicLink();
|
|
11204
11240
|
} catch {
|
|
11205
11241
|
return false;
|
|
@@ -11210,7 +11246,7 @@ function getNodeErrorCode(error) {
|
|
|
11210
11246
|
}
|
|
11211
11247
|
async function removeTemporaryCacheEntry(entryDir) {
|
|
11212
11248
|
try {
|
|
11213
|
-
await
|
|
11249
|
+
await fsp10.rm(entryDir, { force: true, recursive: true });
|
|
11214
11250
|
} catch {}
|
|
11215
11251
|
}
|
|
11216
11252
|
function getCurrentUserCacheSegment() {
|
|
@@ -11229,7 +11265,7 @@ function getCurrentUid() {
|
|
|
11229
11265
|
}
|
|
11230
11266
|
async function isPrivateCacheDirectory(directory) {
|
|
11231
11267
|
try {
|
|
11232
|
-
const stats = await
|
|
11268
|
+
const stats = await fsp10.lstat(directory);
|
|
11233
11269
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
11234
11270
|
return false;
|
|
11235
11271
|
}
|
|
@@ -11247,11 +11283,11 @@ async function isPrivateCacheDirectory(directory) {
|
|
|
11247
11283
|
}
|
|
11248
11284
|
async function ensurePrivateCacheDirectory(directory) {
|
|
11249
11285
|
try {
|
|
11250
|
-
await
|
|
11286
|
+
await fsp10.mkdir(directory, {
|
|
11251
11287
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
11252
11288
|
recursive: true
|
|
11253
11289
|
});
|
|
11254
|
-
const stats = await
|
|
11290
|
+
const stats = await fsp10.lstat(directory);
|
|
11255
11291
|
if (!stats.isDirectory() || stats.isSymbolicLink()) {
|
|
11256
11292
|
return false;
|
|
11257
11293
|
}
|
|
@@ -11261,7 +11297,7 @@ async function ensurePrivateCacheDirectory(directory) {
|
|
|
11261
11297
|
}
|
|
11262
11298
|
if (process.platform !== "win32") {
|
|
11263
11299
|
if ((stats.mode & 63) !== 0) {
|
|
11264
|
-
await
|
|
11300
|
+
await fsp10.chmod(directory, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
11265
11301
|
}
|
|
11266
11302
|
}
|
|
11267
11303
|
return isPrivateCacheDirectory(directory);
|
|
@@ -11319,7 +11355,7 @@ function getCacheEntryPaths(descriptor) {
|
|
|
11319
11355
|
};
|
|
11320
11356
|
}
|
|
11321
11357
|
async function isReusableCacheEntry(entryDir, markerPath, sourceDir) {
|
|
11322
|
-
return await isPrivateCacheDirectory(entryDir) && await
|
|
11358
|
+
return await isPrivateCacheDirectory(entryDir) && await pathExists2(markerPath) && await isDirectoryPath(sourceDir);
|
|
11323
11359
|
}
|
|
11324
11360
|
function parseCacheMarkerMetadata(markerText) {
|
|
11325
11361
|
let marker;
|
|
@@ -11349,6 +11385,13 @@ function parseCacheMarkerMetadata(markerText) {
|
|
|
11349
11385
|
metadata
|
|
11350
11386
|
};
|
|
11351
11387
|
}
|
|
11388
|
+
async function readCacheEntryMarker(markerPath) {
|
|
11389
|
+
try {
|
|
11390
|
+
return parseCacheMarkerMetadata(await fsp10.readFile(markerPath, "utf8"));
|
|
11391
|
+
} catch {
|
|
11392
|
+
return null;
|
|
11393
|
+
}
|
|
11394
|
+
}
|
|
11352
11395
|
function cacheMetadataMatches(actual, expected) {
|
|
11353
11396
|
return Object.entries(expected).every(([key, value]) => actual[key] === value);
|
|
11354
11397
|
}
|
|
@@ -11356,6 +11399,19 @@ function getExternalTemplateCacheNowMs(now) {
|
|
|
11356
11399
|
const nowMs = now instanceof Date ? now.getTime() : typeof now === "number" ? now : Date.now();
|
|
11357
11400
|
return Number.isFinite(nowMs) ? nowMs : Date.now();
|
|
11358
11401
|
}
|
|
11402
|
+
function isCacheEntryFreshForTtl(createdAtMs, nowMs, ttlMs) {
|
|
11403
|
+
return ttlMs === null || createdAtMs >= nowMs - ttlMs;
|
|
11404
|
+
}
|
|
11405
|
+
async function getReusableCacheEntryMarker(entryDir, markerPath, sourceDir) {
|
|
11406
|
+
if (!await isReusableCacheEntry(entryDir, markerPath, sourceDir)) {
|
|
11407
|
+
return null;
|
|
11408
|
+
}
|
|
11409
|
+
return readCacheEntryMarker(markerPath);
|
|
11410
|
+
}
|
|
11411
|
+
async function isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs, ttlMs) {
|
|
11412
|
+
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
11413
|
+
return marker !== null && isCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs);
|
|
11414
|
+
}
|
|
11359
11415
|
function isPathInsideDirectory(directory, candidatePath) {
|
|
11360
11416
|
const relativePath = path16.relative(directory, candidatePath);
|
|
11361
11417
|
return relativePath.length > 0 && !relativePath.startsWith("..") && !path16.isAbsolute(relativePath);
|
|
@@ -11365,12 +11421,82 @@ async function removeCacheEntryWithinRoot(cacheRoot, entryDir) {
|
|
|
11365
11421
|
return false;
|
|
11366
11422
|
}
|
|
11367
11423
|
try {
|
|
11368
|
-
await
|
|
11424
|
+
await fsp10.rm(entryDir, { force: true, recursive: true });
|
|
11369
11425
|
return true;
|
|
11370
11426
|
} catch {
|
|
11371
11427
|
return false;
|
|
11372
11428
|
}
|
|
11373
11429
|
}
|
|
11430
|
+
function getCachePruneMarkerPath(cacheRoot) {
|
|
11431
|
+
return path16.join(cacheRoot, CACHE_PRUNE_MARKER_FILE);
|
|
11432
|
+
}
|
|
11433
|
+
function parseCachePruneMarker(markerText) {
|
|
11434
|
+
let marker;
|
|
11435
|
+
try {
|
|
11436
|
+
marker = JSON.parse(markerText);
|
|
11437
|
+
} catch {
|
|
11438
|
+
return null;
|
|
11439
|
+
}
|
|
11440
|
+
if (typeof marker !== "object" || marker === null || Array.isArray(marker)) {
|
|
11441
|
+
return null;
|
|
11442
|
+
}
|
|
11443
|
+
const rawPrunedAt = marker.prunedAt;
|
|
11444
|
+
const prunedAtMs = typeof rawPrunedAt === "string" ? Date.parse(rawPrunedAt) : Number.NaN;
|
|
11445
|
+
const rawPruneIntervalMs = marker.pruneIntervalMs;
|
|
11446
|
+
const rawTtlMs = marker.ttlMs;
|
|
11447
|
+
if (typeof rawTtlMs !== "number" || !Number.isFinite(rawTtlMs)) {
|
|
11448
|
+
return null;
|
|
11449
|
+
}
|
|
11450
|
+
if (!Number.isFinite(prunedAtMs)) {
|
|
11451
|
+
return null;
|
|
11452
|
+
}
|
|
11453
|
+
if (rawPruneIntervalMs !== null && (typeof rawPruneIntervalMs !== "number" || !Number.isFinite(rawPruneIntervalMs))) {
|
|
11454
|
+
return null;
|
|
11455
|
+
}
|
|
11456
|
+
return {
|
|
11457
|
+
prunedAtMs,
|
|
11458
|
+
pruneIntervalMs: rawPruneIntervalMs ?? null,
|
|
11459
|
+
ttlMs: rawTtlMs
|
|
11460
|
+
};
|
|
11461
|
+
}
|
|
11462
|
+
async function shouldSkipExternalTemplateCachePrune({
|
|
11463
|
+
cacheRoot,
|
|
11464
|
+
force,
|
|
11465
|
+
nowMs,
|
|
11466
|
+
pruneIntervalMs,
|
|
11467
|
+
ttlMs
|
|
11468
|
+
}) {
|
|
11469
|
+
if (force || pruneIntervalMs === null) {
|
|
11470
|
+
return false;
|
|
11471
|
+
}
|
|
11472
|
+
let markerText;
|
|
11473
|
+
try {
|
|
11474
|
+
markerText = await fsp10.readFile(getCachePruneMarkerPath(cacheRoot), "utf8");
|
|
11475
|
+
} catch {
|
|
11476
|
+
return false;
|
|
11477
|
+
}
|
|
11478
|
+
const marker = parseCachePruneMarker(markerText);
|
|
11479
|
+
if (!marker || marker.ttlMs !== ttlMs || marker.pruneIntervalMs !== pruneIntervalMs) {
|
|
11480
|
+
return false;
|
|
11481
|
+
}
|
|
11482
|
+
const elapsedMs = nowMs - marker.prunedAtMs;
|
|
11483
|
+
return elapsedMs >= 0 && elapsedMs < pruneIntervalMs;
|
|
11484
|
+
}
|
|
11485
|
+
async function writeExternalTemplateCachePruneMarker({
|
|
11486
|
+
cacheRoot,
|
|
11487
|
+
nowMs,
|
|
11488
|
+
pruneIntervalMs,
|
|
11489
|
+
ttlMs
|
|
11490
|
+
}) {
|
|
11491
|
+
try {
|
|
11492
|
+
await fsp10.writeFile(getCachePruneMarkerPath(cacheRoot), `${JSON.stringify({
|
|
11493
|
+
prunedAt: new Date(nowMs).toISOString(),
|
|
11494
|
+
pruneIntervalMs,
|
|
11495
|
+
ttlMs
|
|
11496
|
+
}, null, 2)}
|
|
11497
|
+
`, "utf8");
|
|
11498
|
+
} catch {}
|
|
11499
|
+
}
|
|
11374
11500
|
async function pruneExternalTemplateCache(options = {}) {
|
|
11375
11501
|
const env = options.env ?? process.env;
|
|
11376
11502
|
const cacheRoot = getExternalTemplateCacheRoot(env);
|
|
@@ -11378,23 +11504,39 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
11378
11504
|
env,
|
|
11379
11505
|
ttlDays: options.ttlDays
|
|
11380
11506
|
});
|
|
11507
|
+
const pruneIntervalMs = resolveExternalTemplateCachePruneIntervalMs({
|
|
11508
|
+
env,
|
|
11509
|
+
pruneIntervalMs: options.pruneIntervalMs
|
|
11510
|
+
});
|
|
11381
11511
|
const result = {
|
|
11382
11512
|
cacheRoot,
|
|
11383
11513
|
prunedEntries: 0,
|
|
11384
11514
|
scannedEntries: 0,
|
|
11385
11515
|
skippedEntries: 0,
|
|
11516
|
+
skippedByThrottle: false,
|
|
11386
11517
|
ttlMs
|
|
11387
11518
|
};
|
|
11388
11519
|
if (ttlMs === null || !await isPrivateCacheDirectory(cacheRoot)) {
|
|
11389
11520
|
return result;
|
|
11390
11521
|
}
|
|
11522
|
+
const nowMs = getExternalTemplateCacheNowMs(options.now);
|
|
11523
|
+
if (await shouldSkipExternalTemplateCachePrune({
|
|
11524
|
+
cacheRoot,
|
|
11525
|
+
force: options.force,
|
|
11526
|
+
nowMs,
|
|
11527
|
+
pruneIntervalMs,
|
|
11528
|
+
ttlMs
|
|
11529
|
+
})) {
|
|
11530
|
+
result.skippedByThrottle = true;
|
|
11531
|
+
return result;
|
|
11532
|
+
}
|
|
11391
11533
|
let namespaceEntries;
|
|
11392
11534
|
try {
|
|
11393
|
-
namespaceEntries = await
|
|
11535
|
+
namespaceEntries = await fsp10.readdir(cacheRoot, { withFileTypes: true });
|
|
11394
11536
|
} catch {
|
|
11395
11537
|
return result;
|
|
11396
11538
|
}
|
|
11397
|
-
const expiresBeforeMs =
|
|
11539
|
+
const expiresBeforeMs = nowMs - ttlMs;
|
|
11398
11540
|
for (const namespaceEntry of namespaceEntries) {
|
|
11399
11541
|
if (!namespaceEntry.isDirectory()) {
|
|
11400
11542
|
continue;
|
|
@@ -11406,7 +11548,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
11406
11548
|
}
|
|
11407
11549
|
let cacheEntries;
|
|
11408
11550
|
try {
|
|
11409
|
-
cacheEntries = await
|
|
11551
|
+
cacheEntries = await fsp10.readdir(namespaceDir, { withFileTypes: true });
|
|
11410
11552
|
} catch {
|
|
11411
11553
|
result.skippedEntries += 1;
|
|
11412
11554
|
continue;
|
|
@@ -11427,18 +11569,7 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
11427
11569
|
}
|
|
11428
11570
|
const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
|
|
11429
11571
|
const sourceDir = path16.join(entryDir, "source");
|
|
11430
|
-
|
|
11431
|
-
result.skippedEntries += 1;
|
|
11432
|
-
continue;
|
|
11433
|
-
}
|
|
11434
|
-
let markerText;
|
|
11435
|
-
try {
|
|
11436
|
-
markerText = await fsp9.readFile(markerPath, "utf8");
|
|
11437
|
-
} catch {
|
|
11438
|
-
result.skippedEntries += 1;
|
|
11439
|
-
continue;
|
|
11440
|
-
}
|
|
11441
|
-
const marker = parseCacheMarkerMetadata(markerText);
|
|
11572
|
+
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
11442
11573
|
if (!marker) {
|
|
11443
11574
|
result.skippedEntries += 1;
|
|
11444
11575
|
continue;
|
|
@@ -11452,6 +11583,12 @@ async function pruneExternalTemplateCache(options = {}) {
|
|
|
11452
11583
|
}
|
|
11453
11584
|
}
|
|
11454
11585
|
}
|
|
11586
|
+
await writeExternalTemplateCachePruneMarker({
|
|
11587
|
+
cacheRoot,
|
|
11588
|
+
nowMs,
|
|
11589
|
+
pruneIntervalMs,
|
|
11590
|
+
ttlMs
|
|
11591
|
+
});
|
|
11455
11592
|
return result;
|
|
11456
11593
|
}
|
|
11457
11594
|
async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
@@ -11466,10 +11603,12 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
11466
11603
|
if (!await isPrivateCacheDirectory(cacheRoot) || !await isPrivateCacheDirectory(namespaceDir)) {
|
|
11467
11604
|
return null;
|
|
11468
11605
|
}
|
|
11606
|
+
const ttlMs = resolveExternalTemplateCacheTtlMs();
|
|
11607
|
+
const nowMs = getExternalTemplateCacheNowMs(undefined);
|
|
11469
11608
|
await pruneExternalTemplateCache();
|
|
11470
11609
|
let entries;
|
|
11471
11610
|
try {
|
|
11472
|
-
entries = await
|
|
11611
|
+
entries = await fsp10.readdir(namespaceDir, { withFileTypes: true });
|
|
11473
11612
|
} catch {
|
|
11474
11613
|
return null;
|
|
11475
11614
|
}
|
|
@@ -11481,17 +11620,8 @@ async function findReusableExternalTemplateSourceCache(descriptor) {
|
|
|
11481
11620
|
const entryDir = path16.join(namespaceDir, entry.name);
|
|
11482
11621
|
const markerPath = path16.join(entryDir, CACHE_MARKER_FILE);
|
|
11483
11622
|
const sourceDir = path16.join(entryDir, "source");
|
|
11484
|
-
|
|
11485
|
-
|
|
11486
|
-
}
|
|
11487
|
-
let markerText;
|
|
11488
|
-
try {
|
|
11489
|
-
markerText = await fsp9.readFile(markerPath, "utf8");
|
|
11490
|
-
} catch {
|
|
11491
|
-
continue;
|
|
11492
|
-
}
|
|
11493
|
-
const marker = parseCacheMarkerMetadata(markerText);
|
|
11494
|
-
if (!marker || !cacheMetadataMatches(marker.metadata, descriptor.metadata)) {
|
|
11623
|
+
const marker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
11624
|
+
if (!marker || !isCacheEntryFreshForTtl(marker.createdAtMs, nowMs, ttlMs) || !cacheMetadataMatches(marker.metadata, descriptor.metadata)) {
|
|
11495
11625
|
continue;
|
|
11496
11626
|
}
|
|
11497
11627
|
if (!bestEntry || marker.createdAtMs > bestEntry.createdAtMs) {
|
|
@@ -11518,23 +11648,29 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
11518
11648
|
if (!await ensurePrivateCacheDirectory(cacheRoot) || !await ensurePrivateCacheDirectory(namespaceDir)) {
|
|
11519
11649
|
return null;
|
|
11520
11650
|
}
|
|
11651
|
+
const ttlMs = resolveExternalTemplateCacheTtlMs();
|
|
11652
|
+
const nowMs = getExternalTemplateCacheNowMs(undefined);
|
|
11521
11653
|
await pruneExternalTemplateCache();
|
|
11522
|
-
|
|
11654
|
+
const existingMarker = await getReusableCacheEntryMarker(entryDir, markerPath, sourceDir);
|
|
11655
|
+
if (existingMarker && isCacheEntryFreshForTtl(existingMarker.createdAtMs, nowMs, ttlMs)) {
|
|
11523
11656
|
return {
|
|
11524
11657
|
cacheHit: true,
|
|
11525
11658
|
sourceDir
|
|
11526
11659
|
};
|
|
11527
11660
|
}
|
|
11661
|
+
if (existingMarker) {
|
|
11662
|
+
await removeCacheEntryWithinRoot(cacheRoot, entryDir);
|
|
11663
|
+
}
|
|
11528
11664
|
const temporaryEntryDir = path16.join(namespaceDir, `.tmp-${cacheKey}-${process.pid}-${Date.now()}-${Math.random().toString(16).slice(2)}`);
|
|
11529
11665
|
const temporarySourceDir = path16.join(temporaryEntryDir, "source");
|
|
11530
11666
|
let populateFailed = false;
|
|
11531
11667
|
try {
|
|
11532
|
-
await
|
|
11668
|
+
await fsp10.mkdir(temporarySourceDir, {
|
|
11533
11669
|
mode: PRIVATE_CACHE_DIRECTORY_MODE,
|
|
11534
11670
|
recursive: true
|
|
11535
11671
|
});
|
|
11536
11672
|
if (process.platform !== "win32") {
|
|
11537
|
-
await
|
|
11673
|
+
await fsp10.chmod(temporaryEntryDir, PRIVATE_CACHE_DIRECTORY_MODE);
|
|
11538
11674
|
}
|
|
11539
11675
|
try {
|
|
11540
11676
|
await populateSourceDir(temporarySourceDir);
|
|
@@ -11542,14 +11678,14 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
11542
11678
|
populateFailed = true;
|
|
11543
11679
|
throw error;
|
|
11544
11680
|
}
|
|
11545
|
-
await
|
|
11681
|
+
await fsp10.writeFile(path16.join(temporaryEntryDir, CACHE_MARKER_FILE), `${JSON.stringify({
|
|
11546
11682
|
createdAt: new Date().toISOString(),
|
|
11547
11683
|
key: cacheKey,
|
|
11548
11684
|
metadata: sanitizeCacheMetadata(descriptor.metadata),
|
|
11549
11685
|
namespace: descriptor.namespace
|
|
11550
11686
|
}, null, 2)}
|
|
11551
11687
|
`, "utf8");
|
|
11552
|
-
await
|
|
11688
|
+
await fsp10.rename(temporaryEntryDir, entryDir);
|
|
11553
11689
|
return {
|
|
11554
11690
|
cacheHit: false,
|
|
11555
11691
|
sourceDir
|
|
@@ -11563,7 +11699,7 @@ async function resolveExternalTemplateSourceCache(descriptor, populateSourceDir)
|
|
|
11563
11699
|
throw error;
|
|
11564
11700
|
}
|
|
11565
11701
|
const errorCode = getNodeErrorCode(error);
|
|
11566
|
-
if (CACHE_PUBLISH_RACE_ERROR_CODES.has(errorCode) && await
|
|
11702
|
+
if (CACHE_PUBLISH_RACE_ERROR_CODES.has(errorCode) && await isReusableFreshCacheEntry(entryDir, markerPath, sourceDir, nowMs, ttlMs)) {
|
|
11567
11703
|
return {
|
|
11568
11704
|
cacheHit: true,
|
|
11569
11705
|
sourceDir
|
|
@@ -11621,8 +11757,8 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
11621
11757
|
throw new Error(`Failed to download npm template tarball for ${locator.raw}: ${tarballResponse.status}`);
|
|
11622
11758
|
}
|
|
11623
11759
|
const tarballPath = path17.join(path17.dirname(unpackDir), "template.tgz");
|
|
11624
|
-
await
|
|
11625
|
-
await
|
|
11760
|
+
await fsp11.mkdir(unpackDir, { recursive: true });
|
|
11761
|
+
await fsp11.writeFile(tarballPath, await readBufferResponseWithLimit(tarballResponse, {
|
|
11626
11762
|
label: `npm template tarball for ${locator.raw}@${resolvedVersion}`,
|
|
11627
11763
|
maxBytes: getExternalTemplateTarballMaxBytes()
|
|
11628
11764
|
}));
|
|
@@ -11631,7 +11767,7 @@ async function downloadNpmTemplateTarball(locator, resolvedVersion, tarballUrl,
|
|
|
11631
11767
|
file: tarballPath,
|
|
11632
11768
|
strip: 1
|
|
11633
11769
|
});
|
|
11634
|
-
await
|
|
11770
|
+
await fsp11.rm(tarballPath, { force: true });
|
|
11635
11771
|
await assertNoSymlinks2(unpackDir);
|
|
11636
11772
|
}
|
|
11637
11773
|
function selectRegistryVersion(metadata, locator) {
|
|
@@ -11743,8 +11879,8 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
11743
11879
|
return null;
|
|
11744
11880
|
}
|
|
11745
11881
|
const workspacePackagesRoot = path17.resolve(PROJECT_TOOLS_PACKAGE_ROOT, "..");
|
|
11746
|
-
if (
|
|
11747
|
-
for (const entry of
|
|
11882
|
+
if (fs11.existsSync(workspacePackagesRoot)) {
|
|
11883
|
+
for (const entry of fs11.readdirSync(workspacePackagesRoot, {
|
|
11748
11884
|
withFileTypes: true
|
|
11749
11885
|
})) {
|
|
11750
11886
|
if (!entry.isDirectory()) {
|
|
@@ -11752,10 +11888,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
11752
11888
|
}
|
|
11753
11889
|
const packageDir = path17.join(workspacePackagesRoot, entry.name);
|
|
11754
11890
|
const packageJsonPath = path17.join(packageDir, "package.json");
|
|
11755
|
-
if (!
|
|
11891
|
+
if (!fs11.existsSync(packageJsonPath)) {
|
|
11756
11892
|
continue;
|
|
11757
11893
|
}
|
|
11758
|
-
const manifest = JSON.parse(
|
|
11894
|
+
const manifest = JSON.parse(fs11.readFileSync(packageJsonPath, "utf8"));
|
|
11759
11895
|
if (manifest.name === locator.name) {
|
|
11760
11896
|
return {
|
|
11761
11897
|
blockDir: packageDir,
|
|
@@ -11766,7 +11902,7 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
11766
11902
|
}
|
|
11767
11903
|
const workspaceRequire = createRequire2(path17.join(path17.resolve(cwd), "__wp_typia_template_resolver__.cjs"));
|
|
11768
11904
|
try {
|
|
11769
|
-
const packageJsonPath =
|
|
11905
|
+
const packageJsonPath = fs11.realpathSync(workspaceRequire.resolve(`${locator.name}/package.json`));
|
|
11770
11906
|
const sourceDir = path17.dirname(packageJsonPath);
|
|
11771
11907
|
return {
|
|
11772
11908
|
blockDir: sourceDir,
|
|
@@ -11777,10 +11913,10 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
11777
11913
|
if (errorCode === "MODULE_NOT_FOUND" || errorCode === "ERR_PACKAGE_PATH_NOT_EXPORTED") {
|
|
11778
11914
|
for (const basePath of workspaceRequire.resolve.paths(locator.name) ?? []) {
|
|
11779
11915
|
const packageJsonPath = path17.join(basePath, locator.name, "package.json");
|
|
11780
|
-
if (!
|
|
11916
|
+
if (!fs11.existsSync(packageJsonPath)) {
|
|
11781
11917
|
continue;
|
|
11782
11918
|
}
|
|
11783
|
-
const sourceDir = path17.dirname(
|
|
11919
|
+
const sourceDir = path17.dirname(fs11.realpathSync(packageJsonPath));
|
|
11784
11920
|
return {
|
|
11785
11921
|
blockDir: sourceDir,
|
|
11786
11922
|
rootDir: sourceDir
|
|
@@ -11793,25 +11929,25 @@ function resolveInstalledNpmTemplateSource(locator, cwd) {
|
|
|
11793
11929
|
}
|
|
11794
11930
|
function isOfficialWorkspaceTemplateSeed(seed) {
|
|
11795
11931
|
const packageJsonPath = path17.join(seed.rootDir, "package.json");
|
|
11796
|
-
if (!
|
|
11932
|
+
if (!fs11.existsSync(packageJsonPath)) {
|
|
11797
11933
|
return false;
|
|
11798
11934
|
}
|
|
11799
11935
|
try {
|
|
11800
|
-
const packageJson = JSON.parse(
|
|
11936
|
+
const packageJson = JSON.parse(fs11.readFileSync(packageJsonPath, "utf8"));
|
|
11801
11937
|
return packageJson.name === OFFICIAL_WORKSPACE_TEMPLATE_PACKAGE;
|
|
11802
11938
|
} catch {
|
|
11803
11939
|
return false;
|
|
11804
11940
|
}
|
|
11805
11941
|
}
|
|
11806
11942
|
async function assertNoSymlinks2(sourceDir) {
|
|
11807
|
-
const stats = await
|
|
11943
|
+
const stats = await fsp11.lstat(sourceDir);
|
|
11808
11944
|
if (stats.isSymbolicLink()) {
|
|
11809
11945
|
throw new Error(`Template sources may not include symbolic links: ${sourceDir}`);
|
|
11810
11946
|
}
|
|
11811
11947
|
if (!stats.isDirectory()) {
|
|
11812
11948
|
return;
|
|
11813
11949
|
}
|
|
11814
|
-
for (const entry of await
|
|
11950
|
+
for (const entry of await fsp11.readdir(sourceDir)) {
|
|
11815
11951
|
await assertNoSymlinks2(path17.join(sourceDir, entry));
|
|
11816
11952
|
}
|
|
11817
11953
|
}
|
|
@@ -11846,7 +11982,7 @@ function resolveGitHubTemplateDirectory(checkoutDir, locator) {
|
|
|
11846
11982
|
if (relativeSourceDir.startsWith("..") || path17.isAbsolute(relativeSourceDir)) {
|
|
11847
11983
|
throw new Error("GitHub template path must stay within the cloned repository.");
|
|
11848
11984
|
}
|
|
11849
|
-
if (!
|
|
11985
|
+
if (!fs11.existsSync(sourceDir)) {
|
|
11850
11986
|
throw new Error(`GitHub template path does not exist: ${locator.sourcePath}`);
|
|
11851
11987
|
}
|
|
11852
11988
|
return sourceDir;
|
|
@@ -12050,7 +12186,7 @@ async function resolveGitHubTemplateSource(locator) {
|
|
|
12050
12186
|
async function resolveTemplateSeed(locator, cwd) {
|
|
12051
12187
|
if (locator.kind === "path") {
|
|
12052
12188
|
const sourceDir = path17.resolve(cwd, locator.templatePath);
|
|
12053
|
-
if (!
|
|
12189
|
+
if (!fs11.existsSync(sourceDir)) {
|
|
12054
12190
|
throw new Error(`Template path does not exist: ${sourceDir}`);
|
|
12055
12191
|
}
|
|
12056
12192
|
await assertNoSymlinks2(sourceDir);
|
|
@@ -12095,10 +12231,10 @@ async function resolveTemplateSource(templateId, cwd, variables, variant) {
|
|
|
12095
12231
|
throw new Error(`--variant is only supported for official external template configs. Received variant "${variant}" for "${templateId}".`);
|
|
12096
12232
|
}
|
|
12097
12233
|
normalizedSeed = await normalizeWpTypiaTemplateSeed(seed);
|
|
12098
|
-
const supportsMigrationUi =
|
|
12234
|
+
const supportsMigrationUi = await getTemplateProjectTypeAsync(seed.blockDir) === "workspace";
|
|
12099
12235
|
return {
|
|
12100
12236
|
id: templateId,
|
|
12101
|
-
defaultCategory:
|
|
12237
|
+
defaultCategory: await getDefaultCategoryAsync(seed.blockDir),
|
|
12102
12238
|
description: "A remote wp-typia template source",
|
|
12103
12239
|
features: ["Remote source", "wp-typia format"],
|
|
12104
12240
|
format,
|
|
@@ -12115,28 +12251,37 @@ async function resolveTemplateSource(templateId, cwd, variables, variant) {
|
|
|
12115
12251
|
const renderedFormat = normalizedSeed.formatHint ?? await detectTemplateSourceFormat(normalizedSeed.blockDir);
|
|
12116
12252
|
if (renderedFormat === "wp-typia") {
|
|
12117
12253
|
const normalized3 = await normalizeWpTypiaTemplateSeed(normalizedSeed);
|
|
12118
|
-
|
|
12119
|
-
|
|
12120
|
-
|
|
12121
|
-
|
|
12122
|
-
|
|
12123
|
-
|
|
12124
|
-
|
|
12125
|
-
|
|
12126
|
-
|
|
12127
|
-
|
|
12128
|
-
|
|
12129
|
-
|
|
12130
|
-
|
|
12131
|
-
|
|
12132
|
-
|
|
12133
|
-
|
|
12134
|
-
|
|
12135
|
-
|
|
12136
|
-
|
|
12137
|
-
|
|
12138
|
-
|
|
12139
|
-
|
|
12254
|
+
try {
|
|
12255
|
+
const [projectType, defaultCategory] = await Promise.all([
|
|
12256
|
+
getTemplateProjectTypeAsync(normalizedSeed.blockDir),
|
|
12257
|
+
getDefaultCategoryAsync(normalizedSeed.blockDir)
|
|
12258
|
+
]);
|
|
12259
|
+
const supportsMigrationUi = projectType === "workspace";
|
|
12260
|
+
return {
|
|
12261
|
+
cleanup: async () => {
|
|
12262
|
+
await normalized3.cleanup?.();
|
|
12263
|
+
await seed.cleanup?.();
|
|
12264
|
+
},
|
|
12265
|
+
defaultCategory,
|
|
12266
|
+
description: "A wp-typia scaffold normalized from an official external template config",
|
|
12267
|
+
features: [
|
|
12268
|
+
"Remote source",
|
|
12269
|
+
"official external template",
|
|
12270
|
+
"wp-typia format",
|
|
12271
|
+
...supportsMigrationUi ? ["workspace-capable scaffold"] : []
|
|
12272
|
+
],
|
|
12273
|
+
format,
|
|
12274
|
+
id: "remote:create-block-external",
|
|
12275
|
+
isOfficialWorkspaceTemplate,
|
|
12276
|
+
selectedVariant: normalizedSeed.selectedVariant ?? null,
|
|
12277
|
+
supportsMigrationUi,
|
|
12278
|
+
templateDir: normalized3.blockDir,
|
|
12279
|
+
warnings: normalizedSeed.warnings ?? []
|
|
12280
|
+
};
|
|
12281
|
+
} catch (error) {
|
|
12282
|
+
await normalized3.cleanup?.();
|
|
12283
|
+
throw error;
|
|
12284
|
+
}
|
|
12140
12285
|
}
|
|
12141
12286
|
const normalized2 = await normalizeCreateBlockSubset(normalizedSeed, context);
|
|
12142
12287
|
return {
|
|
@@ -12200,10 +12345,16 @@ function compareVersionFloors(left, right) {
|
|
|
12200
12345
|
return 0;
|
|
12201
12346
|
}
|
|
12202
12347
|
function pickHigherVersionFloor(current, candidate) {
|
|
12203
|
-
if (
|
|
12348
|
+
if (current !== undefined) {
|
|
12349
|
+
parseVersionFloorParts(current);
|
|
12350
|
+
}
|
|
12351
|
+
if (candidate !== undefined) {
|
|
12352
|
+
parseVersionFloorParts(candidate);
|
|
12353
|
+
}
|
|
12354
|
+
if (candidate === undefined) {
|
|
12204
12355
|
return current;
|
|
12205
12356
|
}
|
|
12206
|
-
if (
|
|
12357
|
+
if (current === undefined) {
|
|
12207
12358
|
return candidate;
|
|
12208
12359
|
}
|
|
12209
12360
|
return compareVersionFloors(current, candidate) >= 0 ? current : candidate;
|
|
@@ -12283,6 +12434,24 @@ function normalizeSelections(selections) {
|
|
|
12283
12434
|
}
|
|
12284
12435
|
return [...normalized.values()];
|
|
12285
12436
|
}
|
|
12437
|
+
function validateFeatureMinimumVersions(definition) {
|
|
12438
|
+
for (const [platform, value] of [
|
|
12439
|
+
["wordpress", definition.minimumVersions?.wordpress],
|
|
12440
|
+
["php", definition.minimumVersions?.php]
|
|
12441
|
+
]) {
|
|
12442
|
+
if (value === undefined) {
|
|
12443
|
+
continue;
|
|
12444
|
+
}
|
|
12445
|
+
try {
|
|
12446
|
+
pickHigherVersionFloor(value, undefined);
|
|
12447
|
+
} catch (error) {
|
|
12448
|
+
throw new Error([
|
|
12449
|
+
`Invalid ${platform} minimum version floor for AI feature "${definition.id}": "${value}".`,
|
|
12450
|
+
'Expected dotted numeric segments such as "6.7" or "8.1.2".'
|
|
12451
|
+
].join(" "), { cause: error });
|
|
12452
|
+
}
|
|
12453
|
+
}
|
|
12454
|
+
}
|
|
12286
12455
|
function resolveAiFeatureCapabilityPlan(selections, registry = DEFAULT_AI_FEATURE_REGISTRY) {
|
|
12287
12456
|
const requiredFeatures = [];
|
|
12288
12457
|
const optionalFeatures = [];
|
|
@@ -12293,6 +12462,7 @@ function resolveAiFeatureCapabilityPlan(selections, registry = DEFAULT_AI_FEATUR
|
|
|
12293
12462
|
if (!definition) {
|
|
12294
12463
|
throw new Error(`Unknown AI feature capability "${selection.featureId}".`);
|
|
12295
12464
|
}
|
|
12465
|
+
validateFeatureMinimumVersions(definition);
|
|
12296
12466
|
const resolvedDefinition = {
|
|
12297
12467
|
...definition,
|
|
12298
12468
|
mode: selection.mode
|
|
@@ -12340,17 +12510,44 @@ var REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY = [
|
|
|
12340
12510
|
function pickHigherScaffoldVersionFloor(current, candidate) {
|
|
12341
12511
|
return pickHigherVersionFloor(current, candidate) ?? current;
|
|
12342
12512
|
}
|
|
12343
|
-
function pickHigherHeaderVersionFloor(policyValue, currentValue
|
|
12513
|
+
function pickHigherHeaderVersionFloor(policyValue, currentValue, {
|
|
12514
|
+
headerName,
|
|
12515
|
+
onWarning
|
|
12516
|
+
}) {
|
|
12344
12517
|
const normalizedCurrentValue = currentValue.trim();
|
|
12345
12518
|
if (!normalizedCurrentValue) {
|
|
12346
12519
|
return policyValue;
|
|
12347
12520
|
}
|
|
12348
12521
|
try {
|
|
12349
12522
|
return pickHigherScaffoldVersionFloor(policyValue, normalizedCurrentValue);
|
|
12350
|
-
} catch {
|
|
12523
|
+
} catch (error) {
|
|
12524
|
+
const warning = [
|
|
12525
|
+
`Invalid plugin header version floor for ${headerName}: "${normalizedCurrentValue}".`,
|
|
12526
|
+
'Expected dotted numeric segments such as "6.7" or "8.1.2".',
|
|
12527
|
+
`Replacing it with compatibility policy value "${policyValue}".`
|
|
12528
|
+
].join(" ");
|
|
12529
|
+
if (!onWarning) {
|
|
12530
|
+
throw new Error(warning, { cause: error });
|
|
12531
|
+
}
|
|
12532
|
+
onWarning(warning);
|
|
12351
12533
|
return policyValue;
|
|
12352
12534
|
}
|
|
12353
12535
|
}
|
|
12536
|
+
function assertPolicyVersionFloor(headerName, value) {
|
|
12537
|
+
try {
|
|
12538
|
+
parseVersionFloorParts(value);
|
|
12539
|
+
} catch (error) {
|
|
12540
|
+
throw new Error([
|
|
12541
|
+
`Invalid scaffold compatibility policy floor for ${headerName}: "${value}".`,
|
|
12542
|
+
'Expected dotted numeric segments such as "6.7" or "8.1.2".'
|
|
12543
|
+
].join(" "), { cause: error });
|
|
12544
|
+
}
|
|
12545
|
+
}
|
|
12546
|
+
function assertPluginHeaderPolicyVersionFloors(pluginHeader) {
|
|
12547
|
+
assertPolicyVersionFloor("Requires at least", pluginHeader.requiresAtLeast);
|
|
12548
|
+
assertPolicyVersionFloor("Tested up to", pluginHeader.testedUpTo);
|
|
12549
|
+
assertPolicyVersionFloor("Requires PHP", pluginHeader.requiresPhp);
|
|
12550
|
+
}
|
|
12354
12551
|
function formatRuntimeGate(feature) {
|
|
12355
12552
|
return (feature.runtimeGates ?? []).map((gate) => `${feature.label}: ${gate.kind} ${gate.value}`);
|
|
12356
12553
|
}
|
|
@@ -12400,17 +12597,21 @@ function renderScaffoldCompatibilityConfig(policy, indent = "\t\t") {
|
|
|
12400
12597
|
`).map((line, index) => index === 0 ? line : `${indent}${line}`).join(`
|
|
12401
12598
|
`);
|
|
12402
12599
|
}
|
|
12403
|
-
function replacePluginHeaderVersionFloor(source, pattern, policyValue) {
|
|
12600
|
+
function replacePluginHeaderVersionFloor(source, pattern, policyValue, headerName, options) {
|
|
12404
12601
|
return source.replace(pattern, (_match, prefix, currentValue, lineEnding) => {
|
|
12405
12602
|
const versionPrefix = prefix.endsWith(":") ? `${prefix} ` : prefix;
|
|
12406
|
-
return `${versionPrefix}${pickHigherHeaderVersionFloor(policyValue, currentValue
|
|
12603
|
+
return `${versionPrefix}${pickHigherHeaderVersionFloor(policyValue, currentValue, {
|
|
12604
|
+
headerName,
|
|
12605
|
+
onWarning: options.onWarning
|
|
12606
|
+
})}${lineEnding}`;
|
|
12407
12607
|
});
|
|
12408
12608
|
}
|
|
12409
|
-
function updatePluginHeaderCompatibility(source, policy) {
|
|
12609
|
+
function updatePluginHeaderCompatibility(source, policy, options = {}) {
|
|
12410
12610
|
const { pluginHeader } = policy;
|
|
12411
|
-
|
|
12412
|
-
const
|
|
12413
|
-
|
|
12611
|
+
assertPluginHeaderPolicyVersionFloors(pluginHeader);
|
|
12612
|
+
const nextSource = replacePluginHeaderVersionFloor(source, /(\* Requires at least:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresAtLeast, "Requires at least", options);
|
|
12613
|
+
const nextSourceWithTestedUpTo = replacePluginHeaderVersionFloor(nextSource, /(\* Tested up to:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.testedUpTo, "Tested up to", options);
|
|
12614
|
+
return replacePluginHeaderVersionFloor(nextSourceWithTestedUpTo, /(\* Requires PHP:[^\S\r\n]*)([^\r\n]*)(\r?)/u, pluginHeader.requiresPhp, "Requires PHP", options);
|
|
12414
12615
|
}
|
|
12415
12616
|
|
|
12416
12617
|
// ../wp-typia-project-tools/src/runtime/block-generator-service-spec.ts
|
|
@@ -17358,16 +17559,16 @@ async function scaffoldProject({
|
|
|
17358
17559
|
title: "Finalizing scaffold output"
|
|
17359
17560
|
});
|
|
17360
17561
|
const readmePath = path18.join(projectDir, "README.md");
|
|
17361
|
-
if (!
|
|
17362
|
-
await
|
|
17562
|
+
if (!fs12.existsSync(readmePath)) {
|
|
17563
|
+
await fsp12.writeFile(readmePath, buildReadme(resolvedTemplateId, variables, resolvedPackageManager, {
|
|
17363
17564
|
withMigrationUi: isBuiltInTemplate || isWorkspace ? withMigrationUi : false,
|
|
17364
17565
|
withTestPreset: isBuiltInTemplate ? withTestPreset : false,
|
|
17365
17566
|
withWpEnv: isBuiltInTemplate ? withWpEnv : false
|
|
17366
17567
|
}), "utf8");
|
|
17367
17568
|
}
|
|
17368
17569
|
const gitignorePath = path18.join(projectDir, ".gitignore");
|
|
17369
|
-
const existingGitignore =
|
|
17370
|
-
await
|
|
17570
|
+
const existingGitignore = fs12.existsSync(gitignorePath) ? await fsp12.readFile(gitignorePath, "utf8") : "";
|
|
17571
|
+
await fsp12.writeFile(gitignorePath, mergeTextLines(buildGitignore(), existingGitignore), "utf8");
|
|
17371
17572
|
await normalizePackageJson(projectDir, resolvedPackageManager);
|
|
17372
17573
|
if (isBuiltInTemplate) {
|
|
17373
17574
|
const variableGroups = getScaffoldTemplateVariableGroups(variables);
|
|
@@ -17449,4 +17650,4 @@ async function resolveOptionalInteractiveExternalLayerId({
|
|
|
17449
17650
|
|
|
17450
17651
|
export { syncPersistenceRestArtifacts, copyInterpolatedDirectory, listInterpolatedDirectoryOutputs, getPrimaryDevelopmentScript, getOptionalOnboardingSteps, getOptionalOnboardingNote, getOptionalOnboardingShortNote, formatNonEmptyTargetDirectoryError, require_semver2 as require_semver, parseTemplateLocator, 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 };
|
|
17451
17652
|
|
|
17452
|
-
//# debugId=
|
|
17653
|
+
//# debugId=F116A78569127ED064756E2164756E21
|