wp-typia 0.20.0 → 0.20.1
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 +360 -335
- package/dist-bunli/.bunli/commands.gen.js.map +9 -5
- package/dist-bunli/{cli-add-pq6wm87p.js → cli-add-gcwww85p.js} +249 -243
- package/dist-bunli/{cli-add-pq6wm87p.js.map → cli-add-gcwww85p.js.map} +7 -5
- package/dist-bunli/{cli-2ybmc22r.js → cli-cfx3gm1r.js} +48 -44
- package/dist-bunli/{cli-2ybmc22r.js.map → cli-cfx3gm1r.js.map} +6 -4
- package/dist-bunli/{cli-7yg38ht2.js → cli-mgh3f3k5.js} +3 -3
- package/dist-bunli/{cli-7yg38ht2.js.map → cli-mgh3f3k5.js.map} +1 -1
- package/dist-bunli/{cli-scaffold-s3nhwe7x.js → cli-scaffold-f1bdt68d.js} +1 -1
- package/dist-bunli/cli.js +2 -2
- package/dist-bunli/{command-list-37n1za5q.js → command-list-66cqt7y8.js} +3 -3
- package/dist-bunli/node-cli.js +3 -3
- package/dist-bunli/node-cli.js.map +1 -1
- package/package.json +2 -2
- /package/dist-bunli/{cli-scaffold-s3nhwe7x.js.map → cli-scaffold-f1bdt68d.js.map} +0 -0
- /package/dist-bunli/{command-list-37n1za5q.js.map → command-list-66cqt7y8.js.map} +0 -0
|
@@ -14,7 +14,7 @@ import {
|
|
|
14
14
|
resolveTemplateSeed,
|
|
15
15
|
scaffoldProject,
|
|
16
16
|
syncPersistenceRestArtifacts
|
|
17
|
-
} from "./cli-
|
|
17
|
+
} from "./cli-cfx3gm1r.js";
|
|
18
18
|
import {
|
|
19
19
|
ensureMigrationDirectories,
|
|
20
20
|
parseMigrationConfig,
|
|
@@ -745,7 +745,7 @@ async function runAddBlockCommand({
|
|
|
745
745
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace.ts
|
|
746
746
|
import fs4 from "fs";
|
|
747
747
|
import { promises as fsp5 } from "fs";
|
|
748
|
-
import
|
|
748
|
+
import path8 from "path";
|
|
749
749
|
|
|
750
750
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-assets.ts
|
|
751
751
|
import fs3 from "fs";
|
|
@@ -1558,10 +1558,209 @@ async function runAddBindingSourceCommand({
|
|
|
1558
1558
|
}
|
|
1559
1559
|
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
|
|
1560
1560
|
import { promises as fsp4 } from "fs";
|
|
1561
|
-
import
|
|
1561
|
+
import path7 from "path";
|
|
1562
1562
|
|
|
1563
|
-
// ../wp-typia-project-tools/src/runtime/rest-
|
|
1563
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest-anchors.ts
|
|
1564
1564
|
import path5 from "path";
|
|
1565
|
+
var REST_RESOURCE_SERVER_GLOB = "/inc/rest/*.php";
|
|
1566
|
+
function escapeRegex2(value) {
|
|
1567
|
+
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
1568
|
+
}
|
|
1569
|
+
async function ensureRestResourceBootstrapAnchors(workspace) {
|
|
1570
|
+
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
1571
|
+
await patchFile(bootstrapPath, (source) => {
|
|
1572
|
+
let nextSource = source;
|
|
1573
|
+
const registerFunctionName = `${workspace.workspace.phpPrefix}_register_rest_resources`;
|
|
1574
|
+
const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
|
|
1575
|
+
const registerFunction = `
|
|
1576
|
+
|
|
1577
|
+
function ${registerFunctionName}() {
|
|
1578
|
+
foreach ( glob( __DIR__ . '${REST_RESOURCE_SERVER_GLOB}' ) ?: array() as $rest_resource_module ) {
|
|
1579
|
+
require_once $rest_resource_module;
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1582
|
+
`;
|
|
1583
|
+
const insertionAnchors = [
|
|
1584
|
+
/add_action\(\s*["']init["']\s*,\s*["'][^"']+_load_textdomain["']\s*\);\s*\n/u,
|
|
1585
|
+
/\?>\s*$/u
|
|
1586
|
+
];
|
|
1587
|
+
const hasPhpFunctionDefinition = (functionName) => new RegExp(`function\\s+${escapeRegex2(functionName)}\\s*\\(`, "u").test(nextSource);
|
|
1588
|
+
const insertPhpSnippet = (snippet) => {
|
|
1589
|
+
for (const anchor of insertionAnchors) {
|
|
1590
|
+
const candidate = nextSource.replace(anchor, (match) => `${snippet}
|
|
1591
|
+
${match}`);
|
|
1592
|
+
if (candidate !== nextSource) {
|
|
1593
|
+
nextSource = candidate;
|
|
1594
|
+
return;
|
|
1595
|
+
}
|
|
1596
|
+
}
|
|
1597
|
+
nextSource = `${nextSource.trimEnd()}
|
|
1598
|
+
${snippet}
|
|
1599
|
+
`;
|
|
1600
|
+
};
|
|
1601
|
+
const appendPhpSnippet = (snippet) => {
|
|
1602
|
+
const closingTagPattern = /\?>\s*$/u;
|
|
1603
|
+
if (closingTagPattern.test(nextSource)) {
|
|
1604
|
+
nextSource = nextSource.replace(closingTagPattern, `${snippet}
|
|
1605
|
+
?>`);
|
|
1606
|
+
return;
|
|
1607
|
+
}
|
|
1608
|
+
nextSource = `${nextSource.trimEnd()}
|
|
1609
|
+
${snippet}
|
|
1610
|
+
`;
|
|
1611
|
+
};
|
|
1612
|
+
if (!hasPhpFunctionDefinition(registerFunctionName)) {
|
|
1613
|
+
insertPhpSnippet(registerFunction);
|
|
1614
|
+
} else if (!nextSource.includes(REST_RESOURCE_SERVER_GLOB)) {
|
|
1615
|
+
throw new Error([
|
|
1616
|
+
`Unable to patch ${path5.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
|
|
1617
|
+
`The existing ${registerFunctionName}() definition does not include ${REST_RESOURCE_SERVER_GLOB}.`,
|
|
1618
|
+
"Restore the generated bootstrap shape or wire the REST resource loader manually before retrying."
|
|
1619
|
+
].join(" "));
|
|
1620
|
+
}
|
|
1621
|
+
if (!nextSource.includes(registerHook)) {
|
|
1622
|
+
appendPhpSnippet(registerHook);
|
|
1623
|
+
}
|
|
1624
|
+
return nextSource;
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
function assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
|
|
1628
|
+
if (!nextSource.includes(target) && !hasAnchor) {
|
|
1629
|
+
throw new Error([
|
|
1630
|
+
`ensureRestResourceSyncScriptAnchors could not patch ${path5.basename(syncRestScriptPath)}.`,
|
|
1631
|
+
`Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
|
|
1632
|
+
"Restore the generated template or add the REST_RESOURCES wiring manually before retrying."
|
|
1633
|
+
].join(" "));
|
|
1634
|
+
}
|
|
1635
|
+
}
|
|
1636
|
+
function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement, anchorDescription, syncRestScriptPath) {
|
|
1637
|
+
if (nextSource.includes(target)) {
|
|
1638
|
+
return nextSource;
|
|
1639
|
+
}
|
|
1640
|
+
const hasAnchor = typeof anchor === "string" ? nextSource.includes(anchor) : anchor.test(nextSource);
|
|
1641
|
+
assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath);
|
|
1642
|
+
return nextSource.replace(anchor, replacement);
|
|
1643
|
+
}
|
|
1644
|
+
async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
1645
|
+
const syncRestScriptPath = path5.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
1646
|
+
await patchFile(syncRestScriptPath, (source) => {
|
|
1647
|
+
let nextSource = source;
|
|
1648
|
+
const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
|
|
1649
|
+
const helperInsertionAnchor = "async function assertTypeArtifactsCurrent";
|
|
1650
|
+
const restBlocksAnchor = "const restBlocks = BLOCKS.filter( isRestEnabledBlock );";
|
|
1651
|
+
const noResourcesPattern = /if \( restBlocks.length === 0 \) \{[\s\S]*?\n\t\treturn;\n\t\}/u;
|
|
1652
|
+
const consoleLogPattern = /\n\tconsole\.log\(\n\t\toptions\.check/u;
|
|
1653
|
+
nextSource = replaceRequiredSyncRestSource(nextSource, "REST_RESOURCES", importAnchor, [
|
|
1654
|
+
"import {",
|
|
1655
|
+
"\tBLOCKS,",
|
|
1656
|
+
"\tREST_RESOURCES,",
|
|
1657
|
+
"\ttype WorkspaceBlockConfig,",
|
|
1658
|
+
"\ttype WorkspaceRestResourceConfig,",
|
|
1659
|
+
"} from './block-config';"
|
|
1660
|
+
].join(`
|
|
1661
|
+
`), "BLOCKS import", syncRestScriptPath);
|
|
1662
|
+
nextSource = replaceRequiredSyncRestSource(nextSource, "function isWorkspaceRestResource(", helperInsertionAnchor, [
|
|
1663
|
+
"function isWorkspaceRestResource(",
|
|
1664
|
+
"\tresource: WorkspaceRestResourceConfig",
|
|
1665
|
+
"): resource is WorkspaceRestResourceConfig & {",
|
|
1666
|
+
"\tclientFile: string;",
|
|
1667
|
+
"\topenApiFile: string;",
|
|
1668
|
+
"\trestManifest: NonNullable< WorkspaceRestResourceConfig[ 'restManifest' ] >;",
|
|
1669
|
+
"\ttypesFile: string;",
|
|
1670
|
+
"\tvalidatorsFile: string;",
|
|
1671
|
+
"} {",
|
|
1672
|
+
"\treturn (",
|
|
1673
|
+
"\t\ttypeof resource.clientFile === 'string' &&",
|
|
1674
|
+
"\t\ttypeof resource.openApiFile === 'string' &&",
|
|
1675
|
+
"\t\ttypeof resource.typesFile === 'string' &&",
|
|
1676
|
+
"\t\ttypeof resource.validatorsFile === 'string' &&",
|
|
1677
|
+
"\t\ttypeof resource.restManifest === 'object' &&",
|
|
1678
|
+
"\t\tresource.restManifest !== null",
|
|
1679
|
+
"\t);",
|
|
1680
|
+
"}",
|
|
1681
|
+
"",
|
|
1682
|
+
"async function assertTypeArtifactsCurrent"
|
|
1683
|
+
].join(`
|
|
1684
|
+
`), "type artifact assertion helper", syncRestScriptPath);
|
|
1685
|
+
nextSource = replaceRequiredSyncRestSource(nextSource, "const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );", restBlocksAnchor, [
|
|
1686
|
+
"const restBlocks = BLOCKS.filter( isRestEnabledBlock );",
|
|
1687
|
+
"const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );"
|
|
1688
|
+
].join(`
|
|
1689
|
+
`), "restBlocks filter", syncRestScriptPath);
|
|
1690
|
+
nextSource = replaceRequiredSyncRestSource(nextSource, "restBlocks.length === 0 && restResources.length === 0", noResourcesPattern, [
|
|
1691
|
+
"if ( restBlocks.length === 0 && restResources.length === 0 ) {",
|
|
1692
|
+
"\t\tconsole.log(",
|
|
1693
|
+
"\t\t\toptions.check",
|
|
1694
|
+
"\t\t\t\t? '\u2139\uFE0F No REST-enabled workspace blocks or plugin-level REST resources are registered yet. `sync-rest --check` is already clean.'",
|
|
1695
|
+
"\t\t\t\t: '\u2139\uFE0F No REST-enabled workspace blocks or plugin-level REST resources are registered yet.'",
|
|
1696
|
+
"\t\t);",
|
|
1697
|
+
"\t\treturn;",
|
|
1698
|
+
"\t}"
|
|
1699
|
+
].join(`
|
|
1700
|
+
`), "no-resources guard", syncRestScriptPath);
|
|
1701
|
+
nextSource = replaceRequiredSyncRestSource(nextSource, "for ( const resource of restResources ) {", consoleLogPattern, [
|
|
1702
|
+
"",
|
|
1703
|
+
"\tfor ( const resource of restResources ) {",
|
|
1704
|
+
"\t\tconst contracts = resource.restManifest.contracts;",
|
|
1705
|
+
"",
|
|
1706
|
+
"\t\tfor ( const [ baseName, contract ] of Object.entries( contracts ) ) {",
|
|
1707
|
+
"\t\t\tawait syncTypeSchemas(",
|
|
1708
|
+
"\t\t\t\t{",
|
|
1709
|
+
"\t\t\t\t\tjsonSchemaFile: path.join(",
|
|
1710
|
+
"\t\t\t\t\t\tpath.dirname( resource.typesFile ),",
|
|
1711
|
+
"\t\t\t\t\t\t'api-schemas',",
|
|
1712
|
+
"\t\t\t\t\t\t`${ baseName }.schema.json`",
|
|
1713
|
+
"\t\t\t\t\t),",
|
|
1714
|
+
"\t\t\t\t\topenApiFile: path.join(",
|
|
1715
|
+
"\t\t\t\t\t\tpath.dirname( resource.typesFile ),",
|
|
1716
|
+
"\t\t\t\t\t\t'api-schemas',",
|
|
1717
|
+
"\t\t\t\t\t\t`${ baseName }.openapi.json`",
|
|
1718
|
+
"\t\t\t\t\t),",
|
|
1719
|
+
"\t\t\t\t\tsourceTypeName: contract.sourceTypeName,",
|
|
1720
|
+
"\t\t\t\t\ttypesFile: resource.typesFile,",
|
|
1721
|
+
"\t\t\t\t},",
|
|
1722
|
+
"\t\t\t\t{",
|
|
1723
|
+
"\t\t\t\t\tcheck: options.check,",
|
|
1724
|
+
"\t\t\t\t}",
|
|
1725
|
+
"\t\t\t);",
|
|
1726
|
+
"\t\t}",
|
|
1727
|
+
"",
|
|
1728
|
+
"\t\tawait syncRestOpenApi(",
|
|
1729
|
+
"\t\t\t{",
|
|
1730
|
+
"\t\t\t\tmanifest: resource.restManifest,",
|
|
1731
|
+
"\t\t\t\topenApiFile: resource.openApiFile,",
|
|
1732
|
+
"\t\t\t\ttypesFile: resource.typesFile,",
|
|
1733
|
+
"\t\t\t},",
|
|
1734
|
+
"\t\t\t{",
|
|
1735
|
+
"\t\t\t\tcheck: options.check,",
|
|
1736
|
+
"\t\t\t}",
|
|
1737
|
+
"\t\t);",
|
|
1738
|
+
"",
|
|
1739
|
+
"\t\tawait syncEndpointClient(",
|
|
1740
|
+
"\t\t\t{",
|
|
1741
|
+
"\t\t\t\tclientFile: resource.clientFile,",
|
|
1742
|
+
"\t\t\t\tmanifest: resource.restManifest,",
|
|
1743
|
+
"\t\t\t\ttypesFile: resource.typesFile,",
|
|
1744
|
+
"\t\t\t\tvalidatorsFile: resource.validatorsFile,",
|
|
1745
|
+
"\t\t\t},",
|
|
1746
|
+
"\t\t\t{",
|
|
1747
|
+
"\t\t\t\tcheck: options.check,",
|
|
1748
|
+
"\t\t\t}",
|
|
1749
|
+
"\t\t);",
|
|
1750
|
+
"\t}",
|
|
1751
|
+
"",
|
|
1752
|
+
"\tconsole.log(",
|
|
1753
|
+
"\t\toptions.check"
|
|
1754
|
+
].join(`
|
|
1755
|
+
`), "success log insertion point", syncRestScriptPath);
|
|
1756
|
+
nextSource = nextSource.replace("\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date with the TypeScript types!", "\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date for workspace blocks and plugin-level resources!");
|
|
1757
|
+
nextSource = nextSource.replace("\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated from TypeScript types!", "\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated for workspace blocks and plugin-level resources!");
|
|
1758
|
+
return nextSource;
|
|
1759
|
+
});
|
|
1760
|
+
}
|
|
1761
|
+
|
|
1762
|
+
// ../wp-typia-project-tools/src/runtime/rest-resource-artifacts.ts
|
|
1763
|
+
import path6 from "path";
|
|
1565
1764
|
import {
|
|
1566
1765
|
defineEndpointManifest,
|
|
1567
1766
|
syncEndpointClient,
|
|
@@ -1697,8 +1896,8 @@ async function syncRestResourceArtifacts({
|
|
|
1697
1896
|
const manifest = buildRestResourceEndpointManifest(variables, methods);
|
|
1698
1897
|
for (const [baseName, contract] of Object.entries(manifest.contracts)) {
|
|
1699
1898
|
await syncTypeSchemas({
|
|
1700
|
-
jsonSchemaFile:
|
|
1701
|
-
openApiFile:
|
|
1899
|
+
jsonSchemaFile: path6.join(outputDir, "api-schemas", `${baseName}.schema.json`),
|
|
1900
|
+
openApiFile: path6.join(outputDir, "api-schemas", `${baseName}.openapi.json`),
|
|
1702
1901
|
projectRoot: projectDir,
|
|
1703
1902
|
sourceTypeName: contract.sourceTypeName,
|
|
1704
1903
|
typesFile
|
|
@@ -1706,7 +1905,7 @@ async function syncRestResourceArtifacts({
|
|
|
1706
1905
|
}
|
|
1707
1906
|
await syncRestOpenApi({
|
|
1708
1907
|
manifest,
|
|
1709
|
-
openApiFile:
|
|
1908
|
+
openApiFile: path6.join(outputDir, "api.openapi.json"),
|
|
1710
1909
|
projectRoot: projectDir,
|
|
1711
1910
|
typesFile
|
|
1712
1911
|
});
|
|
@@ -1719,14 +1918,7 @@ async function syncRestResourceArtifacts({
|
|
|
1719
1918
|
});
|
|
1720
1919
|
}
|
|
1721
1920
|
|
|
1722
|
-
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
|
|
1723
|
-
var REST_RESOURCE_SERVER_GLOB = "/inc/rest/*.php";
|
|
1724
|
-
function escapeRegex2(value) {
|
|
1725
|
-
return value.replace(/[.*+?^${}()|[\]\\]/gu, "\\$&");
|
|
1726
|
-
}
|
|
1727
|
-
function quotePhpString2(value) {
|
|
1728
|
-
return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
|
|
1729
|
-
}
|
|
1921
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest-source-emitters.ts
|
|
1730
1922
|
function toPascalCaseFromSlug2(slug) {
|
|
1731
1923
|
return normalizeBlockSlug(slug).split("-").filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1)).join("");
|
|
1732
1924
|
}
|
|
@@ -1949,21 +2141,7 @@ export function deleteResource( request: ${pascalCase}DeleteQuery ) {
|
|
|
1949
2141
|
return callEndpoint( restResourceDeleteEndpoint, request );
|
|
1950
2142
|
}`);
|
|
1951
2143
|
}
|
|
1952
|
-
|
|
1953
|
-
callEndpoint,
|
|
1954
|
-
resolveRestRouteUrl,
|
|
1955
|
-
} from '@wp-typia/rest';
|
|
1956
|
-
|
|
1957
|
-
import type {
|
|
1958
|
-
${Array.from(typeImports).sort().join(`,
|
|
1959
|
-
`)},
|
|
1960
|
-
} from './api-types';
|
|
1961
|
-
import {
|
|
1962
|
-
${clientEndpointImports.sort().join(`,
|
|
1963
|
-
`)},
|
|
1964
|
-
} from './api-client';
|
|
1965
|
-
${writeMethods.length > 0 ? `
|
|
1966
|
-
function resolveRestNonce( fallback?: string ): string | undefined {
|
|
2144
|
+
const resolveRestNonceSource = writeMethods.length > 0 ? `function resolveRestNonce( fallback?: string ): string | undefined {
|
|
1967
2145
|
if ( typeof fallback === 'string' && fallback.length > 0 ) {
|
|
1968
2146
|
return fallback;
|
|
1969
2147
|
}
|
|
@@ -1983,7 +2161,22 @@ function resolveRestNonce( fallback?: string ): string | undefined {
|
|
|
1983
2161
|
? wpApiSettings.nonce
|
|
1984
2162
|
: undefined;
|
|
1985
2163
|
}
|
|
1986
|
-
|
|
2164
|
+
|
|
2165
|
+
` : "";
|
|
2166
|
+
return `import {
|
|
2167
|
+
callEndpoint,
|
|
2168
|
+
resolveRestRouteUrl,
|
|
2169
|
+
} from '@wp-typia/rest';
|
|
2170
|
+
|
|
2171
|
+
import type {
|
|
2172
|
+
${Array.from(typeImports).sort().join(`,
|
|
2173
|
+
`)},
|
|
2174
|
+
} from './api-types';
|
|
2175
|
+
import {
|
|
2176
|
+
${clientEndpointImports.sort().join(`,
|
|
2177
|
+
`)},
|
|
2178
|
+
} from './api-client';
|
|
2179
|
+
${resolveRestNonceSource}
|
|
1987
2180
|
${exportedBindings.join(`
|
|
1988
2181
|
|
|
1989
2182
|
`)}
|
|
@@ -2109,6 +2302,11 @@ ${exportedBindings.join(`
|
|
|
2109
2302
|
`)}
|
|
2110
2303
|
`;
|
|
2111
2304
|
}
|
|
2305
|
+
|
|
2306
|
+
// ../wp-typia-project-tools/src/runtime/cli-add-workspace-rest.ts
|
|
2307
|
+
function quotePhpString2(value) {
|
|
2308
|
+
return `'${value.replace(/\\/gu, "\\\\").replace(/'/gu, "\\'")}'`;
|
|
2309
|
+
}
|
|
2112
2310
|
function buildRestResourceRouteRegistrations(restResourceSlug, methods, functions) {
|
|
2113
2311
|
const collectionRoutes = [];
|
|
2114
2312
|
const itemRoutes = [];
|
|
@@ -2526,198 +2724,6 @@ ${routeRegistrations}
|
|
|
2526
2724
|
add_action( 'rest_api_init', '${registerRoutesFunctionName}' );
|
|
2527
2725
|
`;
|
|
2528
2726
|
}
|
|
2529
|
-
async function ensureRestResourceBootstrapAnchors(workspace) {
|
|
2530
|
-
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
2531
|
-
await patchFile(bootstrapPath, (source) => {
|
|
2532
|
-
let nextSource = source;
|
|
2533
|
-
const registerFunctionName = `${workspace.workspace.phpPrefix}_register_rest_resources`;
|
|
2534
|
-
const registerHook = `add_action( 'init', '${registerFunctionName}', 20 );`;
|
|
2535
|
-
const registerFunction = `
|
|
2536
|
-
|
|
2537
|
-
function ${registerFunctionName}() {
|
|
2538
|
-
foreach ( glob( __DIR__ . '${REST_RESOURCE_SERVER_GLOB}' ) ?: array() as $rest_resource_module ) {
|
|
2539
|
-
require_once $rest_resource_module;
|
|
2540
|
-
}
|
|
2541
|
-
}
|
|
2542
|
-
`;
|
|
2543
|
-
const insertionAnchors = [
|
|
2544
|
-
/add_action\(\s*["']init["']\s*,\s*["'][^"']+_load_textdomain["']\s*\);\s*\n/u,
|
|
2545
|
-
/\?>\s*$/u
|
|
2546
|
-
];
|
|
2547
|
-
const hasPhpFunctionDefinition = (functionName) => new RegExp(`function\\s+${escapeRegex2(functionName)}\\s*\\(`, "u").test(nextSource);
|
|
2548
|
-
const insertPhpSnippet = (snippet) => {
|
|
2549
|
-
for (const anchor of insertionAnchors) {
|
|
2550
|
-
const candidate = nextSource.replace(anchor, (match) => `${snippet}
|
|
2551
|
-
${match}`);
|
|
2552
|
-
if (candidate !== nextSource) {
|
|
2553
|
-
nextSource = candidate;
|
|
2554
|
-
return;
|
|
2555
|
-
}
|
|
2556
|
-
}
|
|
2557
|
-
nextSource = `${nextSource.trimEnd()}
|
|
2558
|
-
${snippet}
|
|
2559
|
-
`;
|
|
2560
|
-
};
|
|
2561
|
-
const appendPhpSnippet = (snippet) => {
|
|
2562
|
-
const closingTagPattern = /\?>\s*$/u;
|
|
2563
|
-
if (closingTagPattern.test(nextSource)) {
|
|
2564
|
-
nextSource = nextSource.replace(closingTagPattern, `${snippet}
|
|
2565
|
-
?>`);
|
|
2566
|
-
return;
|
|
2567
|
-
}
|
|
2568
|
-
nextSource = `${nextSource.trimEnd()}
|
|
2569
|
-
${snippet}
|
|
2570
|
-
`;
|
|
2571
|
-
};
|
|
2572
|
-
if (!hasPhpFunctionDefinition(registerFunctionName)) {
|
|
2573
|
-
insertPhpSnippet(registerFunction);
|
|
2574
|
-
} else if (!nextSource.includes(REST_RESOURCE_SERVER_GLOB)) {
|
|
2575
|
-
throw new Error([
|
|
2576
|
-
`Unable to patch ${path6.basename(bootstrapPath)} in ensureRestResourceBootstrapAnchors.`,
|
|
2577
|
-
`The existing ${registerFunctionName}() definition does not include ${REST_RESOURCE_SERVER_GLOB}.`,
|
|
2578
|
-
"Restore the generated bootstrap shape or wire the REST resource loader manually before retrying."
|
|
2579
|
-
].join(" "));
|
|
2580
|
-
}
|
|
2581
|
-
if (!nextSource.includes(registerHook)) {
|
|
2582
|
-
appendPhpSnippet(registerHook);
|
|
2583
|
-
}
|
|
2584
|
-
return nextSource;
|
|
2585
|
-
});
|
|
2586
|
-
}
|
|
2587
|
-
function assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath) {
|
|
2588
|
-
if (!nextSource.includes(target) && !hasAnchor) {
|
|
2589
|
-
throw new Error([
|
|
2590
|
-
`ensureRestResourceSyncScriptAnchors could not patch ${path6.basename(syncRestScriptPath)}.`,
|
|
2591
|
-
`Missing expected ${anchorDescription} anchor in scripts/sync-rest-contracts.ts.`,
|
|
2592
|
-
"Restore the generated template or add the REST_RESOURCES wiring manually before retrying."
|
|
2593
|
-
].join(" "));
|
|
2594
|
-
}
|
|
2595
|
-
}
|
|
2596
|
-
function replaceRequiredSyncRestSource(nextSource, target, anchor, replacement, anchorDescription, syncRestScriptPath) {
|
|
2597
|
-
if (nextSource.includes(target)) {
|
|
2598
|
-
return nextSource;
|
|
2599
|
-
}
|
|
2600
|
-
const hasAnchor = typeof anchor === "string" ? nextSource.includes(anchor) : anchor.test(nextSource);
|
|
2601
|
-
assertSyncRestAnchor(nextSource, target, anchorDescription, hasAnchor, syncRestScriptPath);
|
|
2602
|
-
return nextSource.replace(anchor, replacement);
|
|
2603
|
-
}
|
|
2604
|
-
async function ensureRestResourceSyncScriptAnchors(workspace) {
|
|
2605
|
-
const syncRestScriptPath = path6.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
2606
|
-
await patchFile(syncRestScriptPath, (source) => {
|
|
2607
|
-
let nextSource = source;
|
|
2608
|
-
const importAnchor = "import { BLOCKS, type WorkspaceBlockConfig } from './block-config';";
|
|
2609
|
-
const helperInsertionAnchor = "async function assertTypeArtifactsCurrent";
|
|
2610
|
-
const restBlocksAnchor = "const restBlocks = BLOCKS.filter( isRestEnabledBlock );";
|
|
2611
|
-
const noResourcesPattern = /if \( restBlocks.length === 0 \) \{[\s\S]*?\n\t\treturn;\n\t\}/u;
|
|
2612
|
-
const consoleLogPattern = /\n\tconsole\.log\(\n\t\toptions\.check/u;
|
|
2613
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "REST_RESOURCES", importAnchor, [
|
|
2614
|
-
"import {",
|
|
2615
|
-
"\tBLOCKS,",
|
|
2616
|
-
"\tREST_RESOURCES,",
|
|
2617
|
-
"\ttype WorkspaceBlockConfig,",
|
|
2618
|
-
"\ttype WorkspaceRestResourceConfig,",
|
|
2619
|
-
"} from './block-config';"
|
|
2620
|
-
].join(`
|
|
2621
|
-
`), "BLOCKS import", syncRestScriptPath);
|
|
2622
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "function isWorkspaceRestResource(", helperInsertionAnchor, [
|
|
2623
|
-
"function isWorkspaceRestResource(",
|
|
2624
|
-
"\tresource: WorkspaceRestResourceConfig",
|
|
2625
|
-
"): resource is WorkspaceRestResourceConfig & {",
|
|
2626
|
-
"\tclientFile: string;",
|
|
2627
|
-
"\topenApiFile: string;",
|
|
2628
|
-
"\trestManifest: NonNullable< WorkspaceRestResourceConfig[ 'restManifest' ] >;",
|
|
2629
|
-
"\ttypesFile: string;",
|
|
2630
|
-
"\tvalidatorsFile: string;",
|
|
2631
|
-
"} {",
|
|
2632
|
-
"\treturn (",
|
|
2633
|
-
"\t\ttypeof resource.clientFile === 'string' &&",
|
|
2634
|
-
"\t\ttypeof resource.openApiFile === 'string' &&",
|
|
2635
|
-
"\t\ttypeof resource.typesFile === 'string' &&",
|
|
2636
|
-
"\t\ttypeof resource.validatorsFile === 'string' &&",
|
|
2637
|
-
"\t\ttypeof resource.restManifest === 'object' &&",
|
|
2638
|
-
"\t\tresource.restManifest !== null",
|
|
2639
|
-
"\t);",
|
|
2640
|
-
"}",
|
|
2641
|
-
"",
|
|
2642
|
-
"async function assertTypeArtifactsCurrent"
|
|
2643
|
-
].join(`
|
|
2644
|
-
`), "type artifact assertion helper", syncRestScriptPath);
|
|
2645
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );", restBlocksAnchor, [
|
|
2646
|
-
"const restBlocks = BLOCKS.filter( isRestEnabledBlock );",
|
|
2647
|
-
"const restResources = REST_RESOURCES.filter( isWorkspaceRestResource );"
|
|
2648
|
-
].join(`
|
|
2649
|
-
`), "restBlocks filter", syncRestScriptPath);
|
|
2650
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "restBlocks.length === 0 && restResources.length === 0", noResourcesPattern, [
|
|
2651
|
-
"if ( restBlocks.length === 0 && restResources.length === 0 ) {",
|
|
2652
|
-
"\t\tconsole.log(",
|
|
2653
|
-
"\t\t\toptions.check",
|
|
2654
|
-
"\t\t\t\t? '\u2139\uFE0F No REST-enabled workspace blocks or plugin-level REST resources are registered yet. `sync-rest --check` is already clean.'",
|
|
2655
|
-
"\t\t\t\t: '\u2139\uFE0F No REST-enabled workspace blocks or plugin-level REST resources are registered yet.'",
|
|
2656
|
-
"\t\t);",
|
|
2657
|
-
"\t\treturn;",
|
|
2658
|
-
"\t}"
|
|
2659
|
-
].join(`
|
|
2660
|
-
`), "no-resources guard", syncRestScriptPath);
|
|
2661
|
-
nextSource = replaceRequiredSyncRestSource(nextSource, "for ( const resource of restResources ) {", consoleLogPattern, [
|
|
2662
|
-
"",
|
|
2663
|
-
"\tfor ( const resource of restResources ) {",
|
|
2664
|
-
"\t\tconst contracts = resource.restManifest.contracts;",
|
|
2665
|
-
"",
|
|
2666
|
-
"\t\tfor ( const [ baseName, contract ] of Object.entries( contracts ) ) {",
|
|
2667
|
-
"\t\t\tawait syncTypeSchemas(",
|
|
2668
|
-
"\t\t\t\t{",
|
|
2669
|
-
"\t\t\t\t\tjsonSchemaFile: path.join(",
|
|
2670
|
-
"\t\t\t\t\t\tpath.dirname( resource.typesFile ),",
|
|
2671
|
-
"\t\t\t\t\t\t'api-schemas',",
|
|
2672
|
-
"\t\t\t\t\t\t`${ baseName }.schema.json`",
|
|
2673
|
-
"\t\t\t\t\t),",
|
|
2674
|
-
"\t\t\t\t\topenApiFile: path.join(",
|
|
2675
|
-
"\t\t\t\t\t\tpath.dirname( resource.typesFile ),",
|
|
2676
|
-
"\t\t\t\t\t\t'api-schemas',",
|
|
2677
|
-
"\t\t\t\t\t\t`${ baseName }.openapi.json`",
|
|
2678
|
-
"\t\t\t\t\t),",
|
|
2679
|
-
"\t\t\t\t\tsourceTypeName: contract.sourceTypeName,",
|
|
2680
|
-
"\t\t\t\t\ttypesFile: resource.typesFile,",
|
|
2681
|
-
"\t\t\t\t},",
|
|
2682
|
-
"\t\t\t\t{",
|
|
2683
|
-
"\t\t\t\t\tcheck: options.check,",
|
|
2684
|
-
"\t\t\t\t}",
|
|
2685
|
-
"\t\t\t);",
|
|
2686
|
-
"\t\t}",
|
|
2687
|
-
"",
|
|
2688
|
-
"\t\tawait syncRestOpenApi(",
|
|
2689
|
-
"\t\t\t{",
|
|
2690
|
-
"\t\t\t\tmanifest: resource.restManifest,",
|
|
2691
|
-
"\t\t\t\topenApiFile: resource.openApiFile,",
|
|
2692
|
-
"\t\t\t\ttypesFile: resource.typesFile,",
|
|
2693
|
-
"\t\t\t},",
|
|
2694
|
-
"\t\t\t{",
|
|
2695
|
-
"\t\t\t\tcheck: options.check,",
|
|
2696
|
-
"\t\t\t}",
|
|
2697
|
-
"\t\t);",
|
|
2698
|
-
"",
|
|
2699
|
-
"\t\tawait syncEndpointClient(",
|
|
2700
|
-
"\t\t\t{",
|
|
2701
|
-
"\t\t\t\tclientFile: resource.clientFile,",
|
|
2702
|
-
"\t\t\t\tmanifest: resource.restManifest,",
|
|
2703
|
-
"\t\t\t\ttypesFile: resource.typesFile,",
|
|
2704
|
-
"\t\t\t\tvalidatorsFile: resource.validatorsFile,",
|
|
2705
|
-
"\t\t\t},",
|
|
2706
|
-
"\t\t\t{",
|
|
2707
|
-
"\t\t\t\tcheck: options.check,",
|
|
2708
|
-
"\t\t\t}",
|
|
2709
|
-
"\t\t);",
|
|
2710
|
-
"\t}",
|
|
2711
|
-
"",
|
|
2712
|
-
"\tconsole.log(",
|
|
2713
|
-
"\t\toptions.check"
|
|
2714
|
-
].join(`
|
|
2715
|
-
`), "success log insertion point", syncRestScriptPath);
|
|
2716
|
-
nextSource = nextSource.replace("\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date with the TypeScript types!", "\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents are already up to date for workspace blocks and plugin-level resources!");
|
|
2717
|
-
nextSource = nextSource.replace("\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated from TypeScript types!", "\u2705 REST contract schemas, portable API clients, and endpoint-aware OpenAPI documents generated for workspace blocks and plugin-level resources!");
|
|
2718
|
-
return nextSource;
|
|
2719
|
-
});
|
|
2720
|
-
}
|
|
2721
2727
|
async function runAddRestResourceCommand({
|
|
2722
2728
|
cwd = process.cwd(),
|
|
2723
2729
|
methods,
|
|
@@ -2730,16 +2736,16 @@ async function runAddRestResourceCommand({
|
|
|
2730
2736
|
const resolvedNamespace = resolveRestResourceNamespace(workspace.workspace.namespace, namespace);
|
|
2731
2737
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
2732
2738
|
assertRestResourceDoesNotExist(workspace.projectDir, restResourceSlug, inventory);
|
|
2733
|
-
const blockConfigPath =
|
|
2739
|
+
const blockConfigPath = path7.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
2734
2740
|
const bootstrapPath = getWorkspaceBootstrapPath(workspace);
|
|
2735
|
-
const syncRestScriptPath =
|
|
2736
|
-
const restResourceDir =
|
|
2737
|
-
const typesFilePath =
|
|
2738
|
-
const validatorsFilePath =
|
|
2739
|
-
const apiFilePath =
|
|
2740
|
-
const dataFilePath =
|
|
2741
|
-
const clientFilePath =
|
|
2742
|
-
const phpFilePath =
|
|
2741
|
+
const syncRestScriptPath = path7.join(workspace.projectDir, "scripts", "sync-rest-contracts.ts");
|
|
2742
|
+
const restResourceDir = path7.join(workspace.projectDir, "src", "rest", restResourceSlug);
|
|
2743
|
+
const typesFilePath = path7.join(restResourceDir, "api-types.ts");
|
|
2744
|
+
const validatorsFilePath = path7.join(restResourceDir, "api-validators.ts");
|
|
2745
|
+
const apiFilePath = path7.join(restResourceDir, "api.ts");
|
|
2746
|
+
const dataFilePath = path7.join(restResourceDir, "data.ts");
|
|
2747
|
+
const clientFilePath = path7.join(restResourceDir, "api-client.ts");
|
|
2748
|
+
const phpFilePath = path7.join(workspace.projectDir, "inc", "rest", `${restResourceSlug}.php`);
|
|
2743
2749
|
const mutationSnapshot = {
|
|
2744
2750
|
fileSources: await snapshotWorkspaceFiles([
|
|
2745
2751
|
blockConfigPath,
|
|
@@ -2751,7 +2757,7 @@ async function runAddRestResourceCommand({
|
|
|
2751
2757
|
};
|
|
2752
2758
|
try {
|
|
2753
2759
|
await fsp4.mkdir(restResourceDir, { recursive: true });
|
|
2754
|
-
await fsp4.mkdir(
|
|
2760
|
+
await fsp4.mkdir(path7.dirname(phpFilePath), { recursive: true });
|
|
2755
2761
|
await ensureRestResourceBootstrapAnchors(workspace);
|
|
2756
2762
|
await ensureRestResourceSyncScriptAnchors(workspace);
|
|
2757
2763
|
await fsp4.writeFile(typesFilePath, buildRestResourceTypesSource(restResourceSlug, resolvedMethods), "utf8");
|
|
@@ -2894,14 +2900,14 @@ ${VARIATIONS_CALL_LINE}
|
|
|
2894
2900
|
}
|
|
2895
2901
|
}
|
|
2896
2902
|
if (!nextSource.includes(VARIATIONS_CALL_LINE)) {
|
|
2897
|
-
throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${
|
|
2903
|
+
throw new Error(`Unable to inject ${VARIATIONS_CALL_LINE} into ${path8.basename(blockIndexPath)}.`);
|
|
2898
2904
|
}
|
|
2899
2905
|
return nextSource;
|
|
2900
2906
|
});
|
|
2901
2907
|
}
|
|
2902
2908
|
async function writeVariationRegistry(projectDir, blockSlug, variationSlug) {
|
|
2903
|
-
const variationsDir =
|
|
2904
|
-
const variationsIndexPath =
|
|
2909
|
+
const variationsDir = path8.join(projectDir, "src", "blocks", blockSlug, "variations");
|
|
2910
|
+
const variationsIndexPath = path8.join(variationsDir, "index.ts");
|
|
2905
2911
|
await fsp5.mkdir(variationsDir, { recursive: true });
|
|
2906
2912
|
const existingVariationSlugs = fs4.readdirSync(variationsDir).filter((entry) => entry.endsWith(".ts") && entry !== "index.ts").map((entry) => entry.replace(/\.ts$/u, ""));
|
|
2907
2913
|
const nextVariationSlugs = Array.from(new Set([...existingVariationSlugs, variationSlug])).sort();
|
|
@@ -2918,11 +2924,11 @@ async function runAddVariationCommand({
|
|
|
2918
2924
|
const inventory = readWorkspaceInventory(workspace.projectDir);
|
|
2919
2925
|
resolveWorkspaceBlock(inventory, blockSlug);
|
|
2920
2926
|
assertVariationDoesNotExist(workspace.projectDir, blockSlug, variationSlug, inventory);
|
|
2921
|
-
const blockConfigPath =
|
|
2922
|
-
const blockIndexPath =
|
|
2923
|
-
const variationsDir =
|
|
2924
|
-
const variationFilePath =
|
|
2925
|
-
const variationsIndexPath =
|
|
2927
|
+
const blockConfigPath = path8.join(workspace.projectDir, "scripts", "block-config.ts");
|
|
2928
|
+
const blockIndexPath = path8.join(workspace.projectDir, "src", "blocks", blockSlug, "index.tsx");
|
|
2929
|
+
const variationsDir = path8.join(workspace.projectDir, "src", "blocks", blockSlug, "variations");
|
|
2930
|
+
const variationFilePath = path8.join(variationsDir, `${variationSlug}.ts`);
|
|
2931
|
+
const variationsIndexPath = path8.join(variationsDir, "index.ts");
|
|
2926
2932
|
const mutationSnapshot = {
|
|
2927
2933
|
fileSources: await snapshotWorkspaceFiles([
|
|
2928
2934
|
blockConfigPath,
|
|
@@ -2967,7 +2973,7 @@ async function runAddHookedBlockCommand({
|
|
|
2967
2973
|
throw new Error("`wp-typia add hooked-block` cannot hook a block relative to its own block name.");
|
|
2968
2974
|
}
|
|
2969
2975
|
const { blockJson, blockJsonPath } = readWorkspaceBlockJson(workspace.projectDir, blockSlug);
|
|
2970
|
-
const blockJsonRelativePath =
|
|
2976
|
+
const blockJsonRelativePath = path8.relative(workspace.projectDir, blockJsonPath);
|
|
2971
2977
|
const blockHooks = getMutableBlockHooks(blockJson, blockJsonRelativePath);
|
|
2972
2978
|
if (Object.prototype.hasOwnProperty.call(blockHooks, resolvedAnchorBlockName)) {
|
|
2973
2979
|
throw new Error(`${blockJsonRelativePath} already defines a blockHooks entry for "${resolvedAnchorBlockName}".`);
|
|
@@ -3007,4 +3013,4 @@ export {
|
|
|
3007
3013
|
ADD_BLOCK_TEMPLATE_IDS
|
|
3008
3014
|
};
|
|
3009
3015
|
|
|
3010
|
-
//# debugId=
|
|
3016
|
+
//# debugId=BD6B18859A84FB8164756E2164756E21
|