kizlo 0.6.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/dist/brand/icons.d.ts +10 -12
  2. package/dist/brand/icons.js +19 -17
  3. package/dist/cli/commands/dev.js +26 -15
  4. package/dist/cli/commands/init.js +1 -1
  5. package/dist/cli/daemon/config.js +1 -1
  6. package/dist/cli/daemon/generate.js +1 -1
  7. package/dist/cli/daemon/lock.js +1 -1
  8. package/dist/cli/utils.js +2 -2
  9. package/dist/cli/wp/bootstrap.js +1 -1
  10. package/dist/cli/wp/byo.js +1 -1
  11. package/dist/cli/wp/compose/override.js +1 -1
  12. package/dist/cli/wp/compose/override.test.ts +0 -2
  13. package/dist/cli/wp/compose/override.ts +0 -4
  14. package/dist/cli/wp/constants.d.ts +35 -0
  15. package/dist/cli/wp/constants.js +13 -2
  16. package/dist/cli/wp/dev.js +18 -3
  17. package/dist/cli/wp/phpunit.js +1 -1
  18. package/dist/cli/wp/session.js +2 -2
  19. package/dist/cli/wp/setup.js +1 -1
  20. package/dist/cli/wp/utils.d.ts +1 -9
  21. package/dist/cli/wp/utils.js +3 -15
  22. package/dist/index.d.ts +7 -5
  23. package/dist/index.js +4 -1
  24. package/dist/integrations/nextjs/manifest.js +2 -9
  25. package/dist/integrations/nextjs/metadata.d.ts +1 -1
  26. package/dist/integrations/nextjs/metadata.js +1 -2
  27. package/dist/integrations/nextjs/revalidate.d.ts +4 -1
  28. package/dist/integrations/nextjs/robots.d.ts +2 -1
  29. package/dist/integrations/nextjs/robots.js +2 -9
  30. package/dist/integrations/nextjs/utils.d.ts +13 -0
  31. package/dist/integrations/nextjs/utils.js +38 -1
  32. package/dist/nextjs/server.d.ts +5 -3
  33. package/dist/nextjs/server.js +5 -3
  34. package/dist/nextjs.d.ts +1 -2
  35. package/dist/nextjs.js +1 -2
  36. package/dist/package.js +1 -1
  37. package/dist/router.d.ts +9 -8
  38. package/dist/seo/sitemap.d.ts +1 -1
  39. package/dist/seo/utils.d.ts +12 -2
  40. package/dist/seo/utils.js +1 -1
  41. package/dist/settings/index.js +5 -0
  42. package/dist/settings/service.d.ts +2 -1
  43. package/dist/settings/service.interface.d.ts +3 -2
  44. package/dist/settings/service.js +3 -0
  45. package/dist/test.d.ts +4 -3
  46. package/dist/test.js +3 -2
  47. package/package.json +2 -3
@@ -7,29 +7,27 @@ interface IconDescriptor {
7
7
  type: string;
8
8
  /** `"any"` for scalable/single sources; omitted for `.ico`. */
9
9
  sizes?: string;
10
- /** Media query for scheme-specific variants, e.g. `(prefers-color-scheme: dark)`. */
11
- media?: string;
12
10
  }
13
11
  interface ManifestIcon {
14
12
  src: string;
15
13
  type: string;
16
14
  sizes: string;
17
- /**
18
- * `"maskable"` marks art with a safe zone the launcher may crop to any
19
- * adaptive shape; omitted (default `"any"`) sources render uncropped.
20
- */
21
- purpose?: "any" | "maskable";
22
15
  }
23
16
  interface ResolvedIcons {
24
- /** `rel="icon"` candidates: the light source plus an optional dark variant. */
17
+ /**
18
+ * `rel="icon"` candidate: a single scheme-agnostic source, or empty. Browsers
19
+ * disagree on scheme-swapping favicons (Safari ignores the `media` attribute
20
+ * and never re-evaluates an SVG's internal `@media`), so one icon that reads
21
+ * on both light and dark tab bars is the only cross-browser-safe surface.
22
+ */
25
23
  icon: IconDescriptor[];
26
24
  /** `rel="apple-touch-icon"` candidate (raster-guarded), or empty. */
27
25
  appleTouch: IconDescriptor[];
28
26
  /**
29
- * Web-manifest icon entries (raster or SVG): the square brand icon as the
30
- * default `"any"` source — expanded to one entry per real square rendition —
31
- * plus the dedicated Android icon as `"maskable"` when provided. Either may
32
- * be absent.
27
+ * Web-manifest icon entries (raster or SVG): a single square source —
28
+ * expanded to one entry per real square rendition — that every non-iOS
29
+ * install surface (Android, Chrome, macOS Safari) renders uncropped. Absent
30
+ * when no manifest-compatible source exists.
33
31
  */
34
32
  manifestIcons: ManifestIcon[];
35
33
  }
@@ -32,12 +32,20 @@ function manifestSource(media) {
32
32
  function pixelSize(media) {
33
33
  return media.width && media.height ? `${media.width}x${media.height}` : "any";
34
34
  }
35
- function toDescriptor(media, extra) {
35
+ /**
36
+ * Append the attachment id as a `?v=` cache-buster. Safari (and every browser)
37
+ * keys its favicon cache by URL, so tying the version to the attachment id means
38
+ * the URL changes when a different icon is chosen — busting the stale cache —
39
+ * while staying stable across renders when the icon is unchanged.
40
+ */
41
+ function versioned(src, id) {
42
+ return `${src}${src.includes("?") ? "&" : "?"}v=${id}`;
43
+ }
44
+ function toDescriptor(media) {
36
45
  return {
37
- url: media.src,
46
+ url: versioned(media.src, media.id),
38
47
  type: media.mime ?? "",
39
- sizes: media.mime && ICO_MIMES.has(media.mime) ? void 0 : pixelSize(media),
40
- ...extra
48
+ sizes: media.mime && ICO_MIMES.has(media.mime) ? void 0 : pixelSize(media)
41
49
  };
42
50
  }
43
51
  /**
@@ -47,14 +55,12 @@ function toDescriptor(media, extra) {
47
55
  * or above the floor so browsers get genuine 192/512-ish icons; if none qualify
48
56
  * (e.g. a non-square upload) the original is used as-is.
49
57
  */
50
- function toManifestIcons(media, purpose) {
58
+ function toManifestIcons(media) {
51
59
  const type = media.mime ?? "";
52
- const withPurpose = purpose ? { purpose } : {};
53
60
  if (media.mime === SVG_MIME) return [{
54
61
  src: media.src,
55
62
  type,
56
- sizes: "any",
57
- ...withPurpose
63
+ sizes: "any"
58
64
  }];
59
65
  const square = [{
60
66
  src: media.src,
@@ -75,8 +81,7 @@ function toManifestIcons(media, purpose) {
75
81
  icons.push({
76
82
  src: r.src,
77
83
  type,
78
- sizes,
79
- ...withPurpose
84
+ sizes
80
85
  });
81
86
  }
82
87
  return icons;
@@ -87,16 +92,13 @@ function toManifestIcons(media, purpose) {
87
92
  */
88
93
  function resolveIcons(brand) {
89
94
  const icon = [];
90
- const light = brand.favicon ?? brand.logo_icon;
91
- if (light) icon.push(toDescriptor(light));
92
- if (brand.favicon_dark) icon.push(toDescriptor(brand.favicon_dark, { media: "(prefers-color-scheme: dark)" }));
93
- const apple = raster(brand.ios_app_icon) ?? raster(brand.favicon);
95
+ const primary = brand.favicon ?? brand.logo_icon;
96
+ if (primary) icon.push(toDescriptor(primary));
97
+ const apple = raster(brand.app_icon) ?? raster(brand.favicon);
94
98
  const appleTouch = apple ? [toDescriptor(apple)] : [];
95
99
  const manifestIcons = [];
96
- const anySource = manifestSource(brand.logo_icon) ?? manifestSource(brand.favicon);
100
+ const anySource = manifestSource(brand.app_icon) ?? manifestSource(brand.logo_icon) ?? manifestSource(brand.favicon);
97
101
  if (anySource) manifestIcons.push(...toManifestIcons(anySource));
98
- const maskable = manifestSource(brand.android_app_icon);
99
- if (maskable) manifestIcons.push(...toManifestIcons(maskable, "maskable"));
100
102
  return {
101
103
  icon,
102
104
  appleTouch,
@@ -7,11 +7,10 @@ import { bootstrapDev } from "../wp/dev.js";
7
7
  import { reapOrphans, registerSession, removeProjectContainers, spawnWatchdog, unregisterSession } from "../wp/session.js";
8
8
  import { syncSiteSettings } from "../wp/settings.js";
9
9
  import { devStack } from "../wp/stack.js";
10
- import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
11
10
  import { join } from "node:path";
11
+ import { existsSync, readFileSync, rmSync, writeFileSync } from "node:fs";
12
12
  import { defineCommand } from "citty";
13
13
  import { randomBytes } from "node:crypto";
14
- import { networkInterfaces } from "node:os";
15
14
 
16
15
  //#region src/cli/commands/dev.ts
17
16
  async function resolve$1(cwd) {
@@ -26,22 +25,17 @@ function note(text) {
26
25
  const { dim, reset } = palette();
27
26
  process.stdout.write(` ${dim}${text}${reset}\n`);
28
27
  }
29
- /** First non-internal IPv4 address, for the LAN-reachable "Network" URL (undefined when offline). */
30
- function lanAddress() {
31
- for (const ifaces of Object.values(networkInterfaces())) for (const iface of ifaces ?? []) if (iface.family === "IPv4" && !iface.internal) return iface.address;
32
- }
33
28
  /**
34
- * Print the connection summary as an aligned, Next.js-style block. Shows the wp-admin
35
- * URL on localhost ("Local") and — when a LAN address exists — on the network, so the
36
- * stack can be opened from other devices. On a fresh install, also show the one-time
37
- * wp-admin password (it's never stored, so this is the only chance to see it).
29
+ * Print the connection summary as an aligned, Next.js-style block. Shows the wp-admin URL on
30
+ * the loopback ("Local") and — when the stack is installed on a LAN address rather than
31
+ * localhost — on the network, so it can be opened from other devices. On a fresh install, also
32
+ * show the one-time wp-admin password (it's never stored, so this is the only chance to see it).
38
33
  */
39
34
  function printSummary(info) {
40
35
  const { cyan, dim, reset } = palette();
41
- const port = new URL(info.url).port;
42
- const lan = lanAddress();
43
- const rows = [["WP Local", `${info.url}/wp-admin`]];
44
- if (lan) rows.push(["WP Network", `http://${lan}:${port}/wp-admin`]);
36
+ const { port, hostname } = new URL(info.url);
37
+ const rows = [["WP Local", `http://localhost:${port}/wp-admin`]];
38
+ if (hostname !== "localhost") rows.push(["WP Network", `${info.url}/wp-admin`]);
45
39
  rows.push(["Database Connection", `127.0.0.1:${info.dbPort}`]);
46
40
  const width = Math.max(...rows.map(([label]) => label.length)) + 1;
47
41
  const lines = ["", ...rows.map(([label, value]) => ` ${dim}- ${`${label}:`.padEnd(width)}${reset} ${cyan}${value}${reset}`)];
@@ -104,6 +98,23 @@ function updateWpEnv(cfg, info) {
104
98
  };
105
99
  }
106
100
  /**
101
+ * Re-point `KIZLO_DEV_WORDPRESS_URL` at the current dev URL on a warm resume, so a LAN address that
102
+ * changed since the last session (a new DHCP lease, a different network) doesn't leave the app talking
103
+ * to a dead IP. Only this one key is rewritten — the credentials and secret from the fresh install are
104
+ * preserved — and it's a no-op when `.env` is absent (nothing provisioned yet) or already current.
105
+ * The full fresh-install write goes through {@link updateWpEnv} instead; this covers the resume path it
106
+ * skips. Returns true when it changed the file. The app still needs a restart to read the new value.
107
+ */
108
+ function syncDevUrl(cfg, url) {
109
+ const envPath = join(cfg.configDir, ".env");
110
+ if (!existsSync(envPath)) return false;
111
+ const existing = readFileSync(envPath, "utf8");
112
+ if (readEnvValue(existing, "KIZLO_DEV_WORDPRESS_URL") === url) return false;
113
+ const { content } = mergeEnv(existing, { KIZLO_DEV_WORDPRESS_URL: url }, new Set(["KIZLO_DEV_WORDPRESS_URL"]), envGroups("KIZLO_BACKEND_URL"));
114
+ writeFileSync(envPath, content);
115
+ return true;
116
+ }
117
+ /**
107
118
  * Arm the foreground teardown — call this *before* the containers start, so a cancel at
108
119
  * any point (even mid-startup, with mysql up but wordpress still booting) stops whatever
109
120
  * already came up. The teardown is owned by a detached **watchdog** process, not by this
@@ -189,7 +200,7 @@ async function startForeground(cfg) {
189
200
  });
190
201
  if (!sync.ok) note(`Could not sync the site settings to WordPress (${sync.error}) — make sure the kizlo plugin is active, then set them from the Kizlo settings.`);
191
202
  }
192
- }
203
+ } else if (syncDevUrl(ready, creds.url)) note("Updated .env WordPress URL to the current network address — restart your app to pick it up");
193
204
  printSummary(creds);
194
205
  const { green, dim, bold, reset } = palette();
195
206
  const ms = Date.now() - start;
@@ -10,8 +10,8 @@ import { syncSiteSettings } from "../wp/settings.js";
10
10
  import { devStack } from "../wp/stack.js";
11
11
  import { PRESETS, detectPreset, getPreset } from "../presets/index.js";
12
12
  import z from "zod/v4";
13
- import fs from "node:fs";
14
13
  import path from "node:path";
14
+ import fs from "node:fs";
15
15
  import { defineCommand } from "citty";
16
16
  import * as p from "@clack/prompts";
17
17
  import { randomBytes } from "node:crypto";
@@ -2,8 +2,8 @@ import { credentialsPath, findConfigDir } from "../wp/utils.js";
2
2
  import { log } from "./logger.js";
3
3
  import { detectPackageManager } from "../utils.js";
4
4
  import z from "zod/v4";
5
- import fs from "node:fs";
6
5
  import path from "node:path";
6
+ import fs from "node:fs";
7
7
  import { createJiti } from "jiti";
8
8
 
9
9
  //#region src/cli/daemon/config.ts
@@ -1,7 +1,7 @@
1
1
  import { generateContract } from "../../shared/contract.js";
2
2
  import { loadEnvFiles } from "../utils.js";
3
- import fs from "node:fs";
4
3
  import path from "node:path";
4
+ import fs from "node:fs";
5
5
  import { createJiti } from "jiti";
6
6
 
7
7
  //#region src/cli/daemon/generate.ts
@@ -1,5 +1,5 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
2
+ import fs from "node:fs";
3
3
 
4
4
  //#region src/cli/daemon/lock.ts
5
5
  function lockPath(cwd) {
package/dist/cli/utils.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import { log } from "./daemon/logger.js";
2
2
  import { PortInUseError, resolveHostPort } from "./wp/ports.js";
3
- import { spawnSync } from "node:child_process";
4
- import fs from "node:fs";
5
3
  import path from "node:path";
6
4
  import { fileURLToPath } from "node:url";
5
+ import { spawnSync } from "node:child_process";
6
+ import fs from "node:fs";
7
7
  import * as p from "@clack/prompts";
8
8
 
9
9
  //#region src/cli/utils.ts
@@ -1,5 +1,5 @@
1
- import { compose, composeUp, wpCli } from "./docker.js";
2
1
  import { DEFAULT_PLUGINS, DEFAULT_PORT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER } from "./constants.js";
2
+ import { compose, composeUp, wpCli } from "./docker.js";
3
3
  import { ensurePlugins } from "./utils.js";
4
4
 
5
5
  //#region src/cli/wp/bootstrap.ts
@@ -1,6 +1,6 @@
1
+ import { join, resolve, sep } from "node:path";
1
2
  import { execFileSync } from "node:child_process";
2
3
  import { cpSync, createReadStream, existsSync, mkdirSync, readdirSync, renameSync, rmSync } from "node:fs";
3
- import { join, resolve, sep } from "node:path";
4
4
  import { createInterface } from "node:readline";
5
5
 
6
6
  //#region src/cli/wp/byo.ts
@@ -1,6 +1,6 @@
1
1
  import { OPCACHE_INI, REMAP_ENTRYPOINT } from "../constants.js";
2
- import { mkdirSync, writeFileSync } from "node:fs";
3
2
  import { basename, dirname, isAbsolute, resolve } from "node:path";
3
+ import { mkdirSync, writeFileSync } from "node:fs";
4
4
 
5
5
  //#region src/cli/wp/compose/override.ts
6
6
  /** Generated dev override location, relative to the config root. */
@@ -72,7 +72,6 @@ describe("writeDevOverride", () => {
72
72
  expect(body).toContain(`- "${REMAP_ENTRYPOINT}:/usr/local/bin/kizlo-remap-entrypoint.sh:ro"`)
73
73
  expect(body).toContain('KIZLO_PUID: "1000"')
74
74
  expect(body).toContain('KIZLO_PGID: "1000"')
75
- // wp-cli runs directly as the host user (no entrypoint wrapper needed there).
76
75
  expect(body).toContain('user: "1000:1000"')
77
76
  })
78
77
  })
@@ -96,7 +95,6 @@ describe("writeTestOverride", () => {
96
95
  const pluginBind = `- "${path.join(dir, "plugins/kizlo-woocommerce")}:/var/www/html/wp-content/plugins/kizlo-woocommerce"`
97
96
  expect(body).toContain(" wordpress:")
98
97
  expect(body).toContain(" wp-cli:")
99
- // One bind per service.
100
98
  expect(body.split(pluginBind).length - 1).toBe(2)
101
99
  })
102
100
 
@@ -84,8 +84,6 @@ export function writeDevOverride(configDir: string, opts: DevOverrideOptions): s
84
84
  const rootBind = bind(opts.wordpressDir, WP_ROOT)
85
85
  const remap = opts.hostUser
86
86
  ? {
87
- // Run the wrapper as root so it can retag www-data, then it hands off to
88
- // the normal entrypoint; wp-cli just runs directly as the host user.
89
87
  wordpress: {
90
88
  user: "0:0",
91
89
  entrypoint: ["sh", REMAP_TARGET],
@@ -104,8 +102,6 @@ export function writeDevOverride(configDir: string, opts: DevOverrideOptions): s
104
102
  }
105
103
  const wpCli: ServiceBlock = { user: remap?.wpCliUser, volumes: [rootBind, ...mounts] }
106
104
 
107
- // Publish MySQL on a host port (loopback only) so advanced users can point a SQL
108
- // client at the dev database. Internal-only when no port is configured.
109
105
  const services = [renderService("wordpress", wordpress), renderService("wp-cli", wpCli)]
110
106
  if (opts.dbPort) services.push(renderService("mysql", { ports: [`127.0.0.1:${opts.dbPort}:3306`] }))
111
107
 
@@ -0,0 +1,35 @@
1
+ import { PluginSource, TestAdminUser, TestUser } from "./types.js";
2
+
3
+ //#region src/cli/wp/constants.d.ts
4
+ declare const DEFAULT_PORT = 8080;
5
+ /** Build a GitHub release-zip URL for `PluginSource.source` (asset named `<tag>.zip`). */
6
+ declare function githubRelease(repo: string, tag: string): string;
7
+ /**
8
+ * Download URL for a Kizlo plugin's latest release, served by kizlo.io (it 302s to
9
+ * the current GitHub release asset). Always tracks the newest published version —
10
+ * use {@link githubRelease} instead to pin a specific tag.
11
+ */
12
+ declare function kizloRelease(slug: string): string;
13
+ /** The docker-compose file shipped alongside this module (in both `src/` and `dist/`). */
14
+ declare const COMPOSE_FILE: string;
15
+ /** Dev PHP OPcache config, shipped alongside this module and bind-mounted into the dev stack. */
16
+ declare const OPCACHE_INI: string;
17
+ /** Linux-only entrypoint that retags www-data to the host user (see the script for why). */
18
+ declare const REMAP_ENTRYPOINT: string;
19
+ declare const CONFIG_FILES: string[];
20
+ /** Credentials artifact location, relative to the config root. */
21
+ declare const CREDENTIALS_REL = ".kizlo/test-credentials.json";
22
+ /**
23
+ * DB-side marker written as the final bootstrap step and checked by `isSeeded`.
24
+ * It records that this database holds a completed bootstrap — independent of any
25
+ * fixture content, which is optional and varies per consumer. Bump `SEED_VERSION`
26
+ * to force a reseed when the bootstrap contract changes.
27
+ */
28
+ declare const SEED_MARKER_OPTION = "kizlo_test_seeded";
29
+ declare const SEED_VERSION = "1";
30
+ /** The kizlo core WordPress plugin, always installed during bootstrap. */
31
+ declare const DEFAULT_PLUGINS: PluginSource[];
32
+ declare const TEST_ADMIN: Omit<TestAdminUser, "id" | "applicationPassword">;
33
+ declare const TEST_USER: Omit<TestUser, "id">;
34
+ //#endregion
35
+ export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
@@ -1,9 +1,20 @@
1
- import { kizloRelease } from "./utils.js";
2
1
  import { dirname, resolve } from "node:path";
3
2
  import { fileURLToPath } from "node:url";
4
3
 
5
4
  //#region src/cli/wp/constants.ts
6
5
  const DEFAULT_PORT = 8080;
6
+ /** Build a GitHub release-zip URL for `PluginSource.source` (asset named `<tag>.zip`). */
7
+ function githubRelease(repo, tag) {
8
+ return `https://github.com/${repo}/releases/download/${tag}/${tag}.zip`;
9
+ }
10
+ /**
11
+ * Download URL for a Kizlo plugin's latest release, served by kizlo.io (it 302s to
12
+ * the current GitHub release asset). Always tracks the newest published version —
13
+ * use {@link githubRelease} instead to pin a specific tag.
14
+ */
15
+ function kizloRelease(slug) {
16
+ return `https://kizlo.io/plugins/${slug}/download`;
17
+ }
7
18
  const HERE = dirname(fileURLToPath(import.meta.url));
8
19
  /** The docker-compose file shipped alongside this module (in both `src/` and `dist/`). */
9
20
  const COMPOSE_FILE = resolve(HERE, "compose/docker-compose.yml");
@@ -48,4 +59,4 @@ const TEST_USER = {
48
59
  };
49
60
 
50
61
  //#endregion
51
- export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER };
62
+ export { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease };
@@ -1,18 +1,33 @@
1
1
  import { WordPressService } from "../../wordpress/service.js";
2
- import { compose, composeUp, wpCli } from "./docker.js";
3
2
  import { DEFAULT_PLUGINS, TEST_ADMIN } from "./constants.js";
3
+ import { compose, composeUp, wpCli } from "./docker.js";
4
4
  import { ensurePlugins } from "./utils.js";
5
5
  import { createAdminAppPassword, seedUsers } from "./bootstrap.js";
6
6
  import { prepareByo } from "./byo.js";
7
- import { existsSync, rmSync } from "node:fs";
8
7
  import { join } from "node:path";
8
+ import { existsSync, rmSync } from "node:fs";
9
9
  import { randomBytes } from "node:crypto";
10
+ import { networkInterfaces } from "node:os";
10
11
 
11
12
  //#region src/cli/wp/dev.ts
12
13
  /** A strong random admin password (144 bits, URL/JSON/CLI-safe characters). */
13
14
  function generatePassword() {
14
15
  return randomBytes(18).toString("base64url");
15
16
  }
17
+ /** First non-internal IPv4 address — the router-assigned LAN address (undefined when offline). */
18
+ function lanAddress() {
19
+ for (const ifaces of Object.values(networkInterfaces())) for (const iface of ifaces ?? []) if (iface.family === "IPv4" && !iface.internal) return iface.address;
20
+ }
21
+ /**
22
+ * The URL the dev stack is provisioned at. We prefer the router-assigned LAN address over `localhost`
23
+ * so it's reachable from off the host (the app in a container or on another device). Serving WordPress
24
+ * under the request host is already handled by the container's `WORDPRESS_CONFIG_EXTRA` (it derives
25
+ * `WP_HOME`/`WP_SITEURL` from `HTTP_HOST` per request), so this is only the address we write into `.env`
26
+ * and print. Falls back to `localhost` when the machine is offline, so bare local dev still works.
27
+ */
28
+ function devUrl(port) {
29
+ return `http://${lanAddress() ?? "localhost"}:${port}`;
30
+ }
16
31
  /**
17
32
  * Seed `dev.fixtures` into a freshly installed dev stack, reusing the test seeding
18
33
  * primitives: seed the default subscriber so `ctx.userId` exists, then run each `seed`
@@ -58,7 +73,7 @@ async function seedDevFixtures(cfg, url) {
58
73
  * concern.
59
74
  */
60
75
  async function bootstrapDev(cfg) {
61
- const url = `http://localhost:${cfg.port}`;
76
+ const url = devUrl(cfg.port);
62
77
  const byo = !existsSync(join(cfg.wordpressDir, "wp-includes", "version.php")) && cfg.byo ? await prepareByo(cfg.byo, cfg.wordpressDir, cfg.configDir) : void 0;
63
78
  await composeUp();
64
79
  const installed = (await compose([
@@ -1,8 +1,8 @@
1
1
  import { isLocalPlugin } from "./types.js";
2
2
  import { compose } from "./docker.js";
3
3
  import { log } from "../daemon/logger.js";
4
- import { existsSync } from "node:fs";
5
4
  import { basename, isAbsolute, resolve } from "node:path";
5
+ import { existsSync } from "node:fs";
6
6
 
7
7
  //#region src/cli/wp/phpunit.ts
8
8
  const PLUGINS_DIR = `/var/www/html/wp-content/plugins`;
@@ -1,7 +1,7 @@
1
- import { execFile, spawn } from "node:child_process";
2
- import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
1
  import { dirname, join } from "node:path";
4
2
  import { fileURLToPath } from "node:url";
3
+ import { execFile, spawn } from "node:child_process";
4
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import { promisify } from "node:util";
6
6
  import { homedir } from "node:os";
7
7
 
@@ -1,8 +1,8 @@
1
1
  import { WordPressService } from "../../wordpress/service.js";
2
2
  import { credentialsPath } from "./utils.js";
3
3
  import { bootstrapWp } from "./bootstrap.js";
4
- import { mkdirSync, writeFileSync } from "node:fs";
5
4
  import { dirname } from "node:path";
5
+ import { mkdirSync, writeFileSync } from "node:fs";
6
6
 
7
7
  //#region src/cli/wp/setup.ts
8
8
  /**
@@ -14,14 +14,6 @@ import { DevPluginSource, PluginSource, TestCredentials } from "./types.js";
14
14
  * Bumping `SEED_VERSION` invalidates older marks and forces a reseed.
15
15
  */
16
16
  declare function isSeeded(): Promise<boolean>;
17
- /** Build a GitHub release-zip URL for `PluginSource.source` (asset named `<tag>.zip`). */
18
- declare function githubRelease(repo: string, tag: string): string;
19
- /**
20
- * Download URL for a Kizlo plugin's latest release, served by kizlo.io (it 302s to
21
- * the current GitHub release asset). Always tracks the newest published version —
22
- * use {@link githubRelease} instead to pin a specific tag.
23
- */
24
- declare function kizloRelease(slug: string): string;
25
17
  /** Resolve a `PluginSource` to the `(name, source)` pair `ensurePlugin` needs. */
26
18
  declare function resolvePluginSource(plugin: PluginSource): [name: string, source: string];
27
19
  /**
@@ -63,4 +55,4 @@ declare function getTestCredentials(): TestCredentials;
63
55
  */
64
56
  declare function recordedPort(): number | undefined;
65
57
  //#endregion
66
- export { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isSeeded, kizloRelease, recordedPort, resolvePluginSource };
58
+ export { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource };
@@ -1,8 +1,8 @@
1
1
  import { isLocalPlugin } from "./types.js";
2
- import { compose, wpCli } from "./docker.js";
3
2
  import { CONFIG_FILES, CREDENTIALS_REL, SEED_MARKER_OPTION, SEED_VERSION } from "./constants.js";
4
- import { existsSync, readFileSync } from "node:fs";
3
+ import { compose, wpCli } from "./docker.js";
5
4
  import { basename, dirname, resolve } from "node:path";
5
+ import { existsSync, readFileSync } from "node:fs";
6
6
 
7
7
  //#region src/cli/wp/utils.ts
8
8
  /**
@@ -29,18 +29,6 @@ async function isSeeded() {
29
29
  ]);
30
30
  return marker.code === 0 && marker.stdout.trim() === SEED_VERSION;
31
31
  }
32
- /** Build a GitHub release-zip URL for `PluginSource.source` (asset named `<tag>.zip`). */
33
- function githubRelease(repo, tag) {
34
- return `https://github.com/${repo}/releases/download/${tag}/${tag}.zip`;
35
- }
36
- /**
37
- * Download URL for a Kizlo plugin's latest release, served by kizlo.io (it 302s to
38
- * the current GitHub release asset). Always tracks the newest published version —
39
- * use {@link githubRelease} instead to pin a specific tag.
40
- */
41
- function kizloRelease(slug) {
42
- return `https://kizlo.io/plugins/${slug}/download`;
43
- }
44
32
  /** Resolve a `PluginSource` to the `(name, source)` pair `ensurePlugin` needs. */
45
33
  function resolvePluginSource(plugin) {
46
34
  return typeof plugin === "string" ? [plugin, plugin] : [plugin.name, plugin.source];
@@ -160,4 +148,4 @@ function recordedPort() {
160
148
  }
161
149
 
162
150
  //#endregion
163
- export { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isSeeded, kizloRelease, recordedPort, resolvePluginSource };
151
+ export { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource };
package/dist/index.d.ts CHANGED
@@ -17,20 +17,19 @@ import "./wordpress/index.js";
17
17
  import { DevPluginSource, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, LocalPlugin, PluginSource, SeedContext, TestAdminUser, TestCredentials, TestUser, defineFixture, isLocalPlugin } from "./cli/wp/types.js";
18
18
  import { AuthAdapter, AuthGetUser, AuthUser, authMock, createAuthAdapter } from "./adapters/auth.js";
19
19
  import { CaptchaAdapter, altcha, arkose, createCaptchaAdapter, friendlyCaptcha, hcaptcha, recaptcha, turnstile } from "./adapters/captcha.js";
20
- import { CONTENT_TYPES, ContentType, ListSitemapUrlInput, ListSitemapUrlInputBase, Robots, RobotsRule, Seo, SeoHead, SeoSchema, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList } from "./seo/schema.js";
21
- import { WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapIndex, WPK_SitemapUrl, WPK_SitemapUrlImage } from "./seo/types.js";
22
- import { SitemapIndexEntry } from "./seo/utils.js";
23
20
  import { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder, Media, PreviewTokenData, PreviewTokenPayload } from "./shared/schema.js";
24
21
  import { AnyContext, AnyNestedClient, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, HTTPMethod, List, MaybeOptionalOptions, RedirectInput, RedirectStatus } from "./shared/types.js";
25
22
  import { createCookiesAdapter } from "./adapters/cookies.js";
26
23
  import { ConnInfo, GeoAdapter, GeoGetConnInfo, createGeoAdapter, geoMock } from "./adapters/geo.js";
27
24
  import { geoVercelNext } from "./adapters/geo.vercel.js";
28
25
  import { ConsoleLogAdapterOptions, Environment, LogLevel, LogPayload, Logger, LoggerAdapter, consoleLog, createLoggerAdapter, noopAdapter } from "./adapters/logger.js";
29
- import { AuthorsSettings, AuthorsSettingsInput, BrandSettings, BrandSettingsInput, CrawlingSettings, CrawlingSettingsInput, IdentitySettings, IdentitySettingsInput, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, PersonSettings, PersonSettingsInput, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, Settings, SiteSettings, SiteSettingsInput, SocialProfile, TaxonomySettings, TaxonomySettingsInput, WebhookSettings, WebhookSettingsInput } from "./settings/service.interface.js";
26
+ import { AuthorsSettings, AuthorsSettingsInput, BrandSettings, BrandSettingsInput, CrawlingSettings, CrawlingSettingsInput, IdentitySettings, IdentitySettingsInput, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, PersonSettings, PersonSettingsInput, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, Settings, SiteSettings, SiteSettingsInput, SocialProfile, TaxonomySettings, TaxonomySettingsInput, UploadsSettings, UploadsSettingsInput, WebhookSettings, WebhookSettingsInput } from "./settings/service.interface.js";
30
27
  import { IconDescriptor, ManifestIcon, ResolvedIcons, resolveIcons } from "./brand/icons.js";
28
+ import { CookiesStorage } from "./cookie.js";
31
29
  import { SettingsService } from "./settings/service.js";
32
30
  import { Service, ServiceConfig } from "./service.js";
33
31
  import { AuthUserFn, ConnInfoFn, Context, ContextConfig, ServerContext, VerifyCaptchaFn, VerifyPreviewTokenFn } from "./context.js";
32
+ import { ROUTER_MAP, RouterMap } from "./router.js";
34
33
  import { AnyEventSchema, AnyEvents, EventHandler, EventHandlerFn, InferEventUnion, WebhookOptions, createEventHandler, createWebhookRouter } from "./webhook/index.js";
35
34
  import { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorMapLike, ErrorDefinition, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError } from "./shared/error.js";
36
35
  import { AnyMiddleware, ExtractMiddlewareContextOutput, InferUses, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, createMiddleware } from "./shared/middleware.js";
@@ -40,10 +39,13 @@ import { AnyKizloConfig, CreateKizloOptions, Kizlo, KizloConfig, KizloTarget, Ro
40
39
  import { WEB_MANIFEST_ROUTE, WebManifest, buildWebManifest, createManifestRoute } from "./brand/manifest.js";
41
40
  import "./brand/index.js";
42
41
  import { KizloClient, KizloClientConfig, createKizloClient } from "./client.js";
42
+ import { CONTENT_TYPES, ContentType, ListSitemapUrlInput, ListSitemapUrlInputBase, Robots, RobotsRule, Seo, SeoHead, SeoSchema, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList } from "./seo/schema.js";
43
+ import { WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapIndex, WPK_SitemapUrl, WPK_SitemapUrlImage } from "./seo/types.js";
44
+ import { SitemapIndexEntry, deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse } from "./seo/utils.js";
43
45
  import { CreateSitemapRouteOptions, SITEMAP_BASE, SITEMAP_INDEX_SLUG, SitemapRouteExtra, createSitemapRoute } from "./seo/sitemap.js";
44
46
  import { Contract, ContractProcedure, generateContract, isContractProcedure, restoreContract } from "./shared/contract.js";
45
47
  import { ShaAlgorithm, compare, hash, hmac } from "./shared/crypto.js";
46
48
  import { Identifier, parseIdentifier } from "./shared/identifier.js";
47
49
  import { createOrpcRouter } from "./shared/router.js";
48
50
  import { deserializeCurrencyFormat, deserializeListMetadata, emptyList, serializeCurrencyFormat } from "./shared/serialize.js";
49
- export { AnyContext, AnyEventSchema, AnyEvents, AnyExtension, AnyKizloConfig, AnyMiddleware, AnyNestedClient, AnyProcedure, AnyProcedureRouter, AuthAdapter, AuthGetUser, AuthUser, AuthUserFn, AuthorsSettings, AuthorsSettingsInput, BaseHandlerOptions, BrandSettings, BrandSettingsInput, CART_HASH_HEADER_KEY, COMMON_ERRORS, CONTENT_TYPES, CaptchaAdapter, CommentService, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, ConnInfo, ConnInfoFn, ConsoleLogAdapterOptions, ContentType, Context, ContextConfig, Contract, ContractProcedure, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, CrawlingSettings, CrawlingSettingsInput, CreateKizloOptions, CreateSitemapRouteOptions, CurrencyFormat, DefinedErrorMapLike, DevPluginSource, Environment, ErrorDefinition, EventHandler, EventHandlerFn, Extension, ExtensionInitFn, ExtensionInitOptions, ExtensionInitResult, ExtractExtensionRouter, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, Fixture, FixtureCleanupFn, FixtureSeedFn, GeoAdapter, GeoGetConnInfo, HTTPMethod, IconDescriptor, Identifier, IdentifierInput, IdentitySettings, IdentitySettingsInput, InferEventUnion, InferExtensionRouter, InferUses, InvocationScope, JsonValue, Kizlo, KizloClient, KizloClientConfig, KizloConfig, KizloError, KizloErrorOptions, KizloTarget, LIST_ORDER, List, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, LocalPlugin, LogLevel, LogPayload, Logger, LoggerAdapter, ManifestIcon, MaybeOptionalOptions, Media, MenuItemService, MenuService, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, PersonSettings, PersonSettingsInput, PluginSource, PostService, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, PreviewTokenData, PreviewTokenPayload, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureOptions, RedirectInput, RedirectStatus, ResolveParamsPart, ResolvedIcons, ResolvedSchemaInput, ResolvedSchemaOutput, Robots, RobotsRule, RootRouter, RouterDepthTuple, S2SClient, SAFE_REQUEST_TIMEOUT, SITEMAP_BASE, SITEMAP_INDEX_SLUG, SchemaIO, SeedContext, Seo, SeoHead, SeoSchema, ServerContext, Service, ServiceAdapters, ServiceConfig, Settings, SettingsService, ShaAlgorithm, SiteSettings, SiteSettingsInput, Sitemap, SitemapIndex, type SitemapIndexEntry, SitemapList, SitemapRouteExtra, SitemapUrl, SitemapUrlImage, SitemapUrlList, SocialProfile, TaxonomySettings, TaxonomySettingsInput, TestAdminUser, TestCredentials, TestUser, ThrowableErrorFn, ThrowableErrorMap, UNEXPECTED_BODY_SNIPPET_LENGTH, UserService, VerifyCaptchaFn, VerifyPreviewTokenFn, WC_CORE_BASE, WC_STORE_BASE, WEB_MANIFEST_ROUTE, WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapIndex, WPK_SitemapUrl, WPK_SitemapUrlImage, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE, WP_CORE_BASE, WP_Comment, WP_CommentAvatarUrls, WP_CommentContent, WP_CommentContentInput, WP_CommentCreateErrorCode, WP_CommentCreateInput, WP_CommentDeleteErrorCode, WP_CommentDeleteInput, WP_CommentDeleteResponse, WP_CommentLinks, WP_CommentListErrorCode, WP_CommentListInput, WP_CommentOrderBy, WP_CommentRetrieveErrorCode, WP_CommentRetrieveInput, WP_CommentStatus, WP_CommentStatusFilter, WP_CommentStatusInput, WP_CommentType, WP_CommentUpdateErrorCode, WP_CommentUpdateInput, WP_CommonErrorCode, WP_Context, WP_CurrencyFormat, WP_Error, WP_ErrorData, WP_KIZLO_BASE, WP_Link, WP_List, WP_ListMetadata, WP_ListOrder, WP_Menu, WP_MenuCreateErrorCode, WP_MenuCreateInput, WP_MenuDeleteErrorCode, WP_MenuDeleteInput, WP_MenuDeleteResponse, WP_MenuItem, WP_MenuItemCreateErrorCode, WP_MenuItemCreateInput, WP_MenuItemDeleteErrorCode, WP_MenuItemDeleteInput, WP_MenuItemDeleteResponse, WP_MenuItemLinks, WP_MenuItemListErrorCode, WP_MenuItemListInput, WP_MenuItemOrderBy, WP_MenuItemRetrieveErrorCode, WP_MenuItemRetrieveInput, WP_MenuItemStatus, WP_MenuItemStatusFilter, WP_MenuItemTarget, WP_MenuItemTaxRelation, WP_MenuItemTitle, WP_MenuItemTitleInput, WP_MenuItemType, WP_MenuItemUpdateErrorCode, WP_MenuItemUpdateInput, WP_MenuLinks, WP_MenuListErrorCode, WP_MenuListInput, WP_MenuOrderBy, WP_MenuRetrieveErrorCode, WP_MenuRetrieveInput, WP_MenuUpdateErrorCode, WP_MenuUpdateInput, WP_Post, WP_PostCommentStatus, WP_PostContent, WP_PostContentInput, WP_PostCreateErrorCode, WP_PostCreateInput, WP_PostDeleteErrorCode, WP_PostDeleteInput, WP_PostDeleteResponse, WP_PostExcerpt, WP_PostExcerptInput, WP_PostFormat, WP_PostGuid, WP_PostLinks, WP_PostListErrorCode, WP_PostListInput, WP_PostOrderBy, WP_PostRetrieveErrorCode, WP_PostRetrieveInput, WP_PostStatus, WP_PostStatusFilter, WP_PostTaxRelation, WP_PostTitle, WP_PostTitleInput, WP_PostUpdateErrorCode, WP_PostUpdateInput, WP_RequestInput, WP_Result, WP_User, WP_UserAvatarUrls, WP_UserCapabilities, WP_UserCreateErrorCode, WP_UserCreateInput, WP_UserDeleteErrorCode, WP_UserDeleteInput, WP_UserDeleteMeErrorCode, WP_UserDeleteMeInput, WP_UserDeleteMeResponse, WP_UserDeleteResponse, WP_UserLinks, WP_UserListErrorCode, WP_UserListInput, WP_UserOrderBy, WP_UserRetrieveErrorCode, WP_UserRetrieveInput, WP_UserRetrieveMeErrorCode, WP_UserRetrieveMeInput, WP_UserUpdateErrorCode, WP_UserUpdateInput, WP_UserUpdateMeErrorCode, WP_UserUpdateMeInput, WP_UserWho, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressCredentials, WordPressService, altcha, arkose, authMock, buildProcedure, buildWebManifest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createExtension, createGeoAdapter, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, noopAdapter, parseIdentifier, recaptcha, resolveIcons, resolveKizloConfig, restoreContract, schemaType, serializeCurrencyFormat, toKizloError, turnstile };
51
+ export { AnyContext, AnyEventSchema, AnyEvents, AnyExtension, AnyKizloConfig, AnyMiddleware, AnyNestedClient, AnyProcedure, AnyProcedureRouter, AuthAdapter, AuthGetUser, AuthUser, AuthUserFn, AuthorsSettings, AuthorsSettingsInput, BaseHandlerOptions, BrandSettings, BrandSettingsInput, CART_HASH_HEADER_KEY, COMMON_ERRORS, CONTENT_TYPES, CaptchaAdapter, CommentService, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, ConnInfo, ConnInfoFn, ConsoleLogAdapterOptions, ContentType, Context, ContextConfig, Contract, ContractProcedure, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, CookiesStorage, CrawlingSettings, CrawlingSettingsInput, CreateKizloOptions, CreateSitemapRouteOptions, CurrencyFormat, DefinedErrorMapLike, DevPluginSource, Environment, ErrorDefinition, EventHandler, EventHandlerFn, Extension, ExtensionInitFn, ExtensionInitOptions, ExtensionInitResult, ExtractExtensionRouter, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, Fixture, FixtureCleanupFn, FixtureSeedFn, GeoAdapter, GeoGetConnInfo, HTTPMethod, IconDescriptor, Identifier, IdentifierInput, IdentitySettings, IdentitySettingsInput, InferEventUnion, InferExtensionRouter, InferUses, InvocationScope, JsonValue, Kizlo, KizloClient, KizloClientConfig, KizloConfig, KizloError, KizloErrorOptions, KizloTarget, LIST_ORDER, List, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, LocalPlugin, LogLevel, LogPayload, Logger, LoggerAdapter, ManifestIcon, MaybeOptionalOptions, Media, MenuItemService, MenuService, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, PersonSettings, PersonSettingsInput, PluginSource, PostService, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, PreviewTokenData, PreviewTokenPayload, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureOptions, ROUTER_MAP, RedirectInput, RedirectStatus, ResolveParamsPart, ResolvedIcons, ResolvedSchemaInput, ResolvedSchemaOutput, Robots, RobotsRule, RootRouter, RouterDepthTuple, RouterMap, S2SClient, SAFE_REQUEST_TIMEOUT, SITEMAP_BASE, SITEMAP_INDEX_SLUG, SchemaIO, SeedContext, Seo, SeoHead, SeoSchema, ServerContext, Service, ServiceAdapters, ServiceConfig, Settings, SettingsService, ShaAlgorithm, SiteSettings, SiteSettingsInput, Sitemap, SitemapIndex, SitemapIndexEntry, SitemapList, SitemapRouteExtra, SitemapUrl, SitemapUrlImage, SitemapUrlList, SocialProfile, TaxonomySettings, TaxonomySettingsInput, TestAdminUser, TestCredentials, TestUser, ThrowableErrorFn, ThrowableErrorMap, UNEXPECTED_BODY_SNIPPET_LENGTH, UploadsSettings, UploadsSettingsInput, UserService, VerifyCaptchaFn, VerifyPreviewTokenFn, WC_CORE_BASE, WC_STORE_BASE, WEB_MANIFEST_ROUTE, WPK_ListSitemapUrlInput, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapContentType, WPK_SitemapIndex, WPK_SitemapUrl, WPK_SitemapUrlImage, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE, WP_CORE_BASE, WP_Comment, WP_CommentAvatarUrls, WP_CommentContent, WP_CommentContentInput, WP_CommentCreateErrorCode, WP_CommentCreateInput, WP_CommentDeleteErrorCode, WP_CommentDeleteInput, WP_CommentDeleteResponse, WP_CommentLinks, WP_CommentListErrorCode, WP_CommentListInput, WP_CommentOrderBy, WP_CommentRetrieveErrorCode, WP_CommentRetrieveInput, WP_CommentStatus, WP_CommentStatusFilter, WP_CommentStatusInput, WP_CommentType, WP_CommentUpdateErrorCode, WP_CommentUpdateInput, WP_CommonErrorCode, WP_Context, WP_CurrencyFormat, WP_Error, WP_ErrorData, WP_KIZLO_BASE, WP_Link, WP_List, WP_ListMetadata, WP_ListOrder, WP_Menu, WP_MenuCreateErrorCode, WP_MenuCreateInput, WP_MenuDeleteErrorCode, WP_MenuDeleteInput, WP_MenuDeleteResponse, WP_MenuItem, WP_MenuItemCreateErrorCode, WP_MenuItemCreateInput, WP_MenuItemDeleteErrorCode, WP_MenuItemDeleteInput, WP_MenuItemDeleteResponse, WP_MenuItemLinks, WP_MenuItemListErrorCode, WP_MenuItemListInput, WP_MenuItemOrderBy, WP_MenuItemRetrieveErrorCode, WP_MenuItemRetrieveInput, WP_MenuItemStatus, WP_MenuItemStatusFilter, WP_MenuItemTarget, WP_MenuItemTaxRelation, WP_MenuItemTitle, WP_MenuItemTitleInput, WP_MenuItemType, WP_MenuItemUpdateErrorCode, WP_MenuItemUpdateInput, WP_MenuLinks, WP_MenuListErrorCode, WP_MenuListInput, WP_MenuOrderBy, WP_MenuRetrieveErrorCode, WP_MenuRetrieveInput, WP_MenuUpdateErrorCode, WP_MenuUpdateInput, WP_Post, WP_PostCommentStatus, WP_PostContent, WP_PostContentInput, WP_PostCreateErrorCode, WP_PostCreateInput, WP_PostDeleteErrorCode, WP_PostDeleteInput, WP_PostDeleteResponse, WP_PostExcerpt, WP_PostExcerptInput, WP_PostFormat, WP_PostGuid, WP_PostLinks, WP_PostListErrorCode, WP_PostListInput, WP_PostOrderBy, WP_PostRetrieveErrorCode, WP_PostRetrieveInput, WP_PostStatus, WP_PostStatusFilter, WP_PostTaxRelation, WP_PostTitle, WP_PostTitleInput, WP_PostUpdateErrorCode, WP_PostUpdateInput, WP_RequestInput, WP_Result, WP_User, WP_UserAvatarUrls, WP_UserCapabilities, WP_UserCreateErrorCode, WP_UserCreateInput, WP_UserDeleteErrorCode, WP_UserDeleteInput, WP_UserDeleteMeErrorCode, WP_UserDeleteMeInput, WP_UserDeleteMeResponse, WP_UserDeleteResponse, WP_UserLinks, WP_UserListErrorCode, WP_UserListInput, WP_UserOrderBy, WP_UserRetrieveErrorCode, WP_UserRetrieveInput, WP_UserRetrieveMeErrorCode, WP_UserRetrieveMeInput, WP_UserUpdateErrorCode, WP_UserUpdateInput, WP_UserUpdateMeErrorCode, WP_UserUpdateMeInput, WP_UserWho, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressCredentials, WordPressService, altcha, arkose, authMock, buildProcedure, buildWebManifest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createExtension, createGeoAdapter, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, noopAdapter, parseIdentifier, parseSitemapSlug, recaptcha, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, toKizloError, turnstile, xmlResponse };
package/dist/index.js CHANGED
@@ -14,6 +14,7 @@ import { createOrpcRouter } from "./shared/router.js";
14
14
  import { generateContract, isContractProcedure, restoreContract } from "./shared/contract.js";
15
15
  import { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder, Media, PreviewTokenData, PreviewTokenPayload } from "./shared/schema.js";
16
16
  import { KizloClient, createKizloClient } from "./client.js";
17
+ import { CookiesStorage } from "./cookie.js";
17
18
  import { CART_HASH_HEADER_KEY, SAFE_REQUEST_TIMEOUT, UNEXPECTED_BODY_SNIPPET_LENGTH, WC_CORE_BASE, WC_STORE_BASE, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE, WP_CORE_BASE, WP_KIZLO_BASE } from "./wordpress/constants.js";
18
19
  import { CommentService } from "./wordpress/comment/service.js";
19
20
  import { WP_Error } from "./wordpress/error.js";
@@ -29,10 +30,12 @@ import { Context } from "./context.js";
29
30
  import { deserializeCurrencyFormat, deserializeListMetadata, emptyList, serializeCurrencyFormat } from "./shared/serialize.js";
30
31
  import { parseIdentifier } from "./shared/identifier.js";
31
32
  import { CONTENT_TYPES, ContentType, ListSitemapUrlInput, ListSitemapUrlInputBase, Robots, RobotsRule, Seo, SeoHead, SeoSchema, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList } from "./seo/schema.js";
33
+ import { deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse } from "./seo/utils.js";
34
+ import { ROUTER_MAP } from "./router.js";
32
35
  import { createEventHandler, createWebhookRouter } from "./webhook/index.js";
33
36
  import { Kizlo, createKizlo, resolveKizloConfig } from "./kizlo.js";
34
37
  import { SITEMAP_BASE, SITEMAP_INDEX_SLUG, createSitemapRoute } from "./seo/sitemap.js";
35
38
  import { createExtension } from "./shared/extension.js";
36
39
  import { createMiddleware } from "./shared/middleware.js";
37
40
 
38
- export { CART_HASH_HEADER_KEY, COMMON_ERRORS, CONTENT_TYPES, CommentService, ContentType, Context, CurrencyFormat, IdentifierInput, Kizlo, KizloClient, KizloError, LIST_ORDER, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, Media, MenuItemService, MenuService, PostService, PreviewTokenData, PreviewTokenPayload, Robots, RobotsRule, SAFE_REQUEST_TIMEOUT, SITEMAP_BASE, SITEMAP_INDEX_SLUG, Seo, SeoHead, SeoSchema, Service, SettingsService, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList, UNEXPECTED_BODY_SNIPPET_LENGTH, UserService, WC_CORE_BASE, WC_STORE_BASE, WEB_MANIFEST_ROUTE, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE, WP_CORE_BASE, WP_Error, WP_KIZLO_BASE, WordPressService, altcha, arkose, authMock, buildProcedure, buildWebManifest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createExtension, createGeoAdapter, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, noopAdapter, parseIdentifier, recaptcha, resolveIcons, resolveKizloConfig, restoreContract, schemaType, serializeCurrencyFormat, toKizloError, turnstile };
41
+ export { CART_HASH_HEADER_KEY, COMMON_ERRORS, CONTENT_TYPES, CommentService, ContentType, Context, CookiesStorage, CurrencyFormat, IdentifierInput, Kizlo, KizloClient, KizloError, LIST_ORDER, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, Media, MenuItemService, MenuService, PostService, PreviewTokenData, PreviewTokenPayload, ROUTER_MAP, Robots, RobotsRule, SAFE_REQUEST_TIMEOUT, SITEMAP_BASE, SITEMAP_INDEX_SLUG, Seo, SeoHead, SeoSchema, Service, SettingsService, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList, UNEXPECTED_BODY_SNIPPET_LENGTH, UserService, WC_CORE_BASE, WC_STORE_BASE, WEB_MANIFEST_ROUTE, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE, WP_CORE_BASE, WP_Error, WP_KIZLO_BASE, WordPressService, altcha, arkose, authMock, buildProcedure, buildWebManifest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createExtension, createGeoAdapter, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, noopAdapter, parseIdentifier, parseSitemapSlug, recaptcha, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, toKizloError, turnstile, xmlResponse };
@@ -1,17 +1,10 @@
1
1
  import { WEB_MANIFEST_ROUTE, createManifestRoute } from "../../brand/manifest.js";
2
+ import { createCachedTextRoute } from "./utils.js";
2
3
 
3
4
  //#region src/integrations/nextjs/manifest.ts
4
5
  const MANIFEST_CACHE_TAG = "kizlo:manifest";
5
6
  function createManifestRoute$1(client) {
6
- const handler = createManifestRoute(client);
7
- let getBody;
8
- return async function GET(request) {
9
- if (!getBody) {
10
- const { unstable_cache } = await import("next/cache");
11
- getBody = unstable_cache(async () => (await handler(request)).text(), [MANIFEST_CACHE_TAG], { tags: [MANIFEST_CACHE_TAG] });
12
- }
13
- return new Response(await getBody(), { headers: { "Content-Type": "application/manifest+json" } });
14
- };
7
+ return createCachedTextRoute(createManifestRoute(client), MANIFEST_CACHE_TAG, "application/manifest+json");
15
8
  }
16
9
 
17
10
  //#endregion
@@ -1,5 +1,5 @@
1
- import { SeoHead } from "../../seo/schema.js";
2
1
  import { S2SClient } from "../../kizlo.js";
2
+ import { SeoHead } from "../../seo/schema.js";
3
3
  import { Metadata, Viewport } from "next";
4
4
 
5
5
  //#region src/integrations/nextjs/metadata.d.ts
@@ -45,8 +45,7 @@ function toNextIcon(icon) {
45
45
  return {
46
46
  url: icon.url,
47
47
  type: icon.type,
48
- sizes: icon.sizes,
49
- media: icon.media
48
+ sizes: icon.sizes
50
49
  };
51
50
  }
52
51
  function createPageMetadata(head) {
@@ -1,4 +1,6 @@
1
1
  import { KizloEvent } from "../../webhook/schema.js";
2
+ import { AnyProcedureRouter } from "../../shared/procedure.js";
3
+ import { Extension } from "../../shared/extension.js";
2
4
  import "../../index.js";
3
5
  import { Pathname } from "@kizlo/shared";
4
6
 
@@ -24,5 +26,6 @@ interface NextRevalidateOptions {
24
26
  */
25
27
  sitemap?: false | RevalidateTarget | RevalidateTarget[];
26
28
  }
29
+ declare function nextRevalidation(options?: NextRevalidateOptions): Extension<"nextjs-revalidation", AnyProcedureRouter>;
27
30
  //#endregion
28
- export { NextRevalidateOptions };
31
+ export { NextRevalidateOptions, RevalidatePathFn, RevalidateTagFn, RevalidateTarget, nextRevalidation };
@@ -1,6 +1,7 @@
1
1
  import { S2SClient } from "../../kizlo.js";
2
2
 
3
3
  //#region src/integrations/nextjs/robots.d.ts
4
+ declare const ROBOTS_CACHE_TAG = "kizlo:robots";
4
5
  declare function createRobotsRoute(client: S2SClient<[]>): (request: Request) => Promise<Response>;
5
6
  //#endregion
6
- export { createRobotsRoute };
7
+ export { ROBOTS_CACHE_TAG, createRobotsRoute };
@@ -1,17 +1,10 @@
1
+ import { createCachedTextRoute } from "./utils.js";
1
2
  import { createRobotsRoute } from "../../seo/robots.js";
2
3
 
3
4
  //#region src/integrations/nextjs/robots.ts
4
5
  const ROBOTS_CACHE_TAG = "kizlo:robots";
5
6
  function createRobotsRoute$1(client) {
6
- const handler = createRobotsRoute(client);
7
- let getBody;
8
- return async function GET(request) {
9
- if (!getBody) {
10
- const { unstable_cache } = await import("next/cache");
11
- getBody = unstable_cache(async () => (await handler(request)).text(), [ROBOTS_CACHE_TAG], { tags: [ROBOTS_CACHE_TAG] });
12
- }
13
- return new Response(await getBody(), { headers: { "Content-Type": "text/plain; charset=utf-8" } });
14
- };
7
+ return createCachedTextRoute(createRobotsRoute(client), ROBOTS_CACHE_TAG, "text/plain; charset=utf-8");
15
8
  }
16
9
 
17
10
  //#endregion
@@ -0,0 +1,13 @@
1
+ import { CookiesAdapter } from "../../shared/types.js";
2
+
3
+ //#region src/integrations/nextjs/utils.d.ts
4
+ declare function createNextCookiesInterface(): CookiesAdapter;
5
+ /**
6
+ * Wrap a core route handler in a lazily-initialised `unstable_cache` keyed by
7
+ * `cacheTag`, serving the handler's text body with a fixed `Content-Type`. The
8
+ * cache import is deferred so the module stays loadable outside a Next request.
9
+ */
10
+ declare function createCachedTextRoute(handler: (request: Request) => Promise<Response>, cacheTag: string, contentType: string): (request: Request) => Promise<Response>;
11
+ declare function getServerBaseUrl(): string;
12
+ //#endregion
13
+ export { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl };
@@ -1,6 +1,43 @@
1
1
  import { KizloError } from "../../shared/error.js";
2
2
 
3
3
  //#region src/integrations/nextjs/utils.ts
4
+ function createNextCookiesInterface() {
5
+ return {
6
+ getAll: async () => {
7
+ const cookies = (await import("next/headers")).cookies;
8
+ return (await cookies()).getAll();
9
+ },
10
+ setAll: async (cookieList) => {
11
+ const cookies = (await import("next/headers")).cookies;
12
+ const cookieJar = await cookies();
13
+ try {
14
+ for (const cookie of cookieList) cookieJar.set(cookie.name, cookie.value, cookie.options);
15
+ } catch {}
16
+ },
17
+ deleteAll: async (cookieList) => {
18
+ const cookies = (await import("next/headers")).cookies;
19
+ const cookieJar = await cookies();
20
+ try {
21
+ for (const cookie of cookieList) cookieJar.delete(cookie.name);
22
+ } catch {}
23
+ }
24
+ };
25
+ }
26
+ /**
27
+ * Wrap a core route handler in a lazily-initialised `unstable_cache` keyed by
28
+ * `cacheTag`, serving the handler's text body with a fixed `Content-Type`. The
29
+ * cache import is deferred so the module stays loadable outside a Next request.
30
+ */
31
+ function createCachedTextRoute(handler, cacheTag, contentType) {
32
+ let getBody;
33
+ return async function GET(request) {
34
+ if (!getBody) {
35
+ const { unstable_cache } = await import("next/cache");
36
+ getBody = unstable_cache(async () => (await handler(request)).text(), [cacheTag], { tags: [cacheTag] });
37
+ }
38
+ return new Response(await getBody(), { headers: { "Content-Type": contentType } });
39
+ };
40
+ }
4
41
  function getServerBaseUrl() {
5
42
  const baseUrl = process.env.NEXT_PUBLIC_KIZLO_BACKEND_URL;
6
43
  if (!baseUrl) throw new KizloError("MISSING_ENV_VARIABLE", { message: "Please define NEXT_PUBLIC_KIZLO_BACKEND_URL in your .env file." });
@@ -8,4 +45,4 @@ function getServerBaseUrl() {
8
45
  }
9
46
 
10
47
  //#endregion
11
- export { getServerBaseUrl };
48
+ export { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl };
@@ -1,7 +1,9 @@
1
1
  import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
2
- import { createRootMetadata, createRootViewport } from "../integrations/nextjs/metadata.js";
2
+ import { NextRevalidateOptions, RevalidatePathFn, RevalidateTagFn, RevalidateTarget, nextRevalidation } from "../integrations/nextjs/revalidate.js";
3
3
  import { KizloServerOptions, createKizlo } from "../integrations/nextjs/kizlo.server.js";
4
4
  import { MANIFEST_CACHE_TAG, createManifestRoute } from "../integrations/nextjs/manifest.js";
5
- import { createRobotsRoute } from "../integrations/nextjs/robots.js";
5
+ import { createPageMetadata, createRootMetadata, createRootViewport } from "../integrations/nextjs/metadata.js";
6
+ import { ROBOTS_CACHE_TAG, createRobotsRoute } from "../integrations/nextjs/robots.js";
6
7
  import { SITEMAP_CACHE_TAG, SITEMAP_ROUTE, createSitemapRoute } from "../integrations/nextjs/sitemap.js";
7
- export { KizloServerOptions, MANIFEST_CACHE_TAG, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createKizlo, createManifestRoute, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRoute };
8
+ import { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl } from "../integrations/nextjs/utils.js";
9
+ export { KizloServerOptions, MANIFEST_CACHE_TAG, NextRevalidateOptions, ROBOTS_CACHE_TAG, RevalidatePathFn, RevalidateTagFn, RevalidateTarget, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createCachedTextRoute, createKizlo, createManifestRoute, createNextCookiesInterface, createPageMetadata, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRoute, getServerBaseUrl, nextRevalidation };
@@ -1,8 +1,10 @@
1
1
  import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
2
- import { createRootMetadata, createRootViewport } from "../integrations/nextjs/metadata.js";
3
- import { createRobotsRoute } from "../integrations/nextjs/robots.js";
2
+ import { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl } from "../integrations/nextjs/utils.js";
3
+ import { ROBOTS_CACHE_TAG, createRobotsRoute } from "../integrations/nextjs/robots.js";
4
4
  import { SITEMAP_CACHE_TAG, SITEMAP_ROUTE, createSitemapRoute } from "../integrations/nextjs/sitemap.js";
5
+ import { nextRevalidation } from "../integrations/nextjs/revalidate.js";
5
6
  import { createKizlo } from "../integrations/nextjs/kizlo.server.js";
6
7
  import { MANIFEST_CACHE_TAG, createManifestRoute } from "../integrations/nextjs/manifest.js";
8
+ import { createPageMetadata, createRootMetadata, createRootViewport } from "../integrations/nextjs/metadata.js";
7
9
 
8
- export { MANIFEST_CACHE_TAG, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createKizlo, createManifestRoute, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRoute };
10
+ export { MANIFEST_CACHE_TAG, ROBOTS_CACHE_TAG, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createCachedTextRoute, createKizlo, createManifestRoute, createNextCookiesInterface, createPageMetadata, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRoute, getServerBaseUrl, nextRevalidation };
package/dist/nextjs.d.ts CHANGED
@@ -1,3 +1,2 @@
1
1
  import { KizloClientOptions, createKizloClient } from "./integrations/nextjs/kizlo.client.js";
2
- import { createPageMetadata } from "./integrations/nextjs/metadata.js";
3
- export { KizloClientOptions, createKizloClient, createPageMetadata };
2
+ export { KizloClientOptions, createKizloClient };
package/dist/nextjs.js CHANGED
@@ -1,4 +1,3 @@
1
1
  import { createKizloClient } from "./integrations/nextjs/kizlo.client.js";
2
- import { createPageMetadata } from "./integrations/nextjs/metadata.js";
3
2
 
4
- export { createKizloClient, createPageMetadata };
3
+ export { createKizloClient };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.6.0";
2
+ var version = "0.7.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };
package/dist/router.d.ts CHANGED
@@ -167,7 +167,7 @@ declare const ROUTER_MAP: {
167
167
  include?: string | number | (string | number)[] | undefined;
168
168
  offset?: string | number | undefined;
169
169
  order?: "asc" | "desc" | undefined;
170
- orderby?: "date" | "id" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | undefined;
170
+ orderby?: "id" | "date" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | undefined;
171
171
  searchColumns?: string[] | undefined;
172
172
  slug?: string | string[] | undefined;
173
173
  taxRelation?: "AND" | "OR" | undefined;
@@ -433,7 +433,7 @@ declare const ROUTER_MAP: {
433
433
  include?: string | number | (string | number)[] | undefined;
434
434
  offset?: string | number | undefined;
435
435
  order?: "asc" | "desc" | undefined;
436
- orderby?: "date" | "id" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | "menu_order" | undefined;
436
+ orderby?: "id" | "date" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | "menu_order" | undefined;
437
437
  searchColumns?: string[] | undefined;
438
438
  slug?: string | string[] | undefined;
439
439
  taxRelation?: "AND" | "OR" | undefined;
@@ -504,7 +504,7 @@ declare const ROUTER_MAP: {
504
504
  include?: string | number | (string | number)[] | undefined;
505
505
  offset?: string | number | undefined;
506
506
  order?: "asc" | "desc" | undefined;
507
- orderby?: "date" | "id" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | "menu_order" | undefined;
507
+ orderby?: "id" | "date" | "slug" | "title" | "author" | "include" | "parent" | "relevance" | "include_slugs" | "menu_order" | undefined;
508
508
  searchColumns?: string[] | undefined;
509
509
  slug?: string | string[] | undefined;
510
510
  taxRelation?: "AND" | "OR" | undefined;
@@ -610,7 +610,7 @@ declare const ROUTER_MAP: {
610
610
  include?: string | number | (string | number)[] | undefined;
611
611
  offset?: string | number | undefined;
612
612
  order?: "asc" | "desc" | undefined;
613
- orderby?: "date" | "id" | "post" | "include" | "parent" | undefined;
613
+ orderby?: "id" | "date" | "post" | "include" | "parent" | undefined;
614
614
  parent?: string | number | (string | number)[] | undefined;
615
615
  parentExclude?: string | number | (string | number)[] | undefined;
616
616
  post?: string | number | (string | number)[] | undefined;
@@ -779,9 +779,7 @@ declare const ROUTER_MAP: {
779
779
  logo_wordmark?: number | null | undefined;
780
780
  logo_wordmark_dark?: number | null | undefined;
781
781
  favicon?: number | null | undefined;
782
- favicon_dark?: number | null | undefined;
783
- ios_app_icon?: number | null | undefined;
784
- android_app_icon?: number | null | undefined;
782
+ app_icon?: number | null | undefined;
785
783
  theme_color?: number | null | undefined;
786
784
  theme_color_dark?: number | null | undefined;
787
785
  background_color?: number | null | undefined;
@@ -821,6 +819,9 @@ declare const ROUTER_MAP: {
821
819
  taxonomies?: string[] | undefined;
822
820
  webhook_urls?: string[] | undefined;
823
821
  }, null, DefinedErrorMapLike>;
822
+ updateUploads: Procedure<"internal", {
823
+ allowed_mimes?: _kizlo_shared0.UploadMime[] | undefined;
824
+ }, null, DefinedErrorMapLike>;
824
825
  updatePostType: Procedure<"internal", {
825
826
  slug: string;
826
827
  data: {
@@ -854,4 +855,4 @@ declare const ROUTER_MAP: {
854
855
  };
855
856
  type RouterMap = typeof ROUTER_MAP;
856
857
  //#endregion
857
- export { RouterMap };
858
+ export { ROUTER_MAP, RouterMap };
@@ -1,6 +1,6 @@
1
+ import { S2SClient } from "../kizlo.js";
1
2
  import { SitemapUrl } from "./schema.js";
2
3
  import { SitemapIndexEntry } from "./utils.js";
3
- import { S2SClient } from "../kizlo.js";
4
4
 
5
5
  //#region src/seo/sitemap.d.ts
6
6
 
@@ -1,6 +1,16 @@
1
- import { Sitemap } from "./schema.js";
1
+ import { Seo, Sitemap, SitemapUrl } from "./schema.js";
2
+ import { WPK_Seo } from "./types.js";
2
3
 
3
4
  //#region src/seo/utils.d.ts
5
+ declare function deserializeSeo(data: WPK_Seo): Seo;
4
6
  type SitemapIndexEntry = Pick<Sitemap, "key" | "pages" | "lastmod">;
7
+ declare function sitemapEntryPath(key: string, page: number): string;
8
+ declare function parseSitemapSlug(slug: string): {
9
+ key: string;
10
+ page: number;
11
+ } | null;
12
+ declare function renderSitemapIndex(sitemaps: readonly SitemapIndexEntry[], origin: string): string;
13
+ declare function renderUrlSet(urls: SitemapUrl[]): string;
14
+ declare function xmlResponse(body: string): Response;
5
15
  //#endregion
6
- export { SitemapIndexEntry };
16
+ export { SitemapIndexEntry, deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
package/dist/seo/utils.js CHANGED
@@ -73,4 +73,4 @@ function xmlResponse(body) {
73
73
  }
74
74
 
75
75
  //#endregion
76
- export { deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, xmlResponse };
76
+ export { deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
@@ -52,6 +52,11 @@ const SETTINGS_ROUTER_MAP = {
52
52
  input: schemaType(),
53
53
  output: schemaType()
54
54
  }, async ({ context, input, errors }) => resolveUpdate(await context.service.settings.updateWebhook(input), context, errors, "Update webhook settings")),
55
+ updateUploads: createProcedure({
56
+ scope: "internal",
57
+ input: schemaType(),
58
+ output: schemaType()
59
+ }, async ({ context, input, errors }) => resolveUpdate(await context.service.settings.updateUploads(input), context, errors, "Update uploads settings")),
55
60
  updatePostType: createProcedure({
56
61
  scope: "internal",
57
62
  input: schemaType(),
@@ -1,5 +1,5 @@
1
1
  import { WP_Result } from "../wordpress/types.js";
2
- import { AuthorsSettingsInput, BrandSettingsInput, CrawlingSettingsInput, IdentitySettingsInput, PostTypeSettingsInput, Settings, SiteSettingsInput, TaxonomySettingsInput, WebhookSettingsInput } from "./service.interface.js";
2
+ import { AuthorsSettingsInput, BrandSettingsInput, CrawlingSettingsInput, IdentitySettingsInput, PostTypeSettingsInput, Settings, SiteSettingsInput, TaxonomySettingsInput, UploadsSettingsInput, WebhookSettingsInput } from "./service.interface.js";
3
3
  import { Service } from "../service.js";
4
4
  import "../index.js";
5
5
 
@@ -15,6 +15,7 @@ declare class SettingsService {
15
15
  updateIdentity(input: IdentitySettingsInput): Promise<WP_Result<null, "invalid_param">>;
16
16
  updateAuthors(input: AuthorsSettingsInput): Promise<WP_Result<null, "invalid_param">>;
17
17
  updateCrawling(input: CrawlingSettingsInput): Promise<WP_Result<null, "invalid_param">>;
18
+ updateUploads(input: UploadsSettingsInput): Promise<WP_Result<null, "invalid_param">>;
18
19
  updatePostType(slug: string, input: PostTypeSettingsInput): Promise<WP_Result<null, "invalid_param">>;
19
20
  updateTaxonomy(slug: string, input: TaxonomySettingsInput): Promise<WP_Result<null, "invalid_param">>;
20
21
  private update;
@@ -1,4 +1,4 @@
1
- import { AuthorsSettings, BrandSettings, CrawlingSettings, IdentitySettings, OrganizationFounder, OrganizationSettings, PersonSettings, PostStatusDefinition, PostTypeSettings, Settings, SiteSettings, SocialProfile, TaxonomySettings, WebhookSettings } from "@kizlo/shared";
1
+ import { AuthorsSettings, BrandSettings, CrawlingSettings, IdentitySettings, OrganizationFounder, OrganizationSettings, PersonSettings, PostStatusDefinition, PostTypeSettings, Settings, SiteSettings, SocialProfile, TaxonomySettings, UploadsSettings, WebhookSettings } from "@kizlo/shared";
2
2
 
3
3
  //#region src/settings/service.interface.d.ts
4
4
  type SiteSettingsInput = Partial<Omit<SiteSettings, "fallback_image"> & {
@@ -19,7 +19,8 @@ type IdentitySettingsInput = Partial<{
19
19
  }>;
20
20
  type AuthorsSettingsInput = Partial<AuthorsSettings>;
21
21
  type CrawlingSettingsInput = Partial<CrawlingSettings>;
22
+ type UploadsSettingsInput = Partial<UploadsSettings>;
22
23
  type PostTypeSettingsInput = Partial<Pick<PostTypeSettings, "title_structure" | "description_structure" | "search_engine_visibility" | "webpage_type" | "article_type" | "seo_enabled" | "pathname_structure" | "comment_action_structure" | "rest_api_enabled" | "publicly_queryable" | "breadcrumbs">>;
23
24
  type TaxonomySettingsInput = Partial<Pick<TaxonomySettings, "title_structure" | "description_structure" | "search_engine_visibility" | "seo_enabled" | "pathname_structure" | "rest_api_enabled" | "publicly_queryable" | "breadcrumbs">>;
24
25
  //#endregion
25
- export { type AuthorsSettings, AuthorsSettingsInput, type BrandSettings, BrandSettingsInput, type CrawlingSettings, CrawlingSettingsInput, type IdentitySettings, IdentitySettingsInput, type OrganizationFounder, type OrganizationSettings, OrganizationSettingsInput, type PersonSettings, PersonSettingsInput, type PostStatusDefinition, type PostTypeSettings, PostTypeSettingsInput, type Settings, type SiteSettings, SiteSettingsInput, type SocialProfile, type TaxonomySettings, TaxonomySettingsInput, type WebhookSettings, WebhookSettingsInput };
26
+ export { type AuthorsSettings, AuthorsSettingsInput, type BrandSettings, BrandSettingsInput, type CrawlingSettings, CrawlingSettingsInput, type IdentitySettings, IdentitySettingsInput, type OrganizationFounder, type OrganizationSettings, OrganizationSettingsInput, type PersonSettings, PersonSettingsInput, type PostStatusDefinition, type PostTypeSettings, PostTypeSettingsInput, type Settings, type SiteSettings, SiteSettingsInput, type SocialProfile, type TaxonomySettings, TaxonomySettingsInput, type UploadsSettings, UploadsSettingsInput, type WebhookSettings, WebhookSettingsInput };
@@ -28,6 +28,9 @@ var SettingsService = class {
28
28
  async updateCrawling(input) {
29
29
  return this.update("/settings/crawling", input);
30
30
  }
31
+ async updateUploads(input) {
32
+ return this.update("/settings/uploads", input);
33
+ }
31
34
  async updatePostType(slug, input) {
32
35
  return this.update(`/settings/post_types/${slug}`, input);
33
36
  }
package/dist/test.d.ts CHANGED
@@ -1,6 +1,7 @@
1
- import { DockerStack, RunResult, Stack, compose, composeDown, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
2
1
  import { DevPluginSource, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, LocalPlugin, PluginSource, SeedContext, TestAdminUser, TestCredentials, TestUser, defineFixture, isLocalPlugin } from "./cli/wp/types.js";
3
- import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isSeeded, kizloRelease, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
2
+ import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
3
+ import { DockerStack, RunResult, Stack, compose, composeDown, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
4
+ import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
4
5
  import { TestAuthAdapterUser, toTestUser } from "./test/users.js";
5
6
  import { testAuthAdapter } from "./test/auth.js";
6
7
  import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
@@ -9,4 +10,4 @@ import { KizloClientTestInstance, getKizloClientTestInstance } from "./test/clie
9
10
  import { menuFixture } from "./menu/fixture.js";
10
11
  import { postFixture } from "./post/fixture.js";
11
12
  import { coreFixtures } from "./test/fixtures.js";
12
- export { CAPTCHA_TEST_TOKEN_PASS, DevPluginSource, DockerStack, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, KizloClientTestInstance, KizloTestInstance, LocalPlugin, PluginSource, RunResult, SeedContext, Stack, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
13
+ export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, DevPluginSource, DockerStack, Fixture, FixtureCleanupFn, FixtureSeedFn, JsonValue, KizloClientTestInstance, KizloTestInstance, LocalPlugin, OPCACHE_INI, PluginSource, REMAP_ENTRYPOINT, RunResult, SEED_MARKER_OPTION, SEED_VERSION, SeedContext, Stack, TEST_ADMIN, TEST_USER, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
package/dist/test.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { defineFixture, isLocalPlugin } from "./cli/wp/types.js";
2
+ import { COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, githubRelease, kizloRelease } from "./cli/wp/constants.js";
2
3
  import { compose, composeDown, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
3
- import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isSeeded, kizloRelease, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
4
+ import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, isSeeded, recordedPort, resolvePluginSource } from "./cli/wp/utils.js";
4
5
  import { testAuthAdapter } from "./test/auth.js";
5
6
  import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
6
7
  import { getKizloClientTestInstance } from "./test/client.js";
@@ -10,4 +11,4 @@ import { coreFixtures } from "./test/fixtures.js";
10
11
  import { toTestUser } from "./test/users.js";
11
12
  import { getKizloTestInstance } from "./test/server.js";
12
13
 
13
- export { CAPTCHA_TEST_TOKEN_PASS, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
14
+ export { CAPTCHA_TEST_TOKEN_PASS, COMPOSE_FILE, CONFIG_FILES, CREDENTIALS_REL, DEFAULT_PLUGINS, DEFAULT_PORT, OPCACHE_INI, REMAP_ENTRYPOINT, SEED_MARKER_OPTION, SEED_VERSION, TEST_ADMIN, TEST_USER, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, dockerAvailable, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, recordedPort, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kizlo",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "description": "A headless WordPress toolkit for TypeScript.",
6
6
  "keywords": [
@@ -76,7 +76,7 @@
76
76
  },
77
77
  "dependencies": {
78
78
  "@clack/prompts": "^1.5.1",
79
- "@kizlo/shared": "0.3.0",
79
+ "@kizlo/shared": "0.4.0",
80
80
  "@orpc/client": "^1.14.3",
81
81
  "@orpc/contract": "^1.14.3",
82
82
  "@orpc/openapi": "^1.14.3",
@@ -87,7 +87,6 @@
87
87
  "consola": "^3.2.3",
88
88
  "cookie": "^1.0.2",
89
89
  "jiti": "^2.7.0",
90
- "jose": "6.1.0",
91
90
  "zod": "^4.3.6"
92
91
  },
93
92
  "peerDependencies": {