@wp-typia/project-tools 0.24.7 → 0.24.9
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.
|
@@ -1,24 +1,53 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { parseScaffoldBlockMetadata } from "@wp-typia/block-runtime/blocks";
|
|
4
|
-
import
|
|
4
|
+
import { WORDPRESS_BLOCK_API_COMPATIBILITY } from "@wp-typia/block-types/blocks/compatibility";
|
|
5
5
|
import { createDoctorCheck, resolveWorkspaceBootstrapPath, } from "./cli-doctor-workspace-shared.js";
|
|
6
6
|
import { readJsonFileSync } from "../shared/json-utils.js";
|
|
7
|
-
import { getPropertyNameText } from "../shared/ts-property-names.js";
|
|
8
7
|
import { compareVersionFloors, pickHigherVersionFloor, } from "../shared/version-floor.js";
|
|
9
8
|
import { DEFAULT_SCAFFOLD_WORDPRESS_TARGET_VERSION } from "../templates/scaffold-compatibility.js";
|
|
10
9
|
const WORDPRESS_VERSION_CHECK_CODES = {
|
|
11
10
|
featureMinimum: "wp-typia.workspace.wordpress.feature-minimum",
|
|
12
11
|
testedTarget: "wp-typia.workspace.wordpress.tested-target",
|
|
13
12
|
};
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
13
|
+
// Both entries read the same `variations` field and are distinguished by value type.
|
|
14
|
+
const BLOCK_VARIATION_BLOCK_JSON_KEYS = {
|
|
15
|
+
registrationBlockJsonMetadata: "variations",
|
|
16
|
+
registrationMetadataFile: "variations",
|
|
18
17
|
};
|
|
19
18
|
function isEnabledMetadataValue(value) {
|
|
20
19
|
return value !== undefined && value !== false && value !== null;
|
|
21
20
|
}
|
|
21
|
+
function isEnabledBlockVariationMetadataFeature(feature, value) {
|
|
22
|
+
if (feature === "registrationBlockJsonMetadata") {
|
|
23
|
+
return Array.isArray(value) && value.length > 0;
|
|
24
|
+
}
|
|
25
|
+
if (feature === "registrationMetadataFile") {
|
|
26
|
+
return typeof value === "string" && value.trim().length > 0;
|
|
27
|
+
}
|
|
28
|
+
return isEnabledMetadataValue(value);
|
|
29
|
+
}
|
|
30
|
+
function getNestedMetadataValue(object, key) {
|
|
31
|
+
if (!object) {
|
|
32
|
+
return undefined;
|
|
33
|
+
}
|
|
34
|
+
if (Object.prototype.hasOwnProperty.call(object, key)) {
|
|
35
|
+
return object[key];
|
|
36
|
+
}
|
|
37
|
+
return key
|
|
38
|
+
.split(".")
|
|
39
|
+
.reduce((current, segment) => {
|
|
40
|
+
if (current === null ||
|
|
41
|
+
typeof current !== "object" ||
|
|
42
|
+
Array.isArray(current)) {
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
const record = current;
|
|
46
|
+
return Object.prototype.hasOwnProperty.call(record, segment)
|
|
47
|
+
? record[segment]
|
|
48
|
+
: undefined;
|
|
49
|
+
}, object);
|
|
50
|
+
}
|
|
22
51
|
function getBootstrapHeaderValue(source, headerName) {
|
|
23
52
|
const escapedHeaderName = headerName.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
24
53
|
const pattern = new RegExp(`^\\s*\\*\\s*${escapedHeaderName}:\\s*([^\\r\\n]*)`, "mu");
|
|
@@ -42,6 +71,15 @@ function pushRequirement(requirements, label, version) {
|
|
|
42
71
|
version,
|
|
43
72
|
});
|
|
44
73
|
}
|
|
74
|
+
function pushBlockApiRequirement(requirements, labelPrefix, entry) {
|
|
75
|
+
pushRequirement(requirements, `${labelPrefix} ${entry.label}`, entry.since);
|
|
76
|
+
}
|
|
77
|
+
function readExistingTextFile(filePath) {
|
|
78
|
+
if (!fs.existsSync(filePath)) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
return fs.readFileSync(filePath, "utf8");
|
|
82
|
+
}
|
|
45
83
|
function collectBlockMetadataRequirements(workspace, inventory) {
|
|
46
84
|
const issues = [];
|
|
47
85
|
const requirements = [];
|
|
@@ -61,14 +99,31 @@ function collectBlockMetadataRequirements(workspace, inventory) {
|
|
|
61
99
|
issues.push(`${blockJsonRelativePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
62
100
|
continue;
|
|
63
101
|
}
|
|
64
|
-
|
|
65
|
-
|
|
102
|
+
for (const [feature, entry] of Object.entries(WORDPRESS_BLOCK_API_COMPATIBILITY.blockSupports)) {
|
|
103
|
+
if (isEnabledMetadataValue(getNestedMetadataValue(blockJson.supports, feature))) {
|
|
104
|
+
pushBlockApiRequirement(requirements, `Block ${block.slug}`, entry);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
for (const [feature, entry] of Object.entries(WORDPRESS_BLOCK_API_COMPATIBILITY.blockMetadata)) {
|
|
108
|
+
if (isEnabledMetadataValue(getNestedMetadataValue(blockJson, feature))) {
|
|
109
|
+
pushBlockApiRequirement(requirements, `Block ${block.slug}`, entry);
|
|
110
|
+
}
|
|
66
111
|
}
|
|
67
|
-
|
|
68
|
-
|
|
112
|
+
for (const [feature, entry] of Object.entries(WORDPRESS_BLOCK_API_COMPATIBILITY.blockBindings)) {
|
|
113
|
+
if (entry.runtime.includes("block-json") &&
|
|
114
|
+
isEnabledMetadataValue(getNestedMetadataValue(blockJson, feature))) {
|
|
115
|
+
pushBlockApiRequirement(requirements, `Block ${block.slug}`, entry);
|
|
116
|
+
}
|
|
69
117
|
}
|
|
70
|
-
|
|
71
|
-
|
|
118
|
+
for (const [feature, entry] of Object.entries(WORDPRESS_BLOCK_API_COMPATIBILITY.blockVariations)) {
|
|
119
|
+
if (!entry.runtime.includes("block-json")) {
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
const blockJsonFeature = feature;
|
|
123
|
+
const blockJsonKey = BLOCK_VARIATION_BLOCK_JSON_KEYS[blockJsonFeature];
|
|
124
|
+
if (isEnabledBlockVariationMetadataFeature(blockJsonFeature, getNestedMetadataValue(blockJson, blockJsonKey))) {
|
|
125
|
+
pushBlockApiRequirement(requirements, `Block ${block.slug}`, entry);
|
|
126
|
+
}
|
|
72
127
|
}
|
|
73
128
|
}
|
|
74
129
|
return {
|
|
@@ -76,89 +131,100 @@ function collectBlockMetadataRequirements(workspace, inventory) {
|
|
|
76
131
|
requirements,
|
|
77
132
|
};
|
|
78
133
|
}
|
|
79
|
-
function
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
!statement.modifiers?.some((modifier) => modifier.kind === ts.SyntaxKind.ExportKeyword)) {
|
|
83
|
-
continue;
|
|
84
|
-
}
|
|
85
|
-
for (const declaration of statement.declarationList.declarations) {
|
|
86
|
-
if (ts.isIdentifier(declaration.name) &&
|
|
87
|
-
declaration.name.text === exportName &&
|
|
88
|
-
declaration.initializer &&
|
|
89
|
-
ts.isArrayLiteralExpression(declaration.initializer)) {
|
|
90
|
-
return declaration.initializer;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
134
|
+
function hasGeneratedCoreVariationModule(directoryPath, isRootDirectory = true) {
|
|
135
|
+
if (!fs.existsSync(directoryPath)) {
|
|
136
|
+
return false;
|
|
93
137
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
if (!ts.isPropertyAssignment(property)) {
|
|
99
|
-
continue;
|
|
138
|
+
for (const entry of fs.readdirSync(directoryPath, { withFileTypes: true })) {
|
|
139
|
+
const entryPath = path.join(directoryPath, entry.name);
|
|
140
|
+
if (entry.isDirectory() && hasGeneratedCoreVariationModule(entryPath, false)) {
|
|
141
|
+
return true;
|
|
100
142
|
}
|
|
101
|
-
if (
|
|
102
|
-
|
|
143
|
+
if (!isRootDirectory &&
|
|
144
|
+
entry.isFile() &&
|
|
145
|
+
entry.name.endsWith(".ts") &&
|
|
146
|
+
entry.name !== "index.ts") {
|
|
147
|
+
return true;
|
|
103
148
|
}
|
|
104
149
|
}
|
|
105
|
-
return
|
|
106
|
-
}
|
|
107
|
-
function getObjectLiteralProperty(objectLiteral, key) {
|
|
108
|
-
const property = objectLiteral ? getObjectProperty(objectLiteral, key) : undefined;
|
|
109
|
-
return property && ts.isObjectLiteralExpression(property) ? property : undefined;
|
|
150
|
+
return false;
|
|
110
151
|
}
|
|
111
|
-
function
|
|
112
|
-
const
|
|
113
|
-
|
|
152
|
+
function collectVariationRequirements(workspace, inventory) {
|
|
153
|
+
const requirements = [];
|
|
154
|
+
const variationEntries = WORDPRESS_BLOCK_API_COMPATIBILITY.blockVariations;
|
|
155
|
+
for (const variation of inventory.variations) {
|
|
156
|
+
pushBlockApiRequirement(requirements, `Variation ${variation.block}/${variation.slug}`, variationEntries.editorRegistration);
|
|
157
|
+
}
|
|
158
|
+
const coreVariationsDir = path.join(workspace.projectDir, "src", "editor-plugins", "core-variations");
|
|
159
|
+
if (hasGeneratedCoreVariationModule(coreVariationsDir)) {
|
|
160
|
+
pushBlockApiRequirement(requirements, "Core variations editor plugin", variationEntries.editorRegistration);
|
|
161
|
+
}
|
|
162
|
+
return {
|
|
163
|
+
issues: [],
|
|
164
|
+
requirements,
|
|
165
|
+
};
|
|
114
166
|
}
|
|
115
167
|
function collectInventoryCompatibilityRequirements(inventory) {
|
|
116
|
-
const issues = [];
|
|
117
168
|
const requirements = [];
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
continue;
|
|
169
|
+
for (const ability of inventory.abilities) {
|
|
170
|
+
const wordpressMinimum = ability.compatibility?.hardMinimums.wordpress;
|
|
171
|
+
if (wordpressMinimum) {
|
|
172
|
+
requirements.push({
|
|
173
|
+
label: `Ability ${ability.slug} compatibility metadata`,
|
|
174
|
+
version: wordpressMinimum,
|
|
175
|
+
});
|
|
126
176
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
const slug = getStringLiteralProperty(element, "slug") ?? `entry ${elementIndex + 1}`;
|
|
132
|
-
const compatibility = getObjectLiteralProperty(element, "compatibility");
|
|
133
|
-
const hardMinimums = getObjectLiteralProperty(compatibility, "hardMinimums");
|
|
134
|
-
const wordpressMinimum = hardMinimums
|
|
135
|
-
? getObjectProperty(hardMinimums, "wordpress")
|
|
136
|
-
: undefined;
|
|
137
|
-
if (wordpressMinimum === undefined) {
|
|
138
|
-
return;
|
|
139
|
-
}
|
|
140
|
-
if (!ts.isStringLiteralLike(wordpressMinimum)) {
|
|
141
|
-
issues.push(`${section.exportName}[${elementIndex}].compatibility.hardMinimums.wordpress must be a string literal.`);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
177
|
+
}
|
|
178
|
+
for (const aiFeature of inventory.aiFeatures) {
|
|
179
|
+
const wordpressMinimum = aiFeature.compatibility?.hardMinimums.wordpress;
|
|
180
|
+
if (wordpressMinimum) {
|
|
144
181
|
requirements.push({
|
|
145
|
-
label:
|
|
146
|
-
version: wordpressMinimum
|
|
182
|
+
label: `AI feature ${aiFeature.slug} compatibility metadata`,
|
|
183
|
+
version: wordpressMinimum,
|
|
147
184
|
});
|
|
148
|
-
}
|
|
185
|
+
}
|
|
149
186
|
}
|
|
150
187
|
return {
|
|
151
|
-
issues,
|
|
188
|
+
issues: [],
|
|
189
|
+
requirements,
|
|
190
|
+
};
|
|
191
|
+
}
|
|
192
|
+
function collectBindingSourceRequirements(workspace, inventory) {
|
|
193
|
+
const requirements = [];
|
|
194
|
+
const bindingEntries = WORDPRESS_BLOCK_API_COMPATIBILITY.blockBindings;
|
|
195
|
+
for (const bindingSource of inventory.bindingSources) {
|
|
196
|
+
pushBlockApiRequirement(requirements, `Binding source ${bindingSource.slug}`, bindingEntries.serverRegistration);
|
|
197
|
+
pushBlockApiRequirement(requirements, `Binding source ${bindingSource.slug}`, bindingEntries.editorRegistration);
|
|
198
|
+
const editorFilePath = path.join(workspace.projectDir, bindingSource.editorFile);
|
|
199
|
+
if (readExistingTextFile(editorFilePath)?.includes("getFieldsList")) {
|
|
200
|
+
pushBlockApiRequirement(requirements, `Binding source ${bindingSource.slug}`, bindingEntries.editorFieldsList);
|
|
201
|
+
}
|
|
202
|
+
const serverFilePath = path.join(workspace.projectDir, bindingSource.serverFile);
|
|
203
|
+
if (readExistingTextFile(serverFilePath)?.includes("block_bindings_supported_attributes_")) {
|
|
204
|
+
pushBlockApiRequirement(requirements, `Binding source ${bindingSource.slug}`, bindingEntries.supportedAttributesFilter);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return {
|
|
208
|
+
issues: [],
|
|
152
209
|
requirements,
|
|
153
210
|
};
|
|
154
211
|
}
|
|
155
212
|
function collectWordPressVersionRequirements(workspace, inventory) {
|
|
156
213
|
const blockRequirements = collectBlockMetadataRequirements(workspace, inventory);
|
|
214
|
+
const variationRequirements = collectVariationRequirements(workspace, inventory);
|
|
215
|
+
const bindingRequirements = collectBindingSourceRequirements(workspace, inventory);
|
|
157
216
|
const inventoryRequirements = collectInventoryCompatibilityRequirements(inventory);
|
|
158
217
|
return {
|
|
159
|
-
issues: [
|
|
218
|
+
issues: [
|
|
219
|
+
...blockRequirements.issues,
|
|
220
|
+
...variationRequirements.issues,
|
|
221
|
+
...bindingRequirements.issues,
|
|
222
|
+
...inventoryRequirements.issues,
|
|
223
|
+
],
|
|
160
224
|
requirements: [
|
|
161
225
|
...blockRequirements.requirements,
|
|
226
|
+
...variationRequirements.requirements,
|
|
227
|
+
...bindingRequirements.requirements,
|
|
162
228
|
...inventoryRequirements.requirements,
|
|
163
229
|
],
|
|
164
230
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import ts from "typescript";
|
|
2
2
|
import { getPropertyNameText } from "../shared/ts-property-names.js";
|
|
3
|
+
import { parseVersionFloorParts } from "../shared/version-floor.js";
|
|
3
4
|
import { assertParsedInventoryEntry, } from "./workspace-inventory-parser-validation.js";
|
|
4
5
|
function findExportedArrayLiteral(sourceFile, exportName) {
|
|
5
6
|
for (const statement of sourceFile.statements) {
|
|
@@ -129,6 +130,19 @@ function getOptionalNestedStringProperty(objectLiteral, key, context) {
|
|
|
129
130
|
}
|
|
130
131
|
return expression.text;
|
|
131
132
|
}
|
|
133
|
+
function getOptionalVersionFloorProperty(objectLiteral, key, context) {
|
|
134
|
+
const value = getOptionalNestedStringProperty(objectLiteral, key, context);
|
|
135
|
+
if (value === undefined) {
|
|
136
|
+
return undefined;
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
parseVersionFloorParts(value);
|
|
140
|
+
}
|
|
141
|
+
catch {
|
|
142
|
+
throw new Error(`${context}.${key} must be a dotted numeric version such as "6.7" or "8.1.2" in scripts/block-config.ts.`);
|
|
143
|
+
}
|
|
144
|
+
return value;
|
|
145
|
+
}
|
|
132
146
|
function getRequiredStringArrayProperty(objectLiteral, key, context) {
|
|
133
147
|
const expression = findObjectPropertyExpression(objectLiteral, key);
|
|
134
148
|
if (!expression) {
|
|
@@ -150,8 +164,8 @@ function parseCompatibilityConfigLiteral(objectLiteral, context) {
|
|
|
150
164
|
if (mode !== "baseline" && mode !== "optional" && mode !== "required") {
|
|
151
165
|
throw new Error(`${context}.mode must be baseline, optional, or required in scripts/block-config.ts.`);
|
|
152
166
|
}
|
|
153
|
-
const php =
|
|
154
|
-
const wordpress =
|
|
167
|
+
const php = getOptionalVersionFloorProperty(hardMinimumsObject, "php", `${context}.hardMinimums`);
|
|
168
|
+
const wordpress = getOptionalVersionFloorProperty(hardMinimumsObject, "wordpress", `${context}.hardMinimums`);
|
|
155
169
|
return {
|
|
156
170
|
hardMinimums: {
|
|
157
171
|
...(php ? { php } : {}),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wp-typia/project-tools",
|
|
3
|
-
"version": "0.24.
|
|
3
|
+
"version": "0.24.9",
|
|
4
4
|
"description": "Project orchestration and programmatic tooling for wp-typia",
|
|
5
5
|
"packageManager": "bun@1.3.11",
|
|
6
6
|
"type": "module",
|
|
@@ -121,7 +121,7 @@
|
|
|
121
121
|
"package.json"
|
|
122
122
|
],
|
|
123
123
|
"scripts": {
|
|
124
|
-
"build": "bun run --filter @wp-typia/api-client build && bun run --filter @wp-typia/block-runtime build && rm -rf dist && tsc -p tsconfig.runtime.json",
|
|
124
|
+
"build": "bun run --filter @wp-typia/block-types build && bun run --filter @wp-typia/api-client build && bun run --filter @wp-typia/block-runtime build && rm -rf dist && tsc -p tsconfig.runtime.json",
|
|
125
125
|
"prepack": "bun run build && node ./scripts/publish-manifest.mjs prepare",
|
|
126
126
|
"postpack": "node ./scripts/publish-manifest.mjs restore",
|
|
127
127
|
"test": "bun run build && bun test tests/*.test.ts",
|
|
@@ -168,7 +168,7 @@
|
|
|
168
168
|
"@wp-typia/api-client": "^0.4.6",
|
|
169
169
|
"@wp-typia/block-runtime": "^0.7.1",
|
|
170
170
|
"@wp-typia/rest": "^0.3.14",
|
|
171
|
-
"@wp-typia/block-types": "^0.3.
|
|
171
|
+
"@wp-typia/block-types": "^0.3.5",
|
|
172
172
|
"mustache": "^4.2.0",
|
|
173
173
|
"npm-package-arg": "^13.0.0",
|
|
174
174
|
"semver": "^7.7.3",
|