kizlo 0.15.2 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/logger.d.ts +2 -5
- package/dist/adapters/logger.js +1 -1
- package/dist/adapters/types.d.ts +19 -0
- package/dist/adapters/types.js +17 -0
- package/dist/astro/server.d.ts +2 -2
- package/dist/astro/server.js +2 -2
- package/dist/category/index.js +2 -2
- package/dist/cli/commands/_setup.js +10 -10
- package/dist/cli/commands/dev.js +7 -7
- package/dist/cli/daemon/generate.js +19 -9
- package/dist/cli/daemon/jiti.js +4 -5
- package/dist/cli/daemon/watch.js +3 -2
- package/dist/cli/presets/template.js +1 -1
- package/dist/cli/utils.js +6 -6
- package/dist/cli/wp/bootstrap.js +15 -11
- package/dist/cli/wp/constants.js +1 -1
- package/dist/cli/wp/dev.js +6 -23
- package/dist/cli/wp/types.d.ts +2 -2
- package/dist/cli/wp/utils.d.ts +1 -1
- package/dist/cli/wp/utils.js +1 -1
- package/dist/client.d.ts +7 -7
- package/dist/client.js +1 -1
- package/dist/comment/index.js +2 -2
- package/dist/config.d.ts +8 -8
- package/dist/context.d.ts +5 -5
- package/dist/context.js +5 -5
- package/dist/index.d.ts +7 -6
- package/dist/index.js +5 -4
- package/dist/integrations/astro/integration.d.ts +12 -0
- package/dist/integrations/astro/integration.js +14 -0
- package/dist/integrations/astro/kizlo.client.d.ts +4 -4
- package/dist/integrations/astro/utils.d.ts +4 -5
- package/dist/integrations/astro/utils.js +5 -6
- package/dist/integrations/nextjs/integration.d.ts +15 -0
- package/dist/integrations/nextjs/integration.js +18 -0
- package/dist/integrations/nextjs/kizlo.client.d.ts +2 -2
- package/dist/integrations/nextjs/revalidate.d.ts +2 -3
- package/dist/integrations/nextjs/revalidate.js +4 -4
- package/dist/integrations/nextjs/utils.js +2 -2
- package/dist/integrations/node/integration.d.ts +12 -0
- package/dist/integrations/node/integration.js +14 -0
- package/dist/integrations/runtime-env.js +25 -0
- package/dist/integrations/tanstack-start/api.d.ts +1 -1
- package/dist/integrations/tanstack-start/integration.d.ts +12 -0
- package/dist/integrations/tanstack-start/integration.js +14 -0
- package/dist/integrations/tanstack-start/kizlo.client.d.ts +4 -4
- package/dist/integrations/tanstack-start/utils.d.ts +1 -1
- package/dist/integrations/tanstack-start/utils.js +3 -3
- package/dist/kizlo.d.ts +33 -70
- package/dist/kizlo.js +91 -75
- package/dist/menu/index.js +2 -2
- package/dist/nextjs/server.d.ts +2 -2
- package/dist/nextjs/server.js +2 -2
- package/dist/node.d.ts +2 -0
- package/dist/node.js +3 -0
- package/dist/package.js +1 -1
- package/dist/page/index.js +2 -2
- package/dist/post/index.js +2 -2
- package/dist/{router.d.ts → procedures.d.ts} +11 -11
- package/dist/procedures.js +23 -0
- package/dist/seo/index.js +2 -2
- package/dist/settings/index.js +2 -2
- package/dist/shared/constants.js +1 -9
- package/dist/shared/contract-generation.js +14 -0
- package/dist/shared/contract.d.ts +2 -2
- package/dist/shared/contract.js +2 -2
- package/dist/shared/integration.d.ts +91 -0
- package/dist/shared/integration.js +59 -0
- package/dist/shared/procedure.d.ts +8 -8
- package/dist/shared/result.d.ts +2 -2
- package/dist/shared/router.d.ts +2 -2
- package/dist/shared/router.js +2 -2
- package/dist/tag/index.js +2 -2
- package/dist/tanstack-start/server.d.ts +2 -2
- package/dist/tanstack-start/server.js +2 -2
- package/package.json +8 -2
- package/dist/integrations/astro/kizlo.server.d.ts +0 -10
- package/dist/integrations/astro/kizlo.server.js +0 -12
- package/dist/integrations/nextjs/kizlo.server.d.ts +0 -11
- package/dist/integrations/nextjs/kizlo.server.js +0 -15
- package/dist/integrations/tanstack-start/kizlo.server.d.ts +0 -14
- package/dist/integrations/tanstack-start/kizlo.server.js +0 -15
- package/dist/router.js +0 -23
- package/dist/shared/extension.d.ts +0 -58
- package/dist/shared/extension.js +0 -37
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
import { LiteralUnion } from "@kizlo/shared";
|
|
2
|
-
|
|
3
1
|
//#region src/adapters/logger.d.ts
|
|
4
2
|
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
5
|
-
type Environment = LiteralUnion<"development" | "production" | "test", string>;
|
|
6
3
|
interface LogPayload {
|
|
7
4
|
/** Severity of the record: `debug`, `info`, `warn`, or `error`. */
|
|
8
5
|
level: LogLevel;
|
|
@@ -16,7 +13,7 @@ interface LogPayload {
|
|
|
16
13
|
error?: Error;
|
|
17
14
|
}
|
|
18
15
|
type LoggerAdapter = (payload: LogPayload) => void | Promise<void>;
|
|
19
|
-
/** Author a custom logger adapter
|
|
16
|
+
/** Author a custom logger adapter. Types your handler against the {@link LoggerAdapter} contract. */
|
|
20
17
|
declare function createLoggerAdapter(adapter: LoggerAdapter): LoggerAdapter;
|
|
21
18
|
interface Logger {
|
|
22
19
|
debug(message: string, context?: Record<string, unknown>): void;
|
|
@@ -35,4 +32,4 @@ interface ConsoleLogAdapterOptions {
|
|
|
35
32
|
declare function consoleLog(opts?: ConsoleLogAdapterOptions): LoggerAdapter;
|
|
36
33
|
declare const noopAdapter: LoggerAdapter;
|
|
37
34
|
//#endregion
|
|
38
|
-
export { ConsoleLogAdapterOptions,
|
|
35
|
+
export { ConsoleLogAdapterOptions, LogLevel, LogPayload, Logger, LoggerAdapter, consoleLog, createLoggerAdapter, noopAdapter };
|
package/dist/adapters/logger.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region src/adapters/logger.ts
|
|
2
|
-
/** Author a custom logger adapter
|
|
2
|
+
/** Author a custom logger adapter. Types your handler against the {@link LoggerAdapter} contract. */
|
|
3
3
|
function createLoggerAdapter(adapter) {
|
|
4
4
|
return adapter;
|
|
5
5
|
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { AuthAdapter } from "./auth.js";
|
|
2
|
+
import { CaptchaAdapter } from "./captcha.js";
|
|
3
|
+
import { CookiesAdapter } from "../shared/types.js";
|
|
4
|
+
import { GeoAdapter } from "./geo.js";
|
|
5
|
+
import { LoggerAdapter } from "./logger.js";
|
|
6
|
+
|
|
7
|
+
//#region src/adapters/types.d.ts
|
|
8
|
+
/** The service contracts Kizlo integrations can provide at runtime. */
|
|
9
|
+
interface ServiceAdapters {
|
|
10
|
+
auth?: AuthAdapter;
|
|
11
|
+
captcha?: CaptchaAdapter;
|
|
12
|
+
geo?: GeoAdapter;
|
|
13
|
+
logger?: LoggerAdapter;
|
|
14
|
+
cookies?: CookiesAdapter;
|
|
15
|
+
}
|
|
16
|
+
/** Merge adapter contributions in order without letting `undefined` erase an earlier value. */
|
|
17
|
+
declare function mergeServiceAdapters(...contributions: (ServiceAdapters | undefined)[]): ServiceAdapters;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { ServiceAdapters, mergeServiceAdapters };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/adapters/types.ts
|
|
2
|
+
/** Merge adapter contributions in order without letting `undefined` erase an earlier value. */
|
|
3
|
+
function mergeServiceAdapters(...contributions) {
|
|
4
|
+
const adapters = {};
|
|
5
|
+
for (const contribution of contributions) {
|
|
6
|
+
if (!contribution) continue;
|
|
7
|
+
if (contribution.auth !== void 0) adapters.auth = contribution.auth;
|
|
8
|
+
if (contribution.captcha !== void 0) adapters.captcha = contribution.captcha;
|
|
9
|
+
if (contribution.geo !== void 0) adapters.geo = contribution.geo;
|
|
10
|
+
if (contribution.logger !== void 0) adapters.logger = contribution.logger;
|
|
11
|
+
if (contribution.cookies !== void 0) adapters.cookies = contribution.cookies;
|
|
12
|
+
}
|
|
13
|
+
return adapters;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { mergeServiceAdapters };
|
package/dist/astro/server.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
|
|
2
2
|
import { renderJsonLd } from "../seo/utils.js";
|
|
3
|
-
import {
|
|
3
|
+
import { AstroOptions, astro } from "../integrations/astro/integration.js";
|
|
4
4
|
import { AstroRoute, AstroRouteContext, getServerBaseUrl } from "../integrations/astro/utils.js";
|
|
5
5
|
import { createManifestRoute } from "../integrations/astro/manifest.js";
|
|
6
6
|
import { PageHead, RootHead, ThemeColor, resolvePageHead, resolveRootHead } from "../integrations/astro/metadata.js";
|
|
7
7
|
import { createRobotsRoute } from "../integrations/astro/robots.js";
|
|
8
8
|
import { createSitemapRedirectRoute, createSitemapRoute } from "../integrations/astro/sitemap.js";
|
|
9
|
-
export { AstroRoute, AstroRouteContext,
|
|
9
|
+
export { AstroOptions, AstroRoute, AstroRouteContext, PageHead, RootHead, ThemeColor, WEB_MANIFEST_ROUTE, astro, createManifestRoute, createRobotsRoute, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, renderJsonLd, resolvePageHead, resolveRootHead };
|
package/dist/astro/server.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
|
|
2
2
|
import { renderJsonLd } from "../seo/utils.js";
|
|
3
3
|
import { getServerBaseUrl } from "../integrations/astro/utils.js";
|
|
4
|
-
import {
|
|
4
|
+
import { astro } from "../integrations/astro/integration.js";
|
|
5
5
|
import { createManifestRoute } from "../integrations/astro/manifest.js";
|
|
6
6
|
import { resolvePageHead, resolveRootHead } from "../integrations/astro/metadata.js";
|
|
7
7
|
import { createRobotsRoute } from "../integrations/astro/robots.js";
|
|
8
8
|
import { createSitemapRedirectRoute, createSitemapRoute } from "../integrations/astro/sitemap.js";
|
|
9
9
|
|
|
10
|
-
export { WEB_MANIFEST_ROUTE,
|
|
10
|
+
export { WEB_MANIFEST_ROUTE, astro, createManifestRoute, createRobotsRoute, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, renderJsonLd, resolvePageHead, resolveRootHead };
|
package/dist/category/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { deserializeCategory } from "./utils.js";
|
|
|
7
7
|
import { normalizeArrayableValue } from "@kizlo/shared";
|
|
8
8
|
|
|
9
9
|
//#region src/category/index.ts
|
|
10
|
-
const
|
|
10
|
+
const CATEGORY_PROCEDURES = {
|
|
11
11
|
get: createProcedure({
|
|
12
12
|
scope: "api",
|
|
13
13
|
method: "GET",
|
|
@@ -74,4 +74,4 @@ const CATEGORY_ROUTER_MAP = {
|
|
|
74
74
|
};
|
|
75
75
|
|
|
76
76
|
//#endregion
|
|
77
|
-
export {
|
|
77
|
+
export { CATEGORY_PROCEDURES };
|
|
@@ -37,17 +37,17 @@ function remoteKeys(envKeys) {
|
|
|
37
37
|
}
|
|
38
38
|
/**
|
|
39
39
|
* The `.env` keys setup manages and the values to write, branched on the connection mode. Local
|
|
40
|
-
* WordPress writes the `KIZLO_LOCAL_WP_*` / `KIZLO_LOCAL_WP_SECRET` set plus `
|
|
40
|
+
* WordPress writes the `KIZLO_LOCAL_WP_*` / `KIZLO_LOCAL_WP_SECRET` set plus `KIZLO_MODE=local`,
|
|
41
41
|
* so it never touches the remote keys (a user can point those at a real site). A remote site writes
|
|
42
|
-
* the bare remote keys exactly as before — no `
|
|
42
|
+
* the bare remote keys exactly as before — no `KIZLO_MODE`, since `"remote"` is the default.
|
|
43
43
|
*/
|
|
44
44
|
function managedEnv(envKeys, conn) {
|
|
45
45
|
if (conn.mode === "local") {
|
|
46
|
-
const {
|
|
46
|
+
const { mode, siteSecret: siteSecret$1, wpUrl: wpUrl$1, wpUsername: wpUsername$1, wpPassword: wpPassword$1 } = envKeys.local;
|
|
47
47
|
return {
|
|
48
48
|
keys: [
|
|
49
49
|
envKeys.baseUrl,
|
|
50
|
-
|
|
50
|
+
mode,
|
|
51
51
|
siteSecret$1,
|
|
52
52
|
wpUrl$1,
|
|
53
53
|
wpUsername$1,
|
|
@@ -55,7 +55,7 @@ function managedEnv(envKeys, conn) {
|
|
|
55
55
|
],
|
|
56
56
|
values: {
|
|
57
57
|
[envKeys.baseUrl]: conn.baseUrl,
|
|
58
|
-
[
|
|
58
|
+
[mode]: "local",
|
|
59
59
|
[siteSecret$1]: conn.siteSecret,
|
|
60
60
|
[wpUrl$1]: conn.wpUrl,
|
|
61
61
|
[wpUsername$1]: conn.wpUsername,
|
|
@@ -375,7 +375,7 @@ async function provisionLocalStack(cfg, siteSecret, baseUrl) {
|
|
|
375
375
|
url: info.url,
|
|
376
376
|
username: info.username,
|
|
377
377
|
appPassword,
|
|
378
|
-
adminPassword: info.
|
|
378
|
+
adminPassword: info.adminPassword,
|
|
379
379
|
secretSyncError: sync.ok ? void 0 : sync.error
|
|
380
380
|
};
|
|
381
381
|
}
|
|
@@ -398,7 +398,7 @@ async function provisionLocalWordPress(cwd, conn) {
|
|
|
398
398
|
}
|
|
399
399
|
/**
|
|
400
400
|
* The template's own `.env.example`, when it ships one. Templates own the framework-specific key names
|
|
401
|
-
* (e.g. `
|
|
401
|
+
* (e.g. `NEXT_PUBLIC_KIZLO_BASE_URL`) and the shared section layout, so their file is the source of the
|
|
402
402
|
* scaffold's `.env.example` — see {@link writeEnv}. Undefined for the base preset (no template dir).
|
|
403
403
|
*/
|
|
404
404
|
function readEnvExample(templateDir) {
|
|
@@ -407,14 +407,14 @@ function readEnvExample(templateDir) {
|
|
|
407
407
|
}
|
|
408
408
|
/**
|
|
409
409
|
* The `.env.example` body for the base preset, which ships no template file. Lists the API URL and the
|
|
410
|
-
* remote connection keys, then the commented `
|
|
410
|
+
* remote connection keys, then the commented `KIZLO_MODE=local` toggle for the local-dev path. Real
|
|
411
411
|
* templates carry their own `.env.example` (passed to {@link writeEnv}) so its structure and comments
|
|
412
412
|
* stay consistent with the `.env` the scaffold writes.
|
|
413
413
|
*/
|
|
414
414
|
function generatedEnvExample(envKeys) {
|
|
415
415
|
const exampleKeys = [envKeys.baseUrl, ...remoteKeys(envKeys)];
|
|
416
416
|
const { content } = mergeEnv("", Object.fromEntries(exampleKeys.map((key) => [key, ""])), new Set(exampleKeys), envGroups(envKeys));
|
|
417
|
-
return `${content}\n# Point the app at local WordPress (managed by \`kizlo dev\`) instead of the keys above:\n# ${envKeys.local.
|
|
417
|
+
return `${content}\n# Point the app at local WordPress (managed by \`kizlo dev\`) instead of the keys above:\n# ${envKeys.local.mode}=local\n`;
|
|
418
418
|
}
|
|
419
419
|
/**
|
|
420
420
|
* The managed keys already present in an existing `.env` — the values a write would overwrite. Collected
|
|
@@ -471,7 +471,7 @@ function nextStepsLines(conn, prefix = "") {
|
|
|
471
471
|
const login = conn.mode === "local" && conn.adminPassword ? [
|
|
472
472
|
``,
|
|
473
473
|
`Log in to wp-admin (${conn.wpUrl}/wp-admin):`,
|
|
474
|
-
` ${conn.wpUsername} / ${conn.adminPassword}
|
|
474
|
+
` ${conn.wpUsername} / ${conn.adminPassword}`
|
|
475
475
|
] : [];
|
|
476
476
|
return [
|
|
477
477
|
`Start developing:`,
|
package/dist/cli/commands/dev.js
CHANGED
|
@@ -42,7 +42,7 @@ function note(text) {
|
|
|
42
42
|
* Print the connection summary as an aligned, Next.js-style block. Shows the wp-admin URL on
|
|
43
43
|
* the loopback ("Local") and — when local WordPress is installed on a LAN address rather than
|
|
44
44
|
* localhost — on the network, so it can be opened from other devices. On a fresh install, also
|
|
45
|
-
* show the
|
|
45
|
+
* show the default wp-admin login.
|
|
46
46
|
*/
|
|
47
47
|
function printSummary(info) {
|
|
48
48
|
const { cyan, dim, reset } = palette();
|
|
@@ -52,7 +52,7 @@ function printSummary(info) {
|
|
|
52
52
|
rows.push(["Database Connection", `127.0.0.1:${info.dbPort}`]);
|
|
53
53
|
const width = Math.max(...rows.map(([label]) => label.length)) + 1;
|
|
54
54
|
const lines = ["", ...rows.map(([label, value]) => ` ${dim}- ${`${label}:`.padEnd(width)}${reset} ${cyan}${value}${reset}`)];
|
|
55
|
-
if (info.
|
|
55
|
+
if (info.adminPassword) lines.push("", ` ${dim}admin login:${reset} ${info.username} / ${info.adminPassword}`);
|
|
56
56
|
if (info.seeded > 0) lines.push(` ${dim}seeded ${info.seeded} fixture${info.seeded === 1 ? "" : "s"}${reset}`);
|
|
57
57
|
process.stdout.write(`${lines.join("\n")}\n`);
|
|
58
58
|
}
|
|
@@ -71,13 +71,13 @@ function readEnvValue(content, key) {
|
|
|
71
71
|
return content.match(new RegExp(`^\\s*${key}\\s*=\\s*(.*)$`, "m"))?.[1]?.trim() || void 0;
|
|
72
72
|
}
|
|
73
73
|
/**
|
|
74
|
-
* The Kizlo backend URL from `.env` — the one key ending in `
|
|
75
|
-
* or a framework-prefixed `
|
|
74
|
+
* The Kizlo backend URL from `.env` — the one key ending in `KIZLO_BASE_URL` (`KIZLO_BASE_URL`,
|
|
75
|
+
* or a framework-prefixed `NEXT_PUBLIC_KIZLO_BASE_URL`). It's the handler mount the plugin delivers
|
|
76
76
|
* webhook events to; its origin is the site's canonical URL. User-managed (init writes it), so dev
|
|
77
77
|
* only reads it. Undefined before `kizlo init` has populated `.env`.
|
|
78
78
|
*/
|
|
79
79
|
function readBaseUrl(content) {
|
|
80
|
-
return content.match(/^\s*[A-Z_]*
|
|
80
|
+
return content.match(/^\s*[A-Z_]*KIZLO_BASE_URL\s*=\s*(.*)$/m)?.[1]?.trim() || void 0;
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Rewrite the local WordPress connection in `.env` after a fresh install. A reset (or first boot)
|
|
@@ -86,7 +86,7 @@ function readBaseUrl(content) {
|
|
|
86
86
|
* connection keys are overwritten; everything else in `.env` is preserved, and the file is created
|
|
87
87
|
* if absent. Gated by the caller on a minted `appPassword`, so a warm resume never churns it.
|
|
88
88
|
*
|
|
89
|
-
* `
|
|
89
|
+
* `KIZLO_MODE=local` and `KIZLO_LOCAL_WP_SECRET` are written too but kept out of the overwrite set,
|
|
90
90
|
* so a value the user already set is preserved — booting local WordPress only fills them when absent.
|
|
91
91
|
* The resolved local secret (the existing one, or a freshly minted one) and the Kizlo server base URL
|
|
92
92
|
* are returned so the caller can sync them into the plugin.
|
|
@@ -101,7 +101,7 @@ function updateWpEnv(cfg, info) {
|
|
|
101
101
|
KIZLO_LOCAL_WP_USERNAME: info.username,
|
|
102
102
|
KIZLO_LOCAL_WP_APP_PASSWORD: info.appPassword,
|
|
103
103
|
KIZLO_LOCAL_WP_SECRET: siteSecret,
|
|
104
|
-
|
|
104
|
+
KIZLO_MODE: "local"
|
|
105
105
|
}, new Set(WP_ENV_KEYS), envGroups(DEFAULT_ENV_KEYS));
|
|
106
106
|
writeFileSync(envPath, content);
|
|
107
107
|
return {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { generateContract } from "../../shared/contract.js";
|
|
2
|
-
import { resolveWordPressConnection } from "../../kizlo.js";
|
|
2
|
+
import { integrationEnv, resolveWordPressConnection } from "../../kizlo.js";
|
|
3
3
|
import { WORDPRESS_CLIENT_META_REL } from "../wp/constants.js";
|
|
4
|
+
import { node } from "../../integrations/node/integration.js";
|
|
4
5
|
import { log } from "./logger.js";
|
|
5
6
|
import { loadEnvFiles } from "../utils.js";
|
|
6
7
|
import { importIgnoringVirtualModules } from "./jiti.js";
|
|
@@ -14,21 +15,27 @@ import fs from "node:fs";
|
|
|
14
15
|
|
|
15
16
|
//#region src/cli/daemon/generate.ts
|
|
16
17
|
/**
|
|
17
|
-
* The generated barrel
|
|
18
|
+
* The generated barrel is also written as a stub by `kizlo init`. It re-exports `endpoints` rather
|
|
18
19
|
* than pre-wrapping it: a server entry passes `wordpress: { endpoints }` itself, so the rest of the
|
|
19
20
|
* WordPress options stay visible at the call site instead of hiding inside a generated object.
|
|
20
21
|
*/
|
|
21
22
|
const CONTRACT_BARREL = [
|
|
22
|
-
`import type {
|
|
23
|
+
`import type { procedures } from ".."`,
|
|
23
24
|
`import contractJson from "./contract.json"`,
|
|
24
25
|
``,
|
|
25
|
-
`export const contract = contractJson as unknown as typeof
|
|
26
|
+
`export const contract = contractJson as unknown as typeof procedures`,
|
|
26
27
|
`export { endpoints, type WordPressClient } from "./wordpress"`,
|
|
27
28
|
``
|
|
28
29
|
].join("\n");
|
|
30
|
+
var LegacyRouterExportError = class extends Error {
|
|
31
|
+
name = "LegacyRouterExportError";
|
|
32
|
+
constructor(entry) {
|
|
33
|
+
super(`The Kizlo server at ${entry} exports \`router\`, which is no longer supported. Rename that export to \`procedures\` and run \`kizlo generate\` again.`);
|
|
34
|
+
}
|
|
35
|
+
};
|
|
29
36
|
/**
|
|
30
37
|
* `wordpress.ts` before the first generation. WordPress is reachable but untyped until then, so a
|
|
31
|
-
* freshly scaffolded project compiles
|
|
38
|
+
* freshly scaffolded project compiles, including Kizlo's own procedures, before it has ever
|
|
32
39
|
* connected. `kizlo dev` / `kizlo generate` replaces this with the real client. `any` rather than an
|
|
33
40
|
* empty tree on purpose: every endpoint a procedure names has to resolve to something until the
|
|
34
41
|
* real shapes arrive, which `WP_Client` preserves by passing `any` through.
|
|
@@ -165,7 +172,7 @@ function reportPluginVersion(installed) {
|
|
|
165
172
|
/** Fetch `/introspect`, reporting its diagnostics in the CLI's voice. Returns undefined on a 304. */
|
|
166
173
|
async function fetchDocument(cwd, options, etag) {
|
|
167
174
|
loadEnvFiles(cwd);
|
|
168
|
-
const result = await fetchIntrospection(options.credentials ?? resolveWordPressConnection(void 0).credentials, {
|
|
175
|
+
const result = await fetchIntrospection(options.credentials ?? resolveWordPressConnection(void 0, integrationEnv([node()])).credentials, {
|
|
169
176
|
etag: options.strict ? void 0 : etag,
|
|
170
177
|
fetch: options.fetch
|
|
171
178
|
});
|
|
@@ -231,9 +238,12 @@ function writeGeneratedWordPress(cfg, client, meta) {
|
|
|
231
238
|
async function generateOnce(cfg, options = {}) {
|
|
232
239
|
loadEnvFiles(cfg.cwd);
|
|
233
240
|
const entry = path.resolve(cfg.cwd, cfg.serverEntry);
|
|
234
|
-
const
|
|
235
|
-
if (!
|
|
236
|
-
|
|
241
|
+
const server = await importIgnoringVirtualModules(cfg.cwd, entry);
|
|
242
|
+
if (!server.procedures) {
|
|
243
|
+
if (server.router) throw new LegacyRouterExportError(cfg.serverEntry);
|
|
244
|
+
return false;
|
|
245
|
+
}
|
|
246
|
+
const contract = JSON.stringify(await generateContract(server.procedures));
|
|
237
247
|
const wordpress = await generateWordPressOnce(cfg, options);
|
|
238
248
|
fs.mkdirSync(path.resolve(cfg.cwd, cfg.generatedDir), { recursive: true });
|
|
239
249
|
atomicWrite(path.resolve(cfg.cwd, cfg.contractPath), contract);
|
package/dist/cli/daemon/jiti.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { isContractGeneration, setContractGeneration } from "../../shared/contract-generation.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import fs from "node:fs";
|
|
4
4
|
import { createJiti } from "jiti";
|
|
@@ -20,13 +20,12 @@ import { createJiti } from "jiti";
|
|
|
20
20
|
async function importIgnoringVirtualModules(cwd, entry) {
|
|
21
21
|
const deps = declaredDeps(cwd);
|
|
22
22
|
const virtualModules = {};
|
|
23
|
-
const previousGenerationFlag =
|
|
24
|
-
|
|
23
|
+
const previousGenerationFlag = isContractGeneration();
|
|
24
|
+
setContractGeneration(true);
|
|
25
25
|
try {
|
|
26
26
|
return await importLoop(cwd, entry, deps, virtualModules);
|
|
27
27
|
} finally {
|
|
28
|
-
|
|
29
|
-
else process.env[CONTRACT_GENERATION_ENV] = previousGenerationFlag;
|
|
28
|
+
setContractGeneration(previousGenerationFlag);
|
|
30
29
|
}
|
|
31
30
|
}
|
|
32
31
|
async function importLoop(cwd, entry, deps, virtualModules) {
|
package/dist/cli/daemon/watch.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { resolveWordPressConnection } from "../../kizlo.js";
|
|
1
|
+
import { integrationEnv, resolveWordPressConnection } from "../../kizlo.js";
|
|
2
|
+
import { node } from "../../integrations/node/integration.js";
|
|
2
3
|
import { log } from "./logger.js";
|
|
3
4
|
import { loadEnvFiles } from "../utils.js";
|
|
4
5
|
import { resolveConfig, resolveWordPressClientDir } from "./config.js";
|
|
@@ -149,7 +150,7 @@ async function startWatcher(cwd, opts) {
|
|
|
149
150
|
return;
|
|
150
151
|
}
|
|
151
152
|
loadEnvFiles(cwd);
|
|
152
|
-
const { credentials } = resolveWordPressConnection(void 0);
|
|
153
|
+
const { credentials } = resolveWordPressConnection(void 0, integrationEnv([node()]));
|
|
153
154
|
if (wordpressClientDir) try {
|
|
154
155
|
if (await generateWorkspaceClientOnce(cwd, wordpressClientDir, { credentials }) === "generated") log.success("WordPress client generated");
|
|
155
156
|
} catch (error) {
|
package/dist/cli/utils.js
CHANGED
|
@@ -460,7 +460,7 @@ function envKeysPresent(contents, keys) {
|
|
|
460
460
|
* first stamped release). Real templates carry their own `env`, so this is the standard `KIZLO_*` set.
|
|
461
461
|
*/
|
|
462
462
|
const DEFAULT_ENV_KEYS = {
|
|
463
|
-
baseUrl: "
|
|
463
|
+
baseUrl: "KIZLO_BASE_URL",
|
|
464
464
|
remote: {
|
|
465
465
|
siteSecret: "KIZLO_WP_SECRET",
|
|
466
466
|
wpUrl: "KIZLO_WP_URL",
|
|
@@ -468,7 +468,7 @@ const DEFAULT_ENV_KEYS = {
|
|
|
468
468
|
wpPassword: "KIZLO_WP_APP_PASSWORD"
|
|
469
469
|
},
|
|
470
470
|
local: {
|
|
471
|
-
|
|
471
|
+
mode: "KIZLO_MODE",
|
|
472
472
|
siteSecret: "KIZLO_LOCAL_WP_SECRET",
|
|
473
473
|
wpUrl: "KIZLO_LOCAL_WP_URL",
|
|
474
474
|
wpUsername: "KIZLO_LOCAL_WP_USERNAME",
|
|
@@ -477,7 +477,7 @@ const DEFAULT_ENV_KEYS = {
|
|
|
477
477
|
};
|
|
478
478
|
/**
|
|
479
479
|
* The grouped `.env` layout shared by `init` and `dev`, so both write the same sectioned file:
|
|
480
|
-
* a
|
|
480
|
+
* a mode switch, the base URL, then the remote and local connection blocks. The key names come from
|
|
481
481
|
* the resolved {@link EnvKeys} (the template's `env` contract), so the sections stay labelled correctly
|
|
482
482
|
* whatever a template calls them. Only sections whose keys are actually being appended get a header, so
|
|
483
483
|
* a remote run skips the local block and vice versa.
|
|
@@ -485,11 +485,11 @@ const DEFAULT_ENV_KEYS = {
|
|
|
485
485
|
function envGroups(envKeys) {
|
|
486
486
|
return [
|
|
487
487
|
{
|
|
488
|
-
comment: "Kizlo
|
|
489
|
-
keys: [envKeys.local.
|
|
488
|
+
comment: "Kizlo Mode (local | remote)",
|
|
489
|
+
keys: [envKeys.local.mode]
|
|
490
490
|
},
|
|
491
491
|
{
|
|
492
|
-
comment: "Kizlo
|
|
492
|
+
comment: "Kizlo Base URL",
|
|
493
493
|
keys: [envKeys.baseUrl]
|
|
494
494
|
},
|
|
495
495
|
{
|
package/dist/cli/wp/bootstrap.js
CHANGED
|
@@ -3,6 +3,19 @@ import { compose, composeUp, wpCli, wpEval } from "./docker.js";
|
|
|
3
3
|
import { ensurePlugins, settleFixtures } from "./utils.js";
|
|
4
4
|
|
|
5
5
|
//#region src/cli/wp/bootstrap.ts
|
|
6
|
+
/** Install a local WordPress site with the shared admin credentials. */
|
|
7
|
+
async function installWordPress(url, title) {
|
|
8
|
+
await wpCli([
|
|
9
|
+
"core",
|
|
10
|
+
"install",
|
|
11
|
+
`--url=${url}`,
|
|
12
|
+
`--title=${title}`,
|
|
13
|
+
`--admin_user=${TEST_ADMIN.username}`,
|
|
14
|
+
`--admin_password=${TEST_ADMIN.password}`,
|
|
15
|
+
`--admin_email=${TEST_ADMIN.email}`,
|
|
16
|
+
"--skip-email"
|
|
17
|
+
]);
|
|
18
|
+
}
|
|
6
19
|
async function seedUsers() {
|
|
7
20
|
const existing = await wpCli([
|
|
8
21
|
"user",
|
|
@@ -59,16 +72,7 @@ async function bootstrapWp(config) {
|
|
|
59
72
|
"wp",
|
|
60
73
|
"core",
|
|
61
74
|
"is-installed"
|
|
62
|
-
])).code !== 0) await
|
|
63
|
-
"core",
|
|
64
|
-
"install",
|
|
65
|
-
`--url=${url}`,
|
|
66
|
-
"--title=Kizlo Test",
|
|
67
|
-
`--admin_user=${TEST_ADMIN.username}`,
|
|
68
|
-
`--admin_password=${TEST_ADMIN.password}`,
|
|
69
|
-
`--admin_email=${TEST_ADMIN.email}`,
|
|
70
|
-
"--skip-email"
|
|
71
|
-
]);
|
|
75
|
+
])).code !== 0) await installWordPress(url, "Kizlo Test");
|
|
72
76
|
await wpCli([
|
|
73
77
|
"rewrite",
|
|
74
78
|
"structure",
|
|
@@ -118,4 +122,4 @@ async function bootstrapWp(config) {
|
|
|
118
122
|
}
|
|
119
123
|
|
|
120
124
|
//#endregion
|
|
121
|
-
export { bootstrapWp, createAdminAppPassword, seedUsers };
|
|
125
|
+
export { bootstrapWp, createAdminAppPassword, installWordPress, seedUsers };
|
package/dist/cli/wp/constants.js
CHANGED
package/dist/cli/wp/dev.js
CHANGED
|
@@ -4,17 +4,12 @@ import { compose, composePull, composeUp, wpCli, wpEval } from "./docker.js";
|
|
|
4
4
|
import { ensurePlugins, settleFixtures } from "./utils.js";
|
|
5
5
|
import { log } from "../daemon/logger.js";
|
|
6
6
|
import { warnVersionDrift } from "./version.js";
|
|
7
|
-
import { createAdminAppPassword, seedUsers } from "./bootstrap.js";
|
|
7
|
+
import { createAdminAppPassword, installWordPress, seedUsers } from "./bootstrap.js";
|
|
8
8
|
import { join } from "node:path";
|
|
9
9
|
import { existsSync } from "node:fs";
|
|
10
|
-
import { randomBytes } from "node:crypto";
|
|
11
10
|
import { networkInterfaces } from "node:os";
|
|
12
11
|
|
|
13
12
|
//#region src/cli/wp/dev.ts
|
|
14
|
-
/** A strong random admin password (144 bits, URL/JSON/CLI-safe characters). */
|
|
15
|
-
function generatePassword() {
|
|
16
|
-
return randomBytes(18).toString("base64url");
|
|
17
|
-
}
|
|
18
13
|
const VIRTUAL_INTERFACE = /^(?:docker|br-|veth|utun|tun|tap)/i;
|
|
19
14
|
const PRIVATE_IPV4 = /^(?:10\.|192\.168\.|172\.(?:1[6-9]|2\d|3[01])\.)/;
|
|
20
15
|
/** Preferred private IPv4 address on a physical interface (undefined when offline). */
|
|
@@ -74,9 +69,8 @@ async function seedDevFixtures(cfg, url) {
|
|
|
74
69
|
* sources + bind-mounted locals). An already-provisioned install is left untouched
|
|
75
70
|
* (idempotent reruns).
|
|
76
71
|
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
* that's a test concern.
|
|
72
|
+
* A fresh install uses the shared local admin credentials and returns the password so
|
|
73
|
+
* the command can show the login. Existing installs are left untouched.
|
|
80
74
|
*/
|
|
81
75
|
async function bootstrapDev(cfg) {
|
|
82
76
|
const url = devUrl(cfg.port);
|
|
@@ -90,19 +84,8 @@ async function bootstrapDev(cfg) {
|
|
|
90
84
|
"core",
|
|
91
85
|
"is-installed"
|
|
92
86
|
])).code === 0;
|
|
93
|
-
let password;
|
|
94
87
|
if (!installed) {
|
|
95
|
-
|
|
96
|
-
await wpCli([
|
|
97
|
-
"core",
|
|
98
|
-
"install",
|
|
99
|
-
`--url=${url}`,
|
|
100
|
-
"--title=Kizlo Dev",
|
|
101
|
-
`--admin_user=${TEST_ADMIN.username}`,
|
|
102
|
-
`--admin_password=${password}`,
|
|
103
|
-
`--admin_email=${TEST_ADMIN.email}`,
|
|
104
|
-
"--skip-email"
|
|
105
|
-
]);
|
|
88
|
+
await installWordPress(url, "Kizlo Dev");
|
|
106
89
|
await wpCli([
|
|
107
90
|
"rewrite",
|
|
108
91
|
"structure",
|
|
@@ -122,14 +105,14 @@ async function bootstrapDev(cfg) {
|
|
|
122
105
|
wpEval
|
|
123
106
|
});
|
|
124
107
|
const seeded = !installed && cfg.fixtures.length ? await seedDevFixtures(cfg, url) : 0;
|
|
125
|
-
const appPassword =
|
|
108
|
+
const appPassword = !installed ? await createAdminAppPassword("kizlo-dev") : void 0;
|
|
126
109
|
return {
|
|
127
110
|
url,
|
|
128
111
|
username: TEST_ADMIN.username,
|
|
129
112
|
dbPort: cfg.dbPort,
|
|
130
113
|
seeded,
|
|
131
114
|
appPassword,
|
|
132
|
-
|
|
115
|
+
adminPassword: !installed ? TEST_ADMIN.password : void 0
|
|
133
116
|
};
|
|
134
117
|
}
|
|
135
118
|
|
package/dist/cli/wp/types.d.ts
CHANGED
|
@@ -87,7 +87,7 @@ interface SettleContext {
|
|
|
87
87
|
type FixtureSeedFn = (ctx: SeedContext) => Promise<Record<string, JsonValue>>;
|
|
88
88
|
type FixtureSettleFn = (ctx: SettleContext) => Promise<void>;
|
|
89
89
|
type FixtureCleanupFn = (ctx: SeedContext) => Promise<void>;
|
|
90
|
-
/** The serializable test layer an
|
|
90
|
+
/** The serializable test layer an integration ships alongside its live code. */
|
|
91
91
|
interface Fixture {
|
|
92
92
|
/** Namespace key under `TestCredentials.fixtures`. */
|
|
93
93
|
name: string;
|
|
@@ -107,7 +107,7 @@ interface Fixture {
|
|
|
107
107
|
* a minute ago and one booted last week describe the same WordPress.
|
|
108
108
|
*/
|
|
109
109
|
settle?: FixtureSettleFn;
|
|
110
|
-
/** Build this
|
|
110
|
+
/** Build this integration's world once during seeding; return created handles. */
|
|
111
111
|
seed?: FixtureSeedFn;
|
|
112
112
|
/** Revert per-test mutations (teardown); does NOT uninstall plugins or seeded data. */
|
|
113
113
|
cleanup?: FixtureCleanupFn;
|
package/dist/cli/wp/utils.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ declare function ensurePlugin(name: string, source: string): Promise<void>;
|
|
|
31
31
|
declare function activateLocalPlugin(pluginPath: string): Promise<void>;
|
|
32
32
|
/**
|
|
33
33
|
* Ensure every plugin is active. Installable sources go first so a bind-mounted
|
|
34
|
-
* local plugin that depends on one (e.g. a WooCommerce
|
|
34
|
+
* local plugin that depends on one (e.g. a WooCommerce integration) finds it already
|
|
35
35
|
* present; then each {@link LocalPlugin} is activated by basename. A local plugin
|
|
36
36
|
* whose slug matches an installable (e.g. mounting `kizlo` over the released
|
|
37
37
|
* `kizlo`) is seen as already installed, so `ensurePlugin` activates the live
|
package/dist/cli/wp/utils.js
CHANGED
|
@@ -95,7 +95,7 @@ async function activateLocalPlugin(pluginPath) {
|
|
|
95
95
|
}
|
|
96
96
|
/**
|
|
97
97
|
* Ensure every plugin is active. Installable sources go first so a bind-mounted
|
|
98
|
-
* local plugin that depends on one (e.g. a WooCommerce
|
|
98
|
+
* local plugin that depends on one (e.g. a WooCommerce integration) finds it already
|
|
99
99
|
* present; then each {@link LocalPlugin} is activated by basename. A local plugin
|
|
100
100
|
* whose slug matches an installable (e.g. mounting `kizlo` over the released
|
|
101
101
|
* `kizlo`) is seen as already installed, so `ensurePlugin` activates the live
|
package/dist/client.d.ts
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { AnyProcedureTree, ExtractProcedureByScope } from "./shared/procedure.js";
|
|
2
2
|
import { ResultClient } from "./shared/result.js";
|
|
3
3
|
|
|
4
4
|
//#region src/client.d.ts
|
|
5
|
-
interface KizloClientConfig<T extends
|
|
5
|
+
interface KizloClientConfig<T extends AnyProcedureTree> {
|
|
6
6
|
url?: string;
|
|
7
7
|
contract: T;
|
|
8
8
|
fetch?: (request: Request) => Promise<Response>;
|
|
9
9
|
}
|
|
10
|
-
declare class KizloClient<
|
|
11
|
-
readonly client: ResultClient<ExtractProcedureByScope<
|
|
12
|
-
protected readonly config: KizloClientConfig<
|
|
13
|
-
constructor(config: KizloClientConfig<
|
|
10
|
+
declare class KizloClient<TProcedures extends AnyProcedureTree> {
|
|
11
|
+
readonly client: ResultClient<ExtractProcedureByScope<TProcedures, "remote" | "api">>;
|
|
12
|
+
protected readonly config: KizloClientConfig<TProcedures>;
|
|
13
|
+
constructor(config: KizloClientConfig<TProcedures>);
|
|
14
14
|
private getUrl;
|
|
15
15
|
}
|
|
16
16
|
/**
|
|
17
17
|
* Creates a browser client for a generated contract. Defaults the URL to the
|
|
18
18
|
* current origin (`window.location.origin`); framework packages wrap this to resolve it from their env.
|
|
19
19
|
*/
|
|
20
|
-
declare function createKizloClient<T extends
|
|
20
|
+
declare function createKizloClient<T extends AnyProcedureTree>(contract: T, options?: {
|
|
21
21
|
url?: string;
|
|
22
22
|
}): KizloClient<T>;
|
|
23
23
|
//#endregion
|
package/dist/client.js
CHANGED
|
@@ -27,7 +27,7 @@ var KizloClient = class {
|
|
|
27
27
|
});
|
|
28
28
|
this.client = createResultClient(createORPCClient(new DynamicLink((_, path) => {
|
|
29
29
|
const procedure = getObjectProperty(this.config.contract, path);
|
|
30
|
-
if (!isContractProcedure$1(procedure)) throw new Error(`No valid procedure found at path "${path.join(".")}".
|
|
30
|
+
if (!isContractProcedure$1(procedure)) throw new Error(`No valid procedure found at path "${path.join(".")}". The generated contract may not match the exported procedures.`);
|
|
31
31
|
switch (procedure.scope) {
|
|
32
32
|
case "internal": throw new Error("Internal procedure can only be called on the server.");
|
|
33
33
|
case "api": return openapiLink;
|
package/dist/comment/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { deserializeComment } from "./utils.js";
|
|
|
6
6
|
import { listed } from "@kizlo/shared";
|
|
7
7
|
|
|
8
8
|
//#region src/comment/index.ts
|
|
9
|
-
const
|
|
9
|
+
const COMMENT_PROCEDURES = {
|
|
10
10
|
get: createProcedure({
|
|
11
11
|
scope: "api",
|
|
12
12
|
method: "GET",
|
|
@@ -147,4 +147,4 @@ const COMMENT_ROUTER_MAP = {
|
|
|
147
147
|
};
|
|
148
148
|
|
|
149
149
|
//#endregion
|
|
150
|
-
export {
|
|
150
|
+
export { COMMENT_PROCEDURES };
|