@wp-typia/project-tools 0.23.1 → 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/dist/runtime/built-in-block-non-ts-basic-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-basic-artifacts.js +84 -0
- package/dist/runtime/built-in-block-non-ts-compound-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-compound-artifacts.js +36 -0
- package/dist/runtime/built-in-block-non-ts-compound-templates.d.ts +23 -0
- package/dist/runtime/built-in-block-non-ts-compound-templates.js +453 -0
- package/dist/runtime/built-in-block-non-ts-family-artifacts.d.ts +8 -26
- package/dist/runtime/built-in-block-non-ts-family-artifacts.js +8 -1034
- package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-interactivity-artifacts.js +83 -0
- package/dist/runtime/built-in-block-non-ts-persistence-artifacts.d.ts +9 -0
- package/dist/runtime/built-in-block-non-ts-persistence-artifacts.js +33 -0
- package/dist/runtime/built-in-block-non-ts-persistence-templates.d.ts +23 -0
- package/dist/runtime/built-in-block-non-ts-persistence-templates.js +395 -0
- package/dist/runtime/cli-add-collision.js +8 -0
- package/dist/runtime/cli-add-help.js +10 -7
- package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
- package/dist/runtime/cli-add-kind-ids.js +1 -0
- package/dist/runtime/cli-add-types.d.ts +28 -1
- package/dist/runtime/cli-add-types.js +2 -0
- package/dist/runtime/cli-add-workspace-ability-anchors.d.ts +24 -0
- package/dist/runtime/cli-add-workspace-ability-anchors.js +294 -0
- package/dist/runtime/cli-add-workspace-ability-registry.d.ts +10 -0
- package/dist/runtime/cli-add-workspace-ability-registry.js +51 -0
- package/dist/runtime/cli-add-workspace-ability-scaffold.d.ts +1 -1
- package/dist/runtime/cli-add-workspace-ability-scaffold.js +5 -311
- package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +1 -1
- package/dist/runtime/cli-add-workspace-ai-anchors.d.ts +4 -4
- package/dist/runtime/cli-add-workspace-ai-anchors.js +4 -232
- package/dist/runtime/cli-add-workspace-ai-scaffold.js +4 -2
- package/dist/runtime/cli-add-workspace-ai-source-emitters.d.ts +1 -4
- package/dist/runtime/cli-add-workspace-ai-source-emitters.js +1 -145
- package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.d.ts +5 -0
- package/dist/runtime/cli-add-workspace-ai-sync-rest-anchors.js +236 -0
- package/dist/runtime/cli-add-workspace-ai-sync-script-source.d.ts +4 -0
- package/dist/runtime/cli-add-workspace-ai-sync-script-source.js +145 -0
- package/dist/runtime/cli-add-workspace-assets.d.ts +6 -63
- package/dist/runtime/cli-add-workspace-assets.js +6 -950
- package/dist/runtime/cli-add-workspace-binding-source-anchors.d.ts +23 -0
- package/dist/runtime/cli-add-workspace-binding-source-anchors.js +112 -0
- package/dist/runtime/cli-add-workspace-binding-source-source-emitters.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-binding-source-source-emitters.js +436 -0
- package/dist/runtime/cli-add-workspace-binding-source-types.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-binding-source-types.js +1 -0
- package/dist/runtime/cli-add-workspace-binding-source.d.ts +40 -0
- package/dist/runtime/cli-add-workspace-binding-source.js +275 -0
- package/dist/runtime/cli-add-workspace-block-style.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-block-style.js +148 -0
- package/dist/runtime/cli-add-workspace-block-transform.d.ts +32 -0
- package/dist/runtime/cli-add-workspace-block-transform.js +197 -0
- package/dist/runtime/cli-add-workspace-contract.js +1 -1
- package/dist/runtime/cli-add-workspace-core-variation.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-core-variation.js +322 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-anchors.d.ts +37 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-anchors.js +206 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.d.ts +47 -0
- package/dist/runtime/cli-add-workspace-editor-plugin-source-emitters.js +219 -0
- package/dist/runtime/cli-add-workspace-editor-plugin.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-editor-plugin.js +78 -0
- package/dist/runtime/cli-add-workspace-hooked-block.d.ts +23 -0
- package/dist/runtime/cli-add-workspace-hooked-block.js +57 -0
- package/dist/runtime/cli-add-workspace-integration-env-files.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-integration-env-files.js +65 -0
- package/dist/runtime/cli-add-workspace-integration-env-package-json.d.ts +38 -0
- package/dist/runtime/cli-add-workspace-integration-env-package-json.js +122 -0
- package/dist/runtime/cli-add-workspace-integration-env-source-emitters.d.ts +44 -0
- package/dist/runtime/cli-add-workspace-integration-env-source-emitters.js +262 -0
- package/dist/runtime/cli-add-workspace-integration-env.js +5 -345
- package/dist/runtime/cli-add-workspace-pattern-anchors.d.ts +10 -0
- package/dist/runtime/cli-add-workspace-pattern-anchors.js +95 -0
- package/dist/runtime/cli-add-workspace-pattern-options.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-pattern-options.js +113 -0
- package/dist/runtime/cli-add-workspace-pattern-source-emitters.d.ts +20 -0
- package/dist/runtime/cli-add-workspace-pattern-source-emitters.js +57 -0
- package/dist/runtime/cli-add-workspace-pattern.d.ts +42 -0
- package/dist/runtime/cli-add-workspace-pattern.js +99 -0
- package/dist/runtime/cli-add-workspace-post-meta.js +1 -1
- package/dist/runtime/cli-add-workspace-registration-hooks.d.ts +50 -0
- package/dist/runtime/cli-add-workspace-registration-hooks.js +162 -0
- package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +6 -9
- package/dist/runtime/cli-add-workspace-rest-anchors.js +6 -466
- package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.d.ts +17 -0
- package/dist/runtime/cli-add-workspace-rest-bootstrap-anchors.js +108 -0
- package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.d.ts +9 -0
- package/dist/runtime/cli-add-workspace-rest-contract-sync-anchors.js +142 -0
- package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.d.ts +51 -0
- package/dist/runtime/cli-add-workspace-rest-generated-source-emitters.js +415 -0
- package/dist/runtime/cli-add-workspace-rest-generated.js +5 -3
- package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.d.ts +80 -0
- package/dist/runtime/cli-add-workspace-rest-manual-source-emitters.js +238 -0
- package/dist/runtime/cli-add-workspace-rest-manual.js +3 -16
- package/dist/runtime/cli-add-workspace-rest-php-templates.d.ts +1 -7
- package/dist/runtime/cli-add-workspace-rest-php-templates.js +3 -322
- package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.d.ts +33 -0
- package/dist/runtime/cli-add-workspace-rest-resource-php-routing-template.js +145 -0
- package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.d.ts +9 -0
- package/dist/runtime/cli-add-workspace-rest-resource-sync-anchors.js +162 -0
- package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.d.ts +7 -0
- package/dist/runtime/cli-add-workspace-rest-schema-helper-php-template.js +193 -0
- package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +5 -99
- package/dist/runtime/cli-add-workspace-rest-source-emitters.js +5 -663
- package/dist/runtime/cli-add-workspace-rest-source-utils.d.ts +17 -0
- package/dist/runtime/cli-add-workspace-rest-source-utils.js +50 -0
- package/dist/runtime/cli-add-workspace-rest-sync-script-shared.d.ts +56 -0
- package/dist/runtime/cli-add-workspace-rest-sync-script-shared.js +122 -0
- package/dist/runtime/cli-add-workspace-rest-types.d.ts +3 -3
- package/dist/runtime/cli-add-workspace-variation.d.ts +22 -0
- package/dist/runtime/cli-add-workspace-variation.js +162 -0
- package/dist/runtime/cli-add-workspace.d.ts +42 -107
- package/dist/runtime/cli-add-workspace.js +42 -674
- package/dist/runtime/cli-add.d.ts +3 -3
- package/dist/runtime/cli-add.js +2 -2
- package/dist/runtime/cli-core.d.ts +2 -1
- package/dist/runtime/cli-core.js +1 -1
- package/dist/runtime/cli-doctor-workspace-bindings.js +59 -0
- package/dist/runtime/cli-doctor-workspace-block-addons.js +33 -5
- package/dist/runtime/cli-doctor.d.ts +2 -0
- package/dist/runtime/cli-doctor.js +13 -2
- package/dist/runtime/cli-help.js +6 -4
- package/dist/runtime/index.d.ts +5 -2
- package/dist/runtime/index.js +4 -2
- package/dist/runtime/local-dev-presets.js +2 -1
- package/dist/runtime/package-versions.d.ts +1 -0
- package/dist/runtime/package-versions.js +10 -2
- package/dist/runtime/pattern-catalog.d.ts +122 -0
- package/dist/runtime/pattern-catalog.js +471 -0
- package/dist/runtime/post-meta-binding-fields.d.ts +46 -0
- package/dist/runtime/post-meta-binding-fields.js +135 -0
- package/dist/runtime/typia-llm-json-schema.d.ts +24 -0
- package/dist/runtime/typia-llm-json-schema.js +33 -0
- package/dist/runtime/typia-llm-openapi-constraints.d.ts +20 -0
- package/dist/runtime/typia-llm-openapi-constraints.js +254 -0
- package/dist/runtime/typia-llm-projection.d.ts +25 -0
- package/dist/runtime/typia-llm-projection.js +58 -0
- package/dist/runtime/typia-llm-render.d.ts +21 -0
- package/dist/runtime/typia-llm-render.js +252 -0
- package/dist/runtime/typia-llm-sync.d.ts +10 -0
- package/dist/runtime/typia-llm-sync.js +63 -0
- package/dist/runtime/typia-llm-types.d.ts +197 -0
- package/dist/runtime/typia-llm-types.js +1 -0
- package/dist/runtime/typia-llm.d.ts +9 -255
- package/dist/runtime/typia-llm.js +5 -634
- package/dist/runtime/workspace-inventory-mutations.js +13 -0
- package/dist/runtime/workspace-inventory-section-descriptors.js +9 -1
- package/dist/runtime/workspace-inventory-templates.d.ts +2 -2
- package/dist/runtime/workspace-inventory-templates.js +9 -1
- package/dist/runtime/workspace-inventory-types.d.ts +9 -1
- package/package.json +8 -3
- package/templates/_shared/compound/core/scripts/block-config.ts.mustache +22 -0
- package/templates/_shared/compound/core/scripts/sync-types-to-block-json.ts.mustache +103 -2
- package/templates/_shared/compound/core/src/inner-blocks-templates.ts.mustache +13 -0
- package/templates/_shared/compound/persistence/scripts/block-config.ts.mustache +22 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { PATTERN_CATALOG_SCOPE_IDS, type PatternCatalogScope } from "./pattern-catalog.js";
|
|
1
2
|
export { ADD_KIND_IDS } from "./cli-add-kind-ids.js";
|
|
2
3
|
export type { AddKindId } from "./cli-add-kind-ids.js";
|
|
4
|
+
export { PATTERN_CATALOG_SCOPE_IDS };
|
|
5
|
+
export type { PatternCatalogScope };
|
|
3
6
|
/**
|
|
4
7
|
* Supported plugin-level REST resource methods accepted by
|
|
5
8
|
* `wp-typia add rest-resource --methods`.
|
|
@@ -87,6 +90,18 @@ export interface RunAddVariationCommandOptions {
|
|
|
87
90
|
cwd?: string;
|
|
88
91
|
variationName: string;
|
|
89
92
|
}
|
|
93
|
+
/**
|
|
94
|
+
* Options for `wp-typia add core-variation`.
|
|
95
|
+
*
|
|
96
|
+
* @property cwd Working directory used to resolve the nearest official workspace.
|
|
97
|
+
* @property targetBlockName Full `namespace/block` name that receives the variation.
|
|
98
|
+
* @property variationName Human-entered variation name normalized into a slug.
|
|
99
|
+
*/
|
|
100
|
+
export interface RunAddCoreVariationCommandOptions {
|
|
101
|
+
cwd?: string;
|
|
102
|
+
targetBlockName: string;
|
|
103
|
+
variationName: string;
|
|
104
|
+
}
|
|
90
105
|
/**
|
|
91
106
|
* Options for `wp-typia add style`.
|
|
92
107
|
*
|
|
@@ -126,8 +141,14 @@ export interface RunAddBlockTransformCommandOptions {
|
|
|
126
141
|
* @property patternName Human-entered pattern name normalized into a slug.
|
|
127
142
|
*/
|
|
128
143
|
export interface RunAddPatternCommandOptions {
|
|
144
|
+
catalogTitle?: string;
|
|
145
|
+
contentFile?: string;
|
|
129
146
|
cwd?: string;
|
|
130
147
|
patternName: string;
|
|
148
|
+
patternScope?: PatternCatalogScope | string;
|
|
149
|
+
sectionRole?: string;
|
|
150
|
+
tags?: readonly string[] | string;
|
|
151
|
+
thumbnailUrl?: string;
|
|
131
152
|
}
|
|
132
153
|
/**
|
|
133
154
|
* Options for `wp-typia add binding-source`.
|
|
@@ -136,12 +157,18 @@ export interface RunAddPatternCommandOptions {
|
|
|
136
157
|
* @property blockName Optional existing workspace block slug or full block name.
|
|
137
158
|
* @property bindingSourceName Human-entered binding source name normalized into a slug.
|
|
138
159
|
* @property cwd Working directory used to resolve the nearest official workspace.
|
|
160
|
+
* @property metaPath Optional top-level post-meta field used as the default
|
|
161
|
+
* source argument when `postMetaName` is provided.
|
|
162
|
+
* @property postMetaName Optional generated post-meta contract slug used to
|
|
163
|
+
* back the binding source with `get_post_meta()`.
|
|
139
164
|
*/
|
|
140
165
|
export interface RunAddBindingSourceCommandOptions {
|
|
141
166
|
attributeName?: string;
|
|
142
167
|
blockName?: string;
|
|
143
168
|
bindingSourceName: string;
|
|
144
169
|
cwd?: string;
|
|
170
|
+
metaPath?: string;
|
|
171
|
+
postMetaName?: string;
|
|
145
172
|
}
|
|
146
173
|
/**
|
|
147
174
|
* Options for `wp-typia add contract`.
|
|
@@ -240,7 +267,7 @@ export interface RunAddRestResourceCommandOptions {
|
|
|
240
267
|
secretFieldName?: string;
|
|
241
268
|
secretHasValueFieldName?: string;
|
|
242
269
|
secretMaskedResponseFieldName?: string;
|
|
243
|
-
secretPreserveOnEmpty?: boolean
|
|
270
|
+
secretPreserveOnEmpty?: boolean;
|
|
244
271
|
secretStateFieldName?: string;
|
|
245
272
|
}
|
|
246
273
|
/**
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { suggestCloseId } from "./id-suggestions.js";
|
|
2
|
+
import { PATTERN_CATALOG_SCOPE_IDS, } from "./pattern-catalog.js";
|
|
2
3
|
export { ADD_KIND_IDS } from "./cli-add-kind-ids.js";
|
|
4
|
+
export { PATTERN_CATALOG_SCOPE_IDS };
|
|
3
5
|
/**
|
|
4
6
|
* Supported plugin-level REST resource methods accepted by
|
|
5
7
|
* `wp-typia add rest-resource --methods`.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { WorkspaceProject } from "./workspace-project.js";
|
|
2
|
+
/**
|
|
3
|
+
* Ensure the workspace bootstrap loads generated ability PHP modules and
|
|
4
|
+
* enqueues the generated ability editor script module.
|
|
5
|
+
*/
|
|
6
|
+
export declare function ensureAbilityBootstrapAnchors(workspace: WorkspaceProject): Promise<void>;
|
|
7
|
+
/**
|
|
8
|
+
* Ensure ability package scripts and WordPress ability runtime dependencies
|
|
9
|
+
* are present without downgrading existing compatible ranges.
|
|
10
|
+
*/
|
|
11
|
+
export declare function ensureAbilityPackageScripts(workspace: WorkspaceProject): Promise<void>;
|
|
12
|
+
/**
|
|
13
|
+
* Ensure `scripts/sync-project.ts` delegates to the generated ability sync
|
|
14
|
+
* script when present.
|
|
15
|
+
*/
|
|
16
|
+
export declare function ensureAbilitySyncProjectAnchors(workspace: WorkspaceProject): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Ensure the workspace build script includes optional ability client entries.
|
|
19
|
+
*/
|
|
20
|
+
export declare function ensureAbilityBuildScriptAnchors(workspace: WorkspaceProject): Promise<void>;
|
|
21
|
+
/**
|
|
22
|
+
* Ensure webpack discovers the optional ability client registry bundle.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ensureAbilityWebpackAnchors(workspace: WorkspaceProject): Promise<void>;
|
|
@@ -0,0 +1,294 @@
|
|
|
1
|
+
import { promises as fsp } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import semver from "semver";
|
|
4
|
+
import { getWorkspaceBootstrapPath, patchFile, } from "./cli-add-shared.js";
|
|
5
|
+
import { ABILITY_EDITOR_ASSET, ABILITY_EDITOR_SCRIPT, ABILITY_SERVER_GLOB, WP_ABILITIES_SCRIPT_MODULE_ID, WP_CORE_ABILITIES_SCRIPT_MODULE_ID, } from "./cli-add-workspace-ability-types.js";
|
|
6
|
+
import { appendPhpSnippetBeforeClosingTag, insertPhpSnippetBeforeWorkspaceAnchors, } from "./cli-add-workspace-mutation.js";
|
|
7
|
+
import { readJsonFile } from "./json-utils.js";
|
|
8
|
+
import { DEFAULT_WORDPRESS_ABILITIES_VERSION, DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION, } from "./package-versions.js";
|
|
9
|
+
import { findPhpFunctionRange, hasPhpFunctionCall, hasPhpFunctionDefinition, replacePhpFunctionDefinition, } from "./php-utils.js";
|
|
10
|
+
function resolveManagedDependencyVersion(existingVersion, requiredVersion) {
|
|
11
|
+
if (!existingVersion) {
|
|
12
|
+
return requiredVersion;
|
|
13
|
+
}
|
|
14
|
+
const existingMinimum = semver.minVersion(existingVersion);
|
|
15
|
+
const requiredMinimum = semver.minVersion(requiredVersion);
|
|
16
|
+
if (!existingMinimum || !requiredMinimum) {
|
|
17
|
+
return requiredVersion;
|
|
18
|
+
}
|
|
19
|
+
return semver.gte(existingMinimum, requiredMinimum)
|
|
20
|
+
? existingVersion
|
|
21
|
+
: requiredVersion;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Ensure the workspace bootstrap loads generated ability PHP modules and
|
|
25
|
+
* enqueues the generated ability editor script module.
|
|
26
|
+
*/
|
|
27
|
+
export async function ensureAbilityBootstrapAnchors(workspace) {
|
|
28
|
+
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
29
|
+
await patchFile(bootstrapPath, (source) => {
|
|
30
|
+
let nextSource = source;
|
|
31
|
+
const workspaceBaseName = workspace.packageName.split("/").pop() ?? workspace.packageName;
|
|
32
|
+
const loadFunctionName = `${workspace.workspace.phpPrefix}_load_workflow_abilities`;
|
|
33
|
+
const enqueueFunctionName = `${workspace.workspace.phpPrefix}_enqueue_workflow_abilities`;
|
|
34
|
+
const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
|
|
35
|
+
const adminEnqueueHook = `add_action( 'admin_enqueue_scripts', '${enqueueFunctionName}' );`;
|
|
36
|
+
const editorEnqueueHook = `add_action( 'enqueue_block_editor_assets', '${enqueueFunctionName}' );`;
|
|
37
|
+
const loadFunction = `
|
|
38
|
+
|
|
39
|
+
function ${loadFunctionName}() {
|
|
40
|
+
\tforeach ( glob( __DIR__ . '${ABILITY_SERVER_GLOB}' ) ?: array() as $ability_module ) {
|
|
41
|
+
\t\trequire_once $ability_module;
|
|
42
|
+
\t}
|
|
43
|
+
}
|
|
44
|
+
`;
|
|
45
|
+
const enqueueFunction = `
|
|
46
|
+
|
|
47
|
+
function ${enqueueFunctionName}() {
|
|
48
|
+
\tif ( ! class_exists( 'WP_Ability' ) ) {
|
|
49
|
+
\t\treturn;
|
|
50
|
+
\t}
|
|
51
|
+
|
|
52
|
+
\t$script_path = __DIR__ . '/${ABILITY_EDITOR_SCRIPT}';
|
|
53
|
+
\t$asset_path = __DIR__ . '/${ABILITY_EDITOR_ASSET}';
|
|
54
|
+
|
|
55
|
+
\tif ( ! file_exists( $script_path ) || ! file_exists( $asset_path ) ) {
|
|
56
|
+
\t\treturn;
|
|
57
|
+
\t}
|
|
58
|
+
|
|
59
|
+
\t$asset = require $asset_path;
|
|
60
|
+
\tif ( ! is_array( $asset ) ) {
|
|
61
|
+
\t\t$asset = array();
|
|
62
|
+
\t}
|
|
63
|
+
|
|
64
|
+
\t$dependencies = isset( $asset['dependencies'] ) && is_array( $asset['dependencies'] )
|
|
65
|
+
\t\t? $asset['dependencies']
|
|
66
|
+
\t\t: array();
|
|
67
|
+
|
|
68
|
+
\tforeach ( array( '${WP_CORE_ABILITIES_SCRIPT_MODULE_ID}', '${WP_ABILITIES_SCRIPT_MODULE_ID}' ) as $ability_dependency ) {
|
|
69
|
+
\t\t$has_dependency = false;
|
|
70
|
+
\t\tforeach ( $dependencies as $dependency ) {
|
|
71
|
+
\t\t\t$dependency_id = is_array( $dependency ) && isset( $dependency['id'] )
|
|
72
|
+
\t\t\t\t? $dependency['id']
|
|
73
|
+
\t\t\t\t: $dependency;
|
|
74
|
+
\t\t\tif ( $dependency_id === $ability_dependency ) {
|
|
75
|
+
\t\t\t\t$has_dependency = true;
|
|
76
|
+
\t\t\t\tbreak;
|
|
77
|
+
\t\t\t}
|
|
78
|
+
\t\t}
|
|
79
|
+
\t\tif ( ! $has_dependency ) {
|
|
80
|
+
\t\t\t$dependencies[] = $ability_dependency;
|
|
81
|
+
\t\t}
|
|
82
|
+
\t}
|
|
83
|
+
|
|
84
|
+
\tif ( ! function_exists( 'wp_enqueue_script_module' ) ) {
|
|
85
|
+
\t\treturn;
|
|
86
|
+
\t}
|
|
87
|
+
|
|
88
|
+
\twp_enqueue_script_module(
|
|
89
|
+
\t\t'${workspaceBaseName}-abilities',
|
|
90
|
+
\t\tplugins_url( '${ABILITY_EDITOR_SCRIPT}', __FILE__ ),
|
|
91
|
+
\t\t$dependencies,
|
|
92
|
+
\t\tisset( $asset['version'] ) ? $asset['version'] : filemtime( $script_path )
|
|
93
|
+
\t);
|
|
94
|
+
}
|
|
95
|
+
`;
|
|
96
|
+
if (!hasPhpFunctionDefinition(nextSource, loadFunctionName)) {
|
|
97
|
+
nextSource = insertPhpSnippetBeforeWorkspaceAnchors(nextSource, loadFunction);
|
|
98
|
+
}
|
|
99
|
+
if (!hasPhpFunctionDefinition(nextSource, enqueueFunctionName)) {
|
|
100
|
+
nextSource = insertPhpSnippetBeforeWorkspaceAnchors(nextSource, enqueueFunction);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const functionRange = findPhpFunctionRange(nextSource, enqueueFunctionName);
|
|
104
|
+
const functionSource = functionRange
|
|
105
|
+
? nextSource.slice(functionRange.start, functionRange.end)
|
|
106
|
+
: "";
|
|
107
|
+
if (!hasPhpFunctionCall(functionSource, "wp_enqueue_script_module")) {
|
|
108
|
+
const replacedSource = replacePhpFunctionDefinition(nextSource, enqueueFunctionName, enqueueFunction, { trimReplacementStart: true });
|
|
109
|
+
if (!replacedSource) {
|
|
110
|
+
throw new Error(`Unable to repair ${path.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
|
|
111
|
+
}
|
|
112
|
+
nextSource = replacedSource;
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (!nextSource.includes(loadHook)) {
|
|
116
|
+
nextSource = appendPhpSnippetBeforeClosingTag(nextSource, loadHook);
|
|
117
|
+
}
|
|
118
|
+
if (!nextSource.includes(adminEnqueueHook)) {
|
|
119
|
+
nextSource = appendPhpSnippetBeforeClosingTag(nextSource, adminEnqueueHook);
|
|
120
|
+
}
|
|
121
|
+
if (!nextSource.includes(editorEnqueueHook)) {
|
|
122
|
+
nextSource = appendPhpSnippetBeforeClosingTag(nextSource, editorEnqueueHook);
|
|
123
|
+
}
|
|
124
|
+
return nextSource;
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Ensure ability package scripts and WordPress ability runtime dependencies
|
|
129
|
+
* are present without downgrading existing compatible ranges.
|
|
130
|
+
*/
|
|
131
|
+
export async function ensureAbilityPackageScripts(workspace) {
|
|
132
|
+
const packageJsonPath = path.join(workspace.projectDir, "package.json");
|
|
133
|
+
const packageJson = await readJsonFile(packageJsonPath, {
|
|
134
|
+
context: "workspace package manifest",
|
|
135
|
+
});
|
|
136
|
+
const nextScripts = {
|
|
137
|
+
...(packageJson.scripts ?? {}),
|
|
138
|
+
"sync-abilities": packageJson.scripts?.["sync-abilities"] ?? "tsx scripts/sync-abilities.ts",
|
|
139
|
+
};
|
|
140
|
+
const nextDependencies = {
|
|
141
|
+
...(packageJson.dependencies ?? {}),
|
|
142
|
+
[WP_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_ABILITIES_VERSION),
|
|
143
|
+
[WP_CORE_ABILITIES_SCRIPT_MODULE_ID]: resolveManagedDependencyVersion(packageJson.dependencies?.[WP_CORE_ABILITIES_SCRIPT_MODULE_ID], DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION),
|
|
144
|
+
};
|
|
145
|
+
if (JSON.stringify(nextScripts) === JSON.stringify(packageJson.scripts ?? {}) &&
|
|
146
|
+
JSON.stringify(nextDependencies) ===
|
|
147
|
+
JSON.stringify(packageJson.dependencies ?? {})) {
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
packageJson.scripts = nextScripts;
|
|
151
|
+
packageJson.dependencies = nextDependencies;
|
|
152
|
+
await fsp.writeFile(packageJsonPath, `${JSON.stringify(packageJson, null, "\t")}\n`, "utf8");
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* Ensure `scripts/sync-project.ts` delegates to the generated ability sync
|
|
156
|
+
* script when present.
|
|
157
|
+
*/
|
|
158
|
+
export async function ensureAbilitySyncProjectAnchors(workspace) {
|
|
159
|
+
const syncProjectScriptPath = path.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
160
|
+
await patchFile(syncProjectScriptPath, (source) => {
|
|
161
|
+
let nextSource = source;
|
|
162
|
+
const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
|
|
163
|
+
const syncAbilitiesConst = "const syncAbilitiesScriptPath = path.join( 'scripts', 'sync-abilities.ts' );";
|
|
164
|
+
const syncRestBlockPattern = /if \( fs\.existsSync\( path\.resolve\( process\.cwd\(\), syncRestScriptPath \) \) \) \{\n\s*runSyncScript\( syncRestScriptPath, options \);\n\s*\}/u;
|
|
165
|
+
const syncAbilitiesBlock = [
|
|
166
|
+
"if ( fs.existsSync( path.resolve( process.cwd(), syncAbilitiesScriptPath ) ) ) {",
|
|
167
|
+
"\trunSyncScript( syncAbilitiesScriptPath, options );",
|
|
168
|
+
"}",
|
|
169
|
+
].join("\n");
|
|
170
|
+
if (!nextSource.includes(syncAbilitiesConst)) {
|
|
171
|
+
if (!nextSource.includes(syncRestConst)) {
|
|
172
|
+
throw new Error([
|
|
173
|
+
`ensureAbilitySyncProjectAnchors could not patch ${path.basename(syncProjectScriptPath)}.`,
|
|
174
|
+
"Missing the expected sync-rest script constant in scripts/sync-project.ts.",
|
|
175
|
+
"Restore the generated template or wire sync-abilities manually before retrying.",
|
|
176
|
+
].join(" "));
|
|
177
|
+
}
|
|
178
|
+
nextSource = nextSource.replace(syncRestConst, `${syncRestConst}\n${syncAbilitiesConst}`);
|
|
179
|
+
}
|
|
180
|
+
if (!nextSource.includes("runSyncScript( syncAbilitiesScriptPath, options );")) {
|
|
181
|
+
if (!syncRestBlockPattern.test(nextSource)) {
|
|
182
|
+
throw new Error([
|
|
183
|
+
`ensureAbilitySyncProjectAnchors could not patch ${path.basename(syncProjectScriptPath)}.`,
|
|
184
|
+
"Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
|
|
185
|
+
"Restore the generated template or wire sync-abilities manually before retrying.",
|
|
186
|
+
].join(" "));
|
|
187
|
+
}
|
|
188
|
+
nextSource = nextSource.replace(syncRestBlockPattern, (match) => `${match}\n\n${syncAbilitiesBlock}`);
|
|
189
|
+
}
|
|
190
|
+
return nextSource;
|
|
191
|
+
});
|
|
192
|
+
}
|
|
193
|
+
/**
|
|
194
|
+
* Ensure the workspace build script includes optional ability client entries.
|
|
195
|
+
*/
|
|
196
|
+
export async function ensureAbilityBuildScriptAnchors(workspace) {
|
|
197
|
+
const buildScriptPath = path.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
198
|
+
await patchFile(buildScriptPath, (source) => {
|
|
199
|
+
let nextSource = source;
|
|
200
|
+
if (/['"]src\/abilities\/index\.(?:ts|js)['"]/u.test(nextSource)) {
|
|
201
|
+
return nextSource;
|
|
202
|
+
}
|
|
203
|
+
const sharedEntriesPattern = /(for\s*\(\s*const\s+relativePath\s+of\s+\[)([\s\S]*?)(\]\s*\)\s*\{)/u;
|
|
204
|
+
const match = nextSource.match(sharedEntriesPattern);
|
|
205
|
+
if (!match ||
|
|
206
|
+
!/['"]src\/bindings\/index\.(?:ts|js)['"]/u.test(match[2]) ||
|
|
207
|
+
!/['"]src\/editor-plugins\/index\.(?:tsx|ts|js)['"]/u.test(match[2])) {
|
|
208
|
+
throw new Error([
|
|
209
|
+
`ensureAbilityBuildScriptAnchors could not patch ${path.basename(buildScriptPath)}.`,
|
|
210
|
+
"Missing the expected shared editor entries array in scripts/build-workspace.mjs.",
|
|
211
|
+
"Restore the generated template or wire abilities/index manually before retrying.",
|
|
212
|
+
].join(" "));
|
|
213
|
+
}
|
|
214
|
+
nextSource = nextSource.replace(sharedEntriesPattern, (fullMatch, sharedEntries) => {
|
|
215
|
+
const missingAbilityEntries = [
|
|
216
|
+
"'src/abilities/index.ts'",
|
|
217
|
+
"'src/abilities/index.js'",
|
|
218
|
+
].filter((entry) => !sharedEntries.includes(entry));
|
|
219
|
+
if (missingAbilityEntries.length === 0) {
|
|
220
|
+
return fullMatch;
|
|
221
|
+
}
|
|
222
|
+
const itemIndent = sharedEntries.match(/\n([ \t]*)['"]/u)?.[1] ?? "\t\t";
|
|
223
|
+
const trimmedEntries = sharedEntries.replace(/\s*$/u, "");
|
|
224
|
+
const trailingWhitespace = sharedEntries.slice(trimmedEntries.length);
|
|
225
|
+
const separator = trimmedEntries.trimEnd().endsWith(",") ? "" : ",";
|
|
226
|
+
const nextEntries = `${trimmedEntries}${separator}` +
|
|
227
|
+
missingAbilityEntries.map((entry) => `\n${itemIndent}${entry},`).join("") +
|
|
228
|
+
trailingWhitespace;
|
|
229
|
+
return fullMatch.replace(sharedEntries, nextEntries);
|
|
230
|
+
});
|
|
231
|
+
return nextSource;
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
/**
|
|
235
|
+
* Ensure webpack discovers the optional ability client registry bundle.
|
|
236
|
+
*/
|
|
237
|
+
export async function ensureAbilityWebpackAnchors(workspace) {
|
|
238
|
+
const webpackConfigPath = path.join(workspace.projectDir, "webpack.config.js");
|
|
239
|
+
await patchFile(webpackConfigPath, (source) => {
|
|
240
|
+
if (/['"]abilities\/index['"]/u.test(source)) {
|
|
241
|
+
return source;
|
|
242
|
+
}
|
|
243
|
+
const optionalModuleReturnPattern = /(function\s+getOptionalModuleEntries\s*\(\)\s*\{[\s\S]*?)(\n\treturn Object\.fromEntries\(\s*entries\s*\);\n\})/u;
|
|
244
|
+
if (optionalModuleReturnPattern.test(source)) {
|
|
245
|
+
return source.replace(optionalModuleReturnPattern, `$1
|
|
246
|
+
|
|
247
|
+
\tfor ( const [ entryName, candidates ] of [
|
|
248
|
+
\t\t[
|
|
249
|
+
\t\t\t'abilities/index',
|
|
250
|
+
\t\t\t[ 'src/abilities/index.ts', 'src/abilities/index.js' ],
|
|
251
|
+
\t\t],
|
|
252
|
+
\t] ) {
|
|
253
|
+
\t\tfor ( const relativePath of candidates ) {
|
|
254
|
+
\t\t\tconst entryPath = path.resolve( process.cwd(), relativePath );
|
|
255
|
+
\t\t\tif ( ! fs.existsSync( entryPath ) ) {
|
|
256
|
+
\t\t\t\tcontinue;
|
|
257
|
+
\t\t\t}
|
|
258
|
+
|
|
259
|
+
\t\t\tentries.push( [ entryName, entryPath ] );
|
|
260
|
+
\t\t\tbreak;
|
|
261
|
+
\t\t}
|
|
262
|
+
\t}$2`);
|
|
263
|
+
}
|
|
264
|
+
const sharedEntriesPattern = /for\s*\(\s*const\s+\[\s*entryName\s*,\s*candidates\s*\]\s+of\s+\[([\s\S]*?)\]\s*\)\s*\{/u;
|
|
265
|
+
const match = source.match(sharedEntriesPattern);
|
|
266
|
+
if (!match ||
|
|
267
|
+
!match[1].includes("bindings/index") ||
|
|
268
|
+
!match[1].includes("editor-plugins/index")) {
|
|
269
|
+
throw new Error([
|
|
270
|
+
`ensureAbilityWebpackAnchors could not patch ${path.basename(webpackConfigPath)}.`,
|
|
271
|
+
"Missing the expected shared editor entries block in webpack.config.js.",
|
|
272
|
+
"Restore the generated template or wire abilities/index manually before retrying.",
|
|
273
|
+
].join(" "));
|
|
274
|
+
}
|
|
275
|
+
return source.replace(sharedEntriesPattern, (fullMatch, sharedEntries) => {
|
|
276
|
+
if (/['"]abilities\/index['"]/u.test(sharedEntries)) {
|
|
277
|
+
return fullMatch;
|
|
278
|
+
}
|
|
279
|
+
const tupleIndent = sharedEntries.match(/\n([ \t]*)\[/u)?.[1] ?? "\t\t";
|
|
280
|
+
const nestedIndent = `${tupleIndent}\t`;
|
|
281
|
+
const trimmedEntries = sharedEntries.replace(/\s*$/u, "");
|
|
282
|
+
const trailingWhitespace = sharedEntries.slice(trimmedEntries.length);
|
|
283
|
+
const separator = trimmedEntries.trimEnd().endsWith(",") ? "" : ",";
|
|
284
|
+
const abilityTuple = [
|
|
285
|
+
`${tupleIndent}[`,
|
|
286
|
+
`${nestedIndent}'abilities/index',`,
|
|
287
|
+
`${nestedIndent}[ 'src/abilities/index.ts', 'src/abilities/index.js' ],`,
|
|
288
|
+
`${tupleIndent}],`,
|
|
289
|
+
].join("\n");
|
|
290
|
+
const nextEntries = `${trimmedEntries}${separator}\n${abilityTuple}` + trailingWhitespace;
|
|
291
|
+
return fullMatch.replace(sharedEntries, nextEntries);
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve the workspace ability client registry path, preserving JS registries
|
|
3
|
+
* when older projects already use them.
|
|
4
|
+
*/
|
|
5
|
+
export declare function resolveAbilityRegistryPath(projectDir: string): Promise<string>;
|
|
6
|
+
/**
|
|
7
|
+
* Rewrite the generated ability client registry while preserving existing
|
|
8
|
+
* generated entries and extension-suffixed exports.
|
|
9
|
+
*/
|
|
10
|
+
export declare function writeAbilityRegistry(projectDir: string, abilitySlug: string): Promise<void>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { promises as fsp } from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { readOptionalUtf8File, pathExists } from "./fs-async.js";
|
|
4
|
+
import { buildAbilityRegistrySource, } from "./cli-add-workspace-ability-templates.js";
|
|
5
|
+
import { ABILITY_REGISTRY_END_MARKER, ABILITY_REGISTRY_START_MARKER, } from "./cli-add-workspace-ability-types.js";
|
|
6
|
+
import { escapeRegex } from "./php-utils.js";
|
|
7
|
+
import { readWorkspaceInventoryAsync, } from "./workspace-inventory.js";
|
|
8
|
+
/**
|
|
9
|
+
* Resolve the workspace ability client registry path, preserving JS registries
|
|
10
|
+
* when older projects already use them.
|
|
11
|
+
*/
|
|
12
|
+
export async function resolveAbilityRegistryPath(projectDir) {
|
|
13
|
+
const abilitiesDir = path.join(projectDir, "src", "abilities");
|
|
14
|
+
for (const candidatePath of [
|
|
15
|
+
path.join(abilitiesDir, "index.ts"),
|
|
16
|
+
path.join(abilitiesDir, "index.js"),
|
|
17
|
+
]) {
|
|
18
|
+
if (await pathExists(candidatePath)) {
|
|
19
|
+
return candidatePath;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
return path.join(abilitiesDir, "index.ts");
|
|
23
|
+
}
|
|
24
|
+
async function readAbilityRegistrySlugs(registryPath) {
|
|
25
|
+
const source = await readOptionalUtf8File(registryPath);
|
|
26
|
+
if (source === null) {
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
return Array.from(source.matchAll(/^\s*export\s+\*\s+from\s+['"]\.\/([^/'"]+)\/client(?:\.[cm]?[jt]sx?)?['"];?\s*$/gmu)).map((match) => match[1]);
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Rewrite the generated ability client registry while preserving existing
|
|
33
|
+
* generated entries and extension-suffixed exports.
|
|
34
|
+
*/
|
|
35
|
+
export async function writeAbilityRegistry(projectDir, abilitySlug) {
|
|
36
|
+
const abilitiesDir = path.join(projectDir, "src", "abilities");
|
|
37
|
+
const registryPath = await resolveAbilityRegistryPath(projectDir);
|
|
38
|
+
await fsp.mkdir(abilitiesDir, { recursive: true });
|
|
39
|
+
const existingAbilitySlugs = (await readWorkspaceInventoryAsync(projectDir)).abilities.map((entry) => entry.slug);
|
|
40
|
+
const existingRegistrySlugs = await readAbilityRegistrySlugs(registryPath);
|
|
41
|
+
const nextAbilitySlugs = Array.from(new Set([...existingAbilitySlugs, ...existingRegistrySlugs, abilitySlug])).sort();
|
|
42
|
+
const generatedSection = buildAbilityRegistrySource(nextAbilitySlugs);
|
|
43
|
+
const existingSource = (await readOptionalUtf8File(registryPath)) ?? "";
|
|
44
|
+
const generatedSectionPattern = new RegExp(`${escapeRegex(ABILITY_REGISTRY_START_MARKER)}[\\s\\S]*?${escapeRegex(ABILITY_REGISTRY_END_MARKER)}\\n?`, "u");
|
|
45
|
+
const nextSource = existingSource
|
|
46
|
+
? generatedSectionPattern.test(existingSource)
|
|
47
|
+
? existingSource.replace(generatedSectionPattern, generatedSection)
|
|
48
|
+
: `${existingSource.trimEnd()}\n\n${generatedSection}`
|
|
49
|
+
: generatedSection;
|
|
50
|
+
await fsp.writeFile(registryPath, nextSource, "utf8");
|
|
51
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { ScaffoldAbilityWorkspaceOptions } from "./cli-add-workspace-ability-types.js";
|
|
2
2
|
/**
|
|
3
3
|
* Write generated workflow ability sources and patch shared workspace anchors.
|
|
4
4
|
*/
|