wp-typia 0.22.0 → 0.22.2
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-bunli/.bunli/commands.gen.js +1053 -550
- package/dist-bunli/{cli-39er8888.js → cli-1sm60g1z.js} +19 -2
- package/dist-bunli/{cli-e623rs7g.js → cli-6hcbjvym.js} +1 -1
- package/dist-bunli/{cli-add-kjhghdqq.js → cli-add-s0p4w1wz.js} +655 -294
- package/dist-bunli/{cli-doctor-p3jxvn0k.js → cli-doctor-6dchxz12.js} +1 -1
- package/dist-bunli/{cli-init-djhwr245.js → cli-init-r6h1xchq.js} +2 -2
- package/dist-bunli/{cli-1w5vkye4.js → cli-kww2sraq.js} +9 -7
- package/dist-bunli/{cli-ktp869eh.js → cli-n6hgvysz.js} +36 -23
- package/dist-bunli/{cli-scaffold-376yw891.js → cli-scaffold-f023yxc5.js} +4 -4
- package/dist-bunli/{cli-j180bk07.js → cli-smzkbfna.js} +31 -2
- package/dist-bunli/cli.js +2 -2
- package/dist-bunli/{command-list-jt1a1w7r.js → command-list-d3dcvzg2.js} +184 -127
- package/dist-bunli/{migrations-nwas5bwt.js → migrations-pg5b9fh4.js} +2 -2
- package/dist-bunli/node-cli.js +287 -197
- package/package.json +2 -2
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY,
|
|
5
5
|
assertExternalLayerCompositionOptions,
|
|
6
6
|
copyInterpolatedDirectory,
|
|
7
|
+
createScaffoldCompatibilityConfig,
|
|
7
8
|
getDefaultAnswers,
|
|
8
9
|
listInterpolatedDirectoryOutputs,
|
|
9
10
|
normalizeOptionalCliString,
|
|
@@ -20,7 +21,7 @@ import {
|
|
|
20
21
|
scaffoldProject,
|
|
21
22
|
syncPersistenceRestArtifacts,
|
|
22
23
|
updatePluginHeaderCompatibility
|
|
23
|
-
} from "./cli-
|
|
24
|
+
} from "./cli-kww2sraq.js";
|
|
24
25
|
import {
|
|
25
26
|
DEFAULT_WORDPRESS_ABILITIES_VERSION,
|
|
26
27
|
DEFAULT_WORDPRESS_CORE_ABILITIES_VERSION,
|
|
@@ -28,11 +29,12 @@ import {
|
|
|
28
29
|
DEFAULT_WORDPRESS_DATAVIEWS_VERSION,
|
|
29
30
|
DEFAULT_WORDPRESS_DATA_VERSION,
|
|
30
31
|
DEFAULT_WP_TYPIA_DATAVIEWS_VERSION,
|
|
31
|
-
getPackageVersions
|
|
32
|
-
|
|
32
|
+
getPackageVersions,
|
|
33
|
+
resolveManagedPackageVersionRange
|
|
34
|
+
} from "./cli-1sm60g1z.js";
|
|
33
35
|
import {
|
|
34
36
|
snapshotProjectVersion
|
|
35
|
-
} from "./cli-
|
|
37
|
+
} from "./cli-6hcbjvym.js";
|
|
36
38
|
import {
|
|
37
39
|
ensureMigrationDirectories,
|
|
38
40
|
parseMigrationConfig,
|
|
@@ -45,7 +47,6 @@ import {
|
|
|
45
47
|
} from "./cli-sj5mtyzj.js";
|
|
46
48
|
import"./cli-10pe4mf8.js";
|
|
47
49
|
import {
|
|
48
|
-
PROJECT_TOOLS_PACKAGE_ROOT,
|
|
49
50
|
SHARED_WORKSPACE_TEMPLATE_ROOT
|
|
50
51
|
} from "./cli-tke8twkn.js";
|
|
51
52
|
import {
|
|
@@ -89,11 +90,12 @@ import {
|
|
|
89
90
|
resolveWorkspaceBlock,
|
|
90
91
|
rollbackWorkspaceMutation,
|
|
91
92
|
snapshotWorkspaceFiles,
|
|
93
|
+
toCamelCase,
|
|
92
94
|
toKebabCase,
|
|
93
95
|
toPascalCase,
|
|
94
96
|
toSnakeCase,
|
|
95
97
|
toTitleCase
|
|
96
|
-
} from "./cli-
|
|
98
|
+
} from "./cli-smzkbfna.js";
|
|
97
99
|
import {
|
|
98
100
|
createManagedTempRoot
|
|
99
101
|
} from "./cli-t73q5aqz.js";
|
|
@@ -781,16 +783,15 @@ async function runAddBlockCommand({
|
|
|
781
783
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace.ts
|
|
782
784
|
import fs6 from "fs";
|
|
783
785
|
import { promises as fsp9 } from "fs";
|
|
784
|
-
import
|
|
786
|
+
import path14 from "path";
|
|
785
787
|
|
|
786
|
-
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view.ts
|
|
787
|
-
import fs3 from "fs";
|
|
788
|
-
import { promises as fsp3 } from "fs";
|
|
789
|
-
import { createRequire } from "module";
|
|
790
|
-
import path4 from "path";
|
|
788
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-types.ts
|
|
791
789
|
var ADMIN_VIEW_REST_SOURCE_KIND = "rest-resource";
|
|
792
790
|
var ADMIN_VIEW_CORE_DATA_SOURCE_KIND = "core-data";
|
|
793
|
-
var ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS = [
|
|
791
|
+
var ADMIN_VIEW_CORE_DATA_ENTITY_KIND_IDS = [
|
|
792
|
+
"postType",
|
|
793
|
+
"taxonomy"
|
|
794
|
+
];
|
|
794
795
|
var ADMIN_VIEW_CORE_DATA_ENTITY_SEGMENT_PATTERN = /^[A-Za-z][A-Za-z0-9_-]*$/u;
|
|
795
796
|
var ADMIN_VIEW_CORE_DATA_ENTITY_NAME_PATTERN = /^[a-z0-9][a-z0-9_-]*$/u;
|
|
796
797
|
var ADMIN_VIEW_SOURCE_USAGE = "wp-typia add admin-view <name> --source <rest-resource:slug|core-data:kind/name>";
|
|
@@ -801,28 +802,20 @@ var ADMIN_VIEWS_STYLE_RTL = "build/admin-views/style-index-rtl.css";
|
|
|
801
802
|
var ADMIN_VIEWS_PHP_GLOB = "/inc/admin-views/*.php";
|
|
802
803
|
var ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV = "WP_TYPIA_ALLOW_UNPUBLISHED_DATAVIEWS";
|
|
803
804
|
var ADMIN_VIEW_PUBLIC_INSTALLS_ENABLED = false;
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
const pascalCase = toPascalCase(input);
|
|
807
|
-
return `${pascalCase.charAt(0).toLowerCase()}${pascalCase.slice(1)}`;
|
|
805
|
+
function isAdminViewCoreDataSource(source) {
|
|
806
|
+
return source?.kind === ADMIN_VIEW_CORE_DATA_SOURCE_KIND;
|
|
808
807
|
}
|
|
809
|
-
function
|
|
810
|
-
|
|
811
|
-
if (!trimmed || trimmed.startsWith("workspace:")) {
|
|
812
|
-
return fallback;
|
|
813
|
-
}
|
|
814
|
-
return /^[~^<>=]/u.test(trimmed) ? trimmed : `^${trimmed}`;
|
|
808
|
+
function isAdminViewRestResourceSource(source) {
|
|
809
|
+
return source?.kind === ADMIN_VIEW_REST_SOURCE_KIND;
|
|
815
810
|
}
|
|
816
|
-
function
|
|
817
|
-
|
|
818
|
-
return
|
|
819
|
-
} catch {
|
|
820
|
-
return;
|
|
811
|
+
function formatAdminViewSourceLocator(source) {
|
|
812
|
+
if (isAdminViewCoreDataSource(source)) {
|
|
813
|
+
return `${source.kind}:${source.entityKind}/${source.entityName}`;
|
|
821
814
|
}
|
|
815
|
+
return `${source.kind}:${source.slug}`;
|
|
822
816
|
}
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
817
|
+
|
|
818
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-source.ts
|
|
826
819
|
function isAdminViewUnpublishedDataViewsOverrideEnabled() {
|
|
827
820
|
return process.env[ADMIN_VIEW_ALLOW_UNPUBLISHED_DATAVIEWS_ENV]?.trim() === "1";
|
|
828
821
|
}
|
|
@@ -832,36 +825,6 @@ function assertAdminViewPackageAvailability() {
|
|
|
832
825
|
}
|
|
833
826
|
throw createCliDiagnosticCodeError(CLI_DIAGNOSTIC_CODES.INVALID_ARGUMENT, "`wp-typia add admin-view` is temporarily unavailable because `@wp-typia/dataviews` is not published to npm for public installs yet.");
|
|
834
827
|
}
|
|
835
|
-
function detectJsonIndent(source) {
|
|
836
|
-
const indentMatch = /\n([ \t]+)"/u.exec(source);
|
|
837
|
-
return indentMatch?.[1] ?? 2;
|
|
838
|
-
}
|
|
839
|
-
function resolvePackageVersionRange(packageName, fallback, workspacePackageDirName) {
|
|
840
|
-
if (workspacePackageDirName) {
|
|
841
|
-
const workspaceVersion = readPackageManifestVersion(path4.join(PROJECT_TOOLS_PACKAGE_ROOT, "..", workspacePackageDirName, "package.json"));
|
|
842
|
-
if (workspaceVersion) {
|
|
843
|
-
return normalizeVersionRange(workspaceVersion, fallback);
|
|
844
|
-
}
|
|
845
|
-
}
|
|
846
|
-
try {
|
|
847
|
-
return normalizeVersionRange(readPackageManifestVersion(require2.resolve(`${packageName}/package.json`)), fallback);
|
|
848
|
-
} catch {
|
|
849
|
-
return fallback;
|
|
850
|
-
}
|
|
851
|
-
}
|
|
852
|
-
function getAdminViewRelativeModuleSpecifier(adminViewSlug, workspaceFile) {
|
|
853
|
-
const adminViewDir = `src/admin-views/${adminViewSlug}`;
|
|
854
|
-
const normalizedFile = workspaceFile.replace(/\\/gu, "/");
|
|
855
|
-
const modulePath = normalizedFile.replace(/\.[cm]?[jt]sx?$/u, "");
|
|
856
|
-
const relativeModulePath = path4.posix.relative(adminViewDir, modulePath);
|
|
857
|
-
return relativeModulePath.startsWith(".") ? relativeModulePath : `./${relativeModulePath}`;
|
|
858
|
-
}
|
|
859
|
-
function isAdminViewCoreDataSource(source) {
|
|
860
|
-
return source?.kind === ADMIN_VIEW_CORE_DATA_SOURCE_KIND;
|
|
861
|
-
}
|
|
862
|
-
function isAdminViewRestResourceSource(source) {
|
|
863
|
-
return source?.kind === ADMIN_VIEW_REST_SOURCE_KIND;
|
|
864
|
-
}
|
|
865
828
|
function assertValidCoreDataEntitySegment(label, value) {
|
|
866
829
|
const trimmed = value.trim();
|
|
867
830
|
if (!trimmed) {
|
|
@@ -889,12 +852,6 @@ function assertValidCoreDataEntityKind(value) {
|
|
|
889
852
|
}
|
|
890
853
|
return normalized;
|
|
891
854
|
}
|
|
892
|
-
function formatAdminViewSourceLocator(source) {
|
|
893
|
-
if (isAdminViewCoreDataSource(source)) {
|
|
894
|
-
return `${source.kind}:${source.entityKind}/${source.entityName}`;
|
|
895
|
-
}
|
|
896
|
-
return `${source.kind}:${source.slug}`;
|
|
897
|
-
}
|
|
898
855
|
function parseAdminViewSource(source) {
|
|
899
856
|
const trimmed = source?.trim();
|
|
900
857
|
if (!trimmed) {
|
|
@@ -938,6 +895,24 @@ function resolveRestResourceSource(restResources, source) {
|
|
|
938
895
|
}
|
|
939
896
|
return restResource;
|
|
940
897
|
}
|
|
898
|
+
function resolveAdminViewCoreDataSource(source) {
|
|
899
|
+
return isAdminViewCoreDataSource(source) ? source : undefined;
|
|
900
|
+
}
|
|
901
|
+
|
|
902
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-scaffold.ts
|
|
903
|
+
import fs3 from "fs";
|
|
904
|
+
import { promises as fsp3 } from "fs";
|
|
905
|
+
import path5 from "path";
|
|
906
|
+
|
|
907
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-templates.ts
|
|
908
|
+
import path4 from "path";
|
|
909
|
+
function getAdminViewRelativeModuleSpecifier(adminViewSlug, workspaceFile) {
|
|
910
|
+
const adminViewDir = `src/admin-views/${adminViewSlug}`;
|
|
911
|
+
const normalizedFile = workspaceFile.replace(/\\/gu, "/");
|
|
912
|
+
const modulePath = normalizedFile.replace(/\.[cm]?[jt]sx?$/u, "");
|
|
913
|
+
const relativeModulePath = path4.posix.relative(adminViewDir, modulePath);
|
|
914
|
+
return relativeModulePath.startsWith(".") ? relativeModulePath : `./${relativeModulePath}`;
|
|
915
|
+
}
|
|
941
916
|
function buildAdminViewConfigEntry(adminViewSlug, source) {
|
|
942
917
|
return [
|
|
943
918
|
"\t{",
|
|
@@ -1070,8 +1045,8 @@ function buildAdminViewConfigSource(adminViewSlug, textDomain, source, restResou
|
|
|
1070
1045
|
const camelName = toCamelCase(adminViewSlug);
|
|
1071
1046
|
const itemTypeName = `${pascalName}AdminViewItem`;
|
|
1072
1047
|
const dataViewsName = `${camelName}AdminDataViews`;
|
|
1073
|
-
const isCoreDataSource = source
|
|
1074
|
-
const isTaxonomyCoreDataSource = source
|
|
1048
|
+
const isCoreDataSource = isAdminViewCoreDataSource(source);
|
|
1049
|
+
const isTaxonomyCoreDataSource = isAdminViewCoreDataSource(source) && source.entityKind === "taxonomy";
|
|
1075
1050
|
const defaultViewFields = restResource ? "['id']" : isTaxonomyCoreDataSource ? "['name', 'slug', 'count']" : isCoreDataSource ? "['title', 'slug', 'status', 'updatedAt']" : "['title', 'status', 'updatedAt']";
|
|
1076
1051
|
const searchEnabled = restResource ? "false" : "true";
|
|
1077
1052
|
const titleFieldSource = restResource ? "" : isTaxonomyCoreDataSource ? ` titleField: 'name',
|
|
@@ -1887,12 +1862,31 @@ add_action( 'admin_menu', '${registerFunctionName}' );
|
|
|
1887
1862
|
add_action( 'admin_enqueue_scripts', '${enqueueFunctionName}' );
|
|
1888
1863
|
`;
|
|
1889
1864
|
}
|
|
1865
|
+
|
|
1866
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view-scaffold.ts
|
|
1867
|
+
function detectJsonIndent(source) {
|
|
1868
|
+
const indentMatch = /\n([ \t]+)"/u.exec(source);
|
|
1869
|
+
return indentMatch?.[1] ?? 2;
|
|
1870
|
+
}
|
|
1890
1871
|
async function ensureAdminViewPackageDependencies(workspace, adminViewSource) {
|
|
1891
|
-
const packageJsonPath =
|
|
1892
|
-
const wpTypiaDataViewsVersion =
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1872
|
+
const packageJsonPath = path5.join(workspace.projectDir, "package.json");
|
|
1873
|
+
const wpTypiaDataViewsVersion = resolveManagedPackageVersionRange({
|
|
1874
|
+
fallback: DEFAULT_WP_TYPIA_DATAVIEWS_VERSION,
|
|
1875
|
+
packageName: "@wp-typia/dataviews",
|
|
1876
|
+
workspacePackageDirName: "wp-typia-dataviews"
|
|
1877
|
+
});
|
|
1878
|
+
const wordpressDataViewsVersion = resolveManagedPackageVersionRange({
|
|
1879
|
+
fallback: DEFAULT_WORDPRESS_DATAVIEWS_VERSION,
|
|
1880
|
+
packageName: "@wordpress/dataviews"
|
|
1881
|
+
});
|
|
1882
|
+
const wordpressCoreDataVersion = resolveManagedPackageVersionRange({
|
|
1883
|
+
fallback: DEFAULT_WORDPRESS_CORE_DATA_VERSION,
|
|
1884
|
+
packageName: "@wordpress/core-data"
|
|
1885
|
+
});
|
|
1886
|
+
const wordpressDataVersion = resolveManagedPackageVersionRange({
|
|
1887
|
+
fallback: DEFAULT_WORDPRESS_DATA_VERSION,
|
|
1888
|
+
packageName: "@wordpress/data"
|
|
1889
|
+
});
|
|
1896
1890
|
await patchFile(packageJsonPath, (source) => {
|
|
1897
1891
|
const packageJson = JSON.parse(source);
|
|
1898
1892
|
const coreDataDependencies = isAdminViewCoreDataSource(adminViewSource) ? {
|
|
@@ -1923,6 +1917,7 @@ async function ensureAdminViewBootstrapAnchors(workspace) {
|
|
|
1923
1917
|
let nextSource = source;
|
|
1924
1918
|
const loadFunctionName = `${workspace.workspace.phpPrefix}_load_admin_views`;
|
|
1925
1919
|
const loadHook = `add_action( 'plugins_loaded', '${loadFunctionName}' );`;
|
|
1920
|
+
const loadHookPattern = new RegExp(`add_action\\(\\s*['"]plugins_loaded['"]\\s*,\\s*['"]${loadFunctionName}['"]\\s*\\)\\s*;`, "u");
|
|
1926
1921
|
const loadFunction = `
|
|
1927
1922
|
|
|
1928
1923
|
function ${loadFunctionName}() {
|
|
@@ -1967,19 +1962,19 @@ ${snippet}
|
|
|
1967
1962
|
if (!functionSource.includes(ADMIN_VIEWS_PHP_GLOB)) {
|
|
1968
1963
|
const replacedSource = replacePhpFunctionDefinition(nextSource, loadFunctionName, loadFunction);
|
|
1969
1964
|
if (!replacedSource) {
|
|
1970
|
-
throw new Error(`Unable to repair ${
|
|
1965
|
+
throw new Error(`Unable to repair ${path5.basename(bootstrapPath)} for ${loadFunctionName}.`);
|
|
1971
1966
|
}
|
|
1972
1967
|
nextSource = replacedSource;
|
|
1973
1968
|
}
|
|
1974
1969
|
}
|
|
1975
|
-
if (!
|
|
1970
|
+
if (!loadHookPattern.test(nextSource)) {
|
|
1976
1971
|
appendPhpSnippet(loadHook);
|
|
1977
1972
|
}
|
|
1978
1973
|
return nextSource;
|
|
1979
1974
|
});
|
|
1980
1975
|
}
|
|
1981
1976
|
async function ensureAdminViewBuildScriptAnchors(workspace) {
|
|
1982
|
-
const buildScriptPath =
|
|
1977
|
+
const buildScriptPath = path5.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
1983
1978
|
await patchFile(buildScriptPath, (source) => {
|
|
1984
1979
|
if (/['"]src\/admin-views\/index\.(?:ts|js)['"]/u.test(source)) {
|
|
1985
1980
|
return source;
|
|
@@ -2003,11 +1998,11 @@ async function ensureAdminViewBuildScriptAnchors(workspace) {
|
|
|
2003
1998
|
if (nextSource !== source) {
|
|
2004
1999
|
return nextSource;
|
|
2005
2000
|
}
|
|
2006
|
-
throw new Error(`Unable to update ${
|
|
2001
|
+
throw new Error(`Unable to update ${path5.relative(workspace.projectDir, buildScriptPath)} for admin view shared entries.`);
|
|
2007
2002
|
});
|
|
2008
2003
|
}
|
|
2009
2004
|
async function ensureAdminViewWebpackAnchors(workspace) {
|
|
2010
|
-
const webpackConfigPath =
|
|
2005
|
+
const webpackConfigPath = path5.join(workspace.projectDir, "webpack.config.js");
|
|
2011
2006
|
await patchFile(webpackConfigPath, (source) => {
|
|
2012
2007
|
if (/['"]admin-views\/index['"]/u.test(source)) {
|
|
2013
2008
|
return source;
|
|
@@ -2048,17 +2043,17 @@ async function ensureAdminViewWebpackAnchors(workspace) {
|
|
|
2048
2043
|
}`;
|
|
2049
2044
|
nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
|
|
2050
2045
|
if (nextSource === source) {
|
|
2051
|
-
throw new Error(`Unable to update ${
|
|
2046
|
+
throw new Error(`Unable to update ${path5.relative(workspace.projectDir, webpackConfigPath)} for admin view shared entries.`);
|
|
2052
2047
|
}
|
|
2053
2048
|
return nextSource;
|
|
2054
2049
|
});
|
|
2055
2050
|
}
|
|
2056
2051
|
function resolveAdminViewRegistryPath(projectDir) {
|
|
2057
|
-
const adminViewsDir =
|
|
2052
|
+
const adminViewsDir = path5.join(projectDir, "src", "admin-views");
|
|
2058
2053
|
return [
|
|
2059
|
-
|
|
2060
|
-
|
|
2061
|
-
].find((candidatePath) => fs3.existsSync(candidatePath)) ??
|
|
2054
|
+
path5.join(adminViewsDir, "index.ts"),
|
|
2055
|
+
path5.join(adminViewsDir, "index.js")
|
|
2056
|
+
].find((candidatePath) => fs3.existsSync(candidatePath)) ?? path5.join(adminViewsDir, "index.ts");
|
|
2062
2057
|
}
|
|
2063
2058
|
function readAdminViewRegistrySlugs(registryPath) {
|
|
2064
2059
|
if (!fs3.existsSync(registryPath)) {
|
|
@@ -2068,35 +2063,34 @@ function readAdminViewRegistrySlugs(registryPath) {
|
|
|
2068
2063
|
return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match) => match[1]);
|
|
2069
2064
|
}
|
|
2070
2065
|
async function writeAdminViewRegistry(projectDir, adminViewSlug) {
|
|
2071
|
-
const adminViewsDir =
|
|
2066
|
+
const adminViewsDir = path5.join(projectDir, "src", "admin-views");
|
|
2072
2067
|
const registryPath = resolveAdminViewRegistryPath(projectDir);
|
|
2073
2068
|
await fsp3.mkdir(adminViewsDir, { recursive: true });
|
|
2074
2069
|
const existingAdminViewSlugs = readWorkspaceInventory(projectDir).adminViews.map((entry) => entry.slug);
|
|
2075
2070
|
const existingRegistrySlugs = readAdminViewRegistrySlugs(registryPath);
|
|
2076
|
-
const nextAdminViewSlugs = Array.from(new Set([
|
|
2071
|
+
const nextAdminViewSlugs = Array.from(new Set([
|
|
2072
|
+
...existingAdminViewSlugs,
|
|
2073
|
+
...existingRegistrySlugs,
|
|
2074
|
+
adminViewSlug
|
|
2075
|
+
])).sort();
|
|
2077
2076
|
await fsp3.writeFile(registryPath, buildAdminViewRegistrySource(nextAdminViewSlugs), "utf8");
|
|
2078
2077
|
}
|
|
2079
|
-
async function
|
|
2080
|
-
|
|
2081
|
-
|
|
2082
|
-
|
|
2083
|
-
|
|
2084
|
-
|
|
2085
|
-
|
|
2086
|
-
|
|
2087
|
-
const
|
|
2088
|
-
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
2089
|
-
const restResource = resolveRestResourceSource(inventory.restResources, parsedSource);
|
|
2090
|
-
const coreDataSource = isAdminViewCoreDataSource(parsedSource) ? parsedSource : undefined;
|
|
2091
|
-
assertAdminViewDoesNotExist(workspace.projectDir, adminViewSlug, inventory);
|
|
2092
|
-
const blockConfigPath = path4.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
2078
|
+
async function scaffoldAdminViewWorkspace(options) {
|
|
2079
|
+
const {
|
|
2080
|
+
adminViewSlug,
|
|
2081
|
+
coreDataSource,
|
|
2082
|
+
parsedSource,
|
|
2083
|
+
restResource,
|
|
2084
|
+
workspace
|
|
2085
|
+
} = options;
|
|
2086
|
+
const blockConfigPath = path5.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
2093
2087
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
2094
|
-
const buildScriptPath =
|
|
2095
|
-
const packageJsonPath =
|
|
2096
|
-
const webpackConfigPath =
|
|
2088
|
+
const buildScriptPath = path5.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
2089
|
+
const packageJsonPath = path5.join(workspace.projectDir, "package.json");
|
|
2090
|
+
const webpackConfigPath = path5.join(workspace.projectDir, "webpack.config.js");
|
|
2097
2091
|
const adminViewsIndexPath = resolveAdminViewRegistryPath(workspace.projectDir);
|
|
2098
|
-
const adminViewDir =
|
|
2099
|
-
const adminViewPhpPath =
|
|
2092
|
+
const adminViewDir = path5.join(workspace.projectDir, "src", "admin-views", adminViewSlug);
|
|
2093
|
+
const adminViewPhpPath = path5.join(workspace.projectDir, "inc", "admin-views", `${adminViewSlug}.php`);
|
|
2100
2094
|
const mutationSnapshot = {
|
|
2101
2095
|
fileSources: await snapshotWorkspaceFiles([
|
|
2102
2096
|
adminViewsIndexPath,
|
|
@@ -2111,37 +2105,63 @@ async function runAddAdminViewCommand({
|
|
|
2111
2105
|
};
|
|
2112
2106
|
try {
|
|
2113
2107
|
await fsp3.mkdir(adminViewDir, { recursive: true });
|
|
2114
|
-
await fsp3.mkdir(
|
|
2108
|
+
await fsp3.mkdir(path5.dirname(adminViewPhpPath), { recursive: true });
|
|
2115
2109
|
await ensureAdminViewPackageDependencies(workspace, parsedSource);
|
|
2116
2110
|
await ensureAdminViewBootstrapAnchors(workspace);
|
|
2117
2111
|
await ensureAdminViewBuildScriptAnchors(workspace);
|
|
2118
2112
|
await ensureAdminViewWebpackAnchors(workspace);
|
|
2119
|
-
await fsp3.writeFile(
|
|
2120
|
-
await fsp3.writeFile(
|
|
2121
|
-
await fsp3.writeFile(
|
|
2122
|
-
await fsp3.writeFile(
|
|
2123
|
-
await fsp3.writeFile(
|
|
2124
|
-
await fsp3.writeFile(
|
|
2113
|
+
await fsp3.writeFile(path5.join(adminViewDir, "types.ts"), buildAdminViewTypesSource(adminViewSlug, restResource, coreDataSource), "utf8");
|
|
2114
|
+
await fsp3.writeFile(path5.join(adminViewDir, "config.ts"), buildAdminViewConfigSource(adminViewSlug, workspace.workspace.textDomain, parsedSource, restResource), "utf8");
|
|
2115
|
+
await fsp3.writeFile(path5.join(adminViewDir, "data.ts"), coreDataSource ? buildCoreDataAdminViewDataSource(adminViewSlug, coreDataSource) : restResource ? buildRestAdminViewDataSource(adminViewSlug, restResource) : buildDefaultAdminViewDataSource(adminViewSlug), "utf8");
|
|
2116
|
+
await fsp3.writeFile(path5.join(adminViewDir, "Screen.tsx"), coreDataSource ? buildCoreDataAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain) : buildAdminViewScreenSource(adminViewSlug, workspace.workspace.textDomain), "utf8");
|
|
2117
|
+
await fsp3.writeFile(path5.join(adminViewDir, "index.tsx"), buildAdminViewEntrySource(adminViewSlug), "utf8");
|
|
2118
|
+
await fsp3.writeFile(path5.join(adminViewDir, "style.scss"), buildAdminViewStyleSource(), "utf8");
|
|
2125
2119
|
await fsp3.writeFile(adminViewPhpPath, buildAdminViewPhpSource(adminViewSlug, workspace), "utf8");
|
|
2126
2120
|
await writeAdminViewRegistry(workspace.projectDir, adminViewSlug);
|
|
2127
2121
|
await appendWorkspaceInventoryEntries(workspace.projectDir, {
|
|
2128
|
-
adminViewEntries: [
|
|
2122
|
+
adminViewEntries: [
|
|
2123
|
+
buildAdminViewConfigEntry(adminViewSlug, parsedSource)
|
|
2124
|
+
]
|
|
2129
2125
|
});
|
|
2130
|
-
return {
|
|
2131
|
-
adminViewSlug,
|
|
2132
|
-
projectDir: workspace.projectDir,
|
|
2133
|
-
source: parsedSource ? formatAdminViewSourceLocator(parsedSource) : undefined
|
|
2134
|
-
};
|
|
2135
2126
|
} catch (error) {
|
|
2136
2127
|
await rollbackWorkspaceMutation(mutationSnapshot);
|
|
2137
2128
|
throw error;
|
|
2138
2129
|
}
|
|
2139
2130
|
}
|
|
2131
|
+
|
|
2132
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-admin-view.ts
|
|
2133
|
+
var ADD_ADMIN_VIEW_USAGE = "wp-typia add admin-view <name> [--source <rest-resource:slug|core-data:kind/name>]";
|
|
2134
|
+
async function runAddAdminViewCommand({
|
|
2135
|
+
adminViewName,
|
|
2136
|
+
cwd = process.cwd(),
|
|
2137
|
+
source
|
|
2138
|
+
}) {
|
|
2139
|
+
const workspace = resolveWorkspaceProject(cwd);
|
|
2140
|
+
assertAdminViewPackageAvailability();
|
|
2141
|
+
const adminViewSlug = assertValidGeneratedSlug("Admin view name", normalizeBlockSlug(adminViewName), ADD_ADMIN_VIEW_USAGE);
|
|
2142
|
+
const parsedSource = parseAdminViewSource(source);
|
|
2143
|
+
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
2144
|
+
const restResource = resolveRestResourceSource(inventory.restResources, parsedSource);
|
|
2145
|
+
const coreDataSource = resolveAdminViewCoreDataSource(parsedSource);
|
|
2146
|
+
assertAdminViewDoesNotExist(workspace.projectDir, adminViewSlug, inventory);
|
|
2147
|
+
await scaffoldAdminViewWorkspace({
|
|
2148
|
+
adminViewSlug,
|
|
2149
|
+
coreDataSource,
|
|
2150
|
+
parsedSource,
|
|
2151
|
+
restResource,
|
|
2152
|
+
workspace
|
|
2153
|
+
});
|
|
2154
|
+
return {
|
|
2155
|
+
adminViewSlug,
|
|
2156
|
+
projectDir: workspace.projectDir,
|
|
2157
|
+
source: parsedSource ? formatAdminViewSourceLocator(parsedSource) : undefined
|
|
2158
|
+
};
|
|
2159
|
+
}
|
|
2140
2160
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-assets.ts
|
|
2141
2161
|
var import_typescript = __toESM(require_typescript(), 1);
|
|
2142
2162
|
import fs4 from "fs";
|
|
2143
2163
|
import { promises as fsp4 } from "fs";
|
|
2144
|
-
import
|
|
2164
|
+
import path6 from "path";
|
|
2145
2165
|
import {
|
|
2146
2166
|
syncBlockMetadata as syncBlockMetadata2
|
|
2147
2167
|
} from "@wp-typia/block-runtime/metadata-core";
|
|
@@ -2425,7 +2445,7 @@ async function ensureBindingTargetBlockAttributeType(projectDir, block, target)
|
|
|
2425
2445
|
if (!block.attributeTypeName) {
|
|
2426
2446
|
throw new Error(`Workspace block "${block.slug}" must include attributeTypeName in scripts/block-config.ts before it can receive binding-source targets.`);
|
|
2427
2447
|
}
|
|
2428
|
-
const typesPath =
|
|
2448
|
+
const typesPath = path6.join(projectDir, block.typesFile);
|
|
2429
2449
|
const source = await fsp4.readFile(typesPath, "utf8");
|
|
2430
2450
|
const targetInterface = getInterfaceDeclaration(source, block.attributeTypeName);
|
|
2431
2451
|
if (!targetInterface) {
|
|
@@ -2437,10 +2457,10 @@ async function ensureBindingTargetBlockAttributeType(projectDir, block, target)
|
|
|
2437
2457
|
await fsp4.writeFile(typesPath, nextSource, "utf8");
|
|
2438
2458
|
}
|
|
2439
2459
|
await syncBlockMetadata2({
|
|
2440
|
-
blockJsonFile:
|
|
2441
|
-
jsonSchemaFile:
|
|
2442
|
-
manifestFile:
|
|
2443
|
-
openApiFile:
|
|
2460
|
+
blockJsonFile: path6.join("src", "blocks", block.slug, "block.json"),
|
|
2461
|
+
jsonSchemaFile: path6.join("src", "blocks", block.slug, "typia.schema.json"),
|
|
2462
|
+
manifestFile: path6.join("src", "blocks", block.slug, "typia.manifest.json"),
|
|
2463
|
+
openApiFile: path6.join("src", "blocks", block.slug, "typia.openapi.json"),
|
|
2444
2464
|
projectRoot: projectDir,
|
|
2445
2465
|
sourceTypeName: block.attributeTypeName,
|
|
2446
2466
|
typesFile: block.typesFile
|
|
@@ -2679,7 +2699,7 @@ ${patternFunctions}
|
|
|
2679
2699
|
}
|
|
2680
2700
|
}
|
|
2681
2701
|
if (!nextSource.includes(patternCategoryFunctionName) || !nextSource.includes(patternRegistrationFunctionName)) {
|
|
2682
|
-
throw new Error(`Unable to inject pattern bootstrap functions into ${
|
|
2702
|
+
throw new Error(`Unable to inject pattern bootstrap functions into ${path6.basename(bootstrapPath)}.`);
|
|
2683
2703
|
}
|
|
2684
2704
|
if (!nextSource.includes(patternCategoryHook)) {
|
|
2685
2705
|
nextSource = `${nextSource.trimEnd()}
|
|
@@ -2867,7 +2887,7 @@ ${snippet}
|
|
|
2867
2887
|
if (missingReferences.length > 0) {
|
|
2868
2888
|
const replacedSource = replacePhpFunctionDefinition(nextSource, enqueueFunctionName, enqueueFunction);
|
|
2869
2889
|
if (!replacedSource) {
|
|
2870
|
-
throw new Error(`Unable to repair ${
|
|
2890
|
+
throw new Error(`Unable to repair ${path6.basename(bootstrapPath)} for ${enqueueFunctionName}.`);
|
|
2871
2891
|
}
|
|
2872
2892
|
nextSource = replacedSource;
|
|
2873
2893
|
}
|
|
@@ -2879,7 +2899,7 @@ ${snippet}
|
|
|
2879
2899
|
});
|
|
2880
2900
|
}
|
|
2881
2901
|
async function ensureEditorPluginBuildScriptAnchors(workspace) {
|
|
2882
|
-
const buildScriptPath =
|
|
2902
|
+
const buildScriptPath = path6.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
2883
2903
|
await patchFile(buildScriptPath, (source) => {
|
|
2884
2904
|
if (/['"]src\/editor-plugins\/index\.(?:ts|js)['"]/u.test(source)) {
|
|
2885
2905
|
return source;
|
|
@@ -2892,13 +2912,13 @@ async function ensureEditorPluginBuildScriptAnchors(workspace) {
|
|
|
2892
2912
|
'src/editor-plugins/index.js',
|
|
2893
2913
|
]`);
|
|
2894
2914
|
if (nextSource === source) {
|
|
2895
|
-
throw new Error(`Unable to update ${
|
|
2915
|
+
throw new Error(`Unable to update ${path6.relative(workspace.projectDir, buildScriptPath)} for editor plugin shared entries.`);
|
|
2896
2916
|
}
|
|
2897
2917
|
return nextSource;
|
|
2898
2918
|
});
|
|
2899
2919
|
}
|
|
2900
2920
|
async function ensureEditorPluginWebpackAnchors(workspace) {
|
|
2901
|
-
const webpackConfigPath =
|
|
2921
|
+
const webpackConfigPath = path6.join(workspace.projectDir, "webpack.config.js");
|
|
2902
2922
|
await patchFile(webpackConfigPath, (source) => {
|
|
2903
2923
|
if (/['"]editor-plugins\/index['"]/u.test(source)) {
|
|
2904
2924
|
return source;
|
|
@@ -2926,17 +2946,17 @@ async function ensureEditorPluginWebpackAnchors(workspace) {
|
|
|
2926
2946
|
}`;
|
|
2927
2947
|
const nextSource = source.replace(legacySharedEntriesBlockPattern, nextSharedEntriesBlock);
|
|
2928
2948
|
if (nextSource === source) {
|
|
2929
|
-
throw new Error(`Unable to update ${
|
|
2949
|
+
throw new Error(`Unable to update ${path6.relative(workspace.projectDir, webpackConfigPath)} for editor plugin shared entries.`);
|
|
2930
2950
|
}
|
|
2931
2951
|
return nextSource;
|
|
2932
2952
|
});
|
|
2933
2953
|
}
|
|
2934
2954
|
function resolveBindingSourceRegistryPath(projectDir) {
|
|
2935
|
-
const bindingsDir =
|
|
2936
|
-
return [
|
|
2955
|
+
const bindingsDir = path6.join(projectDir, "src", "bindings");
|
|
2956
|
+
return [path6.join(bindingsDir, "index.ts"), path6.join(bindingsDir, "index.js")].find((candidatePath) => fs4.existsSync(candidatePath)) ?? path6.join(bindingsDir, "index.ts");
|
|
2937
2957
|
}
|
|
2938
2958
|
async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
|
|
2939
|
-
const bindingsDir =
|
|
2959
|
+
const bindingsDir = path6.join(projectDir, "src", "bindings");
|
|
2940
2960
|
const bindingsIndexPath = resolveBindingSourceRegistryPath(projectDir);
|
|
2941
2961
|
await fsp4.mkdir(bindingsDir, { recursive: true });
|
|
2942
2962
|
const existingBindingSourceSlugs = fs4.readdirSync(bindingsDir, { withFileTypes: true }).filter((entry) => entry.isDirectory()).map((entry) => entry.name);
|
|
@@ -2944,11 +2964,11 @@ async function writeBindingSourceRegistry(projectDir, bindingSourceSlug) {
|
|
|
2944
2964
|
await fsp4.writeFile(bindingsIndexPath, buildBindingSourceIndexSource(nextBindingSourceSlugs), "utf8");
|
|
2945
2965
|
}
|
|
2946
2966
|
function resolveEditorPluginRegistryPath(projectDir) {
|
|
2947
|
-
const editorPluginsDir =
|
|
2967
|
+
const editorPluginsDir = path6.join(projectDir, "src", "editor-plugins");
|
|
2948
2968
|
return [
|
|
2949
|
-
|
|
2950
|
-
|
|
2951
|
-
].find((candidatePath) => fs4.existsSync(candidatePath)) ??
|
|
2969
|
+
path6.join(editorPluginsDir, "index.ts"),
|
|
2970
|
+
path6.join(editorPluginsDir, "index.js")
|
|
2971
|
+
].find((candidatePath) => fs4.existsSync(candidatePath)) ?? path6.join(editorPluginsDir, "index.ts");
|
|
2952
2972
|
}
|
|
2953
2973
|
function readEditorPluginRegistrySlugs(registryPath) {
|
|
2954
2974
|
if (!fs4.existsSync(registryPath)) {
|
|
@@ -2958,7 +2978,7 @@ function readEditorPluginRegistrySlugs(registryPath) {
|
|
|
2958
2978
|
return Array.from(source.matchAll(/^\s*import\s+['"]\.\/([^/'"]+)(?:\/index(?:\.[cm]?[jt]sx?)?)?['"];?\s*$/gmu)).map((match) => match[1]);
|
|
2959
2979
|
}
|
|
2960
2980
|
async function writeEditorPluginRegistry(projectDir, editorPluginSlug) {
|
|
2961
|
-
const editorPluginsDir =
|
|
2981
|
+
const editorPluginsDir = path6.join(projectDir, "src", "editor-plugins");
|
|
2962
2982
|
const registryPath = resolveEditorPluginRegistryPath(projectDir);
|
|
2963
2983
|
await fsp4.mkdir(editorPluginsDir, { recursive: true });
|
|
2964
2984
|
const existingEditorPluginSlugs = readWorkspaceInventory(projectDir).editorPlugins.map((entry) => entry.slug);
|
|
@@ -2976,17 +2996,17 @@ async function runAddEditorPluginCommand({
|
|
|
2976
2996
|
const resolvedSlot = assertValidEditorPluginSlot(slot);
|
|
2977
2997
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
2978
2998
|
assertEditorPluginDoesNotExist(workspace.projectDir, editorPluginSlug, inventory);
|
|
2979
|
-
const blockConfigPath =
|
|
2999
|
+
const blockConfigPath = path6.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
2980
3000
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
2981
|
-
const buildScriptPath =
|
|
3001
|
+
const buildScriptPath = path6.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
2982
3002
|
const editorPluginsIndexPath = resolveEditorPluginRegistryPath(workspace.projectDir);
|
|
2983
|
-
const webpackConfigPath =
|
|
2984
|
-
const editorPluginDir =
|
|
2985
|
-
const entryFilePath =
|
|
2986
|
-
const surfaceFilePath =
|
|
2987
|
-
const dataFilePath =
|
|
2988
|
-
const typesFilePath =
|
|
2989
|
-
const styleFilePath =
|
|
3003
|
+
const webpackConfigPath = path6.join(workspace.projectDir, "webpack.config.js");
|
|
3004
|
+
const editorPluginDir = path6.join(workspace.projectDir, "src", "editor-plugins", editorPluginSlug);
|
|
3005
|
+
const entryFilePath = path6.join(editorPluginDir, "index.tsx");
|
|
3006
|
+
const surfaceFilePath = path6.join(editorPluginDir, "Surface.tsx");
|
|
3007
|
+
const dataFilePath = path6.join(editorPluginDir, "data.ts");
|
|
3008
|
+
const typesFilePath = path6.join(editorPluginDir, "types.ts");
|
|
3009
|
+
const styleFilePath = path6.join(editorPluginDir, "style.scss");
|
|
2990
3010
|
const mutationSnapshot = {
|
|
2991
3011
|
fileSources: await snapshotWorkspaceFiles([
|
|
2992
3012
|
blockConfigPath,
|
|
@@ -3032,16 +3052,16 @@ async function runAddPatternCommand({
|
|
|
3032
3052
|
const patternSlug = assertValidGeneratedSlug("Pattern name", normalizeBlockSlug(patternName), "wp-typia add pattern <name>");
|
|
3033
3053
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
3034
3054
|
assertPatternDoesNotExist(workspace.projectDir, patternSlug, inventory);
|
|
3035
|
-
const blockConfigPath =
|
|
3055
|
+
const blockConfigPath = path6.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
3036
3056
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
3037
|
-
const patternFilePath =
|
|
3057
|
+
const patternFilePath = path6.join(workspace.projectDir, "src", "patterns", `${patternSlug}.php`);
|
|
3038
3058
|
const mutationSnapshot = {
|
|
3039
3059
|
fileSources: await snapshotWorkspaceFiles([blockConfigPath, bootstrapPath]),
|
|
3040
3060
|
snapshotDirs: [],
|
|
3041
3061
|
targetPaths: [patternFilePath]
|
|
3042
3062
|
};
|
|
3043
3063
|
try {
|
|
3044
|
-
await fsp4.mkdir(
|
|
3064
|
+
await fsp4.mkdir(path6.dirname(patternFilePath), { recursive: true });
|
|
3045
3065
|
await ensurePatternBootstrapAnchors(workspace);
|
|
3046
3066
|
await fsp4.writeFile(patternFilePath, buildPatternSource(patternSlug, workspace.workspace.namespace, workspace.workspace.textDomain), "utf8");
|
|
3047
3067
|
await appendWorkspaceInventoryEntries(workspace.projectDir, {
|
|
@@ -3071,18 +3091,18 @@ async function runAddBindingSourceCommand({
|
|
|
3071
3091
|
blockName
|
|
3072
3092
|
}, workspace.workspace.namespace);
|
|
3073
3093
|
const targetBlock = target ? resolveWorkspaceBlock(inventory, target.blockSlug) : undefined;
|
|
3074
|
-
const blockConfigPath =
|
|
3094
|
+
const blockConfigPath = path6.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
3075
3095
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
3076
3096
|
const bindingsIndexPath = resolveBindingSourceRegistryPath(workspace.projectDir);
|
|
3077
|
-
const bindingSourceDir =
|
|
3078
|
-
const serverFilePath =
|
|
3079
|
-
const editorFilePath =
|
|
3080
|
-
const blockJsonPath = target ?
|
|
3097
|
+
const bindingSourceDir = path6.join(workspace.projectDir, "src", "bindings", bindingSourceSlug);
|
|
3098
|
+
const serverFilePath = path6.join(bindingSourceDir, "server.php");
|
|
3099
|
+
const editorFilePath = path6.join(bindingSourceDir, "editor.ts");
|
|
3100
|
+
const blockJsonPath = target ? path6.join(workspace.projectDir, "src", "blocks", target.blockSlug, "block.json") : undefined;
|
|
3081
3101
|
const targetGeneratedMetadataPaths = target ? [
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3102
|
+
path6.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.manifest.json"),
|
|
3103
|
+
path6.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.openapi.json"),
|
|
3104
|
+
path6.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia.schema.json"),
|
|
3105
|
+
path6.join(workspace.projectDir, "src", "blocks", target.blockSlug, "typia-validator.php")
|
|
3086
3106
|
] : [];
|
|
3087
3107
|
const mutationSnapshot = {
|
|
3088
3108
|
fileSources: await snapshotWorkspaceFiles([
|
|
@@ -3090,7 +3110,7 @@ async function runAddBindingSourceCommand({
|
|
|
3090
3110
|
bootstrapPath,
|
|
3091
3111
|
bindingsIndexPath,
|
|
3092
3112
|
...blockJsonPath ? [blockJsonPath] : [],
|
|
3093
|
-
...targetBlock ? [
|
|
3113
|
+
...targetBlock ? [path6.join(workspace.projectDir, targetBlock.typesFile)] : [],
|
|
3094
3114
|
...targetGeneratedMetadataPaths
|
|
3095
3115
|
]),
|
|
3096
3116
|
snapshotDirs: [],
|
|
@@ -3120,10 +3140,10 @@ async function runAddBindingSourceCommand({
|
|
|
3120
3140
|
}
|
|
3121
3141
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
|
|
3122
3142
|
import { promises as fsp5 } from "fs";
|
|
3123
|
-
import
|
|
3143
|
+
import path9 from "path";
|
|
3124
3144
|
|
|
3125
3145
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest-anchors.ts
|
|
3126
|
-
import
|
|
3146
|
+
import path7 from "path";
|
|
3127
3147
|
var REST_RESOURCE_SERVER_GLOB = "/inc/rest/*.php";
|
|
3128
3148
|
async function ensureRestResourceBootstrapAnchors(workspace) {
|
|
3129
3149
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
@@ -3171,7 +3191,7 @@ ${snippet}
|
|
|
3171
3191
|
insertPhpSnippet(registerFunction);
|
|
3172
3192
|
} else if (!nextSource.includes(REST_RESOURCE_SERVER_GLOB)) {
|
|
3173
3193
|
throw new Error([
|
|
3174
|
-
`Unable to patch ${
|
|
3194
|
+
`Unable to patch ${path7.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
|
|
3175
3195
|
`The existing ${registerFunctionName}() definition does not include ${REST_RESOURCE_SERVER_GLOB}.`,
|
|
3176
3196
|
"Restore the generated bootstrap shape or wire the REST resource loader manually before retrying."
|
|
3177
3197
|
].join(" "));
|
|
@@ -3185,7 +3205,7 @@ ${snippet}
|
|
|
3185
3205
|
function assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
|
|
3186
3206
|
if (!nextSource.includes(target) && !hasAnchor) {
|
|
3187
3207
|
throw new Error([
|
|
3188
|
-
`ensureRestResourceSyncScriptAnchors could not patch ${
|
|
3208
|
+
`ensureRestResourceSyncScriptAnchors could not patch ${path7.basename(syncRestScriptPath)}.`,
|
|
3189
3209
|
`Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
|
|
3190
3210
|
"Restore the generated template or add the REST_RESOURCES wiring manually before retrying."
|
|
3191
3211
|
].join(" "));
|
|
@@ -3200,7 +3220,7 @@ function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement,
|
|
|
3200
3220
|
return nextSource.replace(anchor, replacement);
|
|
3201
3221
|
}
|
|
3202
3222
|
async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
3203
|
-
const syncRestScriptPath =
|
|
3223
|
+
const syncRestScriptPath = path7.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
3204
3224
|
await patchFile(syncRestScriptPath, (source) => {
|
|
3205
3225
|
let nextSource = source;
|
|
3206
3226
|
const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
|
|
@@ -3318,7 +3338,7 @@ async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
|
3318
3338
|
}
|
|
3319
3339
|
|
|
3320
3340
|
// ../wp-typia-project-tools/src/runtime/rest-resource-artifacts.ts
|
|
3321
|
-
import
|
|
3341
|
+
import path8 from "path";
|
|
3322
3342
|
import {
|
|
3323
3343
|
defineEndpointManifest,
|
|
3324
3344
|
syncEndpointClient,
|
|
@@ -3454,8 +3474,8 @@ async function syncRestResourceArtifacts({
|
|
|
3454
3474
|
const manifest = buildRestResourceEndpointManifest(variables, methods);
|
|
3455
3475
|
for (const [baseName, contract] of Object.entries(manifest.contracts)) {
|
|
3456
3476
|
await syncTypeSchemas({
|
|
3457
|
-
jsonSchemaFile:
|
|
3458
|
-
openApiFile:
|
|
3477
|
+
jsonSchemaFile: path8.join(outputDir, "api-schemas", `${baseName}.schema.json`),
|
|
3478
|
+
openApiFile: path8.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
|
|
3459
3479
|
projectRoot: projectDir,
|
|
3460
3480
|
sourceTypeName: contract.sourceTypeName,
|
|
3461
3481
|
typesFile
|
|
@@ -3463,7 +3483,7 @@ async function syncRestResourceArtifacts({
|
|
|
3463
3483
|
}
|
|
3464
3484
|
await syncRestOpenApi({
|
|
3465
3485
|
manifest,
|
|
3466
|
-
openApiFile:
|
|
3486
|
+
openApiFile: path8.join(outputDir, "api.openapi.json"),
|
|
3467
3487
|
projectRoot: projectDir,
|
|
3468
3488
|
typesFile
|
|
3469
3489
|
});
|
|
@@ -4288,15 +4308,15 @@ async function runAddRestResourceCommand({
|
|
|
4288
4308
|
const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
|
|
4289
4309
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
4290
4310
|
assertRestResourceDoesNotExist(workspace.projectDir, restResourceSlug, inventory);
|
|
4291
|
-
const blockConfigPath =
|
|
4311
|
+
const blockConfigPath = path9.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
4292
4312
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
4293
|
-
const syncRestScriptPath =
|
|
4294
|
-
const restResourceDir =
|
|
4295
|
-
const typesFilePath =
|
|
4296
|
-
const validatorsFilePath =
|
|
4297
|
-
const apiFilePath =
|
|
4298
|
-
const dataFilePath =
|
|
4299
|
-
const phpFilePath =
|
|
4313
|
+
const syncRestScriptPath = path9.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
4314
|
+
const restResourceDir = path9.join(workspace.projectDir, "src", "rest", restResourceSlug);
|
|
4315
|
+
const typesFilePath = path9.join(restResourceDir, "api-types.ts");
|
|
4316
|
+
const validatorsFilePath = path9.join(restResourceDir, "api-validators.ts");
|
|
4317
|
+
const apiFilePath = path9.join(restResourceDir, "api.ts");
|
|
4318
|
+
const dataFilePath = path9.join(restResourceDir, "data.ts");
|
|
4319
|
+
const phpFilePath = path9.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
|
|
4300
4320
|
const mutationSnapshot = {
|
|
4301
4321
|
fileSources: await snapshotWorkspaceFiles([
|
|
4302
4322
|
blockConfigPath,
|
|
@@ -4308,7 +4328,7 @@ async function runAddRestResourceCommand({
|
|
|
4308
4328
|
};
|
|
4309
4329
|
try {
|
|
4310
4330
|
await fsp5.mkdir(restResourceDir, { recursive: true });
|
|
4311
|
-
await fsp5.mkdir(
|
|
4331
|
+
await fsp5.mkdir(path9.dirname(phpFilePath), { recursive: true });
|
|
4312
4332
|
await ensureRestResourceBootstrapAnchors(workspace);
|
|
4313
4333
|
await ensureRestResourceSyncScriptAnchors(workspace);
|
|
4314
4334
|
await fsp5.writeFile(typesFilePath, buildRestResourceTypesSource(restResourceSlug, resolvedMethods), "utf8");
|
|
@@ -4351,7 +4371,7 @@ async function runAddRestResourceCommand({
|
|
|
4351
4371
|
var import_semver = __toESM(require_semver(), 1);
|
|
4352
4372
|
import fs5 from "fs";
|
|
4353
4373
|
import { promises as fsp6 } from "fs";
|
|
4354
|
-
import
|
|
4374
|
+
import path10 from "path";
|
|
4355
4375
|
import { syncTypeSchemas as syncTypeSchemas2 } from "@wp-typia/block-runtime/metadata-core";
|
|
4356
4376
|
var ABILITY_SERVER_GLOB = "/inc/abilities/*.php";
|
|
4357
4377
|
var ABILITY_EDITOR_SCRIPT = "build/abilities/index.js";
|
|
@@ -4836,8 +4856,8 @@ function buildAbilityRegistrySource(abilitySlugs) {
|
|
|
4836
4856
|
`);
|
|
4837
4857
|
}
|
|
4838
4858
|
function resolveAbilityRegistryPath(projectDir) {
|
|
4839
|
-
const abilitiesDir =
|
|
4840
|
-
return [
|
|
4859
|
+
const abilitiesDir = path10.join(projectDir, "src", "abilities");
|
|
4860
|
+
return [path10.join(abilitiesDir, "index.ts"), path10.join(abilitiesDir, "index.js")].find((candidatePath) => fs5.existsSync(candidatePath)) ?? path10.join(abilitiesDir, "index.ts");
|
|
4841
4861
|
}
|
|
4842
4862
|
function readAbilityRegistrySlugs(registryPath) {
|
|
4843
4863
|
if (!fs5.existsSync(registryPath)) {
|
|
@@ -4847,7 +4867,7 @@ function readAbilityRegistrySlugs(registryPath) {
|
|
|
4847
4867
|
return Array.from(source.matchAll(/^\s*export\s+\*\s+from\s+['"]\.\/([^/'"]+)\/client['"];?\s*$/gmu)).map((match) => match[1]);
|
|
4848
4868
|
}
|
|
4849
4869
|
async function writeAbilityRegistry(projectDir, abilitySlug) {
|
|
4850
|
-
const abilitiesDir =
|
|
4870
|
+
const abilitiesDir = path10.join(projectDir, "src", "abilities");
|
|
4851
4871
|
const registryPath = resolveAbilityRegistryPath(projectDir);
|
|
4852
4872
|
await fsp6.mkdir(abilitiesDir, { recursive: true });
|
|
4853
4873
|
const existingAbilitySlugs = readWorkspaceInventory(projectDir).abilities.map((entry) => entry.slug);
|
|
@@ -4979,7 +4999,7 @@ ${snippet}
|
|
|
4979
4999
|
});
|
|
4980
5000
|
}
|
|
4981
5001
|
async function ensureAbilityPackageScripts(workspace) {
|
|
4982
|
-
const packageJsonPath =
|
|
5002
|
+
const packageJsonPath = path10.join(workspace.projectDir, "package.json");
|
|
4983
5003
|
const packageJson = JSON.parse(await fsp6.readFile(packageJsonPath, "utf8"));
|
|
4984
5004
|
const nextScripts = {
|
|
4985
5005
|
...packageJson.scripts ?? {},
|
|
@@ -4999,7 +5019,7 @@ async function ensureAbilityPackageScripts(workspace) {
|
|
|
4999
5019
|
`, "utf8");
|
|
5000
5020
|
}
|
|
5001
5021
|
async function ensureAbilitySyncProjectAnchors(workspace) {
|
|
5002
|
-
const syncProjectScriptPath =
|
|
5022
|
+
const syncProjectScriptPath = path10.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
5003
5023
|
await patchFile(syncProjectScriptPath, (source) => {
|
|
5004
5024
|
let nextSource = source;
|
|
5005
5025
|
const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
|
|
@@ -5014,7 +5034,7 @@ async function ensureAbilitySyncProjectAnchors(workspace) {
|
|
|
5014
5034
|
if (!nextSource.includes(syncAbilitiesConst)) {
|
|
5015
5035
|
if (!nextSource.includes(syncRestConst)) {
|
|
5016
5036
|
throw new Error([
|
|
5017
|
-
`ensureAbilitySyncProjectAnchors could not patch ${
|
|
5037
|
+
`ensureAbilitySyncProjectAnchors could not patch ${path10.basename(syncProjectScriptPath)}.`,
|
|
5018
5038
|
"Missing the expected sync-rest script constant in scripts/sync-project.ts.",
|
|
5019
5039
|
"Restore the generated template or wire sync-abilities manually before retrying."
|
|
5020
5040
|
].join(" "));
|
|
@@ -5025,7 +5045,7 @@ ${syncAbilitiesConst}`);
|
|
|
5025
5045
|
if (!nextSource.includes("runSyncScript( syncAbilitiesScriptPath, options );")) {
|
|
5026
5046
|
if (!syncRestBlockPattern.test(nextSource)) {
|
|
5027
5047
|
throw new Error([
|
|
5028
|
-
`ensureAbilitySyncProjectAnchors could not patch ${
|
|
5048
|
+
`ensureAbilitySyncProjectAnchors could not patch ${path10.basename(syncProjectScriptPath)}.`,
|
|
5029
5049
|
"Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
|
|
5030
5050
|
"Restore the generated template or wire sync-abilities manually before retrying."
|
|
5031
5051
|
].join(" "));
|
|
@@ -5038,7 +5058,7 @@ ${syncAbilitiesBlock}`);
|
|
|
5038
5058
|
});
|
|
5039
5059
|
}
|
|
5040
5060
|
async function ensureAbilityBuildScriptAnchors(workspace) {
|
|
5041
|
-
const buildScriptPath =
|
|
5061
|
+
const buildScriptPath = path10.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
5042
5062
|
await patchFile(buildScriptPath, (source) => {
|
|
5043
5063
|
let nextSource = source;
|
|
5044
5064
|
if (/['"]src\/abilities\/index\.(?:ts|js)['"]/u.test(nextSource)) {
|
|
@@ -5048,7 +5068,7 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
|
|
|
5048
5068
|
const match = nextSource.match(sharedEntriesPattern);
|
|
5049
5069
|
if (!match || !match[2].includes("src/bindings/index.ts") || !match[2].includes("src/editor-plugins/index.ts")) {
|
|
5050
5070
|
throw new Error([
|
|
5051
|
-
`ensureAbilityBuildScriptAnchors could not patch ${
|
|
5071
|
+
`ensureAbilityBuildScriptAnchors could not patch ${path10.basename(buildScriptPath)}.`,
|
|
5052
5072
|
"Missing the expected shared editor entries array in scripts/build-workspace.mjs.",
|
|
5053
5073
|
"Restore the generated template or wire abilities/index manually before retrying."
|
|
5054
5074
|
].join(" "));
|
|
@@ -5065,7 +5085,7 @@ async function ensureAbilityBuildScriptAnchors(workspace) {
|
|
|
5065
5085
|
});
|
|
5066
5086
|
}
|
|
5067
5087
|
async function ensureAbilityWebpackAnchors(workspace) {
|
|
5068
|
-
const webpackConfigPath =
|
|
5088
|
+
const webpackConfigPath = path10.join(workspace.projectDir, "webpack.config.js");
|
|
5069
5089
|
await patchFile(webpackConfigPath, (source) => {
|
|
5070
5090
|
if (/['"]abilities\/index['"]/u.test(source)) {
|
|
5071
5091
|
return source;
|
|
@@ -5096,7 +5116,7 @@ $2`);
|
|
|
5096
5116
|
const match = source.match(sharedEntriesPattern);
|
|
5097
5117
|
if (!match || !match[1].includes("bindings/index") || !match[1].includes("editor-plugins/index")) {
|
|
5098
5118
|
throw new Error([
|
|
5099
|
-
`ensureAbilityWebpackAnchors could not patch ${
|
|
5119
|
+
`ensureAbilityWebpackAnchors could not patch ${path10.basename(webpackConfigPath)}.`,
|
|
5100
5120
|
"Missing the expected shared editor entries block in webpack.config.js.",
|
|
5101
5121
|
"Restore the generated template or wire abilities/index manually before retrying."
|
|
5102
5122
|
].join(" "));
|
|
@@ -5126,20 +5146,20 @@ async function runAddAbilityCommand({
|
|
|
5126
5146
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
5127
5147
|
assertAbilityDoesNotExist(workspace.projectDir, abilitySlug, inventory);
|
|
5128
5148
|
const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(REQUIRED_WORKSPACE_ABILITY_COMPATIBILITY);
|
|
5129
|
-
const blockConfigPath =
|
|
5149
|
+
const blockConfigPath = path10.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
5130
5150
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
5131
|
-
const buildScriptPath =
|
|
5132
|
-
const packageJsonPath =
|
|
5133
|
-
const syncAbilitiesScriptPath =
|
|
5134
|
-
const syncProjectScriptPath =
|
|
5135
|
-
const webpackConfigPath =
|
|
5151
|
+
const buildScriptPath = path10.join(workspace.projectDir, "scripts", "build-workspace.mjs");
|
|
5152
|
+
const packageJsonPath = path10.join(workspace.projectDir, "package.json");
|
|
5153
|
+
const syncAbilitiesScriptPath = path10.join(workspace.projectDir, "scripts", "sync-abilities.ts");
|
|
5154
|
+
const syncProjectScriptPath = path10.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
5155
|
+
const webpackConfigPath = path10.join(workspace.projectDir, "webpack.config.js");
|
|
5136
5156
|
const abilitiesIndexPath = resolveAbilityRegistryPath(workspace.projectDir);
|
|
5137
|
-
const abilityDir =
|
|
5138
|
-
const configFilePath =
|
|
5139
|
-
const typesFilePath =
|
|
5140
|
-
const dataFilePath =
|
|
5141
|
-
const clientFilePath =
|
|
5142
|
-
const phpFilePath =
|
|
5157
|
+
const abilityDir = path10.join(workspace.projectDir, "src", "abilities", abilitySlug);
|
|
5158
|
+
const configFilePath = path10.join(abilityDir, "ability.config.json");
|
|
5159
|
+
const typesFilePath = path10.join(abilityDir, "types.ts");
|
|
5160
|
+
const dataFilePath = path10.join(abilityDir, "data.ts");
|
|
5161
|
+
const clientFilePath = path10.join(abilityDir, "client.ts");
|
|
5162
|
+
const phpFilePath = path10.join(workspace.projectDir, "inc", "abilities", `${abilitySlug}.php`);
|
|
5143
5163
|
const mutationSnapshot = {
|
|
5144
5164
|
fileSources: await snapshotWorkspaceFiles([
|
|
5145
5165
|
blockConfigPath,
|
|
@@ -5156,7 +5176,7 @@ async function runAddAbilityCommand({
|
|
|
5156
5176
|
};
|
|
5157
5177
|
try {
|
|
5158
5178
|
await fsp6.mkdir(abilityDir, { recursive: true });
|
|
5159
|
-
await fsp6.mkdir(
|
|
5179
|
+
await fsp6.mkdir(path10.dirname(phpFilePath), { recursive: true });
|
|
5160
5180
|
await ensureAbilityBootstrapAnchors(workspace);
|
|
5161
5181
|
await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
|
|
5162
5182
|
await ensureAbilityPackageScripts(workspace);
|
|
@@ -5197,11 +5217,11 @@ async function runAddAbilityCommand({
|
|
|
5197
5217
|
}
|
|
5198
5218
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai.ts
|
|
5199
5219
|
import { promises as fsp8 } from "fs";
|
|
5200
|
-
import
|
|
5220
|
+
import path13 from "path";
|
|
5201
5221
|
|
|
5202
5222
|
// ../wp-typia-project-tools/src/runtime/ai-feature-artifacts.ts
|
|
5203
5223
|
import { mkdir, readFile, writeFile } from "fs/promises";
|
|
5204
|
-
import
|
|
5224
|
+
import path11 from "path";
|
|
5205
5225
|
import {
|
|
5206
5226
|
defineEndpointManifest as defineEndpointManifest2,
|
|
5207
5227
|
syncEndpointClient as syncEndpointClient2,
|
|
@@ -5227,7 +5247,7 @@ function normalizeGeneratedArtifactContent(content) {
|
|
|
5227
5247
|
}
|
|
5228
5248
|
async function reconcileGeneratedArtifact(options) {
|
|
5229
5249
|
if (!options.check) {
|
|
5230
|
-
await mkdir(
|
|
5250
|
+
await mkdir(path11.dirname(options.filePath), {
|
|
5231
5251
|
recursive: true
|
|
5232
5252
|
});
|
|
5233
5253
|
await writeFile(options.filePath, options.content, "utf8");
|
|
@@ -5299,8 +5319,8 @@ async function syncAiFeatureRestArtifacts({
|
|
|
5299
5319
|
const manifest = buildAiFeatureEndpointManifest(variables);
|
|
5300
5320
|
for (const [baseName, contract] of Object.entries(manifest.contracts)) {
|
|
5301
5321
|
await syncTypeSchemas3({
|
|
5302
|
-
jsonSchemaFile:
|
|
5303
|
-
openApiFile:
|
|
5322
|
+
jsonSchemaFile: path11.join(outputDir, "api-schemas", `${baseName}.schema.json`),
|
|
5323
|
+
openApiFile: path11.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
|
|
5304
5324
|
projectRoot: projectDir,
|
|
5305
5325
|
sourceTypeName: contract.sourceTypeName,
|
|
5306
5326
|
typesFile
|
|
@@ -5308,7 +5328,7 @@ async function syncAiFeatureRestArtifacts({
|
|
|
5308
5328
|
}
|
|
5309
5329
|
await syncRestOpenApi2({
|
|
5310
5330
|
manifest,
|
|
5311
|
-
openApiFile:
|
|
5331
|
+
openApiFile: path11.join(outputDir, "api.openapi.json"),
|
|
5312
5332
|
projectRoot: projectDir,
|
|
5313
5333
|
typesFile
|
|
5314
5334
|
}, executionOptions);
|
|
@@ -5326,19 +5346,19 @@ async function syncAiFeatureSchemaArtifact({
|
|
|
5326
5346
|
outputDir,
|
|
5327
5347
|
projectDir
|
|
5328
5348
|
}) {
|
|
5329
|
-
const sourceSchemaPath =
|
|
5349
|
+
const sourceSchemaPath = path11.join(projectDir, outputDir, "api-schemas", "feature-result.schema.json");
|
|
5330
5350
|
const responseSchema = assertJsonObject(JSON.parse(await readFile(sourceSchemaPath, "utf8")), sourceSchemaPath);
|
|
5331
5351
|
const aiSchema = projectWordPressAiSchema(responseSchema);
|
|
5332
5352
|
await reconcileGeneratedArtifact({
|
|
5333
5353
|
check,
|
|
5334
5354
|
content: `${JSON.stringify(aiSchema, null, 2)}
|
|
5335
5355
|
`,
|
|
5336
|
-
filePath:
|
|
5356
|
+
filePath: path11.join(projectDir, aiSchemaFile),
|
|
5337
5357
|
label: "AI feature schema"
|
|
5338
5358
|
});
|
|
5339
5359
|
return {
|
|
5340
5360
|
aiSchema,
|
|
5341
|
-
aiSchemaPath:
|
|
5361
|
+
aiSchemaPath: path11.join(projectDir, aiSchemaFile),
|
|
5342
5362
|
check,
|
|
5343
5363
|
sourceSchemaPath
|
|
5344
5364
|
};
|
|
@@ -5416,6 +5436,45 @@ export interface ${pascalCase}AiFeatureResponse {
|
|
|
5416
5436
|
result: ${pascalCase}AiFeatureResult;
|
|
5417
5437
|
telemetry: ${pascalCase}AiFeatureTelemetry;
|
|
5418
5438
|
}
|
|
5439
|
+
|
|
5440
|
+
export type ${pascalCase}AiFeatureSupportProbeMode = 'request-time';
|
|
5441
|
+
|
|
5442
|
+
export type ${pascalCase}AiFeatureUnavailableErrorCode =
|
|
5443
|
+
'ai_client_unavailable';
|
|
5444
|
+
|
|
5445
|
+
export type ${pascalCase}AiFeatureUnavailableReasonCode =
|
|
5446
|
+
| 'missing-wordpress-ai-client'
|
|
5447
|
+
| 'request-time-support-probe';
|
|
5448
|
+
|
|
5449
|
+
export interface ${pascalCase}AiFeatureSupportReason {
|
|
5450
|
+
code: ${pascalCase}AiFeatureUnavailableReasonCode;
|
|
5451
|
+
label: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
|
|
5452
|
+
message: string & tags.MinLength< 1 > & tags.MaxLength< 4000 >;
|
|
5453
|
+
}
|
|
5454
|
+
|
|
5455
|
+
export interface ${pascalCase}AiFeatureSupportMetadata {
|
|
5456
|
+
featureLabel: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
|
|
5457
|
+
featureSlug: string & tags.MinLength< 1 > & tags.MaxLength< 160 >;
|
|
5458
|
+
compatibility: {
|
|
5459
|
+
hardMinimums: {
|
|
5460
|
+
php?: string;
|
|
5461
|
+
wordpress?: string;
|
|
5462
|
+
};
|
|
5463
|
+
mode: 'baseline' | 'optional' | 'required';
|
|
5464
|
+
optionalFeatureIds: string[];
|
|
5465
|
+
optionalFeatures: string[];
|
|
5466
|
+
requiredFeatureIds: string[];
|
|
5467
|
+
requiredFeatures: string[];
|
|
5468
|
+
runtimeGates: string[];
|
|
5469
|
+
};
|
|
5470
|
+
supportProbe: {
|
|
5471
|
+
endpointMethod: 'POST';
|
|
5472
|
+
endpointPath: string & tags.MinLength< 1 > & tags.MaxLength< 200 >;
|
|
5473
|
+
mode: ${pascalCase}AiFeatureSupportProbeMode;
|
|
5474
|
+
unavailableErrorCode: ${pascalCase}AiFeatureUnavailableErrorCode;
|
|
5475
|
+
};
|
|
5476
|
+
unavailableReasons: ${pascalCase}AiFeatureSupportReason[];
|
|
5477
|
+
}
|
|
5419
5478
|
`;
|
|
5420
5479
|
}
|
|
5421
5480
|
function buildAiFeatureValidatorsSource(aiFeatureSlug) {
|
|
@@ -5451,6 +5510,8 @@ export const apiValidators = {
|
|
|
5451
5510
|
}
|
|
5452
5511
|
function buildAiFeatureApiSource(aiFeatureSlug) {
|
|
5453
5512
|
const pascalCase = toPascalCase(aiFeatureSlug);
|
|
5513
|
+
const compatibility = createScaffoldCompatibilityConfig(resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY));
|
|
5514
|
+
const title = toTitleCase(aiFeatureSlug);
|
|
5454
5515
|
return `import {
|
|
5455
5516
|
callEndpoint,
|
|
5456
5517
|
resolveRestRouteUrl,
|
|
@@ -5458,6 +5519,7 @@ function buildAiFeatureApiSource(aiFeatureSlug) {
|
|
|
5458
5519
|
|
|
5459
5520
|
import type {
|
|
5460
5521
|
${pascalCase}AiFeatureRequest,
|
|
5522
|
+
${pascalCase}AiFeatureSupportMetadata,
|
|
5461
5523
|
} from './api-types';
|
|
5462
5524
|
import {
|
|
5463
5525
|
run${pascalCase}AiFeatureEndpoint,
|
|
@@ -5484,6 +5546,14 @@ function resolveRestNonce( fallback?: string ): string | undefined {
|
|
|
5484
5546
|
: undefined;
|
|
5485
5547
|
}
|
|
5486
5548
|
|
|
5549
|
+
function isPlainObject( value: unknown ): value is Record< string, unknown > {
|
|
5550
|
+
return (
|
|
5551
|
+
!! value &&
|
|
5552
|
+
typeof value === 'object' &&
|
|
5553
|
+
! Array.isArray( value )
|
|
5554
|
+
);
|
|
5555
|
+
}
|
|
5556
|
+
|
|
5487
5557
|
export const aiFeatureRunEndpoint = {
|
|
5488
5558
|
...run${pascalCase}AiFeatureEndpoint,
|
|
5489
5559
|
buildRequestOptions: () => {
|
|
@@ -5499,6 +5569,63 @@ export const aiFeatureRunEndpoint = {
|
|
|
5499
5569
|
},
|
|
5500
5570
|
};
|
|
5501
5571
|
|
|
5572
|
+
export const aiFeatureSupportMetadata = {
|
|
5573
|
+
compatibility: ${JSON.stringify(compatibility, null, "\t")},
|
|
5574
|
+
featureLabel: ${quoteTsString(title)},
|
|
5575
|
+
featureSlug: ${quoteTsString(aiFeatureSlug)},
|
|
5576
|
+
supportProbe: {
|
|
5577
|
+
endpointMethod: 'POST',
|
|
5578
|
+
endpointPath: aiFeatureRunEndpoint.path,
|
|
5579
|
+
mode: 'request-time',
|
|
5580
|
+
unavailableErrorCode: 'ai_client_unavailable',
|
|
5581
|
+
},
|
|
5582
|
+
unavailableReasons: [
|
|
5583
|
+
{
|
|
5584
|
+
code: 'missing-wordpress-ai-client',
|
|
5585
|
+
label: 'WordPress AI Client unavailable',
|
|
5586
|
+
message:
|
|
5587
|
+
'This AI feature stays disabled until the WordPress AI Client is available on the site.',
|
|
5588
|
+
},
|
|
5589
|
+
{
|
|
5590
|
+
code: 'request-time-support-probe',
|
|
5591
|
+
label: 'Support is checked at request time',
|
|
5592
|
+
message:
|
|
5593
|
+
'Support is verified when the feature runs, so editor and admin UIs should degrade gracefully when the site rejects the request.',
|
|
5594
|
+
},
|
|
5595
|
+
],
|
|
5596
|
+
} satisfies ${pascalCase}AiFeatureSupportMetadata;
|
|
5597
|
+
|
|
5598
|
+
export function getAiFeatureSupportHintLines() {
|
|
5599
|
+
return aiFeatureSupportMetadata.unavailableReasons.map(
|
|
5600
|
+
( reason ) => reason.message
|
|
5601
|
+
);
|
|
5602
|
+
}
|
|
5603
|
+
|
|
5604
|
+
export function isAiFeatureSupportUnavailableError( error: unknown ) {
|
|
5605
|
+
if ( ! isPlainObject( error ) ) {
|
|
5606
|
+
return false;
|
|
5607
|
+
}
|
|
5608
|
+
|
|
5609
|
+
const data = isPlainObject( error.data ) ? error.data : undefined;
|
|
5610
|
+
return (
|
|
5611
|
+
error.code === aiFeatureSupportMetadata.supportProbe.unavailableErrorCode ||
|
|
5612
|
+
data?.status === 501
|
|
5613
|
+
);
|
|
5614
|
+
}
|
|
5615
|
+
|
|
5616
|
+
export function resolveAiFeatureUnavailableMessage( error: unknown ) {
|
|
5617
|
+
if (
|
|
5618
|
+
isPlainObject( error ) &&
|
|
5619
|
+
typeof error.message === 'string' &&
|
|
5620
|
+
error.message.length > 0
|
|
5621
|
+
) {
|
|
5622
|
+
return error.message;
|
|
5623
|
+
}
|
|
5624
|
+
|
|
5625
|
+
return aiFeatureSupportMetadata.unavailableReasons[ 0 ]?.message ??
|
|
5626
|
+
'This AI feature is currently unavailable.';
|
|
5627
|
+
}
|
|
5628
|
+
|
|
5502
5629
|
export function runAiFeature( request: ${pascalCase}AiFeatureRequest ) {
|
|
5503
5630
|
return callEndpoint( aiFeatureRunEndpoint, request );
|
|
5504
5631
|
}
|
|
@@ -5517,6 +5644,10 @@ import type {
|
|
|
5517
5644
|
} from './api-types';
|
|
5518
5645
|
import {
|
|
5519
5646
|
aiFeatureRunEndpoint,
|
|
5647
|
+
aiFeatureSupportMetadata,
|
|
5648
|
+
getAiFeatureSupportHintLines,
|
|
5649
|
+
isAiFeatureSupportUnavailableError,
|
|
5650
|
+
resolveAiFeatureUnavailableMessage,
|
|
5520
5651
|
} from './api';
|
|
5521
5652
|
|
|
5522
5653
|
export type UseRun${pascalCase}AiFeatureMutationOptions =
|
|
@@ -5531,6 +5662,13 @@ export function useRun${pascalCase}AiFeatureMutation(
|
|
|
5531
5662
|
) {
|
|
5532
5663
|
return useEndpointMutation( aiFeatureRunEndpoint, options );
|
|
5533
5664
|
}
|
|
5665
|
+
|
|
5666
|
+
export {
|
|
5667
|
+
aiFeatureSupportMetadata,
|
|
5668
|
+
getAiFeatureSupportHintLines,
|
|
5669
|
+
isAiFeatureSupportUnavailableError,
|
|
5670
|
+
resolveAiFeatureUnavailableMessage,
|
|
5671
|
+
};
|
|
5534
5672
|
`;
|
|
5535
5673
|
}
|
|
5536
5674
|
function buildAiFeatureSyncScriptSource() {
|
|
@@ -5662,7 +5800,7 @@ main().catch( ( error ) => {
|
|
|
5662
5800
|
|
|
5663
5801
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-ai-anchors.ts
|
|
5664
5802
|
import { promises as fsp7 } from "fs";
|
|
5665
|
-
import
|
|
5803
|
+
import path12 from "path";
|
|
5666
5804
|
var AI_FEATURE_SERVER_GLOB = "/inc/ai-features/*.php";
|
|
5667
5805
|
async function ensureAiFeatureBootstrapAnchors(workspace) {
|
|
5668
5806
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
@@ -5710,7 +5848,7 @@ ${snippet}
|
|
|
5710
5848
|
insertPhpSnippet(registerFunction);
|
|
5711
5849
|
} else if (!nextSource.includes(AI_FEATURE_SERVER_GLOB)) {
|
|
5712
5850
|
throw new Error([
|
|
5713
|
-
`Unable to patch ${
|
|
5851
|
+
`Unable to patch ${path12.basename(bootstrapPath)} in ensureAiFeatureBootstrapAnchors.`,
|
|
5714
5852
|
`The existing ${registerFunctionName}() definition does not include ${AI_FEATURE_SERVER_GLOB}.`,
|
|
5715
5853
|
"Restore the generated bootstrap shape or wire the AI feature loader manually before retrying."
|
|
5716
5854
|
].join(" "));
|
|
@@ -5722,7 +5860,7 @@ ${snippet}
|
|
|
5722
5860
|
});
|
|
5723
5861
|
}
|
|
5724
5862
|
async function ensureAiFeaturePackageScripts(workspace) {
|
|
5725
|
-
const packageJsonPath =
|
|
5863
|
+
const packageJsonPath = path12.join(workspace.projectDir, "package.json");
|
|
5726
5864
|
const packageJson = JSON.parse(await fsp7.readFile(packageJsonPath, "utf8"));
|
|
5727
5865
|
const nextScripts = {
|
|
5728
5866
|
...packageJson.scripts ?? {},
|
|
@@ -5750,7 +5888,7 @@ async function ensureAiFeaturePackageScripts(workspace) {
|
|
|
5750
5888
|
};
|
|
5751
5889
|
}
|
|
5752
5890
|
async function ensureAiFeatureSyncProjectAnchors(workspace) {
|
|
5753
|
-
const syncProjectScriptPath =
|
|
5891
|
+
const syncProjectScriptPath = path12.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
5754
5892
|
await patchFile(syncProjectScriptPath, (source) => {
|
|
5755
5893
|
let nextSource = source;
|
|
5756
5894
|
const syncRestConst = "const syncRestScriptPath = path.join( 'scripts', 'sync-rest-contracts.ts' );";
|
|
@@ -5765,7 +5903,7 @@ async function ensureAiFeatureSyncProjectAnchors(workspace) {
|
|
|
5765
5903
|
if (!nextSource.includes(syncAiConst)) {
|
|
5766
5904
|
if (!nextSource.includes(syncRestConst)) {
|
|
5767
5905
|
throw new Error([
|
|
5768
|
-
`ensureAiFeatureSyncProjectAnchors could not patch ${
|
|
5906
|
+
`ensureAiFeatureSyncProjectAnchors could not patch ${path12.basename(syncProjectScriptPath)}.`,
|
|
5769
5907
|
"Missing the expected sync-rest script constant in scripts/sync-project.ts.",
|
|
5770
5908
|
"Restore the generated template or wire sync-ai manually before retrying."
|
|
5771
5909
|
].join(" "));
|
|
@@ -5776,7 +5914,7 @@ ${syncAiConst}`);
|
|
|
5776
5914
|
if (!nextSource.includes("runSyncScript( syncAiScriptPath, options );")) {
|
|
5777
5915
|
if (!syncRestBlockPattern.test(nextSource)) {
|
|
5778
5916
|
throw new Error([
|
|
5779
|
-
`ensureAiFeatureSyncProjectAnchors could not patch ${
|
|
5917
|
+
`ensureAiFeatureSyncProjectAnchors could not patch ${path12.basename(syncProjectScriptPath)}.`,
|
|
5780
5918
|
"Missing the expected sync-rest invocation block in scripts/sync-project.ts.",
|
|
5781
5919
|
"Restore the generated template or wire sync-ai manually before retrying."
|
|
5782
5920
|
].join(" "));
|
|
@@ -5791,7 +5929,7 @@ ${syncAiBlock}`);
|
|
|
5791
5929
|
function assertSyncRestAnchor2(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
|
|
5792
5930
|
if (!nextSource.includes(target) && !hasAnchor) {
|
|
5793
5931
|
throw new Error([
|
|
5794
|
-
`ensureAiFeatureSyncRestAnchors could not patch ${
|
|
5932
|
+
`ensureAiFeatureSyncRestAnchors could not patch ${path12.basename(syncRestScriptPath)}.`,
|
|
5795
5933
|
`Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
|
|
5796
5934
|
"Restore the generated template or add the AI feature wiring manually before retrying."
|
|
5797
5935
|
].join(" "));
|
|
@@ -5806,7 +5944,7 @@ function replaceRequiredSyncRestSource2(nextSource, target, anchor, replacement,
|
|
|
5806
5944
|
return nextSource.replace(anchor, replacement);
|
|
5807
5945
|
}
|
|
5808
5946
|
async function ensureAiFeatureSyncRestAnchors(workspace) {
|
|
5809
|
-
const syncRestScriptPath =
|
|
5947
|
+
const syncRestScriptPath = path12.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
5810
5948
|
await patchFile(syncRestScriptPath, (source) => {
|
|
5811
5949
|
let nextSource = source;
|
|
5812
5950
|
const importAnchor = [
|
|
@@ -5943,18 +6081,40 @@ function buildAiFeaturePhpSource(aiFeatureSlug, namespace, phpPrefix, textDomain
|
|
|
5943
6081
|
const normalizeSchemaFunctionName = `${phpPrefix}_${aiFeaturePhpId}_sanitize_ai_feature_schema`;
|
|
5944
6082
|
const validatePayloadFunctionName = `${phpPrefix}_${aiFeaturePhpId}_validate_ai_feature_payload`;
|
|
5945
6083
|
const canManageFunctionName = `${phpPrefix}_${aiFeaturePhpId}_can_manage_ai_feature`;
|
|
6084
|
+
const normalizePromptPayloadFunctionName = `${phpPrefix}_${aiFeaturePhpId}_normalize_ai_feature_prompt_payload`;
|
|
5946
6085
|
const buildPromptFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_prompt`;
|
|
6086
|
+
const resolvePromptOptionsFunctionName = `${phpPrefix}_${aiFeaturePhpId}_resolve_ai_feature_prompt_options`;
|
|
5947
6087
|
const normalizeProviderTypeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_normalize_provider_type`;
|
|
5948
6088
|
const buildTelemetryFunctionName = `${phpPrefix}_${aiFeaturePhpId}_build_ai_feature_telemetry`;
|
|
6089
|
+
const resolveUnavailableMessageFunctionName = `${phpPrefix}_${aiFeaturePhpId}_resolve_ai_feature_unavailable_message`;
|
|
5949
6090
|
const isSupportedFunctionName = `${phpPrefix}_${aiFeaturePhpId}_is_ai_feature_supported`;
|
|
5950
6091
|
const adminNoticeFunctionName = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_admin_notice`;
|
|
5951
6092
|
const handlerFunctionName = `${phpPrefix}_${aiFeaturePhpId}_handle_run_ai_feature`;
|
|
5952
6093
|
const registerRoutesFunctionName = `${phpPrefix}_${aiFeaturePhpId}_register_ai_feature_routes`;
|
|
6094
|
+
const permissionFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_permission`;
|
|
6095
|
+
const promptPayloadFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt_payload`;
|
|
6096
|
+
const promptFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt`;
|
|
6097
|
+
const promptOptionsFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_prompt_options`;
|
|
6098
|
+
const adminNoticeMessageFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_admin_notice_message`;
|
|
6099
|
+
const unavailableMessageFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_unavailable_message`;
|
|
6100
|
+
const telemetryFilterHook = `${phpPrefix}_${aiFeaturePhpId}_ai_feature_telemetry`;
|
|
5953
6101
|
return `<?php
|
|
5954
6102
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
5955
6103
|
return;
|
|
5956
6104
|
}
|
|
5957
6105
|
|
|
6106
|
+
/*
|
|
6107
|
+
* Customization hooks for the ${aiFeatureTitle} AI feature:
|
|
6108
|
+
*
|
|
6109
|
+
* - ${quotePhpString(permissionFilterHook)} filters the default current_user_can( 'edit_posts' ) capability check.
|
|
6110
|
+
* - ${quotePhpString(promptPayloadFilterHook)} filters the validated request payload array before prompt serialization.
|
|
6111
|
+
* - ${quotePhpString(promptFilterHook)} filters the final prompt string after payload normalization.
|
|
6112
|
+
* - ${quotePhpString(promptOptionsFilterHook)} filters prompt options with \`temperature\` and \`modelPreference\` keys.
|
|
6113
|
+
* - ${quotePhpString(adminNoticeMessageFilterHook)} filters the wp-admin notice shown when AI support is unavailable.
|
|
6114
|
+
* - ${quotePhpString(unavailableMessageFilterHook)} filters REST-facing unavailable messages by reason code.
|
|
6115
|
+
* - ${quotePhpString(telemetryFilterHook)} filters the response telemetry array before schema validation. Return a schema-compatible array.
|
|
6116
|
+
*/
|
|
6117
|
+
|
|
5958
6118
|
if ( ! function_exists( '${loadSchemaFunctionName}' ) ) {
|
|
5959
6119
|
function ${loadSchemaFunctionName}( $schema_name ) {
|
|
5960
6120
|
$project_root = dirname( __DIR__, 2 );
|
|
@@ -6021,17 +6181,111 @@ if ( ! function_exists( '${validatePayloadFunctionName}' ) ) {
|
|
|
6021
6181
|
}
|
|
6022
6182
|
|
|
6023
6183
|
if ( ! function_exists( '${canManageFunctionName}' ) ) {
|
|
6024
|
-
function ${canManageFunctionName}() {
|
|
6025
|
-
|
|
6184
|
+
function ${canManageFunctionName}( WP_REST_Request $request = null ) {
|
|
6185
|
+
$permission = apply_filters(
|
|
6186
|
+
${quotePhpString(permissionFilterHook)},
|
|
6187
|
+
current_user_can( 'edit_posts' ),
|
|
6188
|
+
$request
|
|
6189
|
+
);
|
|
6190
|
+
if ( is_wp_error( $permission ) ) {
|
|
6191
|
+
return $permission;
|
|
6192
|
+
}
|
|
6193
|
+
return (bool) $permission;
|
|
6194
|
+
}
|
|
6195
|
+
}
|
|
6196
|
+
|
|
6197
|
+
if ( ! function_exists( '${normalizePromptPayloadFunctionName}' ) ) {
|
|
6198
|
+
function ${normalizePromptPayloadFunctionName}( array $payload ) {
|
|
6199
|
+
$normalized_payload = apply_filters(
|
|
6200
|
+
${quotePhpString(promptPayloadFilterHook)},
|
|
6201
|
+
$payload
|
|
6202
|
+
);
|
|
6203
|
+
return is_array( $normalized_payload ) ? $normalized_payload : $payload;
|
|
6026
6204
|
}
|
|
6027
6205
|
}
|
|
6028
6206
|
|
|
6029
6207
|
if ( ! function_exists( '${buildPromptFunctionName}' ) ) {
|
|
6030
6208
|
function ${buildPromptFunctionName}( array $payload ) {
|
|
6031
|
-
|
|
6209
|
+
$normalized_payload = ${normalizePromptPayloadFunctionName}( $payload );
|
|
6210
|
+
$prompt = sprintf(
|
|
6032
6211
|
'You are helping with the %1$s AI workflow. Read the JSON request payload and return JSON that matches the provided schema. Request payload: %2$s',
|
|
6033
6212
|
${quotePhpString(aiFeatureTitle)},
|
|
6034
|
-
wp_json_encode( $
|
|
6213
|
+
wp_json_encode( $normalized_payload )
|
|
6214
|
+
);
|
|
6215
|
+
$filtered_prompt = apply_filters(
|
|
6216
|
+
${quotePhpString(promptFilterHook)},
|
|
6217
|
+
$prompt,
|
|
6218
|
+
$normalized_payload,
|
|
6219
|
+
$payload
|
|
6220
|
+
);
|
|
6221
|
+
return is_string( $filtered_prompt ) && '' !== $filtered_prompt ? $filtered_prompt : $prompt;
|
|
6222
|
+
}
|
|
6223
|
+
}
|
|
6224
|
+
|
|
6225
|
+
if ( ! function_exists( '${resolvePromptOptionsFunctionName}' ) ) {
|
|
6226
|
+
function ${resolvePromptOptionsFunctionName}( array $payload = array() ) {
|
|
6227
|
+
$options = apply_filters(
|
|
6228
|
+
${quotePhpString(promptOptionsFilterHook)},
|
|
6229
|
+
array(
|
|
6230
|
+
'modelPreference' => array(),
|
|
6231
|
+
'temperature' => 0.2,
|
|
6232
|
+
),
|
|
6233
|
+
$payload
|
|
6234
|
+
);
|
|
6235
|
+
if ( ! is_array( $options ) ) {
|
|
6236
|
+
$options = array();
|
|
6237
|
+
}
|
|
6238
|
+
|
|
6239
|
+
$temperature = 0.2;
|
|
6240
|
+
if ( array_key_exists( 'temperature', $options ) ) {
|
|
6241
|
+
if ( null === $options['temperature'] ) {
|
|
6242
|
+
$temperature = null;
|
|
6243
|
+
} elseif ( is_numeric( $options['temperature'] ) ) {
|
|
6244
|
+
$temperature = (float) $options['temperature'];
|
|
6245
|
+
}
|
|
6246
|
+
}
|
|
6247
|
+
|
|
6248
|
+
$model_preferences = array();
|
|
6249
|
+
if ( isset( $options['modelPreference'] ) ) {
|
|
6250
|
+
$raw_model_preferences = $options['modelPreference'];
|
|
6251
|
+
if ( is_string( $raw_model_preferences ) && '' !== $raw_model_preferences ) {
|
|
6252
|
+
$model_preferences = array( $raw_model_preferences );
|
|
6253
|
+
} elseif ( is_array( $raw_model_preferences ) ) {
|
|
6254
|
+
$model_preferences = array_values(
|
|
6255
|
+
array_filter(
|
|
6256
|
+
array_map(
|
|
6257
|
+
static function ( $candidate ) {
|
|
6258
|
+
if ( is_string( $candidate ) && '' !== $candidate ) {
|
|
6259
|
+
return $candidate;
|
|
6260
|
+
}
|
|
6261
|
+
if ( ! is_array( $candidate ) ) {
|
|
6262
|
+
return null;
|
|
6263
|
+
}
|
|
6264
|
+
|
|
6265
|
+
$normalized = array_values(
|
|
6266
|
+
array_filter(
|
|
6267
|
+
$candidate,
|
|
6268
|
+
static function ( $value ) {
|
|
6269
|
+
return is_string( $value ) && '' !== $value;
|
|
6270
|
+
}
|
|
6271
|
+
)
|
|
6272
|
+
);
|
|
6273
|
+
|
|
6274
|
+
return count( $normalized ) > 0 ? $normalized : null;
|
|
6275
|
+
},
|
|
6276
|
+
$raw_model_preferences
|
|
6277
|
+
),
|
|
6278
|
+
static function ( $candidate ) {
|
|
6279
|
+
return null !== $candidate;
|
|
6280
|
+
}
|
|
6281
|
+
)
|
|
6282
|
+
);
|
|
6283
|
+
}
|
|
6284
|
+
}
|
|
6285
|
+
|
|
6286
|
+
return array(
|
|
6287
|
+
'modelPreference' => $model_preferences,
|
|
6288
|
+
'temperature' => $temperature,
|
|
6035
6289
|
);
|
|
6036
6290
|
}
|
|
6037
6291
|
}
|
|
@@ -6047,7 +6301,7 @@ if ( ! function_exists( '${normalizeProviderTypeFunctionName}' ) ) {
|
|
|
6047
6301
|
}
|
|
6048
6302
|
|
|
6049
6303
|
if ( ! function_exists( '${buildTelemetryFunctionName}' ) ) {
|
|
6050
|
-
function ${buildTelemetryFunctionName}( $result ) {
|
|
6304
|
+
function ${buildTelemetryFunctionName}( $result, array $payload = array(), array $normalized_result = array() ) {
|
|
6051
6305
|
if (
|
|
6052
6306
|
! is_object( $result ) ||
|
|
6053
6307
|
! method_exists( $result, 'getId' ) ||
|
|
@@ -6107,47 +6361,95 @@ if ( ! function_exists( '${buildTelemetryFunctionName}' ) ) {
|
|
|
6107
6361
|
}
|
|
6108
6362
|
}
|
|
6109
6363
|
|
|
6110
|
-
|
|
6364
|
+
$filtered_telemetry = apply_filters(
|
|
6365
|
+
${quotePhpString(telemetryFilterHook)},
|
|
6366
|
+
$telemetry,
|
|
6367
|
+
$result,
|
|
6368
|
+
$payload,
|
|
6369
|
+
$normalized_result
|
|
6370
|
+
);
|
|
6371
|
+
return is_array( $filtered_telemetry ) ? $filtered_telemetry : $telemetry;
|
|
6372
|
+
}
|
|
6373
|
+
}
|
|
6374
|
+
|
|
6375
|
+
if ( ! function_exists( '${resolveUnavailableMessageFunctionName}' ) ) {
|
|
6376
|
+
function ${resolveUnavailableMessageFunctionName}( $message, $reason, array $context = array() ) {
|
|
6377
|
+
$filtered_message = apply_filters(
|
|
6378
|
+
${quotePhpString(unavailableMessageFilterHook)},
|
|
6379
|
+
$message,
|
|
6380
|
+
$reason,
|
|
6381
|
+
$context
|
|
6382
|
+
);
|
|
6383
|
+
return is_string( $filtered_message ) && '' !== $filtered_message ? $filtered_message : $message;
|
|
6111
6384
|
}
|
|
6112
6385
|
}
|
|
6113
6386
|
|
|
6114
6387
|
if ( ! function_exists( '${isSupportedFunctionName}' ) ) {
|
|
6115
|
-
function ${isSupportedFunctionName}() {
|
|
6388
|
+
function ${isSupportedFunctionName}( array $payload = array(), $cache_result = true ) {
|
|
6116
6389
|
static $is_supported = null;
|
|
6117
|
-
|
|
6390
|
+
$use_cache = $cache_result && count( $payload ) === 0;
|
|
6391
|
+
if ( $use_cache && null !== $is_supported ) {
|
|
6118
6392
|
return $is_supported;
|
|
6119
6393
|
}
|
|
6120
6394
|
|
|
6121
6395
|
if ( ! function_exists( 'wp_ai_client_prompt' ) ) {
|
|
6122
|
-
$
|
|
6123
|
-
|
|
6396
|
+
if ( $use_cache ) {
|
|
6397
|
+
$is_supported = false;
|
|
6398
|
+
}
|
|
6399
|
+
return false;
|
|
6124
6400
|
}
|
|
6125
6401
|
|
|
6126
6402
|
$schema = ${loadAiSchemaFunctionName}();
|
|
6127
6403
|
if ( ! is_array( $schema ) ) {
|
|
6128
|
-
$
|
|
6129
|
-
|
|
6404
|
+
if ( $use_cache ) {
|
|
6405
|
+
$is_supported = false;
|
|
6406
|
+
}
|
|
6407
|
+
return false;
|
|
6130
6408
|
}
|
|
6131
6409
|
|
|
6132
6410
|
$prompt = wp_ai_client_prompt( 'AI feature support probe.' );
|
|
6133
6411
|
if ( ! is_object( $prompt ) || ! method_exists( $prompt, 'as_json_response' ) ) {
|
|
6134
|
-
$
|
|
6135
|
-
|
|
6412
|
+
if ( $use_cache ) {
|
|
6413
|
+
$is_supported = false;
|
|
6414
|
+
}
|
|
6415
|
+
return false;
|
|
6416
|
+
}
|
|
6417
|
+
$prompt_options = ${resolvePromptOptionsFunctionName}( $payload );
|
|
6418
|
+
if (
|
|
6419
|
+
array_key_exists( 'temperature', $prompt_options ) &&
|
|
6420
|
+
null !== $prompt_options['temperature'] &&
|
|
6421
|
+
method_exists( $prompt, 'using_temperature' )
|
|
6422
|
+
) {
|
|
6423
|
+
$prompt = $prompt->using_temperature( $prompt_options['temperature'] );
|
|
6424
|
+
}
|
|
6425
|
+
if (
|
|
6426
|
+
! empty( $prompt_options['modelPreference'] ) &&
|
|
6427
|
+
method_exists( $prompt, 'using_model_preference' )
|
|
6428
|
+
) {
|
|
6429
|
+
$prompt = $prompt->using_model_preference( ...$prompt_options['modelPreference'] );
|
|
6136
6430
|
}
|
|
6137
6431
|
|
|
6138
6432
|
$structured_prompt = $prompt->as_json_response( $schema );
|
|
6139
6433
|
if ( ! is_object( $structured_prompt ) ) {
|
|
6140
|
-
$
|
|
6141
|
-
|
|
6434
|
+
if ( $use_cache ) {
|
|
6435
|
+
$is_supported = false;
|
|
6436
|
+
}
|
|
6437
|
+
return false;
|
|
6142
6438
|
}
|
|
6143
6439
|
|
|
6144
6440
|
if ( method_exists( $structured_prompt, 'is_supported_for_text_generation' ) ) {
|
|
6145
|
-
$
|
|
6146
|
-
|
|
6441
|
+
$supported = (bool) $structured_prompt->is_supported_for_text_generation();
|
|
6442
|
+
if ( $use_cache ) {
|
|
6443
|
+
$is_supported = $supported;
|
|
6444
|
+
}
|
|
6445
|
+
return $supported;
|
|
6147
6446
|
}
|
|
6148
6447
|
|
|
6149
|
-
$
|
|
6150
|
-
|
|
6448
|
+
$supported = method_exists( $structured_prompt, 'generate_text_result' );
|
|
6449
|
+
if ( $use_cache ) {
|
|
6450
|
+
$is_supported = $supported;
|
|
6451
|
+
}
|
|
6452
|
+
return $supported;
|
|
6151
6453
|
}
|
|
6152
6454
|
}
|
|
6153
6455
|
|
|
@@ -6162,6 +6464,18 @@ if ( ! function_exists( '${adminNoticeFunctionName}' ) ) {
|
|
|
6162
6464
|
__( 'The %s AI feature is optional and remains disabled until the WordPress AI Client is available with structured text generation support for the generated schema.', ${quotePhpString(textDomain)} ),
|
|
6163
6465
|
${quotePhpString(aiFeatureTitle)}
|
|
6164
6466
|
);
|
|
6467
|
+
$filtered_message = apply_filters(
|
|
6468
|
+
${quotePhpString(adminNoticeMessageFilterHook)},
|
|
6469
|
+
$message,
|
|
6470
|
+
array(
|
|
6471
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6472
|
+
'featureTitle' => ${quotePhpString(aiFeatureTitle)},
|
|
6473
|
+
'namespace' => ${quotePhpString(namespace)},
|
|
6474
|
+
)
|
|
6475
|
+
);
|
|
6476
|
+
if ( is_string( $filtered_message ) && '' !== $filtered_message ) {
|
|
6477
|
+
$message = $filtered_message;
|
|
6478
|
+
}
|
|
6165
6479
|
printf( '<div class="notice notice-warning"><p>%s</p></div>', esc_html( $message ) );
|
|
6166
6480
|
}
|
|
6167
6481
|
}
|
|
@@ -6173,10 +6487,16 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
|
6173
6487
|
return $payload;
|
|
6174
6488
|
}
|
|
6175
6489
|
|
|
6176
|
-
if ( ! ${isSupportedFunctionName}() ) {
|
|
6490
|
+
if ( ! ${isSupportedFunctionName}( $payload, false ) ) {
|
|
6177
6491
|
return new WP_Error(
|
|
6178
6492
|
'ai_client_unavailable',
|
|
6179
|
-
|
|
6493
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6494
|
+
'The WordPress AI Client is unavailable or does not support this feature endpoint.',
|
|
6495
|
+
'support_probe_failed',
|
|
6496
|
+
array(
|
|
6497
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6498
|
+
)
|
|
6499
|
+
),
|
|
6180
6500
|
array( 'status' => 501 )
|
|
6181
6501
|
);
|
|
6182
6502
|
}
|
|
@@ -6190,22 +6510,45 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
|
6190
6510
|
);
|
|
6191
6511
|
}
|
|
6192
6512
|
|
|
6513
|
+
$prompt_options = ${resolvePromptOptionsFunctionName}( $payload );
|
|
6193
6514
|
$prompt = wp_ai_client_prompt( ${buildPromptFunctionName}( $payload ) );
|
|
6194
6515
|
if ( ! is_object( $prompt ) ) {
|
|
6195
6516
|
return new WP_Error(
|
|
6196
6517
|
'ai_client_unavailable',
|
|
6197
|
-
|
|
6518
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6519
|
+
'The WordPress AI Client prompt builder is unavailable on this site.',
|
|
6520
|
+
'prompt_builder_missing',
|
|
6521
|
+
array(
|
|
6522
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6523
|
+
)
|
|
6524
|
+
),
|
|
6198
6525
|
array( 'status' => 501 )
|
|
6199
6526
|
);
|
|
6200
6527
|
}
|
|
6201
6528
|
|
|
6202
|
-
if (
|
|
6203
|
-
|
|
6529
|
+
if (
|
|
6530
|
+
array_key_exists( 'temperature', $prompt_options ) &&
|
|
6531
|
+
null !== $prompt_options['temperature'] &&
|
|
6532
|
+
method_exists( $prompt, 'using_temperature' )
|
|
6533
|
+
) {
|
|
6534
|
+
$prompt = $prompt->using_temperature( $prompt_options['temperature'] );
|
|
6535
|
+
}
|
|
6536
|
+
if (
|
|
6537
|
+
! empty( $prompt_options['modelPreference'] ) &&
|
|
6538
|
+
method_exists( $prompt, 'using_model_preference' )
|
|
6539
|
+
) {
|
|
6540
|
+
$prompt = $prompt->using_model_preference( ...$prompt_options['modelPreference'] );
|
|
6204
6541
|
}
|
|
6205
6542
|
if ( ! method_exists( $prompt, 'as_json_response' ) ) {
|
|
6206
6543
|
return new WP_Error(
|
|
6207
6544
|
'ai_client_unavailable',
|
|
6208
|
-
|
|
6545
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6546
|
+
'The current WordPress AI Client does not expose as_json_response().',
|
|
6547
|
+
'as_json_response_missing',
|
|
6548
|
+
array(
|
|
6549
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6550
|
+
)
|
|
6551
|
+
),
|
|
6209
6552
|
array( 'status' => 501 )
|
|
6210
6553
|
);
|
|
6211
6554
|
}
|
|
@@ -6214,7 +6557,13 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
|
6214
6557
|
if ( ! is_object( $structured_prompt ) ) {
|
|
6215
6558
|
return new WP_Error(
|
|
6216
6559
|
'ai_client_unavailable',
|
|
6217
|
-
|
|
6560
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6561
|
+
'The current WordPress AI Client could not prepare a structured-output prompt.',
|
|
6562
|
+
'structured_prompt_missing',
|
|
6563
|
+
array(
|
|
6564
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6565
|
+
)
|
|
6566
|
+
),
|
|
6218
6567
|
array( 'status' => 501 )
|
|
6219
6568
|
);
|
|
6220
6569
|
}
|
|
@@ -6225,14 +6574,26 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
|
6225
6574
|
) {
|
|
6226
6575
|
return new WP_Error(
|
|
6227
6576
|
'ai_client_unavailable',
|
|
6228
|
-
|
|
6577
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6578
|
+
'The current WordPress AI Client provider or model does not support this structured-output feature.',
|
|
6579
|
+
'text_generation_unsupported',
|
|
6580
|
+
array(
|
|
6581
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6582
|
+
)
|
|
6583
|
+
),
|
|
6229
6584
|
array( 'status' => 501 )
|
|
6230
6585
|
);
|
|
6231
6586
|
}
|
|
6232
6587
|
if ( ! method_exists( $structured_prompt, 'generate_text_result' ) ) {
|
|
6233
6588
|
return new WP_Error(
|
|
6234
6589
|
'ai_client_unavailable',
|
|
6235
|
-
|
|
6590
|
+
${resolveUnavailableMessageFunctionName}(
|
|
6591
|
+
'The current WordPress AI Client does not expose generate_text_result() after as_json_response().',
|
|
6592
|
+
'generate_text_result_missing',
|
|
6593
|
+
array(
|
|
6594
|
+
'featureSlug' => ${quotePhpString(aiFeatureSlug)},
|
|
6595
|
+
)
|
|
6596
|
+
),
|
|
6236
6597
|
array( 'status' => 501 )
|
|
6237
6598
|
);
|
|
6238
6599
|
}
|
|
@@ -6267,7 +6628,7 @@ if ( ! function_exists( '${handlerFunctionName}' ) ) {
|
|
|
6267
6628
|
);
|
|
6268
6629
|
}
|
|
6269
6630
|
|
|
6270
|
-
$telemetry = ${buildTelemetryFunctionName}( $result );
|
|
6631
|
+
$telemetry = ${buildTelemetryFunctionName}( $result, $payload, $normalized_result );
|
|
6271
6632
|
if ( is_wp_error( $telemetry ) ) {
|
|
6272
6633
|
return $telemetry;
|
|
6273
6634
|
}
|
|
@@ -6323,18 +6684,18 @@ async function runAddAiFeatureCommand({
|
|
|
6323
6684
|
const compatibilityPolicy = resolveScaffoldCompatibilityPolicy(OPTIONAL_WORDPRESS_AI_CLIENT_COMPATIBILITY);
|
|
6324
6685
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
6325
6686
|
assertAiFeatureDoesNotExist(workspace.projectDir, aiFeatureSlug, inventory);
|
|
6326
|
-
const blockConfigPath =
|
|
6687
|
+
const blockConfigPath = path13.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
6327
6688
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
6328
|
-
const packageJsonPath =
|
|
6329
|
-
const syncAiScriptPath =
|
|
6330
|
-
const syncProjectScriptPath =
|
|
6331
|
-
const syncRestScriptPath =
|
|
6332
|
-
const aiFeatureDir =
|
|
6333
|
-
const typesFilePath =
|
|
6334
|
-
const validatorsFilePath =
|
|
6335
|
-
const apiFilePath =
|
|
6336
|
-
const dataFilePath =
|
|
6337
|
-
const phpFilePath =
|
|
6689
|
+
const packageJsonPath = path13.join(workspace.projectDir, "package.json");
|
|
6690
|
+
const syncAiScriptPath = path13.join(workspace.projectDir, "scripts", "sync-ai-features.ts");
|
|
6691
|
+
const syncProjectScriptPath = path13.join(workspace.projectDir, "scripts", "sync-project.ts");
|
|
6692
|
+
const syncRestScriptPath = path13.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
6693
|
+
const aiFeatureDir = path13.join(workspace.projectDir, "src", "ai-features", aiFeatureSlug);
|
|
6694
|
+
const typesFilePath = path13.join(aiFeatureDir, "api-types.ts");
|
|
6695
|
+
const validatorsFilePath = path13.join(aiFeatureDir, "api-validators.ts");
|
|
6696
|
+
const apiFilePath = path13.join(aiFeatureDir, "api.ts");
|
|
6697
|
+
const dataFilePath = path13.join(aiFeatureDir, "data.ts");
|
|
6698
|
+
const phpFilePath = path13.join(workspace.projectDir, "inc", "ai-features", `${aiFeatureSlug}.php`);
|
|
6338
6699
|
const mutationSnapshot = {
|
|
6339
6700
|
fileSources: await snapshotWorkspaceFiles([
|
|
6340
6701
|
blockConfigPath,
|
|
@@ -6349,7 +6710,7 @@ async function runAddAiFeatureCommand({
|
|
|
6349
6710
|
};
|
|
6350
6711
|
try {
|
|
6351
6712
|
await fsp8.mkdir(aiFeatureDir, { recursive: true });
|
|
6352
|
-
await fsp8.mkdir(
|
|
6713
|
+
await fsp8.mkdir(path13.dirname(phpFilePath), { recursive: true });
|
|
6353
6714
|
await ensureAiFeatureBootstrapAnchors(workspace);
|
|
6354
6715
|
await patchFile(bootstrapPath, (source) => updatePluginHeaderCompatibility(source, compatibilityPolicy));
|
|
6355
6716
|
const packageScriptChanges = await ensureAiFeaturePackageScripts(workspace);
|
|
@@ -6364,7 +6725,7 @@ async function runAddAiFeatureCommand({
|
|
|
6364
6725
|
const pascalCase = toPascalCase(aiFeatureSlug);
|
|
6365
6726
|
await syncAiFeatureRestArtifacts({
|
|
6366
6727
|
clientFile: `src/ai-features/${aiFeatureSlug}/api-client.ts`,
|
|
6367
|
-
outputDir:
|
|
6728
|
+
outputDir: path13.join("src", "ai-features", aiFeatureSlug),
|
|
6368
6729
|
projectDir: workspace.projectDir,
|
|
6369
6730
|
typesFile: `src/ai-features/${aiFeatureSlug}/api-types.ts`,
|
|
6370
6731
|
validatorsFile: `src/ai-features/${aiFeatureSlug}/api-validators.ts`,
|
|
@@ -6377,7 +6738,7 @@ async function runAddAiFeatureCommand({
|
|
|
6377
6738
|
});
|
|
6378
6739
|
await syncAiFeatureSchemaArtifact({
|
|
6379
6740
|
aiSchemaFile: `src/ai-features/${aiFeatureSlug}/ai-schemas/feature-result.ai.schema.json`,
|
|
6380
|
-
outputDir:
|
|
6741
|
+
outputDir: path13.join("src", "ai-features", aiFeatureSlug),
|
|
6381
6742
|
projectDir: workspace.projectDir
|
|
6382
6743
|
});
|
|
6383
6744
|
await appendWorkspaceInventoryEntries(workspace.projectDir, {
|
|
@@ -6798,7 +7159,7 @@ ${VARIATIONS_CALL_LINE}
|
|
|
6798
7159
|
}
|
|
6799
7160
|
}
|
|
6800
7161
|
if (!hasExecutablePattern(nextSource, VARIATIONS_CALL_PATTERN)) {
|
|
6801
|
-
throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${
|
|
7162
|
+
throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path14.basename(blockIndexPath)}.`);
|
|
6802
7163
|
}
|
|
6803
7164
|
return nextSource;
|
|
6804
7165
|
});
|
|
@@ -6828,7 +7189,7 @@ ${BLOCK_STYLES_CALL_LINE}
|
|
|
6828
7189
|
}
|
|
6829
7190
|
}
|
|
6830
7191
|
if (!hasExecutablePattern(nextSource, BLOCK_STYLES_CALL_PATTERN)) {
|
|
6831
|
-
throw new Error(`Unable to inject ${BLOCK_STYLES_CALL_LINE} into ${
|
|
7192
|
+
throw new Error(`Unable to inject ${BLOCK_STYLES_CALL_LINE} into ${path14.basename(blockIndexPath)}.`);
|
|
6832
7193
|
}
|
|
6833
7194
|
return nextSource;
|
|
6834
7195
|
});
|
|
@@ -6845,7 +7206,7 @@ ${nextSource}`;
|
|
|
6845
7206
|
SCAFFOLD_REGISTRATION_SETTINGS_CALL_PATTERN
|
|
6846
7207
|
]);
|
|
6847
7208
|
if (!callRange) {
|
|
6848
|
-
throw new Error(`Unable to inject ${BLOCK_TRANSFORMS_CALL_LINE} into ${
|
|
7209
|
+
throw new Error(`Unable to inject ${BLOCK_TRANSFORMS_CALL_LINE} into ${path14.basename(blockIndexPath)} because it does not expose a scaffold registration settings object.`);
|
|
6849
7210
|
}
|
|
6850
7211
|
nextSource = [
|
|
6851
7212
|
nextSource.slice(0, callRange.start),
|
|
@@ -6858,42 +7219,42 @@ ${nextSource}`;
|
|
|
6858
7219
|
});
|
|
6859
7220
|
}
|
|
6860
7221
|
async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
|
|
6861
|
-
const variationsDir =
|
|
6862
|
-
const variationsIndexPath =
|
|
7222
|
+
const variationsDir = path14.join(projectDir, "src", "blocks", blockSlug, "variations");
|
|
7223
|
+
const variationsIndexPath = path14.join(variationsDir, "index.ts");
|
|
6863
7224
|
await fsp9.mkdir(variationsDir, { recursive: true });
|
|
6864
7225
|
const existingVariationSlugs = fs6.readdirSync(variationsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
|
|
6865
7226
|
const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
|
|
6866
7227
|
await fsp9.writeFile(variationsIndexPath, buildVariationIndexSource(nextVariationSlugs), "utf8");
|
|
6867
7228
|
}
|
|
6868
7229
|
async function writeBlockStyleRegistry(projectDir, blockSlug, styleSlug) {
|
|
6869
|
-
const stylesDir =
|
|
6870
|
-
const stylesIndexPath =
|
|
7230
|
+
const stylesDir = path14.join(projectDir, "src", "blocks", blockSlug, "styles");
|
|
7231
|
+
const stylesIndexPath = path14.join(stylesDir, "index.ts");
|
|
6871
7232
|
await fsp9.mkdir(stylesDir, { recursive: true });
|
|
6872
7233
|
const existingStyleSlugs = fs6.readdirSync(stylesDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
|
|
6873
7234
|
const nextStyleSlugs = Array.from(new Set([...existingStyleSlugs, styleSlug])).sort();
|
|
6874
7235
|
await fsp9.writeFile(stylesIndexPath, buildBlockStyleIndexSource(nextStyleSlugs), "utf8");
|
|
6875
7236
|
}
|
|
6876
7237
|
async function writeBlockTransformRegistry(projectDir, blockSlug, transformSlug) {
|
|
6877
|
-
const transformsDir =
|
|
6878
|
-
const transformsIndexPath =
|
|
7238
|
+
const transformsDir = path14.join(projectDir, "src", "blocks", blockSlug, "transforms");
|
|
7239
|
+
const transformsIndexPath = path14.join(transformsDir, "index.ts");
|
|
6879
7240
|
await fsp9.mkdir(transformsDir, { recursive: true });
|
|
6880
7241
|
const existingTransformSlugs = fs6.readdirSync(transformsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
|
|
6881
7242
|
const nextTransformSlugs = Array.from(new Set([...existingTransformSlugs, transformSlug])).sort();
|
|
6882
7243
|
await fsp9.writeFile(transformsIndexPath, buildBlockTransformIndexSource(nextTransformSlugs), "utf8");
|
|
6883
7244
|
}
|
|
6884
7245
|
function assertBlockStyleDoesNotExist(projectDir, blockSlug, styleSlug, inventory) {
|
|
6885
|
-
const stylePath =
|
|
7246
|
+
const stylePath = path14.join(projectDir, "src", "blocks", blockSlug, "styles", `${styleSlug}.ts`);
|
|
6886
7247
|
if (fs6.existsSync(stylePath)) {
|
|
6887
|
-
throw new Error(`A block style already exists at ${
|
|
7248
|
+
throw new Error(`A block style already exists at ${path14.relative(projectDir, stylePath)}. Choose a different name.`);
|
|
6888
7249
|
}
|
|
6889
7250
|
if (inventory.blockStyles.some((entry) => entry.block === blockSlug && entry.slug === styleSlug)) {
|
|
6890
7251
|
throw new Error(`A block style inventory entry already exists for ${blockSlug}/${styleSlug}. Choose a different name.`);
|
|
6891
7252
|
}
|
|
6892
7253
|
}
|
|
6893
7254
|
function assertBlockTransformDoesNotExist(projectDir, blockSlug, transformSlug, inventory) {
|
|
6894
|
-
const transformPath =
|
|
7255
|
+
const transformPath = path14.join(projectDir, "src", "blocks", blockSlug, "transforms", `${transformSlug}.ts`);
|
|
6895
7256
|
if (fs6.existsSync(transformPath)) {
|
|
6896
|
-
throw new Error(`A block transform already exists at ${
|
|
7257
|
+
throw new Error(`A block transform already exists at ${path14.relative(projectDir, transformPath)}. Choose a different name.`);
|
|
6897
7258
|
}
|
|
6898
7259
|
if (inventory.blockTransforms.some((entry) => entry.block === blockSlug && entry.slug === transformSlug)) {
|
|
6899
7260
|
throw new Error(`A block transform inventory entry already exists for ${blockSlug}/${transformSlug}. Choose a different name.`);
|
|
@@ -6939,11 +7300,11 @@ async function runAddVariationCommand({
|
|
|
6939
7300
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
6940
7301
|
resolveWorkspaceBlock(inventory, blockSlug);
|
|
6941
7302
|
assertVariationDoesNotExist(workspace.projectDir, blockSlug, variationSlug, inventory);
|
|
6942
|
-
const blockConfigPath =
|
|
6943
|
-
const blockIndexPath =
|
|
6944
|
-
const variationsDir =
|
|
6945
|
-
const variationFilePath =
|
|
6946
|
-
const variationsIndexPath =
|
|
7303
|
+
const blockConfigPath = path14.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
7304
|
+
const blockIndexPath = path14.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
|
|
7305
|
+
const variationsDir = path14.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
|
|
7306
|
+
const variationFilePath = path14.join(variationsDir, `${variationSlug}.ts`);
|
|
7307
|
+
const variationsIndexPath = path14.join(variationsDir, "index.ts");
|
|
6947
7308
|
const shouldRemoveVariationsDirOnRollback = !fs6.existsSync(variationsDir);
|
|
6948
7309
|
const mutationSnapshot = {
|
|
6949
7310
|
fileSources: await snapshotWorkspaceFiles([
|
|
@@ -6986,11 +7347,11 @@ async function runAddBlockStyleCommand({
|
|
|
6986
7347
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
6987
7348
|
resolveWorkspaceBlock(inventory, blockSlug);
|
|
6988
7349
|
assertBlockStyleDoesNotExist(workspace.projectDir, blockSlug, styleSlug, inventory);
|
|
6989
|
-
const blockConfigPath =
|
|
6990
|
-
const blockIndexPath =
|
|
6991
|
-
const stylesDir =
|
|
6992
|
-
const styleFilePath =
|
|
6993
|
-
const stylesIndexPath =
|
|
7350
|
+
const blockConfigPath = path14.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
7351
|
+
const blockIndexPath = path14.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
|
|
7352
|
+
const stylesDir = path14.join(workspace.projectDir, "src", "blocks", blockSlug, "styles");
|
|
7353
|
+
const styleFilePath = path14.join(stylesDir, `${styleSlug}.ts`);
|
|
7354
|
+
const stylesIndexPath = path14.join(stylesDir, "index.ts");
|
|
6994
7355
|
const shouldRemoveStylesDirOnRollback = !fs6.existsSync(stylesDir);
|
|
6995
7356
|
const mutationSnapshot = {
|
|
6996
7357
|
fileSources: await snapshotWorkspaceFiles([
|
|
@@ -7035,11 +7396,11 @@ async function runAddBlockTransformCommand({
|
|
|
7035
7396
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
7036
7397
|
resolveWorkspaceBlock(inventory, target.blockSlug);
|
|
7037
7398
|
assertBlockTransformDoesNotExist(workspace.projectDir, target.blockSlug, transformSlug, inventory);
|
|
7038
|
-
const blockConfigPath =
|
|
7039
|
-
const blockIndexPath =
|
|
7040
|
-
const transformsDir =
|
|
7041
|
-
const transformFilePath =
|
|
7042
|
-
const transformsIndexPath =
|
|
7399
|
+
const blockConfigPath = path14.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
7400
|
+
const blockIndexPath = path14.join(workspace.projectDir, "src", "blocks", target.blockSlug, "index.tsx");
|
|
7401
|
+
const transformsDir = path14.join(workspace.projectDir, "src", "blocks", target.blockSlug, "transforms");
|
|
7402
|
+
const transformFilePath = path14.join(transformsDir, `${transformSlug}.ts`);
|
|
7403
|
+
const transformsIndexPath = path14.join(transformsDir, "index.ts");
|
|
7043
7404
|
const shouldRemoveTransformsDirOnRollback = !fs6.existsSync(transformsDir);
|
|
7044
7405
|
const mutationSnapshot = {
|
|
7045
7406
|
fileSources: await snapshotWorkspaceFiles([
|
|
@@ -7101,7 +7462,7 @@ async function runAddHookedBlockCommand({
|
|
|
7101
7462
|
throw new Error("`wp-typia add hooked-block` cannot hook a block relative to its own block name.");
|
|
7102
7463
|
}
|
|
7103
7464
|
const { blockJson, blockJsonPath } = readWorkspaceBlockJson(workspace.projectDir, blockSlug);
|
|
7104
|
-
const blockJsonRelativePath =
|
|
7465
|
+
const blockJsonRelativePath = path14.relative(workspace.projectDir, blockJsonPath);
|
|
7105
7466
|
const blockHooks = getMutableBlockHooks(blockJson, blockJsonRelativePath);
|
|
7106
7467
|
if (Object.prototype.hasOwnProperty.call(blockHooks, resolvedAnchorBlockName)) {
|
|
7107
7468
|
throw new Error(`${blockJsonRelativePath} already defines a blockHooks entry for "${resolvedAnchorBlockName}".`);
|
|
@@ -7146,4 +7507,4 @@ export {
|
|
|
7146
7507
|
ADD_BLOCK_TEMPLATE_IDS
|
|
7147
7508
|
};
|
|
7148
7509
|
|
|
7149
|
-
//# debugId=
|
|
7510
|
+
//# debugId=FE993C1947A36DF464756E2164756E21
|