@wp-typia/project-tools 0.22.10 → 0.23.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.
Files changed (76) hide show
  1. package/dist/runtime/cli-add-collision.d.ts +25 -0
  2. package/dist/runtime/cli-add-collision.js +76 -0
  3. package/dist/runtime/cli-add-help.js +11 -2
  4. package/dist/runtime/cli-add-kind-ids.d.ts +1 -1
  5. package/dist/runtime/cli-add-kind-ids.js +3 -0
  6. package/dist/runtime/cli-add-types.d.ts +117 -0
  7. package/dist/runtime/cli-add-types.js +26 -0
  8. package/dist/runtime/cli-add-validation.d.ts +90 -1
  9. package/dist/runtime/cli-add-validation.js +304 -1
  10. package/dist/runtime/cli-add-workspace-admin-view-scaffold.js +74 -19
  11. package/dist/runtime/cli-add-workspace-admin-view-source.js +11 -2
  12. package/dist/runtime/cli-add-workspace-admin-view-templates.d.ts +20 -2
  13. package/dist/runtime/cli-add-workspace-admin-view-templates.js +359 -3
  14. package/dist/runtime/cli-add-workspace-admin-view-types.d.ts +21 -0
  15. package/dist/runtime/cli-add-workspace-admin-view-types.js +22 -0
  16. package/dist/runtime/cli-add-workspace-ai-anchors.js +121 -31
  17. package/dist/runtime/cli-add-workspace-contract-source-emitters.d.ts +15 -0
  18. package/dist/runtime/cli-add-workspace-contract-source-emitters.js +42 -0
  19. package/dist/runtime/cli-add-workspace-contract.d.ts +15 -0
  20. package/dist/runtime/cli-add-workspace-contract.js +65 -0
  21. package/dist/runtime/cli-add-workspace-integration-env.d.ts +24 -0
  22. package/dist/runtime/cli-add-workspace-integration-env.js +391 -0
  23. package/dist/runtime/cli-add-workspace-post-meta-anchors.d.ts +23 -0
  24. package/dist/runtime/cli-add-workspace-post-meta-anchors.js +244 -0
  25. package/dist/runtime/cli-add-workspace-post-meta-source-emitters.d.ts +63 -0
  26. package/dist/runtime/cli-add-workspace-post-meta-source-emitters.js +179 -0
  27. package/dist/runtime/cli-add-workspace-post-meta.d.ts +15 -0
  28. package/dist/runtime/cli-add-workspace-post-meta.js +107 -0
  29. package/dist/runtime/cli-add-workspace-rest-anchors.d.ts +1 -0
  30. package/dist/runtime/cli-add-workspace-rest-anchors.js +285 -21
  31. package/dist/runtime/cli-add-workspace-rest-source-emitters.d.ts +90 -2
  32. package/dist/runtime/cli-add-workspace-rest-source-emitters.js +302 -29
  33. package/dist/runtime/cli-add-workspace-rest.d.ts +15 -2
  34. package/dist/runtime/cli-add-workspace-rest.js +329 -21
  35. package/dist/runtime/cli-add-workspace.d.ts +15 -0
  36. package/dist/runtime/cli-add-workspace.js +15 -0
  37. package/dist/runtime/cli-add.d.ts +1 -1
  38. package/dist/runtime/cli-add.js +1 -1
  39. package/dist/runtime/cli-core.d.ts +2 -1
  40. package/dist/runtime/cli-core.js +2 -1
  41. package/dist/runtime/cli-doctor-environment.js +1 -3
  42. package/dist/runtime/cli-doctor-workspace-features.js +128 -10
  43. package/dist/runtime/cli-doctor-workspace-package.d.ts +25 -3
  44. package/dist/runtime/cli-doctor-workspace-package.js +35 -13
  45. package/dist/runtime/cli-doctor-workspace-shared.d.ts +2 -0
  46. package/dist/runtime/cli-doctor-workspace-shared.js +2 -0
  47. package/dist/runtime/cli-doctor-workspace.js +8 -3
  48. package/dist/runtime/cli-help.js +7 -0
  49. package/dist/runtime/cli-init-templates.js +11 -1
  50. package/dist/runtime/contract-artifacts.d.ts +14 -0
  51. package/dist/runtime/contract-artifacts.js +15 -0
  52. package/dist/runtime/index.d.ts +1 -1
  53. package/dist/runtime/index.js +1 -1
  54. package/dist/runtime/rest-resource-artifacts.d.ts +57 -1
  55. package/dist/runtime/rest-resource-artifacts.js +97 -1
  56. package/dist/runtime/template-render.d.ts +1 -1
  57. package/dist/runtime/template-render.js +1 -1
  58. package/dist/runtime/template-source-cache-markers.d.ts +37 -0
  59. package/dist/runtime/template-source-cache-markers.js +125 -0
  60. package/dist/runtime/template-source-cache.d.ts +1 -4
  61. package/dist/runtime/template-source-cache.js +16 -122
  62. package/dist/runtime/template-source-external.d.ts +4 -2
  63. package/dist/runtime/template-source-external.js +4 -2
  64. package/dist/runtime/template-source-remote.d.ts +8 -4
  65. package/dist/runtime/template-source-remote.js +8 -4
  66. package/dist/runtime/workspace-inventory-mutations.js +52 -3
  67. package/dist/runtime/workspace-inventory-parser.d.ts +3 -2
  68. package/dist/runtime/workspace-inventory-parser.js +126 -5
  69. package/dist/runtime/workspace-inventory-read.d.ts +9 -2
  70. package/dist/runtime/workspace-inventory-read.js +9 -2
  71. package/dist/runtime/workspace-inventory-templates.d.ts +16 -1
  72. package/dist/runtime/workspace-inventory-templates.js +74 -4
  73. package/dist/runtime/workspace-inventory-types.d.ts +51 -2
  74. package/dist/runtime/workspace-inventory.d.ts +2 -2
  75. package/dist/runtime/workspace-inventory.js +1 -1
  76. package/package.json +2 -2
@@ -1,10 +1,29 @@
1
1
  import fs from "node:fs";
2
2
  import path from "node:path";
3
- import { EDITOR_PLUGIN_SLOT_IDS, REST_RESOURCE_METHOD_IDS, REST_RESOURCE_NAMESPACE_PATTERN, resolveEditorPluginSlotAlias, } from "./cli-add-shared.js";
4
- import { checkExistingFiles, createDoctorCheck, resolveWorkspaceBootstrapPath, WORKSPACE_ABILITY_EDITOR_ASSET, WORKSPACE_ABILITY_EDITOR_SCRIPT, WORKSPACE_ABILITY_GLOB, WORKSPACE_ADMIN_VIEW_ASSET, WORKSPACE_ADMIN_VIEW_GLOB, WORKSPACE_ADMIN_VIEW_SCRIPT, WORKSPACE_ADMIN_VIEW_STYLE, WORKSPACE_AI_FEATURE_GLOB, WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET, WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT, WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE, WORKSPACE_REST_RESOURCE_GLOB, } from "./cli-doctor-workspace-shared.js";
3
+ import { EDITOR_PLUGIN_SLOT_IDS, MANUAL_REST_CONTRACT_AUTH_IDS, MANUAL_REST_CONTRACT_HTTP_METHOD_IDS, REST_RESOURCE_METHOD_IDS, REST_RESOURCE_NAMESPACE_PATTERN, assertValidPostMetaPostType, isGeneratedRestResourceRoutePatternCompatible, resolveEditorPluginSlotAlias, } from "./cli-add-shared.js";
4
+ import { hasAdminViewManualSettingsRouteParameters, isAdminViewManualSettingsRestResource, } from "./cli-add-workspace-admin-view-types.js";
5
+ import { checkExistingFiles, createDoctorCheck, resolveWorkspaceBootstrapPath, WORKSPACE_ABILITY_EDITOR_ASSET, WORKSPACE_ABILITY_EDITOR_SCRIPT, WORKSPACE_ABILITY_GLOB, WORKSPACE_ADMIN_VIEW_ASSET, WORKSPACE_ADMIN_VIEW_GLOB, WORKSPACE_ADMIN_VIEW_SCRIPT, WORKSPACE_ADMIN_VIEW_STYLE, WORKSPACE_AI_FEATURE_GLOB, WORKSPACE_EDITOR_PLUGIN_EDITOR_ASSET, WORKSPACE_EDITOR_PLUGIN_EDITOR_SCRIPT, WORKSPACE_EDITOR_PLUGIN_EDITOR_STYLE, WORKSPACE_POST_META_GLOB, WORKSPACE_REST_RESOURCE_GLOB, } from "./cli-doctor-workspace-shared.js";
5
6
  import { escapeRegex } from "./php-utils.js";
7
+ function isManualRestResource(restResource) {
8
+ return restResource.mode === "manual";
9
+ }
6
10
  function getWorkspaceRestResourceRequiredFiles(restResource) {
7
11
  const schemaNames = new Set();
12
+ if (isManualRestResource(restResource)) {
13
+ schemaNames.add("query");
14
+ if (restResource.bodyTypeName) {
15
+ schemaNames.add("request");
16
+ }
17
+ schemaNames.add("response");
18
+ return Array.from(new Set([
19
+ restResource.apiFile,
20
+ ...Array.from(schemaNames, (schemaName) => path.join(path.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
21
+ restResource.clientFile,
22
+ restResource.openApiFile,
23
+ restResource.typesFile,
24
+ restResource.validatorsFile,
25
+ ]));
26
+ }
8
27
  if (restResource.methods.includes("list")) {
9
28
  schemaNames.add("list-query");
10
29
  schemaNames.add("list-response");
@@ -30,20 +49,44 @@ function getWorkspaceRestResourceRequiredFiles(restResource) {
30
49
  restResource.apiFile,
31
50
  ...Array.from(schemaNames, (schemaName) => path.join(path.dirname(restResource.typesFile), "api-schemas", `${schemaName}.schema.json`)),
32
51
  restResource.clientFile,
33
- restResource.dataFile,
52
+ ...(restResource.dataFile ? [restResource.dataFile] : []),
34
53
  restResource.openApiFile,
35
- restResource.phpFile,
54
+ ...(restResource.phpFile ? [restResource.phpFile] : []),
36
55
  restResource.typesFile,
37
56
  restResource.validatorsFile,
38
57
  ]));
39
58
  }
40
59
  function checkWorkspaceRestResourceConfig(restResource) {
41
60
  const hasNamespace = REST_RESOURCE_NAMESPACE_PATTERN.test(restResource.namespace);
61
+ if (isManualRestResource(restResource)) {
62
+ const hasAuth = restResource.auth == null ||
63
+ MANUAL_REST_CONTRACT_AUTH_IDS.includes(restResource.auth);
64
+ const hasMethod = typeof restResource.method === "string" &&
65
+ MANUAL_REST_CONTRACT_HTTP_METHOD_IDS.includes(restResource.method);
66
+ const hasPathPattern = typeof restResource.pathPattern === "string" &&
67
+ restResource.pathPattern.startsWith("/") &&
68
+ restResource.pathPattern.length > 1;
69
+ return createDoctorCheck(`REST resource config ${restResource.slug}`, hasNamespace && hasAuth && hasMethod && hasPathPattern ? "pass" : "fail", hasNamespace && hasAuth && hasMethod && hasPathPattern
70
+ ? `Manual REST contract ${restResource.method} /${restResource.namespace}${restResource.pathPattern}`
71
+ : "Manual REST contract namespace, auth, method, or path pattern is invalid");
72
+ }
42
73
  const hasMethods = restResource.methods.length > 0 &&
43
74
  restResource.methods.every((method) => REST_RESOURCE_METHOD_IDS.includes(method));
44
- return createDoctorCheck(`REST resource config ${restResource.slug}`, hasNamespace && hasMethods ? "pass" : "fail", hasNamespace && hasMethods
75
+ const hasGeneratedFiles = typeof restResource.dataFile === "string" &&
76
+ restResource.dataFile.length > 0 &&
77
+ typeof restResource.phpFile === "string" &&
78
+ restResource.phpFile.length > 0;
79
+ const hasRoutePattern = restResource.routePattern == null ||
80
+ (typeof restResource.routePattern === "string" &&
81
+ restResource.routePattern.startsWith("/") &&
82
+ restResource.routePattern.length > 1 &&
83
+ !/\s/u.test(restResource.routePattern) &&
84
+ isGeneratedRestResourceRoutePatternCompatible(restResource.routePattern));
85
+ return createDoctorCheck(`REST resource config ${restResource.slug}`, hasNamespace && hasMethods && hasGeneratedFiles && hasRoutePattern
86
+ ? "pass"
87
+ : "fail", hasNamespace && hasMethods && hasGeneratedFiles && hasRoutePattern
45
88
  ? `REST resource namespace ${restResource.namespace} with methods ${restResource.methods.join(", ")}`
46
- : "REST resource namespace or methods are invalid");
89
+ : "REST resource namespace, methods, dataFile, phpFile, or routePattern are invalid");
47
90
  }
48
91
  function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix) {
49
92
  const bootstrapPath = resolveWorkspaceBootstrapPath(projectDir, packageName);
@@ -59,6 +102,60 @@ function checkWorkspaceRestResourceBootstrap(projectDir, packageName, phpPrefix)
59
102
  ? "REST resource PHP loader hook is present"
60
103
  : "Missing REST resource PHP require glob or init hook");
61
104
  }
105
+ function getWorkspacePostMetaRequiredFiles(postMeta) {
106
+ return Array.from(new Set([
107
+ postMeta.phpFile,
108
+ postMeta.schemaFile,
109
+ postMeta.typesFile,
110
+ ]));
111
+ }
112
+ function checkWorkspacePostMetaConfig(postMeta) {
113
+ let hasPostType = false;
114
+ try {
115
+ hasPostType = assertValidPostMetaPostType(postMeta.postType) === postMeta.postType;
116
+ }
117
+ catch {
118
+ hasPostType = false;
119
+ }
120
+ const hasMetaKey = typeof postMeta.metaKey === "string" &&
121
+ postMeta.metaKey.trim().length > 0 &&
122
+ !/\s/u.test(postMeta.metaKey);
123
+ const hasRestExposure = typeof postMeta.showInRest === "boolean";
124
+ return createDoctorCheck(`Post meta config ${postMeta.slug}`, hasPostType && hasMetaKey && hasRestExposure ? "pass" : "fail", hasPostType && hasMetaKey && hasRestExposure
125
+ ? `Post meta ${postMeta.metaKey} targets ${postMeta.postType}`
126
+ : "Post meta postType, metaKey, or showInRest configuration is invalid");
127
+ }
128
+ function checkWorkspacePostMetaBootstrap(projectDir, packageName, phpPrefix) {
129
+ const bootstrapPath = resolveWorkspaceBootstrapPath(projectDir, packageName);
130
+ if (!fs.existsSync(bootstrapPath)) {
131
+ return createDoctorCheck("Post meta bootstrap", "fail", `Missing ${path.basename(bootstrapPath)}`);
132
+ }
133
+ const source = fs.readFileSync(bootstrapPath, "utf8");
134
+ const registerFunctionName = `${phpPrefix}_register_post_meta_contracts`;
135
+ const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
136
+ const hasServerGlob = source.includes(WORKSPACE_POST_META_GLOB);
137
+ const hasRegisterHook = source.includes(registerHook);
138
+ return createDoctorCheck("Post meta bootstrap", hasServerGlob && hasRegisterHook ? "pass" : "fail", hasServerGlob && hasRegisterHook
139
+ ? "Post meta PHP loader hook is present"
140
+ : "Missing post meta PHP require glob or init hook");
141
+ }
142
+ function checkWorkspacePostMetaPhp(projectDir, postMeta) {
143
+ const phpPath = path.join(projectDir, postMeta.phpFile);
144
+ if (!fs.existsSync(phpPath)) {
145
+ return createDoctorCheck(`Post meta PHP ${postMeta.slug}`, "fail", `Missing ${postMeta.phpFile}`);
146
+ }
147
+ const source = fs.readFileSync(phpPath, "utf8");
148
+ const hasRegisterPostMeta = source.includes("register_post_meta");
149
+ const hasPostType = source.includes(postMeta.postType);
150
+ const hasMetaKey = source.includes(postMeta.metaKey);
151
+ const hasSchemaFile = source.includes(postMeta.schemaFile);
152
+ const hasRestExposure = source.includes("'show_in_rest'");
153
+ return createDoctorCheck(`Post meta PHP ${postMeta.slug}`, hasRegisterPostMeta && hasPostType && hasMetaKey && hasSchemaFile && hasRestExposure
154
+ ? "pass"
155
+ : "fail", hasRegisterPostMeta && hasPostType && hasMetaKey && hasSchemaFile && hasRestExposure
156
+ ? "Post meta registration, schema path, and REST exposure flag are wired"
157
+ : "Missing register_post_meta, post type, meta key, schema path, or show_in_rest wiring");
158
+ }
62
159
  function getWorkspaceAbilityRequiredFiles(ability) {
63
160
  return Array.from(new Set([
64
161
  ability.clientFile,
@@ -259,10 +356,23 @@ function checkWorkspaceAdminViewConfig(adminView, inventory) {
259
356
  const restResource = restResourceSlug
260
357
  ? inventory.restResources.find((entry) => entry.slug === restResourceSlug)
261
358
  : undefined;
262
- const isValid = Boolean(restResource?.methods.includes("list")) || Boolean(coreDataSourceMatch);
359
+ const isListCapableRestResource = Boolean(restResource?.methods.includes("list"));
360
+ const isManualSettingsRestResource = isAdminViewManualSettingsRestResource(restResource);
361
+ const hasManualSettingsRouteParameters = isManualSettingsRestResource &&
362
+ hasAdminViewManualSettingsRouteParameters(restResource);
363
+ const isValid = isListCapableRestResource ||
364
+ (isManualSettingsRestResource && !hasManualSettingsRouteParameters) ||
365
+ Boolean(coreDataSourceMatch);
366
+ const failDetail = hasManualSettingsRouteParameters
367
+ ? `Admin view source ${source} uses route parameters or regex groups and cannot scaffold a singleton settings form`
368
+ : "Admin view source must use rest-resource:<slug> with a list-capable REST resource, a manual settings contract with a body type, or core-data:<postType|taxonomy>/<name>";
263
369
  return createDoctorCheck(`Admin view config ${adminView.slug}`, isValid ? "pass" : "fail", isValid
264
- ? `Admin view source ${source} is list-capable`
265
- : "Admin view source must use rest-resource:<slug> with a list-capable REST resource or core-data:<postType|taxonomy>/<name>");
370
+ ? `Admin view source ${source} is ${isManualSettingsRestResource
371
+ ? "settings-form capable"
372
+ : coreDataSourceMatch
373
+ ? "core-data capable"
374
+ : "list-capable"}`
375
+ : failDetail);
266
376
  }
267
377
  function checkWorkspaceAdminViewBootstrap(projectDir, packageName, phpPrefix) {
268
378
  const bootstrapPath = resolveWorkspaceBootstrapPath(projectDir, packageName);
@@ -335,13 +445,21 @@ function checkWorkspaceAdminViewPhp(projectDir, adminView) {
335
445
  */
336
446
  export function getWorkspaceFeatureDoctorChecks(workspace, inventory) {
337
447
  const checks = [];
338
- if (inventory.restResources.length > 0) {
448
+ if (inventory.restResources.some((restResource) => !isManualRestResource(restResource))) {
339
449
  checks.push(checkWorkspaceRestResourceBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
340
450
  }
341
451
  for (const restResource of inventory.restResources) {
342
452
  checks.push(checkWorkspaceRestResourceConfig(restResource));
343
453
  checks.push(checkExistingFiles(workspace.projectDir, `REST resource ${restResource.slug}`, getWorkspaceRestResourceRequiredFiles(restResource)));
344
454
  }
455
+ if (inventory.postMeta.length > 0) {
456
+ checks.push(checkWorkspacePostMetaBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
457
+ }
458
+ for (const postMeta of inventory.postMeta) {
459
+ checks.push(checkWorkspacePostMetaConfig(postMeta));
460
+ checks.push(checkExistingFiles(workspace.projectDir, `Post meta ${postMeta.slug}`, getWorkspacePostMetaRequiredFiles(postMeta)));
461
+ checks.push(checkWorkspacePostMetaPhp(workspace.projectDir, postMeta));
462
+ }
345
463
  if (inventory.abilities.length > 0) {
346
464
  checks.push(checkWorkspaceAbilityBootstrap(workspace.projectDir, workspace.packageName, workspace.workspace.phpPrefix));
347
465
  checks.push(checkWorkspaceAbilityIndex(workspace.projectDir, inventory.abilities));
@@ -1,18 +1,40 @@
1
1
  import type { DoctorCheck } from "./cli-doctor.js";
2
2
  import type { WorkspacePackageJson, WorkspaceProject } from "./workspace-project.js";
3
+ /**
4
+ * Snapshot of package-level filesystem doctor inputs prepared asynchronously.
5
+ */
6
+ export interface WorkspacePackageDoctorSnapshot {
7
+ /** Whether the expected workspace bootstrap PHP file exists. */
8
+ bootstrapExists: boolean;
9
+ /** Relative path to the expected workspace bootstrap PHP file. */
10
+ bootstrapRelativePath: string;
11
+ /** Whether the migration config file exists. */
12
+ migrationConfigExists: boolean;
13
+ /** Relative path to the migration config file. */
14
+ migrationConfigRelativePath: string;
15
+ }
16
+ /**
17
+ * Prepare package-level workspace doctor inputs without blocking the event loop.
18
+ *
19
+ * @param workspace Resolved workspace metadata and filesystem paths.
20
+ * @param packageJson Parsed workspace package manifest.
21
+ * @returns Snapshot values consumed by synchronous doctor row mappers.
22
+ */
23
+ export declare function prepareWorkspacePackageDoctorSnapshot(workspace: WorkspaceProject, packageJson: WorkspacePackageJson): Promise<WorkspacePackageDoctorSnapshot>;
3
24
  /**
4
25
  * Validate the package metadata that makes a project an official workspace.
5
26
  *
6
27
  * @param workspace Resolved workspace metadata and filesystem paths.
7
28
  * @param packageJson Parsed workspace package manifest.
29
+ * @param snapshot Async filesystem snapshot for package-level doctor inputs.
8
30
  * @returns A `DoctorCheck` describing whether package metadata matches the workspace contract.
9
31
  */
10
- export declare function getWorkspacePackageMetadataCheck(workspace: WorkspaceProject, packageJson: WorkspacePackageJson): DoctorCheck;
32
+ export declare function getWorkspacePackageMetadataCheck(workspace: WorkspaceProject, packageJson: WorkspacePackageJson, snapshot: WorkspacePackageDoctorSnapshot): DoctorCheck;
11
33
  /**
12
34
  * Report whether a workspace configured for migrations exposes the expected doctor inputs.
13
35
  *
14
- * @param workspace Resolved workspace metadata and filesystem paths.
15
36
  * @param packageJson Parsed workspace package manifest.
37
+ * @param snapshot Async filesystem snapshot for package-level doctor inputs.
16
38
  * @returns A migration hint row when the workspace uses migrations, otherwise `null`.
17
39
  */
18
- export declare function getMigrationWorkspaceHintCheck(workspace: WorkspaceProject, packageJson: WorkspacePackageJson): DoctorCheck | null;
40
+ export declare function getMigrationWorkspaceHintCheck(packageJson: WorkspacePackageJson, snapshot: WorkspacePackageDoctorSnapshot): DoctorCheck | null;
@@ -1,18 +1,42 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
2
  import { createDoctorCheck, getWorkspaceBootstrapRelativePath, } from "./cli-doctor-workspace-shared.js";
3
+ import { pathExists } from "./fs-async.js";
4
4
  import { WORKSPACE_TEMPLATE_PACKAGE } from "./workspace-project.js";
5
+ /**
6
+ * Prepare package-level workspace doctor inputs without blocking the event loop.
7
+ *
8
+ * @param workspace Resolved workspace metadata and filesystem paths.
9
+ * @param packageJson Parsed workspace package manifest.
10
+ * @returns Snapshot values consumed by synchronous doctor row mappers.
11
+ */
12
+ export async function prepareWorkspacePackageDoctorSnapshot(workspace, packageJson) {
13
+ const packageName = packageJson.name;
14
+ const bootstrapRelativePath = getWorkspaceBootstrapRelativePath(typeof packageName === "string" && packageName.length > 0
15
+ ? packageName
16
+ : workspace.packageName);
17
+ const migrationConfigRelativePath = path.join("src", "migrations", "config.ts");
18
+ const [bootstrapExists, migrationConfigExists] = await Promise.all([
19
+ pathExists(path.join(workspace.projectDir, bootstrapRelativePath)),
20
+ pathExists(path.join(workspace.projectDir, migrationConfigRelativePath)),
21
+ ]);
22
+ return {
23
+ bootstrapExists,
24
+ bootstrapRelativePath,
25
+ migrationConfigExists,
26
+ migrationConfigRelativePath,
27
+ };
28
+ }
5
29
  /**
6
30
  * Validate the package metadata that makes a project an official workspace.
7
31
  *
8
32
  * @param workspace Resolved workspace metadata and filesystem paths.
9
33
  * @param packageJson Parsed workspace package manifest.
34
+ * @param snapshot Async filesystem snapshot for package-level doctor inputs.
10
35
  * @returns A `DoctorCheck` describing whether package metadata matches the workspace contract.
11
36
  */
12
- export function getWorkspacePackageMetadataCheck(workspace, packageJson) {
37
+ export function getWorkspacePackageMetadataCheck(workspace, packageJson, snapshot) {
13
38
  const issues = [];
14
39
  const packageName = packageJson.name;
15
- const bootstrapRelativePath = getWorkspaceBootstrapRelativePath(typeof packageName === "string" && packageName.length > 0 ? packageName : workspace.packageName);
16
40
  const wpTypia = packageJson.wpTypia;
17
41
  if (typeof packageName !== "string" || packageName.length === 0) {
18
42
  issues.push("package.json must define a string name for workspace bootstrap resolution");
@@ -32,28 +56,26 @@ export function getWorkspacePackageMetadataCheck(workspace, packageJson) {
32
56
  if (wpTypia?.phpPrefix !== workspace.workspace.phpPrefix) {
33
57
  issues.push(`wpTypia.phpPrefix must equal "${workspace.workspace.phpPrefix}"`);
34
58
  }
35
- if (!fs.existsSync(path.join(workspace.projectDir, bootstrapRelativePath))) {
36
- issues.push(`Missing bootstrap file ${bootstrapRelativePath}`);
59
+ if (!snapshot.bootstrapExists) {
60
+ issues.push(`Missing bootstrap file ${snapshot.bootstrapRelativePath}`);
37
61
  }
38
62
  return createDoctorCheck("Workspace package metadata", issues.length === 0 ? "pass" : "fail", issues.length === 0
39
- ? `package.json metadata aligns with ${workspace.packageName} and ${bootstrapRelativePath}`
63
+ ? `package.json metadata aligns with ${workspace.packageName} and ${snapshot.bootstrapRelativePath}`
40
64
  : issues.join("; "));
41
65
  }
42
66
  /**
43
67
  * Report whether a workspace configured for migrations exposes the expected doctor inputs.
44
68
  *
45
- * @param workspace Resolved workspace metadata and filesystem paths.
46
69
  * @param packageJson Parsed workspace package manifest.
70
+ * @param snapshot Async filesystem snapshot for package-level doctor inputs.
47
71
  * @returns A migration hint row when the workspace uses migrations, otherwise `null`.
48
72
  */
49
- export function getMigrationWorkspaceHintCheck(workspace, packageJson) {
73
+ export function getMigrationWorkspaceHintCheck(packageJson, snapshot) {
50
74
  const hasMigrationScript = typeof packageJson.scripts?.["migration:doctor"] === "string";
51
- const migrationConfigRelativePath = path.join("src", "migrations", "config.ts");
52
- const hasMigrationConfig = fs.existsSync(path.join(workspace.projectDir, migrationConfigRelativePath));
53
- if (!hasMigrationScript && !hasMigrationConfig) {
75
+ if (!hasMigrationScript && !snapshot.migrationConfigExists) {
54
76
  return null;
55
77
  }
56
- return createDoctorCheck("Migration workspace", hasMigrationConfig ? "pass" : "fail", hasMigrationConfig
78
+ return createDoctorCheck("Migration workspace", snapshot.migrationConfigExists ? "pass" : "fail", snapshot.migrationConfigExists
57
79
  ? "Run `wp-typia migrate doctor --all` for migration target, snapshot, fixture, and generated artifact checks"
58
- : `Missing ${migrationConfigRelativePath} for the configured migration workspace`);
80
+ : `Missing ${snapshot.migrationConfigRelativePath} for the configured migration workspace`);
59
81
  }
@@ -7,6 +7,8 @@ export declare const WORKSPACE_BINDING_EDITOR_SCRIPT = "build/bindings/index.js"
7
7
  export declare const WORKSPACE_BINDING_EDITOR_ASSET = "build/bindings/index.asset.php";
8
8
  /** Glob pattern for generated REST resource PHP entrypoints. */
9
9
  export declare const WORKSPACE_REST_RESOURCE_GLOB = "/inc/rest/*.php";
10
+ /** Glob pattern for generated post-meta PHP entrypoints. */
11
+ export declare const WORKSPACE_POST_META_GLOB = "/inc/post-meta/*.php";
10
12
  /** Glob pattern for generated ability PHP entrypoints. */
11
13
  export declare const WORKSPACE_ABILITY_GLOB = "/inc/abilities/*.php";
12
14
  /** Relative path to the generated ability editor bundle. */
@@ -8,6 +8,8 @@ export const WORKSPACE_BINDING_EDITOR_SCRIPT = "build/bindings/index.js";
8
8
  export const WORKSPACE_BINDING_EDITOR_ASSET = "build/bindings/index.asset.php";
9
9
  /** Glob pattern for generated REST resource PHP entrypoints. */
10
10
  export const WORKSPACE_REST_RESOURCE_GLOB = "/inc/rest/*.php";
11
+ /** Glob pattern for generated post-meta PHP entrypoints. */
12
+ export const WORKSPACE_POST_META_GLOB = "/inc/post-meta/*.php";
11
13
  /** Glob pattern for generated ability PHP entrypoints. */
12
14
  export const WORKSPACE_ABILITY_GLOB = "/inc/abilities/*.php";
13
15
  /** Relative path to the generated ability editor bundle. */
@@ -1,7 +1,7 @@
1
1
  import { getWorkspaceBindingDoctorChecks, } from "./cli-doctor-workspace-bindings.js";
2
2
  import { getWorkspaceBlockDoctorChecks, } from "./cli-doctor-workspace-blocks.js";
3
3
  import { getWorkspaceFeatureDoctorChecks, } from "./cli-doctor-workspace-features.js";
4
- import { getMigrationWorkspaceHintCheck, getWorkspacePackageMetadataCheck, } from "./cli-doctor-workspace-package.js";
4
+ import { getMigrationWorkspaceHintCheck, getWorkspacePackageMetadataCheck, prepareWorkspacePackageDoctorSnapshot, } from "./cli-doctor-workspace-package.js";
5
5
  import { createDoctorCheck, createDoctorScopeCheck, } from "./cli-doctor-workspace-shared.js";
6
6
  import { readWorkspaceInventoryAsync, } from "./workspace-inventory.js";
7
7
  import { getInvalidWorkspaceProjectReason, parseWorkspacePackageJson, tryResolveWorkspaceProject, } from "./workspace-project.js";
@@ -14,6 +14,7 @@ function formatWorkspaceInventorySummary(inventory) {
14
14
  `${inventory.patterns.length} pattern(s)`,
15
15
  `${inventory.bindingSources.length} binding source(s)`,
16
16
  `${inventory.restResources.length} REST resource(s)`,
17
+ `${inventory.postMeta.length} post meta contract(s)`,
17
18
  `${inventory.abilities.length} ability scaffold(s)`,
18
19
  `${inventory.aiFeatures.length} AI feature(s)`,
19
20
  `${inventory.editorPlugins.length} editor plugin(s)`,
@@ -73,14 +74,18 @@ export async function getWorkspaceDoctorChecks(cwd) {
73
74
  checks.push(createDoctorCheck("Workspace package metadata", "fail", error instanceof Error ? error.message : String(error)));
74
75
  return checks;
75
76
  }
76
- checks.push(getWorkspacePackageMetadataCheck(workspace, workspacePackageJson));
77
+ const packageDoctorSnapshot = await prepareWorkspacePackageDoctorSnapshot(workspace, workspacePackageJson);
78
+ checks.push(getWorkspacePackageMetadataCheck(workspace, workspacePackageJson, packageDoctorSnapshot));
77
79
  try {
78
80
  const inventory = await readWorkspaceInventoryAsync(workspace.projectDir);
79
81
  checks.push(createDoctorCheck("Workspace inventory", "pass", formatWorkspaceInventorySummary(inventory)));
82
+ // The highest-impact remaining probes live in block, binding, and feature
83
+ // categories; keep them synchronous until broader path/content snapshots
84
+ // can preserve their current row ordering and diagnostics.
80
85
  checks.push(...getWorkspaceBlockDoctorChecks(workspace, inventory));
81
86
  checks.push(...getWorkspaceBindingDoctorChecks(workspace, inventory));
82
87
  checks.push(...getWorkspaceFeatureDoctorChecks(workspace, inventory));
83
- const migrationWorkspaceCheck = getMigrationWorkspaceHintCheck(workspace, workspacePackageJson);
88
+ const migrationWorkspaceCheck = getMigrationWorkspaceHintCheck(workspacePackageJson, packageDoctorSnapshot);
84
89
  if (migrationWorkspaceCheck) {
85
90
  checks.push(migrationWorkspaceCheck);
86
91
  }
@@ -20,12 +20,15 @@ export function formatHelpText() {
20
20
  wp-typia init [project-dir] [--apply] [--package-manager <id>]
21
21
  wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>]
22
22
  wp-typia add block <name> [--template <basic|interactivity|persistence|compound>] [--external-layer-source <./path|github:owner/repo/path[#ref]|npm-package>] [--external-layer-id <layer-id>] [--inner-blocks-preset <freeform|ordered|horizontal|locked-structure>] [--alternate-render-targets <email,mjml,plain-text>] [--data-storage <post-meta|custom-table>] [--persistence-policy <authenticated|public>]
23
+ wp-typia add integration-env <name> [--wp-env] [--service <none|docker-compose>]
23
24
  wp-typia add variation <name> --block <block-slug>
24
25
  wp-typia add style <name> --block <block-slug>
25
26
  wp-typia add transform <name> --from <namespace/block> --to <block-slug|namespace/block-slug>
26
27
  wp-typia add pattern <name>
27
28
  wp-typia add binding-source <name> [--block <block-slug|namespace/block-slug> --attribute <attribute>]
28
29
  wp-typia add rest-resource <name> [--namespace <vendor/v1>] [--methods <method[,method...]>]
30
+ wp-typia add rest-resource <name> --manual [--namespace <vendor/v1>] [--method <GET|POST|PUT|PATCH|DELETE>] [--auth <public|authenticated|public-write-protected>] [--path <route-pattern>] [--query-type <Type>] [--body-type <Type>] [--response-type <Type>]
31
+ wp-typia add post-meta <name> --post-type <post-type> [--type <ExportedTypeName>] [--meta-key <meta-key>] [--hide-from-rest]
29
32
  wp-typia add ability <name>
30
33
  wp-typia add ai-feature <name> [--namespace <vendor/v1>]
31
34
  wp-typia add editor-plugin <name> [--slot <sidebar|document-setting-panel>]
@@ -53,6 +56,8 @@ Notes:
53
56
  Pass \`--source rest-resource:<slug>\` to reuse a list-capable REST resource.
54
57
  Pass \`--source core-data:postType/post\` or \`--source core-data:taxonomy/category\` to bind a WordPress-owned entity collection.
55
58
  Generated admin-view workspaces add \`@wp-typia/dataviews\` and the needed WordPress DataViews packages as opt-in dependencies.
59
+ \`add integration-env\` generates an opt-in local smoke starter under \`scripts/integration-smoke/\`, updates \`.env.example\`, and can add \`@wordpress/env\` plus \`.wp-env.json\` when \`--wp-env\` is passed.
60
+ Pass \`--service docker-compose\` to include a placeholder local service stack that can be adapted to project-specific dependencies.
56
61
  \`query-loop\` is create-only. Use \`wp-typia create <project-dir> --template query-loop\`; \`wp-typia add block\` accepts only basic, interactivity, persistence, and compound families.
57
62
  \`add variation\` uses an existing workspace block from \`scripts/block-config.ts\`.
58
63
  \`add style\` registers a Block Styles option for an existing generated block.
@@ -60,6 +65,8 @@ Notes:
60
65
  \`add pattern\` scaffolds a namespaced PHP pattern shell under \`src/patterns/\`.
61
66
  \`add binding-source\` scaffolds shared PHP and editor registration under \`src/bindings/\`; pass \`--block\` and \`--attribute\` together to declare a bindable generated-block attribute.
62
67
  \`add rest-resource\` scaffolds plugin-level TypeScript REST contracts under \`src/rest/\` and PHP route glue under \`inc/rest/\`.
68
+ \`add rest-resource --manual\` tracks an external REST route with typed schemas, OpenAPI, clients, and drift checks without generating PHP route/controller files.
69
+ \`add post-meta\` scaffolds typed post meta contracts under \`src/post-meta/\`, emits schema artifacts, and wires generated \`register_post_meta()\` helpers under \`inc/post-meta/\`.
63
70
  \`add ability\` scaffolds typed workflow abilities under \`src/abilities/\` and server registration under \`inc/abilities/\`.
64
71
  \`add ai-feature\` scaffolds server-owned AI feature endpoints under \`src/ai-features/\` and PHP route glue under \`inc/ai-features/\`.
65
72
  \`add editor-plugin\` scaffolds a document-level editor extension under \`src/editor-plugins/\`; legacy aliases \`PluginSidebar\` and \`PluginDocumentSettingPanel\` resolve to \`sidebar\` and \`document-setting-panel\`.
@@ -182,6 +182,16 @@ function getSyncScriptEnv() {
182
182
  \treturn env;
183
183
  }
184
184
 
185
+ function getOptionalNodeErrorCode( error: unknown ): string | undefined {
186
+ \treturn typeof error === 'object' && error !== null && 'code' in error
187
+ \t\t? String( ( error as { code: unknown } ).code )
188
+ \t\t: undefined;
189
+ }
190
+
191
+ function isFileNotFoundError( error: unknown ): boolean {
192
+ \treturn getOptionalNodeErrorCode( error ) === 'ENOENT';
193
+ }
194
+
185
195
  function runSyncScript( scriptPath: string, options: SyncCliOptions ) {
186
196
  \tconst args = [ scriptPath ];
187
197
  \tif ( options.check ) {
@@ -196,7 +206,7 @@ function runSyncScript( scriptPath: string, options: SyncCliOptions ) {
196
206
  \t} );
197
207
 
198
208
  \tif ( result.error ) {
199
- \t\tif ( ( result.error as NodeJS.ErrnoException ).code === 'ENOENT' ) {
209
+ \t\tif ( isFileNotFoundError( result.error ) ) {
200
210
  \t\t\tthrow new Error(
201
211
  \t\t\t\t'Unable to resolve \`tsx\` for project sync. Install project dependencies or rerun the command through your package manager.'
202
212
  \t\t\t);
@@ -0,0 +1,14 @@
1
+ interface SyncStandaloneContractArtifactsOptions {
2
+ projectDir: string;
3
+ schemaFile: string;
4
+ sourceTypeName: string;
5
+ typesFile: string;
6
+ }
7
+ /**
8
+ * Generate the JSON Schema artifact for a standalone TypeScript contract.
9
+ *
10
+ * @param options Workspace-relative type/schema paths plus the exported source
11
+ * type name.
12
+ */
13
+ export declare function syncStandaloneContractArtifacts({ projectDir, schemaFile, sourceTypeName, typesFile, }: SyncStandaloneContractArtifactsOptions): Promise<void>;
14
+ export {};
@@ -0,0 +1,15 @@
1
+ import { syncTypeSchemas, } from "@wp-typia/block-runtime/metadata-core";
2
+ /**
3
+ * Generate the JSON Schema artifact for a standalone TypeScript contract.
4
+ *
5
+ * @param options Workspace-relative type/schema paths plus the exported source
6
+ * type name.
7
+ */
8
+ export async function syncStandaloneContractArtifacts({ projectDir, schemaFile, sourceTypeName, typesFile, }) {
9
+ await syncTypeSchemas({
10
+ jsonSchemaFile: schemaFile,
11
+ projectRoot: projectDir,
12
+ sourceTypeName,
13
+ typesFile,
14
+ });
15
+ }
@@ -38,5 +38,5 @@ export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOpti
38
38
  export { EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV, pruneExternalTemplateCache, } from "./template-source-cache.js";
39
39
  export type { ExternalTemplateCachePruneOptions, ExternalTemplateCachePruneResult, } from "./template-source-cache.js";
40
40
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
41
- export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
41
+ export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
42
42
  export type { CliDiagnosticCode, CliDiagnosticCodeError, CliDiagnosticMessage, DoctorCheck, EditorPluginSlotId, HookedBlockPositionId, ReadlinePrompt, WorkspaceBlockSelectOption, } from "./cli-core.js";
@@ -29,4 +29,4 @@ export { clearPackageVersionsCache, getPackageVersions, invalidatePackageVersion
29
29
  export { TEMPLATE_IDS, TEMPLATE_REGISTRY, getTemplateById, getTemplateSelectOptions, listTemplates, } from "./template-registry.js";
30
30
  export { EXTERNAL_TEMPLATE_CACHE_TTL_DAYS_ENV, pruneExternalTemplateCache, } from "./template-source-cache.js";
31
31
  export { STALE_TEMP_ROOT_MAX_AGE_MS, WP_TYPIA_TEMP_ROOT_PREFIX, cleanupManagedTempRoot, cleanupStaleTempRoots, createManagedTempRoot, getTrackedTempRoots, } from "./temp-roots.js";
32
- export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
32
+ export { createReadlinePrompt, createCliCommandError, createCliDiagnosticCodeError, CliDiagnosticError, CLI_DIAGNOSTIC_CODES, formatCliDiagnosticError, formatAddHelpText, formatDoctorCheckLine, formatDoctorSummaryLine, formatHelpText, formatTemplateDetails, formatTemplateFeatures, formatTemplateSummary, getDoctorChecks, getDoctorFailureDetailLines, getFailingDoctorChecks, getNextSteps, getOptionalOnboarding, getWorkspaceBlockSelectOptions, getWorkspaceBlockSelectOptionsAsync, HOOKED_BLOCK_POSITION_IDS, EDITOR_PLUGIN_SLOT_IDS, isCliDiagnosticError, runAddAdminViewCommand, runAddAbilityCommand, runAddAiFeatureCommand, runAddBindingSourceCommand, runAddBlockCommand, runAddBlockStyleCommand, runAddBlockTransformCommand, runAddEditorPluginCommand, runAddHookedBlockCommand, runAddPatternCommand, runAddPostMetaCommand, runDoctor, runAddVariationCommand, runScaffoldFlow, } from "./cli-core.js";
@@ -1,7 +1,8 @@
1
- import type { RestResourceMethodId } from "./cli-add-shared.js";
1
+ import type { ManualRestContractAuthId, ManualRestContractHttpMethodId, RestResourceMethodId } from "./cli-add-shared.js";
2
2
  interface RestResourceTemplateVariablesLike {
3
3
  namespace: string;
4
4
  pascalCase: string;
5
+ routePattern?: string;
5
6
  slugKebabCase: string;
6
7
  title: string;
7
8
  }
@@ -14,6 +15,26 @@ interface SyncRestResourceArtifactsOptions {
14
15
  validatorsFile: string;
15
16
  variables: RestResourceTemplateVariablesLike;
16
17
  }
18
+ interface ManualRestContractTemplateVariablesLike {
19
+ auth: ManualRestContractAuthId;
20
+ bodyTypeName?: string;
21
+ method: ManualRestContractHttpMethodId;
22
+ namespace: string;
23
+ pascalCase: string;
24
+ pathPattern: string;
25
+ queryTypeName: string;
26
+ responseTypeName: string;
27
+ slugKebabCase: string;
28
+ title: string;
29
+ }
30
+ interface SyncManualRestContractArtifactsOptions {
31
+ clientFile: string;
32
+ outputDir: string;
33
+ projectDir: string;
34
+ typesFile: string;
35
+ validatorsFile: string;
36
+ variables: ManualRestContractTemplateVariablesLike;
37
+ }
17
38
  /**
18
39
  * Build the endpoint manifest for a workspace-level REST resource scaffold.
19
40
  *
@@ -24,6 +45,33 @@ interface SyncRestResourceArtifactsOptions {
24
45
  export declare function buildRestResourceEndpointManifest(variables: RestResourceTemplateVariablesLike, methods: RestResourceMethodId[]): import("@wp-typia/block-runtime/metadata-core").EndpointManifestDefinition<Record<string, {
25
46
  sourceTypeName: string;
26
47
  }>, import("@wp-typia/block-runtime/schema-core").EndpointOpenApiEndpointDefinition[]>;
48
+ /**
49
+ * Build the endpoint manifest for a type-only manual REST contract. Manual
50
+ * contracts describe routes owned by another integration without generating PHP
51
+ * route glue in the workspace.
52
+ *
53
+ * @param variables Template naming data used for contract names, route path,
54
+ * and OpenAPI info.
55
+ * @returns Endpoint manifest consumed by schema, OpenAPI, and client generators.
56
+ */
57
+ export declare function buildManualRestContractEndpointManifest(variables: ManualRestContractTemplateVariablesLike): import("@wp-typia/block-runtime/metadata-core").EndpointManifestDefinition<Record<string, {
58
+ sourceTypeName: string;
59
+ }>, readonly [{
60
+ readonly wordpressAuth?: {
61
+ mechanism: "rest-nonce";
62
+ } | {
63
+ mechanism: "public-signed-token";
64
+ } | undefined;
65
+ readonly method: "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
66
+ readonly operationId: `call${string}ManualRestContract`;
67
+ readonly path: `/${string}${string}`;
68
+ readonly queryContract: "query";
69
+ readonly responseContract: "response";
70
+ readonly summary: `Call external ${string} REST route.`;
71
+ readonly tags: readonly [string];
72
+ readonly bodyContract?: string | undefined;
73
+ readonly auth: "authenticated" | "public" | "public-write-protected";
74
+ }]>;
27
75
  /**
28
76
  * Synchronize generated schemas, OpenAPI output, and endpoint client code for
29
77
  * a workspace-level REST resource scaffold.
@@ -32,4 +80,12 @@ export declare function buildRestResourceEndpointManifest(variables: RestResourc
32
80
  * @returns A promise that resolves after every generated REST artifact has been refreshed.
33
81
  */
34
82
  export declare function syncRestResourceArtifacts({ clientFile, methods, outputDir, projectDir, typesFile, validatorsFile, variables, }: SyncRestResourceArtifactsOptions): Promise<void>;
83
+ /**
84
+ * Synchronize generated schemas, OpenAPI output, and endpoint client code for a
85
+ * type-only manual REST contract.
86
+ *
87
+ * @param options Contract file paths and naming variables.
88
+ * @returns A promise that resolves after every generated artifact has refreshed.
89
+ */
90
+ export declare function syncManualRestContractArtifacts({ clientFile, outputDir, projectDir, typesFile, validatorsFile, variables, }: SyncManualRestContractArtifactsOptions): Promise<void>;
35
91
  export {};