kizlo 0.10.0 → 0.12.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/README.md +4 -4
- package/dist/astro/server.d.ts +9 -0
- package/dist/astro/server.js +10 -0
- package/dist/astro.d.ts +2 -0
- package/dist/astro.js +3 -0
- package/dist/cli/commands/_setup.js +19 -10
- package/dist/cli/commands/create.js +102 -72
- package/dist/cli/commands/dev.js +113 -20
- package/dist/cli/commands/generate.js +4 -0
- package/dist/cli/commands/init.js +111 -57
- package/dist/cli/daemon/config.js +13 -7
- package/dist/cli/daemon/generate.js +2 -3
- package/dist/cli/daemon/jiti.js +101 -0
- package/dist/cli/daemon/logger.js +1 -1
- package/dist/cli/daemon/reload.js +66 -0
- package/dist/cli/daemon/watch.js +7 -4
- package/dist/cli/presets/source.js +122 -24
- package/dist/cli/presets/template.js +75 -17
- package/dist/cli/wp/settings.js +8 -2
- package/dist/comment/schema.js +2 -2
- package/dist/context.d.ts +9 -0
- package/dist/context.js +20 -2
- package/dist/index.d.ts +4 -4
- package/dist/index.js +3 -3
- package/dist/integrations/astro/kizlo.client.d.ts +15 -0
- package/dist/integrations/astro/kizlo.client.js +13 -0
- package/dist/integrations/astro/kizlo.server.d.ts +10 -0
- package/dist/integrations/astro/kizlo.server.js +12 -0
- package/dist/integrations/astro/manifest.d.ts +9 -0
- package/dist/integrations/astro/manifest.js +11 -0
- package/dist/integrations/astro/metadata.d.ts +64 -0
- package/dist/integrations/astro/metadata.js +71 -0
- package/dist/integrations/astro/robots.d.ts +8 -0
- package/dist/integrations/astro/robots.js +11 -0
- package/dist/integrations/astro/sitemap.d.ts +16 -0
- package/dist/integrations/astro/sitemap.js +20 -0
- package/dist/integrations/astro/utils.d.ts +19 -0
- package/dist/integrations/astro/utils.js +17 -0
- package/dist/integrations/nextjs/metadata.d.ts +1 -0
- package/dist/integrations/nextjs/metadata.js +1 -0
- package/dist/kizlo.d.ts +8 -1
- package/dist/kizlo.js +16 -13
- package/dist/nextjs/server.d.ts +2 -1
- package/dist/nextjs/server.js +2 -1
- package/dist/package.js +1 -1
- package/dist/page/schema.js +2 -2
- package/dist/post/schema.js +2 -2
- package/dist/seo/utils.d.ts +8 -2
- package/dist/seo/utils.js +9 -1
- package/dist/shared/constants.js +9 -1
- package/dist/shared/schema.d.ts +1 -2
- package/dist/shared/schema.js +2 -2
- package/dist/wordpress/service.d.ts +4 -0
- package/dist/wordpress/service.js +5 -0
- package/package.json +18 -2
- package/dist/cli/presets/base.js +0 -40
- package/dist/cli/presets/index.js +0 -16
- package/dist/cli/presets/nextjs.js +0 -16
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { IconDescriptor } from "../../brand/icons.js";
|
|
2
|
+
import { S2SClient } from "../../kizlo.js";
|
|
3
|
+
import { SeoHead } from "../../seo/schema.js";
|
|
4
|
+
import { renderJsonLd } from "../../seo/utils.js";
|
|
5
|
+
|
|
6
|
+
//#region src/integrations/astro/metadata.d.ts
|
|
7
|
+
/** A `<meta name="theme-color">` entry, optionally scoped to a `prefers-color-scheme` media query. */
|
|
8
|
+
interface ThemeColor {
|
|
9
|
+
media?: string;
|
|
10
|
+
color: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Brand + site data for the document `<head>`, resolved from WordPress settings. The `.astro`
|
|
14
|
+
* head component maps this to `<title>`/`<link>`/`<meta>` tags (Astro has no `generateMetadata`,
|
|
15
|
+
* and this package can't compile `.astro`, so the rendering lives in the template).
|
|
16
|
+
*/
|
|
17
|
+
interface RootHead {
|
|
18
|
+
/** Web manifest route to link with `rel="manifest"`. */
|
|
19
|
+
manifest: string;
|
|
20
|
+
icons: {
|
|
21
|
+
icon: IconDescriptor[];
|
|
22
|
+
appleTouch: IconDescriptor[];
|
|
23
|
+
};
|
|
24
|
+
/** Site origin used to resolve relative URLs, when set in WordPress. */
|
|
25
|
+
metadataBase?: string;
|
|
26
|
+
/** Browser-chrome theme color(s); a light/dark pair carries `prefers-color-scheme` media queries. */
|
|
27
|
+
themeColor: ThemeColor[];
|
|
28
|
+
}
|
|
29
|
+
/** Per-page SEO tags, mapped from a post's SEO head. Consumed by the template's head component. */
|
|
30
|
+
interface PageHead {
|
|
31
|
+
title: string;
|
|
32
|
+
description?: string;
|
|
33
|
+
canonical: string;
|
|
34
|
+
robots: string;
|
|
35
|
+
og: {
|
|
36
|
+
type: string;
|
|
37
|
+
title: string;
|
|
38
|
+
description?: string;
|
|
39
|
+
url: string;
|
|
40
|
+
siteName: string;
|
|
41
|
+
locale: string;
|
|
42
|
+
image?: {
|
|
43
|
+
url: string;
|
|
44
|
+
width?: number;
|
|
45
|
+
height?: number;
|
|
46
|
+
alt?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
twitter: {
|
|
50
|
+
card: string;
|
|
51
|
+
title: string;
|
|
52
|
+
description?: string;
|
|
53
|
+
site?: string;
|
|
54
|
+
creator?: string;
|
|
55
|
+
image?: string;
|
|
56
|
+
imageAlt?: string;
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
/** Resolve the root brand/site head from WordPress settings (icons, manifest, theme color, base URL). */
|
|
60
|
+
declare function resolveRootHead(client: S2SClient<[]>): Promise<RootHead>;
|
|
61
|
+
/** Map a post's SEO head to the flat descriptors the template's head component renders. */
|
|
62
|
+
declare function resolvePageHead(head: SeoHead): PageHead;
|
|
63
|
+
//#endregion
|
|
64
|
+
export { PageHead, RootHead, ThemeColor, resolvePageHead, resolveRootHead };
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { resolveIcons } from "../../brand/icons.js";
|
|
2
|
+
import { WEB_MANIFEST_ROUTE } from "../../brand/manifest.js";
|
|
3
|
+
import { renderJsonLd } from "../../seo/utils.js";
|
|
4
|
+
|
|
5
|
+
//#region src/integrations/astro/metadata.ts
|
|
6
|
+
/** Resolve the root brand/site head from WordPress settings (icons, manifest, theme color, base URL). */
|
|
7
|
+
async function resolveRootHead(client) {
|
|
8
|
+
const settings = await client.settings.get.call();
|
|
9
|
+
const { icon, appleTouch } = resolveIcons(settings.brand);
|
|
10
|
+
const light = settings.brand.theme_color;
|
|
11
|
+
const dark = settings.brand.theme_color_dark;
|
|
12
|
+
const themeColor = [];
|
|
13
|
+
if (light) themeColor.push(dark ? {
|
|
14
|
+
media: "(prefers-color-scheme: light)",
|
|
15
|
+
color: light
|
|
16
|
+
} : { color: light });
|
|
17
|
+
if (dark) themeColor.push({
|
|
18
|
+
media: "(prefers-color-scheme: dark)",
|
|
19
|
+
color: dark
|
|
20
|
+
});
|
|
21
|
+
return {
|
|
22
|
+
manifest: WEB_MANIFEST_ROUTE,
|
|
23
|
+
icons: {
|
|
24
|
+
icon,
|
|
25
|
+
appleTouch
|
|
26
|
+
},
|
|
27
|
+
metadataBase: settings.site.url || void 0,
|
|
28
|
+
themeColor
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Map a post's SEO head to the flat descriptors the template's head component renders. */
|
|
32
|
+
function resolvePageHead(head) {
|
|
33
|
+
return {
|
|
34
|
+
title: head.title,
|
|
35
|
+
description: head.og.description || void 0,
|
|
36
|
+
canonical: head.canonical,
|
|
37
|
+
robots: [
|
|
38
|
+
head.robots.index,
|
|
39
|
+
head.robots.follow,
|
|
40
|
+
head.robots.maxSnippet,
|
|
41
|
+
head.robots.maxImagePreview,
|
|
42
|
+
head.robots.maxVideoPreview
|
|
43
|
+
].join(", "),
|
|
44
|
+
og: {
|
|
45
|
+
type: head.og.type,
|
|
46
|
+
title: head.og.title,
|
|
47
|
+
description: head.og.description || void 0,
|
|
48
|
+
url: head.og.url,
|
|
49
|
+
siteName: head.og.siteName,
|
|
50
|
+
locale: head.og.locale,
|
|
51
|
+
image: head.og.image ? {
|
|
52
|
+
url: head.og.image.url,
|
|
53
|
+
width: head.og.image.width ?? void 0,
|
|
54
|
+
height: head.og.image.height ?? void 0,
|
|
55
|
+
alt: head.og.image.alt ?? void 0
|
|
56
|
+
} : void 0
|
|
57
|
+
},
|
|
58
|
+
twitter: {
|
|
59
|
+
card: head.twitter.card,
|
|
60
|
+
title: head.twitter.title,
|
|
61
|
+
description: head.twitter.description || void 0,
|
|
62
|
+
site: head.twitter.site ?? void 0,
|
|
63
|
+
creator: head.twitter.creator ?? void 0,
|
|
64
|
+
image: head.twitter.image ?? void 0,
|
|
65
|
+
imageAlt: head.twitter.imageAlt ?? void 0
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
//#endregion
|
|
71
|
+
export { resolvePageHead, resolveRootHead };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { S2SClient } from "../../kizlo.js";
|
|
2
|
+
import { AstroRoute } from "./utils.js";
|
|
3
|
+
|
|
4
|
+
//#region src/integrations/astro/robots.d.ts
|
|
5
|
+
/** Astro endpoint for `src/pages/robots.txt.ts`. SSR refetches live on each request. */
|
|
6
|
+
declare function createRobotsRoute(client: S2SClient<[]>): AstroRoute;
|
|
7
|
+
//#endregion
|
|
8
|
+
export { createRobotsRoute };
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { createRobotsRoute } from "../../seo/robots.js";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/astro/robots.ts
|
|
4
|
+
/** Astro endpoint for `src/pages/robots.txt.ts`. SSR refetches live on each request. */
|
|
5
|
+
function createRobotsRoute$1(client) {
|
|
6
|
+
const handler = createRobotsRoute(client);
|
|
7
|
+
return (context) => handler(context.request);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
//#endregion
|
|
11
|
+
export { createRobotsRoute$1 as createRobotsRoute };
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { S2SClient } from "../../kizlo.js";
|
|
2
|
+
import { CreateSitemapRouteOptions } from "../../seo/sitemap.js";
|
|
3
|
+
import { AstroRoute } from "./utils.js";
|
|
4
|
+
|
|
5
|
+
//#region src/integrations/astro/sitemap.d.ts
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Astro endpoint for `src/pages/sitemaps/[sitemap].xml.ts`. The core handler reads the slug from the
|
|
9
|
+
* request URL's last segment (`/sitemaps/posts.xml` → `posts.xml`), so forwarding `context.request`
|
|
10
|
+
* needs no `params` plumbing.
|
|
11
|
+
*/
|
|
12
|
+
declare function createSitemapRoute(client: S2SClient<[]>, options?: CreateSitemapRouteOptions): AstroRoute;
|
|
13
|
+
/** Astro endpoint for `src/pages/sitemap.xml.ts`: 308-redirects the well-known path to the index. */
|
|
14
|
+
declare function createSitemapRedirectRoute(): AstroRoute;
|
|
15
|
+
//#endregion
|
|
16
|
+
export { createSitemapRedirectRoute, createSitemapRoute };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { createSitemapRedirectRoute, createSitemapRoute } from "../../seo/sitemap.js";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/astro/sitemap.ts
|
|
4
|
+
/**
|
|
5
|
+
* Astro endpoint for `src/pages/sitemaps/[sitemap].xml.ts`. The core handler reads the slug from the
|
|
6
|
+
* request URL's last segment (`/sitemaps/posts.xml` → `posts.xml`), so forwarding `context.request`
|
|
7
|
+
* needs no `params` plumbing.
|
|
8
|
+
*/
|
|
9
|
+
function createSitemapRoute$1(client, options) {
|
|
10
|
+
const handler = createSitemapRoute(client, options);
|
|
11
|
+
return (context) => handler(context.request);
|
|
12
|
+
}
|
|
13
|
+
/** Astro endpoint for `src/pages/sitemap.xml.ts`: 308-redirects the well-known path to the index. */
|
|
14
|
+
function createSitemapRedirectRoute$1() {
|
|
15
|
+
const handler = createSitemapRedirectRoute();
|
|
16
|
+
return (context) => handler(context.request);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { createSitemapRedirectRoute$1 as createSitemapRedirectRoute, createSitemapRoute$1 as createSitemapRoute };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/integrations/astro/utils.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Minimal shape of Astro's `APIContext` this integration needs — just the standard web `Request`.
|
|
4
|
+
* Typed structurally so the package never has to depend on `astro` (which stays an optional peer).
|
|
5
|
+
*/
|
|
6
|
+
interface AstroRouteContext {
|
|
7
|
+
request: Request;
|
|
8
|
+
}
|
|
9
|
+
/** An Astro endpoint handler (`export const GET = …`): takes the route context, returns a `Response`. */
|
|
10
|
+
type AstroRoute = (context: AstroRouteContext) => Promise<Response> | Response;
|
|
11
|
+
/**
|
|
12
|
+
* The public Kizlo API base URL, read from `process.env` as a last-resort fallback for a client built
|
|
13
|
+
* without an explicit `url`. The server factory (`createKizlo`) reads env the Astro-native way through
|
|
14
|
+
* `astro:env/server`, and client-side code passes `import.meta.env.PUBLIC_KIZLO_API_URL` at the call
|
|
15
|
+
* site (see the template's `client.ts`); this fallback only matters if neither is supplied.
|
|
16
|
+
*/
|
|
17
|
+
declare function getServerBaseUrl(): string;
|
|
18
|
+
//#endregion
|
|
19
|
+
export { AstroRoute, AstroRouteContext, getServerBaseUrl };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { KizloError } from "../../shared/error.js";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/astro/utils.ts
|
|
4
|
+
/**
|
|
5
|
+
* The public Kizlo API base URL, read from `process.env` as a last-resort fallback for a client built
|
|
6
|
+
* without an explicit `url`. The server factory (`createKizlo`) reads env the Astro-native way through
|
|
7
|
+
* `astro:env/server`, and client-side code passes `import.meta.env.PUBLIC_KIZLO_API_URL` at the call
|
|
8
|
+
* site (see the template's `client.ts`); this fallback only matters if neither is supplied.
|
|
9
|
+
*/
|
|
10
|
+
function getServerBaseUrl() {
|
|
11
|
+
const baseUrl = process.env.PUBLIC_KIZLO_API_URL?.trim();
|
|
12
|
+
if (!baseUrl) throw new KizloError("MISSING_ENV_VARIABLE", { message: "Please define PUBLIC_KIZLO_API_URL in your .env file." });
|
|
13
|
+
return baseUrl;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { getServerBaseUrl };
|
package/dist/kizlo.d.ts
CHANGED
|
@@ -75,6 +75,12 @@ interface CreateKizloOptions<TExts extends readonly AnyExtension[] = []> {
|
|
|
75
75
|
credentials?: Partial<WordPressCredentials>;
|
|
76
76
|
};
|
|
77
77
|
}
|
|
78
|
+
/**
|
|
79
|
+
* Reads a single environment variable by name. Defaults to `process.env`, but framework factories can
|
|
80
|
+
* pass their own source: the Astro factory hands in `getSecret` from `astro:env/server`, so `.env` is
|
|
81
|
+
* resolved the Astro-native way (through the dev server / adapter) rather than through `process.env`.
|
|
82
|
+
*/
|
|
83
|
+
type EnvReader = (name: string) => string | undefined;
|
|
78
84
|
/**
|
|
79
85
|
* Resolves a full `KizloConfig` from options and the environment. Shared by the
|
|
80
86
|
* base `createKizlo` and each framework factory — the single place env values
|
|
@@ -83,6 +89,7 @@ interface CreateKizloOptions<TExts extends readonly AnyExtension[] = []> {
|
|
|
83
89
|
declare function resolveKizloConfig<TExts extends readonly AnyExtension[]>(options: CreateKizloOptions<TExts> | undefined, defaults: {
|
|
84
90
|
baseUrlEnvKey: string;
|
|
85
91
|
adapters?: ServiceAdapters;
|
|
92
|
+
env?: EnvReader;
|
|
86
93
|
}): KizloConfig<TExts>;
|
|
87
94
|
/**
|
|
88
95
|
* Creates a Kizlo server from the environment (`KIZLO_API_URL`, `KIZLO_WP_SECRET`,
|
|
@@ -91,4 +98,4 @@ declare function resolveKizloConfig<TExts extends readonly AnyExtension[]>(optio
|
|
|
91
98
|
*/
|
|
92
99
|
declare function createKizlo<TExts extends readonly AnyExtension[] = []>(options?: CreateKizloOptions<TExts>): Kizlo<TExts>;
|
|
93
100
|
//#endregion
|
|
94
|
-
export { AnyKizloConfig, CreateKizloOptions, Kizlo, KizloConfig, KizloConnect, RootRouter, S2SClient, ServiceAdapters, createKizlo, resolveKizloConfig };
|
|
101
|
+
export { AnyKizloConfig, CreateKizloOptions, EnvReader, Kizlo, KizloConfig, KizloConnect, RootRouter, S2SClient, ServiceAdapters, createKizlo, resolveKizloConfig };
|
package/dist/kizlo.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RPC_PROTOCOL_HEADER } from "./shared/constants.js";
|
|
1
|
+
import { CONTRACT_GENERATION_ENV, RPC_PROTOCOL_HEADER } from "./shared/constants.js";
|
|
2
2
|
import { KizloError } from "./shared/error.js";
|
|
3
3
|
import { createOrpcRouter } from "./shared/router.js";
|
|
4
4
|
import { createResultClient } from "./shared/result.js";
|
|
@@ -100,14 +100,16 @@ var Kizlo = class {
|
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
102
|
};
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
return value;
|
|
103
|
+
const processEnvReader = (name) => process.env[name];
|
|
104
|
+
function requireEnv(name, env) {
|
|
105
|
+
const value = env(name)?.trim();
|
|
106
|
+
if (value) return value;
|
|
107
|
+
if (process.env[CONTRACT_GENERATION_ENV]) return `__kizlo_contract_generation__:${name}`;
|
|
108
|
+
throw new KizloError("MISSING_ENV_VARIABLE", { message: `Please define ${name} in your .env file.` });
|
|
107
109
|
}
|
|
108
|
-
function resolveConnect(option) {
|
|
110
|
+
function resolveConnect(option, env) {
|
|
109
111
|
if (option) return option;
|
|
110
|
-
const value =
|
|
112
|
+
const value = env("KIZLO_CONNECT")?.trim();
|
|
111
113
|
if (!value) return "remote";
|
|
112
114
|
if (value !== "local" && value !== "remote") throw new KizloError("INVALID_ENV_VARIABLE", { message: `KIZLO_CONNECT must be "local" or "remote", got "${value}".` });
|
|
113
115
|
return value;
|
|
@@ -128,12 +130,13 @@ function connectEnvKeys(connect) {
|
|
|
128
130
|
* and credentials are read. `baseUrlEnvKey` is the only framework-varying part.
|
|
129
131
|
*/
|
|
130
132
|
function resolveKizloConfig(options, defaults) {
|
|
133
|
+
const env = defaults.env ?? processEnvReader;
|
|
131
134
|
const credentials = options?.wordpress?.credentials;
|
|
132
|
-
const connect = resolveConnect(options?.connect);
|
|
135
|
+
const connect = resolveConnect(options?.connect, env);
|
|
133
136
|
const keys = connectEnvKeys(connect);
|
|
134
137
|
return {
|
|
135
|
-
baseUrl: options?.baseUrl ?? requireEnv(defaults.baseUrlEnvKey),
|
|
136
|
-
siteSecret: options?.siteSecret ?? requireEnv(keys.siteSecret),
|
|
138
|
+
baseUrl: options?.baseUrl ?? requireEnv(defaults.baseUrlEnvKey, env),
|
|
139
|
+
siteSecret: options?.siteSecret ?? requireEnv(keys.siteSecret, env),
|
|
137
140
|
environment: options?.environment ?? process.env.NODE_ENV ?? "development",
|
|
138
141
|
connect,
|
|
139
142
|
extensions: options?.extensions,
|
|
@@ -142,9 +145,9 @@ function resolveKizloConfig(options, defaults) {
|
|
|
142
145
|
...options?.adapters
|
|
143
146
|
},
|
|
144
147
|
credentials: {
|
|
145
|
-
url: credentials?.url ?? requireEnv(keys.url),
|
|
146
|
-
username: credentials?.username ?? requireEnv(keys.username),
|
|
147
|
-
password: credentials?.password ?? requireEnv(keys.password)
|
|
148
|
+
url: credentials?.url ?? requireEnv(keys.url, env),
|
|
149
|
+
username: credentials?.username ?? requireEnv(keys.username, env),
|
|
150
|
+
password: credentials?.password ?? requireEnv(keys.password, env)
|
|
148
151
|
}
|
|
149
152
|
};
|
|
150
153
|
}
|
package/dist/nextjs/server.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
|
|
2
|
+
import { renderJsonLd } from "../seo/utils.js";
|
|
2
3
|
import { createSitemapRedirectRoute } from "../seo/sitemap.js";
|
|
3
4
|
import { NextRevalidateOptions, RevalidatePathFn, RevalidateTagFn, RevalidateTarget, nextRevalidation } from "../integrations/nextjs/revalidate.js";
|
|
4
5
|
import { KizloServerOptions, createKizlo } from "../integrations/nextjs/kizlo.server.js";
|
|
@@ -7,4 +8,4 @@ import { createPageMetadata, createRootMetadata, createRootViewport } from "../i
|
|
|
7
8
|
import { ROBOTS_CACHE_TAG, createRobotsRoute } from "../integrations/nextjs/robots.js";
|
|
8
9
|
import { SITEMAP_CACHE_TAG, SITEMAP_ROUTE, createSitemapRoute } from "../integrations/nextjs/sitemap.js";
|
|
9
10
|
import { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl } from "../integrations/nextjs/utils.js";
|
|
10
|
-
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, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, nextRevalidation };
|
|
11
|
+
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, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, nextRevalidation, renderJsonLd };
|
package/dist/nextjs/server.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { WEB_MANIFEST_ROUTE } from "../brand/manifest.js";
|
|
2
|
+
import { renderJsonLd } from "../seo/utils.js";
|
|
2
3
|
import { createSitemapRedirectRoute } from "../seo/sitemap.js";
|
|
3
4
|
import { createCachedTextRoute, createNextCookiesInterface, getServerBaseUrl } from "../integrations/nextjs/utils.js";
|
|
4
5
|
import { ROBOTS_CACHE_TAG, createRobotsRoute } from "../integrations/nextjs/robots.js";
|
|
@@ -8,4 +9,4 @@ import { createKizlo } from "../integrations/nextjs/kizlo.server.js";
|
|
|
8
9
|
import { MANIFEST_CACHE_TAG, createManifestRoute } from "../integrations/nextjs/manifest.js";
|
|
9
10
|
import { createPageMetadata, createRootMetadata, createRootViewport } from "../integrations/nextjs/metadata.js";
|
|
10
11
|
|
|
11
|
-
export { MANIFEST_CACHE_TAG, ROBOTS_CACHE_TAG, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createCachedTextRoute, createKizlo, createManifestRoute, createNextCookiesInterface, createPageMetadata, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, nextRevalidation };
|
|
12
|
+
export { MANIFEST_CACHE_TAG, ROBOTS_CACHE_TAG, SITEMAP_CACHE_TAG, SITEMAP_ROUTE, WEB_MANIFEST_ROUTE, createCachedTextRoute, createKizlo, createManifestRoute, createNextCookiesInterface, createPageMetadata, createRobotsRoute, createRootMetadata, createRootViewport, createSitemapRedirectRoute, createSitemapRoute, getServerBaseUrl, nextRevalidation, renderJsonLd };
|
package/dist/package.js
CHANGED
package/dist/page/schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IdentifierInput, ListMetadata, ListOrder
|
|
1
|
+
import { IdentifierInput, ListMetadata, ListOrder } from "../shared/schema.js";
|
|
2
2
|
import { WP_PAGE_ORDER_BYES, WP_PAGE_STATUSES } from "../wordpress/page/types.js";
|
|
3
3
|
import { Seo } from "../seo/schema.js";
|
|
4
|
-
import { Metadata, NumberLike, arrayable, lenient } from "@kizlo/shared";
|
|
4
|
+
import { Media, Metadata, NumberLike, arrayable, lenient } from "@kizlo/shared";
|
|
5
5
|
import z from "zod/v4";
|
|
6
6
|
|
|
7
7
|
//#region src/page/schema.ts
|
package/dist/post/schema.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { IdentifierInput, ListMetadata, ListOrder
|
|
1
|
+
import { IdentifierInput, ListMetadata, ListOrder } from "../shared/schema.js";
|
|
2
2
|
import { WP_POST_FORMATS, WP_POST_ORDER_BYES, WP_POST_STATUSES, WP_POST_TAX_RELATIONS } from "../wordpress/post/types.js";
|
|
3
3
|
import { Seo } from "../seo/schema.js";
|
|
4
|
-
import { BooleanLike, Metadata, NumberLike, arrayable, lenient } from "@kizlo/shared";
|
|
4
|
+
import { BooleanLike, Media, Metadata, NumberLike, arrayable, lenient } from "@kizlo/shared";
|
|
5
5
|
import z from "zod/v4";
|
|
6
6
|
|
|
7
7
|
//#region src/post/schema.ts
|
package/dist/seo/utils.d.ts
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
|
-
import { Seo, Sitemap, SitemapUrl } from "./schema.js";
|
|
1
|
+
import { Seo, SeoSchema, Sitemap, SitemapUrl } from "./schema.js";
|
|
2
2
|
import { WPK_Seo } from "./types.js";
|
|
3
3
|
|
|
4
4
|
//#region src/seo/utils.d.ts
|
|
5
5
|
declare function deserializeSeo(data: WPK_Seo): Seo;
|
|
6
|
+
/**
|
|
7
|
+
* Serialize a post's JSON-LD (`data.seo.schema`) for a `<script type="application/ld+json">` tag.
|
|
8
|
+
* Returns `null` when the `@graph` is empty so the template can skip the tag entirely. The result
|
|
9
|
+
* is JSON, safe to inject as script-element text content.
|
|
10
|
+
*/
|
|
11
|
+
declare function renderJsonLd(schema: SeoSchema): string | null;
|
|
6
12
|
type SitemapIndexEntry = Pick<Sitemap, "key" | "pages" | "lastmod">;
|
|
7
13
|
declare function sitemapEntryPath(key: string, page: number): string;
|
|
8
14
|
declare function parseSitemapSlug(slug: string): {
|
|
@@ -13,4 +19,4 @@ declare function renderSitemapIndex(sitemaps: readonly SitemapIndexEntry[], orig
|
|
|
13
19
|
declare function renderUrlSet(urls: SitemapUrl[]): string;
|
|
14
20
|
declare function xmlResponse(body: string): Response;
|
|
15
21
|
//#endregion
|
|
16
|
-
export { SitemapIndexEntry, deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
|
|
22
|
+
export { SitemapIndexEntry, deserializeSeo, parseSitemapSlug, renderJsonLd, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
|
package/dist/seo/utils.js
CHANGED
|
@@ -41,6 +41,14 @@ function deserializeSeo(data) {
|
|
|
41
41
|
schema: data.schema
|
|
42
42
|
};
|
|
43
43
|
}
|
|
44
|
+
/**
|
|
45
|
+
* Serialize a post's JSON-LD (`data.seo.schema`) for a `<script type="application/ld+json">` tag.
|
|
46
|
+
* Returns `null` when the `@graph` is empty so the template can skip the tag entirely. The result
|
|
47
|
+
* is JSON, safe to inject as script-element text content.
|
|
48
|
+
*/
|
|
49
|
+
function renderJsonLd(schema) {
|
|
50
|
+
return schema["@graph"].length ? JSON.stringify(schema) : null;
|
|
51
|
+
}
|
|
44
52
|
function sitemapEntryPath(key, page) {
|
|
45
53
|
return `/sitemaps/${key}${page > 1 ? `-${page}` : ""}.xml`;
|
|
46
54
|
}
|
|
@@ -75,4 +83,4 @@ function xmlResponse(body) {
|
|
|
75
83
|
}
|
|
76
84
|
|
|
77
85
|
//#endregion
|
|
78
|
-
export { deserializeSeo, parseSitemapSlug, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
|
|
86
|
+
export { deserializeSeo, parseSitemapSlug, renderJsonLd, renderSitemapIndex, renderUrlSet, sitemapEntryPath, xmlResponse };
|
package/dist/shared/constants.js
CHANGED
|
@@ -5,6 +5,14 @@ import { milliseconds } from "@kizlo/shared";
|
|
|
5
5
|
const VERSION = version;
|
|
6
6
|
const RPC_PROTOCOL_HEADER = "x-rpc-protocol";
|
|
7
7
|
const SESSION_EXPIRY_MARGIN_MS = milliseconds("5 minutes");
|
|
8
|
+
/**
|
|
9
|
+
* Set in `process.env` by the CLI daemon while it imports the server module solely to read the
|
|
10
|
+
* router's *shape* for contract generation. No request is served in that mode, so `requireEnv`
|
|
11
|
+
* returns a placeholder instead of aborting the import when connection env vars are absent — the
|
|
12
|
+
* router shape doesn't depend on any env value, and framework virtual modules (e.g. Astro's
|
|
13
|
+
* `getSecret`) are stubbed to `undefined` during the shape-only import anyway.
|
|
14
|
+
*/
|
|
15
|
+
const CONTRACT_GENERATION_ENV = "KIZLO_CONTRACT_GENERATION";
|
|
8
16
|
|
|
9
17
|
//#endregion
|
|
10
|
-
export { RPC_PROTOCOL_HEADER };
|
|
18
|
+
export { CONTRACT_GENERATION_ENV, RPC_PROTOCOL_HEADER };
|
package/dist/shared/schema.d.ts
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { Media } from "@kizlo/shared";
|
|
2
1
|
import z from "zod/v4";
|
|
3
2
|
|
|
4
3
|
//#region src/shared/schema.d.ts
|
|
@@ -46,4 +45,4 @@ declare const PreviewTokenData: z.ZodObject<{
|
|
|
46
45
|
}, z.core.$strip>;
|
|
47
46
|
type PreviewTokenData = z.infer<typeof PreviewTokenData>;
|
|
48
47
|
//#endregion
|
|
49
|
-
export { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder,
|
|
48
|
+
export { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder, PreviewTokenData, PreviewTokenPayload };
|
package/dist/shared/schema.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { NumberLike } from "@kizlo/shared";
|
|
2
2
|
import z from "zod/v4";
|
|
3
3
|
|
|
4
4
|
//#region src/shared/schema.ts
|
|
@@ -34,4 +34,4 @@ const PreviewTokenData = z.object({
|
|
|
34
34
|
});
|
|
35
35
|
|
|
36
36
|
//#endregion
|
|
37
|
-
export { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder,
|
|
37
|
+
export { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder, PreviewTokenData, PreviewTokenPayload };
|
|
@@ -20,9 +20,13 @@ declare class WordPressService {
|
|
|
20
20
|
private readonly siteBase;
|
|
21
21
|
private readonly authHeader;
|
|
22
22
|
private readonly defaultTimeout;
|
|
23
|
+
/** Called with the response headers of every non-transport-error response, so callers can observe
|
|
24
|
+
* per-response signals (e.g. the plugin version header) without threading them through every method. */
|
|
25
|
+
private readonly onResponse?;
|
|
23
26
|
constructor(context: {
|
|
24
27
|
credentials: WordPressCredentials;
|
|
25
28
|
timeout?: Duration;
|
|
29
|
+
onResponse?: (headers: Headers) => void;
|
|
26
30
|
});
|
|
27
31
|
post<TData, TCode extends string = never>(path: string, input: {
|
|
28
32
|
body?: unknown;
|
|
@@ -22,6 +22,9 @@ var WordPressService = class {
|
|
|
22
22
|
siteBase;
|
|
23
23
|
authHeader;
|
|
24
24
|
defaultTimeout;
|
|
25
|
+
/** Called with the response headers of every non-transport-error response, so callers can observe
|
|
26
|
+
* per-response signals (e.g. the plugin version header) without threading them through every method. */
|
|
27
|
+
onResponse;
|
|
25
28
|
constructor(context) {
|
|
26
29
|
const credentialBytes = new TextEncoder().encode(`${context.credentials.username}:${context.credentials.password}`);
|
|
27
30
|
let binary = "";
|
|
@@ -29,6 +32,7 @@ var WordPressService = class {
|
|
|
29
32
|
this.authHeader = `${WP_AUTH_TYPE} ${btoa(binary)}`;
|
|
30
33
|
this.siteBase = context.credentials.url.endsWith("/") ? context.credentials.url : `${context.credentials.url}/`;
|
|
31
34
|
this.defaultTimeout = context.timeout ?? SAFE_REQUEST_TIMEOUT;
|
|
35
|
+
this.onResponse = context.onResponse;
|
|
32
36
|
}
|
|
33
37
|
async post(path, input) {
|
|
34
38
|
return this.request({
|
|
@@ -103,6 +107,7 @@ var WordPressService = class {
|
|
|
103
107
|
message: transportErr.message
|
|
104
108
|
})
|
|
105
109
|
};
|
|
110
|
+
this.onResponse?.(response.headers);
|
|
106
111
|
const [readErr, text] = await tryCatch(response.text());
|
|
107
112
|
if (readErr) return {
|
|
108
113
|
data: null,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "kizlo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.12.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "A headless WordPress framework for TypeScript.",
|
|
6
6
|
"keywords": [
|
|
@@ -63,6 +63,18 @@
|
|
|
63
63
|
"types": "./dist/nextjs/server.d.ts",
|
|
64
64
|
"default": "./dist/nextjs/server.js"
|
|
65
65
|
}
|
|
66
|
+
},
|
|
67
|
+
"./astro": {
|
|
68
|
+
"import": {
|
|
69
|
+
"types": "./dist/astro.d.ts",
|
|
70
|
+
"default": "./dist/astro.js"
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
"./astro/server": {
|
|
74
|
+
"import": {
|
|
75
|
+
"types": "./dist/astro/server.d.ts",
|
|
76
|
+
"default": "./dist/astro/server.js"
|
|
77
|
+
}
|
|
66
78
|
}
|
|
67
79
|
},
|
|
68
80
|
"files": [
|
|
@@ -76,7 +88,7 @@
|
|
|
76
88
|
},
|
|
77
89
|
"dependencies": {
|
|
78
90
|
"@clack/prompts": "^1.5.1",
|
|
79
|
-
"@kizlo/shared": "0.
|
|
91
|
+
"@kizlo/shared": "0.6.0",
|
|
80
92
|
"@orpc/client": "^1.14.3",
|
|
81
93
|
"@orpc/contract": "^1.14.3",
|
|
82
94
|
"@orpc/openapi": "^1.14.3",
|
|
@@ -93,11 +105,15 @@
|
|
|
93
105
|
"zod": "^4.3.6"
|
|
94
106
|
},
|
|
95
107
|
"peerDependencies": {
|
|
108
|
+
"astro": "^7.0.0",
|
|
96
109
|
"next": "^14.0.0 || ^15.0.0 || ^16.0.0",
|
|
97
110
|
"react": "^18.0.0 || ^19.0.0",
|
|
98
111
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
99
112
|
},
|
|
100
113
|
"peerDependenciesMeta": {
|
|
114
|
+
"astro": {
|
|
115
|
+
"optional": true
|
|
116
|
+
},
|
|
101
117
|
"next": {
|
|
102
118
|
"optional": true
|
|
103
119
|
},
|
package/dist/cli/presets/base.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { DEFAULT_ENV_KEYS } from "../utils.js";
|
|
2
|
-
|
|
3
|
-
//#region src/cli/presets/base.ts
|
|
4
|
-
const base = {
|
|
5
|
-
id: "base",
|
|
6
|
-
label: "Generic (no framework detected)",
|
|
7
|
-
detect: () => 1,
|
|
8
|
-
envKeys: DEFAULT_ENV_KEYS,
|
|
9
|
-
scaffolds(ctx) {
|
|
10
|
-
return [{
|
|
11
|
-
label: "Kizlo server instance",
|
|
12
|
-
relPath: ctx.serverEntryPath,
|
|
13
|
-
contents: `import { createKizlo } from "kizlo"
|
|
14
|
-
|
|
15
|
-
export const { router, client, context, handler } = createKizlo()
|
|
16
|
-
`
|
|
17
|
-
}, {
|
|
18
|
-
label: "Browser client",
|
|
19
|
-
relPath: ctx.clientPath,
|
|
20
|
-
contents: clientEntry(ctx)
|
|
21
|
-
}];
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
function clientEntry(ctx) {
|
|
25
|
-
if (ctx.clientUrl) return `import { createKizloClient } from "kizlo"
|
|
26
|
-
import { contract } from "./${ctx.serverDirName}/generated"
|
|
27
|
-
|
|
28
|
-
// Your Kizlo backend runs on a different origin than this app. Swap in your bundler's
|
|
29
|
-
// public env var (e.g. import.meta.env.VITE_KIZLO_API_URL) to set it per environment.
|
|
30
|
-
export const client = createKizloClient(contract, { url: "${ctx.clientUrl}" })
|
|
31
|
-
`;
|
|
32
|
-
return `import { createKizloClient } from "kizlo"
|
|
33
|
-
import { contract } from "./${ctx.serverDirName}/generated"
|
|
34
|
-
|
|
35
|
-
export const client = createKizloClient(contract)
|
|
36
|
-
`;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
//#endregion
|
|
40
|
-
export { base };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { base } from "./base.js";
|
|
2
|
-
import { nextjs } from "./nextjs.js";
|
|
3
|
-
|
|
4
|
-
//#region src/cli/presets/index.ts
|
|
5
|
-
/** Framework presets, in declaration order. `base` always matches last. */
|
|
6
|
-
const PRESETS = [nextjs, base];
|
|
7
|
-
function getPreset(id) {
|
|
8
|
-
return PRESETS.find((preset) => preset.id === id);
|
|
9
|
-
}
|
|
10
|
-
/** Highest-scoring preset for the project; falls back to `base`. */
|
|
11
|
-
function detectPreset(ctx) {
|
|
12
|
-
return PRESETS.reduce((best, preset) => preset.detect(ctx) > best.detect(ctx) ? preset : best);
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
//#endregion
|
|
16
|
-
export { PRESETS, detectPreset, getPreset };
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
//#region src/cli/presets/nextjs.ts
|
|
2
|
-
const nextjs = {
|
|
3
|
-
id: "nextjs",
|
|
4
|
-
label: "Next.js",
|
|
5
|
-
detect(ctx) {
|
|
6
|
-
return {
|
|
7
|
-
...ctx.pkg.dependencies,
|
|
8
|
-
...ctx.pkg.devDependencies
|
|
9
|
-
}.next ? 100 : 0;
|
|
10
|
-
},
|
|
11
|
-
apiPath: "/api/kizlo",
|
|
12
|
-
template: "nextjs"
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
//#endregion
|
|
16
|
-
export { nextjs };
|