kizlo 0.20.2 → 0.22.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/category/index.js +3 -3
  2. package/dist/category/schema.d.ts +1 -1
  3. package/dist/cli/commands/_setup.js +5 -1
  4. package/dist/cli/commands/dev.js +63 -20
  5. package/dist/cli/daemon/config.js +27 -3
  6. package/dist/cli/daemon/generate.js +8 -2
  7. package/dist/cli/daemon/watch.js +11 -3
  8. package/dist/cli/mcp/index.js +46 -0
  9. package/dist/cli/mcp/routes.js +42 -0
  10. package/dist/cli/mcp/schema.js +212 -0
  11. package/dist/cli/mcp/search.js +255 -0
  12. package/dist/cli/mcp/server.js +248 -0
  13. package/dist/cli/mcp/state.js +7 -0
  14. package/dist/cli/mcp/tools.js +116 -0
  15. package/dist/comment/index.js +4 -4
  16. package/dist/config.d.ts +17 -1
  17. package/dist/email/service.js +1 -1
  18. package/dist/index.d.ts +3 -3
  19. package/dist/index.js +2 -2
  20. package/dist/integrations/astro/integration.js +2 -0
  21. package/dist/integrations/nextjs/integration.js +2 -0
  22. package/dist/integrations/node/integration.js +2 -0
  23. package/dist/integrations/tanstack-start/integration.js +2 -0
  24. package/dist/kizlo.js +4 -3
  25. package/dist/menu/utils.js +2 -2
  26. package/dist/package.js +1 -1
  27. package/dist/page/index.js +4 -4
  28. package/dist/page/schema.d.ts +1 -1
  29. package/dist/post/index.js +4 -4
  30. package/dist/post/schema.d.ts +1 -1
  31. package/dist/procedures.d.ts +7 -7
  32. package/dist/seo/index.js +13 -11
  33. package/dist/seo/types.d.ts +4 -4
  34. package/dist/settings/service.d.ts +11 -11
  35. package/dist/settings/service.js +15 -15
  36. package/dist/shared/constants.js +3 -1
  37. package/dist/shared/integration.d.ts +9 -1
  38. package/dist/shared/integration.js +6 -3
  39. package/dist/tag/index.js +3 -3
  40. package/dist/tag/schema.d.ts +1 -1
  41. package/dist/wordpress/endpoint.d.ts +13 -3
  42. package/dist/wordpress/endpoint.js +24 -12
  43. package/dist/wordpress/generate.js +57 -9
  44. package/dist/wordpress/index.d.ts +1 -1
  45. package/dist/wordpress/introspection.js +26 -11
  46. package/dist/wordpress/types.d.ts +16 -2
  47. package/package.json +4 -2
@@ -0,0 +1,248 @@
1
+ import { log } from "../daemon/logger.js";
2
+ import { callRoute, describeRoute, searchRoutes } from "./tools.js";
3
+ import z from "zod/v4";
4
+ import { createServer } from "node:http";
5
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
6
+ import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
7
+
8
+ //#region src/cli/mcp/server.ts
9
+ /** The only interface the server is ever bound to. Never `0.0.0.0`: this is a developer's machine. */
10
+ const MCP_HOST = "127.0.0.1";
11
+ /** The one path the server answers on, so a harness config is a URL rather than a URL and a note. */
12
+ const MCP_PATH = "/mcp";
13
+ /** Hosts an `Origin` may name. Everything the loopback interface is reachable as, and nothing else. */
14
+ const LOOPBACK_HOSTS = new Set([
15
+ "127.0.0.1",
16
+ "::1",
17
+ "[::1]",
18
+ "localhost"
19
+ ]);
20
+ /**
21
+ * Whether a request's `Origin` may be served.
22
+ *
23
+ * Binding to loopback keeps other machines out, but not the developer's own browser: a page on any
24
+ * site can `fetch` `http://127.0.0.1`, and while CORS stops it reading the reply, a request that
25
+ * changes WordPress has already happened by then. The MCP specification requires HTTP transports to
26
+ * check `Origin` for exactly this, so a page that names itself is refused before it reaches a tool.
27
+ *
28
+ * No `Origin` is allowed, because that is what a native MCP client sends. Browsers attach the header
29
+ * to cross-origin requests themselves and cannot forge it, so its absence is not something an attacking
30
+ * page can arrange.
31
+ */
32
+ function isAllowedOrigin(origin) {
33
+ if (origin === void 0 || origin === "") return true;
34
+ if (origin === "null") return false;
35
+ try {
36
+ return LOOPBACK_HOSTS.has(new URL(origin).hostname);
37
+ } catch {
38
+ return false;
39
+ }
40
+ }
41
+ /**
42
+ * Render a tool's answer for both kinds of reader: `structuredContent` for a client that parses, and
43
+ * a text block for one that does not.
44
+ *
45
+ * A failure carries no `structuredContent`. A client validates whatever it finds there against the
46
+ * tool's declared output schema whether or not the result is an error, and a failure is not that
47
+ * shape, so putting it there makes a client reject the answer outright instead of reading it. The
48
+ * detail rides in a second text block, which keeps it machine-readable without breaking the contract.
49
+ */
50
+ function toolContent(result, summarize = (value) => JSON.stringify(value, null, 2)) {
51
+ if (!result.ok) return {
52
+ content: [{
53
+ type: "text",
54
+ text: result.error.message
55
+ }, {
56
+ type: "text",
57
+ text: JSON.stringify(result.error, null, 2)
58
+ }],
59
+ isError: true
60
+ };
61
+ return {
62
+ content: [{
63
+ type: "text",
64
+ text: summarize(result.value)
65
+ }],
66
+ structuredContent: result.value
67
+ };
68
+ }
69
+ /**
70
+ * The one result long enough to be worth compressing. Describe and call put their payload in the
71
+ * text block because the payload is the answer; a ranked list is better read than parsed.
72
+ */
73
+ function summarizeSearch(value) {
74
+ const outcome = value;
75
+ if (outcome.count === 0) return outcome.message ?? "No route matches that search.";
76
+ const lines = outcome.routes.map((route) => {
77
+ const evidence = route.evidence.map((item) => `${item.field}:${item.term}`).join(", ");
78
+ const summary = route.summary === void 0 ? "" : ` — ${route.summary}`;
79
+ const deprecated = route.deprecated ? " (deprecated)" : "";
80
+ return `${route.name} — ${route.method} ${route.path}${summary}${deprecated}${evidence === "" ? "" : ` [${evidence}]`}`;
81
+ });
82
+ const more = outcome.nextCursor === void 0 ? "" : `\n${outcome.count - outcome.routes.length} more. Pass cursor "${outcome.nextCursor}" for the next page.`;
83
+ return `${outcome.count} route${outcome.count === 1 ? "" : "s"} match:\n${lines.join("\n")}${more}`;
84
+ }
85
+ /** A ranked result, and the named part of the contract that selected it. */
86
+ const SEARCH_OUTPUT = {
87
+ count: z.number().describe("Matches across the whole catalog, not just this page."),
88
+ routes: z.array(z.object({
89
+ name: z.string(),
90
+ namespace: z.string(),
91
+ method: z.string(),
92
+ path: z.string(),
93
+ summary: z.string().optional(),
94
+ deprecated: z.literal(true).optional(),
95
+ evidence: z.array(z.object({
96
+ field: z.string(),
97
+ term: z.string()
98
+ }))
99
+ })),
100
+ namespaces: z.array(z.string()).describe("Every REST namespace this WordPress serves."),
101
+ nextCursor: z.string().optional().describe("Hand back as `cursor` to read the next page."),
102
+ message: z.string().optional().describe("Present only when nothing matched.")
103
+ };
104
+ const DESCRIBE_OUTPUT = {
105
+ name: z.string(),
106
+ namespace: z.string(),
107
+ method: z.string(),
108
+ path: z.string(),
109
+ summary: z.string().optional(),
110
+ description: z.string().optional(),
111
+ deprecated: z.literal(true).optional(),
112
+ pathParameters: z.array(z.string()),
113
+ input: z.record(z.string(), z.unknown()).describe("JSON Schema for `{ params, query, body }`, with its `$defs`."),
114
+ responses: z.record(z.string(), z.unknown()).describe("Keyed by HTTP status."),
115
+ errors: z.array(z.string()).describe("Error codes this route declares.")
116
+ };
117
+ /**
118
+ * Deliberately permissive. The SDK validates `structuredContent` against this on every successful
119
+ * call, so anything narrower would turn a route whose response does not fit into a protocol error
120
+ * rather than an answer.
121
+ */
122
+ const CALL_OUTPUT = {
123
+ status: z.number(),
124
+ data: z.unknown().optional()
125
+ };
126
+ /**
127
+ * Three dispatchers rather than a tool per route. The contract a seeded WordPress serves runs to well
128
+ * over a hundred routes, and putting their schemas in front of a model up front would cost tens of
129
+ * thousands of tokens in every message. These cost a few hundred and reach all of them — and because
130
+ * they read the document per call, a route registered while `kizlo dev` runs is callable without
131
+ * re-registering anything.
132
+ */
133
+ function createMcpServer(state) {
134
+ const server = new McpServer({
135
+ name: "kizlo",
136
+ version: "1.0.0"
137
+ }, { instructions: [
138
+ "Read and change the WordPress of the Kizlo project this server was started in.",
139
+ "Every REST route that WordPress exposes is reachable here — core, Kizlo's own, and any plugin's — through three tools rather than one tool per route.",
140
+ "Work in that order: `kizlo_search_routes` to find a route, `kizlo_describe_route` to read its contract, `kizlo_call` to run it.",
141
+ "Describe a route before calling it unless you already know its contract. Arguments are grouped into `params`, `query`, and `body`, and the description says which fields belong where.",
142
+ "API errors are passed through unchanged: the code, message, and data are WordPress's own, not this server's summary of them."
143
+ ].join(" ") });
144
+ server.registerTool("kizlo_search_routes", {
145
+ title: "Search WordPress routes",
146
+ description: "Find routes by identity or by meaning: a route name, path, or namespace, or terms from a route's arguments, response fields, description, or error codes. Start here. Omit `query` to browse the whole catalog. Each result names the evidence that selected it, and the route names it returns are what `kizlo_describe_route` and `kizlo_call` take.",
147
+ inputSchema: {
148
+ query: z.string().optional().describe("Terms to rank on. Omit or leave empty to browse every route."),
149
+ namespace: z.string().optional().describe("Only routes in this REST namespace, e.g. \"wp/v2\" or \"kizlo/v1\"."),
150
+ method: z.string().optional().describe("Only routes served with this HTTP method, e.g. \"GET\"."),
151
+ access: z.enum(["read", "write"]).optional().describe("Only reading routes (GET, HEAD, OPTIONS) or only writing ones."),
152
+ limit: z.number().int().optional().describe("Results per page. Defaults to 20, at most 100."),
153
+ cursor: z.string().optional().describe("The `nextCursor` from a previous search, to read the next page.")
154
+ },
155
+ outputSchema: SEARCH_OUTPUT
156
+ }, async (input) => toolContent(searchRoutes(state, input), summarizeSearch));
157
+ server.registerTool("kizlo_describe_route", {
158
+ title: "Describe a WordPress route",
159
+ description: "The complete contract for one route: the JSON Schema for its `params`, `query`, and `body`, with the definitions they reference; the response schema for each HTTP status, with content types and headers; which arguments are interpolated into the path; and the error codes the route declares.",
160
+ inputSchema: { route: z.string().describe("A route name from `kizlo_search_routes`, e.g. `kizlo.postTypes.book.list`.") },
161
+ outputSchema: DESCRIBE_OUTPUT
162
+ }, async ({ route }) => toolContent(describeRoute(state, { route })));
163
+ server.registerTool("kizlo_call", {
164
+ title: "Call a WordPress route",
165
+ description: "Run one route against this project's WordPress and return its response. Arguments go in `input` under the part they belong to: `params` for the values interpolated into the path, `query` for query parameters, and `body` for the payload. `kizlo_describe_route` says which are which.",
166
+ inputSchema: {
167
+ route: z.string().describe("A route name from `kizlo_search_routes`."),
168
+ input: z.object({
169
+ params: z.record(z.string(), z.unknown()).optional().describe("Values interpolated into the path."),
170
+ query: z.record(z.string(), z.unknown()).optional().describe("Query parameters."),
171
+ body: z.unknown().optional().describe("The request payload.")
172
+ }).optional().describe("The route's arguments, grouped as `kizlo_describe_route` describes them.")
173
+ },
174
+ outputSchema: CALL_OUTPUT
175
+ }, async ({ route, input }) => toolContent(await callRoute(state, input === void 0 ? { route } : {
176
+ route,
177
+ input
178
+ })));
179
+ return server;
180
+ }
181
+ /**
182
+ * Bind the MCP server for this session.
183
+ *
184
+ * It binds once and stays bound. The contract watcher restarts whenever `.env` or a config file
185
+ * changes, and tying the socket to that cycle would drop the harness's connection on every save and
186
+ * race the rebind against a port the previous listener had not finished releasing. Nothing here is
187
+ * captured from the watcher either: `state` is read per tool call, so a reload that changes the
188
+ * WordPress connection takes effect on the next call without rebinding anything.
189
+ */
190
+ async function startMcpServer(state, options) {
191
+ const server = createServer((request, response) => {
192
+ if (!isAllowedOrigin(request.headers.origin)) {
193
+ response.writeHead(403, { "content-type": "application/json" });
194
+ response.end(JSON.stringify({ error: `Refused an MCP request from origin ${request.headers.origin}.` }));
195
+ return;
196
+ }
197
+ const { pathname } = new URL(request.url ?? "/", `http://${MCP_HOST}`);
198
+ if (pathname !== MCP_PATH) {
199
+ response.writeHead(404, { "content-type": "application/json" });
200
+ response.end(JSON.stringify({ error: `Nothing is served at ${pathname}. The MCP endpoint is ${MCP_PATH}.` }));
201
+ return;
202
+ }
203
+ dispatch(request, response, state);
204
+ });
205
+ await new Promise((resolve, reject) => {
206
+ server.once("error", reject);
207
+ server.listen(options.port, MCP_HOST, () => {
208
+ server.removeListener("error", reject);
209
+ server.on("error", (error) => log.error("MCP server error:", error));
210
+ resolve();
211
+ });
212
+ });
213
+ const address = server.address();
214
+ const port = typeof address === "object" && address !== null ? address.port : options.port;
215
+ return {
216
+ url: `http://${MCP_HOST}:${port}${MCP_PATH}`,
217
+ port,
218
+ stop: () => stopServer(server)
219
+ };
220
+ }
221
+ /**
222
+ * Answer one request with a server and transport of its own.
223
+ *
224
+ * Stateless, with plain JSON replies: a dev session has exactly one harness attached and nothing to
225
+ * remember between its calls, so there is no session to track and no reason to hold an event stream
226
+ * open. Per request rather than shared, because a stateless transport carries the state of the one
227
+ * exchange it was built for and cannot answer a second. Building three tools again each time costs
228
+ * nothing next to the request, and it is what keeps the tools reading the current `state`.
229
+ */
230
+ async function dispatch(request, response, state) {
231
+ const mcp = createMcpServer(state);
232
+ const transport = new StreamableHTTPServerTransport({ enableJsonResponse: true });
233
+ response.on("close", () => {
234
+ transport.close();
235
+ mcp.close();
236
+ });
237
+ await mcp.connect(transport);
238
+ await transport.handleRequest(request, response);
239
+ }
240
+ async function stopServer(server) {
241
+ await new Promise((resolve) => {
242
+ server.close(() => resolve());
243
+ server.closeAllConnections();
244
+ });
245
+ }
246
+
247
+ //#endregion
248
+ export { MCP_HOST, MCP_PATH, isAllowedOrigin, startMcpServer };
@@ -0,0 +1,7 @@
1
+ //#region src/cli/mcp/state.ts
2
+ function createMcpState() {
3
+ return {};
4
+ }
5
+
6
+ //#endregion
7
+ export { createMcpState };
@@ -0,0 +1,116 @@
1
+ import { buildWordPressRequest } from "../../wordpress/endpoint.js";
2
+ import { WordPressTransport } from "../../wordpress/transport.js";
3
+ import { routesOf } from "./routes.js";
4
+ import { inputJsonSchema, toJsonSchema } from "./schema.js";
5
+ import { searchRoutes } from "./search.js";
6
+
7
+ //#region src/cli/mcp/tools.ts
8
+ /** The document is fetched by the watcher, so the only reason it is missing is that none has arrived yet. */
9
+ const NO_DOCUMENT = "The WordPress contract has not been fetched yet. Retry in a moment; `kizlo dev` refreshes it every few seconds.";
10
+ function failed(message) {
11
+ return {
12
+ ok: false,
13
+ error: {
14
+ kind: "request",
15
+ message
16
+ }
17
+ };
18
+ }
19
+ /**
20
+ * Rank the routes this WordPress serves against a query, or browse them all when there is none.
21
+ *
22
+ * Summaries and match evidence only. The schemas behind these routes are far too large to put in
23
+ * front of a model at once, which is what `kizlo_describe_route` is for.
24
+ */
25
+ function searchRoutes$1(state, input = {}) {
26
+ if (!state.document) return failed(NO_DOCUMENT);
27
+ const outcome = searchRoutes(state.document, input);
28
+ if (outcome.count === 0) {
29
+ const within = [
30
+ input.namespace !== void 0 ? `namespace "${input.namespace}"` : void 0,
31
+ input.method !== void 0 ? `method ${input.method.toUpperCase()}` : void 0,
32
+ input.access !== void 0 ? `${input.access} routes` : void 0
33
+ ].filter((part) => part !== void 0).join(", ");
34
+ return {
35
+ ok: true,
36
+ value: {
37
+ ...outcome,
38
+ message: `No route matches that search${within === "" ? "" : ` within ${within}`}. This WordPress serves these namespaces: ${outcome.namespaces.join(", ")}.`
39
+ }
40
+ };
41
+ }
42
+ return {
43
+ ok: true,
44
+ value: outcome
45
+ };
46
+ }
47
+ /** The full contract for one route, which is what a caller needs before it can build a call. */
48
+ function describeRoute(state, input) {
49
+ if (!state.document) return failed(NO_DOCUMENT);
50
+ const route = routesOf(state.document).get(input.route);
51
+ if (!route) return failed(unknownRoute(input.route));
52
+ return {
53
+ ok: true,
54
+ value: {
55
+ name: route.name,
56
+ namespace: route.namespace,
57
+ method: route.method,
58
+ path: route.path,
59
+ ...route.summary !== void 0 ? { summary: route.summary } : {},
60
+ ...route.description !== void 0 ? { description: route.description } : {},
61
+ ...route.deprecated ? { deprecated: true } : {},
62
+ pathParameters: route.definition.pathParameters,
63
+ input: inputJsonSchema(route.operation.input, state.document),
64
+ responses: responseSchemas(route.operation.responses, state.document),
65
+ errors: route.operation.errors
66
+ }
67
+ };
68
+ }
69
+ /** Run one route against the connected WordPress and hand back what it answered. */
70
+ async function callRoute(state, input) {
71
+ if (!state.document) return failed(NO_DOCUMENT);
72
+ if (!state.credentials) return failed("No WordPress connection is configured, so nothing can be called. Check the connection settings in `.env`.");
73
+ const route = routesOf(state.document).get(input.route);
74
+ if (!route) return failed(unknownRoute(input.route));
75
+ const built = buildWordPressRequest(route.definition, input.input ?? {});
76
+ if (built.error) return failed(built.error.message);
77
+ const response = await new WordPressTransport({ credentials: state.credentials }).request(built.request);
78
+ if (response.error) return {
79
+ ok: false,
80
+ error: {
81
+ kind: "response",
82
+ message: `${route.method} ${route.path} failed (${response.status || "no response"}): ${response.error.code} — ${response.error.message}`,
83
+ route: route.name,
84
+ method: route.method,
85
+ path: route.path,
86
+ status: response.status,
87
+ error: {
88
+ code: response.error.code,
89
+ message: response.error.message,
90
+ data: response.error.data
91
+ }
92
+ }
93
+ };
94
+ return {
95
+ ok: true,
96
+ value: {
97
+ status: response.status,
98
+ data: response.data
99
+ }
100
+ };
101
+ }
102
+ /** The response half of the contract, converted so a caller can read a success or a failure body. */
103
+ function responseSchemas(responses, document) {
104
+ return Object.fromEntries(Object.entries(responses).map(([status, response]) => [status, {
105
+ ...response.description !== void 0 ? { description: response.description } : {},
106
+ ...response.content_type !== void 0 ? { content_type: response.content_type } : {},
107
+ ...response.headers ? { headers: toJsonSchema(response.headers, document) } : {},
108
+ ...response.body ? { body: toJsonSchema(response.body, document) } : {}
109
+ }]));
110
+ }
111
+ function unknownRoute(name) {
112
+ return `No route named "${name}" in this WordPress contract. Call \`kizlo_search_routes\` for the routes it serves.`;
113
+ }
114
+
115
+ //#endregion
116
+ export { callRoute, describeRoute, searchRoutes$1 as searchRoutes };
@@ -17,8 +17,8 @@ const COMMENT_PROCEDURES = {
17
17
  output: Comment
18
18
  }, async ({ context, errors, input }) => {
19
19
  const response = await context.wordpress.comments.retrieve({
20
- id: input.params.id,
21
- password: input.query?.password
20
+ params: { id: input.params.id },
21
+ query: { password: input.query?.password }
22
22
  });
23
23
  if (response.error) switch (response.error.code) {
24
24
  case "rest_comment_invalid_id":
@@ -63,7 +63,7 @@ const COMMENT_PROCEDURES = {
63
63
  post: listed(input.query?.post),
64
64
  search: input.query?.search
65
65
  };
66
- const response = await context.wordpress.comments.list(searchParams);
66
+ const response = await context.wordpress.comments.list({ query: searchParams });
67
67
  if (response.error) switch (response.error.code) {
68
68
  case "rest_cannot_read":
69
69
  case "rest_cannot_read_post":
@@ -114,7 +114,7 @@ const COMMENT_PROCEDURES = {
114
114
  author_url: input.body.authorUrl,
115
115
  parent: input.body.parentId
116
116
  };
117
- const response = await context.wordpress.kizlo.comments.create(submission);
117
+ const response = await context.wordpress.kizlo.comments.create({ body: submission });
118
118
  if (response.error) switch (response.error.code) {
119
119
  case "require_name_email": throw errors.COMMENT_NAME_EMAIL_REQUIRED();
120
120
  case "require_valid_email": throw errors.COMMENT_INVALID_EMAIL();
package/dist/config.d.ts CHANGED
@@ -120,6 +120,16 @@ interface KizloLocalConfig {
120
120
  /** The test stack run by `kizlo test`. Inherits `version` and `fixtures` from {@link KizloLocalConfig.dev}. */
121
121
  test?: KizloTestConfig;
122
122
  }
123
+ interface KizloMcpConfig {
124
+ /**
125
+ * Port the server binds on `127.0.0.1`. Unset, it starts at the Kizlo default and steps off a
126
+ * collision, which is why nothing has to be configured to run two projects at once. Set it when a
127
+ * harness config has to name the port: an explicitly set port is never auto-reassigned, and
128
+ * `kizlo dev` stops rather than serving on one you did not choose.
129
+ * @default 8300
130
+ */
131
+ port?: number;
132
+ }
123
133
  interface KizloGlobalConfig {
124
134
  /**
125
135
  * Where Kizlo generates, and what it watches. A string names the home directory Kizlo owns the
@@ -139,7 +149,13 @@ interface KizloGlobalConfig {
139
149
  * stack name, the per-branch `worktrees` toggle, and the two stacks live.
140
150
  */
141
151
  local?: boolean | KizloLocalConfig;
152
+ /**
153
+ * The MCP server `kizlo dev` serves on loopback, exposing this project's WordPress routes to an AI
154
+ * harness. It runs whenever `kizlo dev` can resolve a WordPress connection; this block only tunes it.
155
+ * It is never part of a built app: the server lives in the CLI, so nothing about it can be deployed.
156
+ */
157
+ mcp?: KizloMcpConfig;
142
158
  }
143
159
  declare function defineConfig(config: KizloGlobalConfig): KizloGlobalConfig;
144
160
  //#endregion
145
- export { KizloDevConfig, KizloDir, KizloGlobalConfig, KizloLocalConfig, KizloTestConfig, defineConfig };
161
+ export { KizloDevConfig, KizloDir, KizloGlobalConfig, KizloLocalConfig, KizloMcpConfig, KizloTestConfig, defineConfig };
@@ -5,7 +5,7 @@ var EmailService = class {
5
5
  this.wordpress = wordpress;
6
6
  }
7
7
  async send(params) {
8
- const { error } = await this.wordpress.email.send(params);
8
+ const { error } = await this.wordpress.kizlo.email.send({ body: params });
9
9
  if (error) throw error;
10
10
  }
11
11
  };
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  import { WP_Error } from "./wordpress/error.js";
2
- import { ActiveWordPressClient, WP_CallOptions, WP_Client, WP_CommonErrorCode, WP_CurrencyFormat, WP_CustomFields, WP_CustomFieldsPath, WP_Endpoint, WP_EndpointData, WP_EndpointDefinition, WP_EndpointError, WP_EndpointInput, WP_EndpointPath, WP_EndpointResult, WP_ErrorData, WP_Failure, WP_List, WP_ListMetadata, WP_RequestBuild, WP_RequestContentType, WP_RequestInput, WP_RequestMethod, WP_ResponseContentType, WP_Result, WP_Success, WP_TransportFailure, WP_TypedHeaders, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry } from "./wordpress/types.js";
2
+ import { ActiveWordPressClient, WP_CallOptions, WP_Client, WP_CommonErrorCode, WP_CurrencyFormat, WP_CustomFields, WP_CustomFieldsPath, WP_Endpoint, WP_EndpointData, WP_EndpointDefinition, WP_EndpointError, WP_EndpointInput, WP_EndpointPath, WP_EndpointResult, WP_ErrorData, WP_Failure, WP_List, WP_ListMetadata, WP_RequestBuild, WP_RequestContentType, WP_RequestInput, WP_RequestMethod, WP_RequestParts, WP_ResponseContentType, WP_Result, WP_Success, WP_TransportFailure, WP_TypedHeaders, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry } from "./wordpress/types.js";
3
3
  import { WordPressTransport, WordPressTransportOptions, WordPressTransportResult } from "./wordpress/transport.js";
4
4
  import { buildWordPressRequest, createWordPressClient, wpEndpoint } from "./wordpress/endpoint.js";
5
5
  import { isWordPressResourceError } from "./wordpress/utils.js";
@@ -28,7 +28,7 @@ import { AnyEventSchema, AnyEvents, EventHandler, EventHandlerFn, InferEventUnio
28
28
  import { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorMapLike, ErrorDefinition, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError } from "./shared/error.js";
29
29
  import { AnyMiddleware, ExtractMiddlewareContextOutput, InferMiddlewares, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, createMiddleware } from "./shared/middleware.js";
30
30
  import { AnyProcedure, AnyProcedureTree, BaseHandlerOptions, ExtractParams, ExtractProcedureByScope, InvocationScope, OpenapiPart, Procedure, ProcedureErrors, ProcedureHandler, ProcedureOptions, ProcedureTreeDepthTuple, ResolveParamsPart, ResolvedSchemaInput, ResolvedSchemaOutput, SchemaIO, buildProcedure, combineDetailed, createProcedure, handleUnexpectedError, schemaType } from "./shared/procedure.js";
31
- import { AnyIntegration, EnvReader, EnvRecord, EnvSource, ExtractIntegrationProcedures, InferIntegrationProcedures, Integration, IntegrationRequirements, KizloEnv, WordPressEnv, assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv } from "./shared/integration.js";
31
+ import { AnyIntegration, EnvReader, EnvRecord, EnvSource, ExtractIntegrationProcedures, InferIntegrationProcedures, Integration, IntegrationRequirements, KizloEnv, WordPressEnv, assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv, sortIntegrations } from "./shared/integration.js";
32
32
  import { InferProcedureData, InferProcedureError, InferProcedureInput, InferProcedureResult, KizloErrorUnion, KizloResult, MaybeCallerOptions, ProcedureMethod, ResultClient, createResultClient } from "./shared/result.js";
33
33
  import { AnyKizloConfig, CreateKizloOptions, Kizlo, KizloConfig, RootProcedures, S2SClient, createKizlo, integrationEnv, resolveKizloConfig, resolveWordPressConnection, wordPressConnectionComplete } from "./kizlo.js";
34
34
  import { WEB_MANIFEST_ROUTE, WebManifest, buildWebManifest, createManifestRoute } from "./brand/manifest.js";
@@ -43,4 +43,4 @@ import { ShaAlgorithm, compare, hash, hmac } from "./shared/crypto.js";
43
43
  import { Identifier, parseIdentifier } from "./shared/identifier.js";
44
44
  import { createOrpcRouter } from "./shared/router.js";
45
45
  import { deserializeCurrencyFormat, deserializeListMetadata, emptyList, serializeCurrencyFormat } from "./shared/serialize.js";
46
- export { ActiveWordPressClient, AnyContext, AnyEventSchema, AnyEvents, AnyIntegration, AnyKizloConfig, AnyMiddleware, AnyNestedClient, AnyProcedure, AnyProcedureTree, AuthAdapter, AuthGetSession, AuthUser, AuthorsSettings, AuthorsSettingsInput, BaseHandlerOptions, BrandSettings, BrandSettingsInput, COMMON_ERRORS, CONTENT_TYPES, CORE_PROCEDURES, CaptchaAdapter, type Category, type CategoryCustomFields, CategoryCustomFieldsSchema, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, ConnInfo, ConnInfoFn, ConsoleLogAdapterOptions, ContentType, Context, ContextConfig, Contract, ContractProcedure, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, CookiesStorage, CoreProcedures, CrawlingSettings, CrawlingSettingsInput, CreateKizloOptions, CreateSitemapRouteOptions, CurrencyFormat, DefinedErrorMapLike, DevPluginSource, EnvReader, EnvRecord, EnvSource, ErrorDefinition, EventHandler, EventHandlerFn, ExtractIntegrationProcedures, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, Fixture, FixtureCleanupFn, FixtureSeedFn, FixtureSettleFn, GeoAdapter, GeoGetConnInfo, HTTPMethod, HeadlessSettings, HeadlessSettingsInput, IconDescriptor, Identifier, IdentifierInput, IdentitySettings, IdentitySettingsInput, InferEventUnion, InferIntegrationProcedures, InferMiddlewares, InferProcedureData, InferProcedureError, InferProcedureInput, InferProcedureResult, Integration, IntegrationRequirements, InvocationScope, JsonValue, Kizlo, KizloClient, KizloClientConfig, KizloConfig, KizloEnv, KizloError, KizloErrorOptions, KizloErrorUnion, KizloResult, LIST_ORDER, List, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, LocalPlugin, LogLevel, LogPayload, Logger, LoggerAdapter, ManifestIcon, MaybeCallerOptions, MaybeOptionalOptions, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, type Page, type PageCustomFields, PageCustomFieldsSchema, PersonSettings, PersonSettingsInput, PluginSource, type Post, type PostCustomFields, PostCustomFieldsSchema, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, PreviewTokenData, PreviewTokenPayload, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureMethod, ProcedureOptions, ProcedureTreeDepthTuple, RedirectInput, RedirectStatus, ResolveParamsPart, ResolvedIcons, ResolvedSchemaInput, ResolvedSchemaOutput, ResultClient, Robots, RobotsRule, RootProcedures, S2SClient, SITEMAP_BASE, SITEMAP_INDEX_SLUG, SchemaIO, SeedContext, Seo, SeoHead, SeoSchema, ServiceAdapters, SessionFn, Settings, SettingsService, SettleContext, ShaAlgorithm, SiteSettings, SiteSettingsInput, Sitemap, SitemapIndex, SitemapIndexEntry, SitemapList, SitemapRouteExtra, SitemapUrl, SitemapUrlImage, SitemapUrlList, SocialProfile, type Tag, type TagCustomFields, TagCustomFieldsSchema, TaxonomySettings, TaxonomySettingsInput, TestAdminUser, TestCredentials, TestUser, ThrowableErrorFn, ThrowableErrorMap, UploadsSettings, UploadsSettingsInput, VerifyCaptchaFn, VerifyPreviewTokenFn, WEB_MANIFEST_ROUTE, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapUrl, WPK_SitemapUrlImage, WP_CallOptions, WP_Client, WP_CommonErrorCode, WP_CurrencyFormat, WP_CustomFields, WP_CustomFieldsPath, WP_Endpoint, WP_EndpointData, WP_EndpointDefinition, WP_EndpointError, WP_EndpointInput, WP_EndpointPath, WP_EndpointResult, WP_Error, WP_ErrorData, WP_Failure, WP_List, WP_ListMetadata, WP_RequestBuild, WP_RequestContentType, WP_RequestInput, WP_RequestMethod, WP_ResponseContentType, WP_Result, WP_Success, WP_TransportFailure, WP_TypedHeaders, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry, WordPressEnv, WordPressTransport, WordPressTransportOptions, WordPressTransportResult, altcha, arkose, assertIntegrationEndpoints, assertIntegrationEnv, authMock, buildProcedure, buildWebManifest, buildWordPressRequest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createGeoAdapter, createIntegration, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createResultClient, createSitemapRedirectRoute, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, createWordPressClient, customFieldsSchema, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, integrationEnv, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, mergeServiceAdapters, missingEndpoints, missingEnv, noopAdapter, parseIdentifier, parseSitemapSlug, readEnv, recaptcha, renderJsonLd, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, resolveWordPressConnection, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, toKizloError, turnstile, wordPressConnectionComplete, wpEndpoint, xmlResponse };
46
+ export { ActiveWordPressClient, AnyContext, AnyEventSchema, AnyEvents, AnyIntegration, AnyKizloConfig, AnyMiddleware, AnyNestedClient, AnyProcedure, AnyProcedureTree, AuthAdapter, AuthGetSession, AuthUser, AuthorsSettings, AuthorsSettingsInput, BaseHandlerOptions, BrandSettings, BrandSettingsInput, COMMON_ERRORS, CONTENT_TYPES, CORE_PROCEDURES, CaptchaAdapter, type Category, type CategoryCustomFields, CategoryCustomFieldsSchema, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, ConnInfo, ConnInfoFn, ConsoleLogAdapterOptions, ContentType, Context, ContextConfig, Contract, ContractProcedure, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, CookiesStorage, CoreProcedures, CrawlingSettings, CrawlingSettingsInput, CreateKizloOptions, CreateSitemapRouteOptions, CurrencyFormat, DefinedErrorMapLike, DevPluginSource, EnvReader, EnvRecord, EnvSource, ErrorDefinition, EventHandler, EventHandlerFn, ExtractIntegrationProcedures, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, Fixture, FixtureCleanupFn, FixtureSeedFn, FixtureSettleFn, GeoAdapter, GeoGetConnInfo, HTTPMethod, HeadlessSettings, HeadlessSettingsInput, IconDescriptor, Identifier, IdentifierInput, IdentitySettings, IdentitySettingsInput, InferEventUnion, InferIntegrationProcedures, InferMiddlewares, InferProcedureData, InferProcedureError, InferProcedureInput, InferProcedureResult, Integration, IntegrationRequirements, InvocationScope, JsonValue, Kizlo, KizloClient, KizloClientConfig, KizloConfig, KizloEnv, KizloError, KizloErrorOptions, KizloErrorUnion, KizloResult, LIST_ORDER, List, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, LocalPlugin, LogLevel, LogPayload, Logger, LoggerAdapter, ManifestIcon, MaybeCallerOptions, MaybeOptionalOptions, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, type Page, type PageCustomFields, PageCustomFieldsSchema, PersonSettings, PersonSettingsInput, PluginSource, type Post, type PostCustomFields, PostCustomFieldsSchema, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, PreviewTokenData, PreviewTokenPayload, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureMethod, ProcedureOptions, ProcedureTreeDepthTuple, RedirectInput, RedirectStatus, ResolveParamsPart, ResolvedIcons, ResolvedSchemaInput, ResolvedSchemaOutput, ResultClient, Robots, RobotsRule, RootProcedures, S2SClient, SITEMAP_BASE, SITEMAP_INDEX_SLUG, SchemaIO, SeedContext, Seo, SeoHead, SeoSchema, ServiceAdapters, SessionFn, Settings, SettingsService, SettleContext, ShaAlgorithm, SiteSettings, SiteSettingsInput, Sitemap, SitemapIndex, SitemapIndexEntry, SitemapList, SitemapRouteExtra, SitemapUrl, SitemapUrlImage, SitemapUrlList, SocialProfile, type Tag, type TagCustomFields, TagCustomFieldsSchema, TaxonomySettings, TaxonomySettingsInput, TestAdminUser, TestCredentials, TestUser, ThrowableErrorFn, ThrowableErrorMap, UploadsSettings, UploadsSettingsInput, VerifyCaptchaFn, VerifyPreviewTokenFn, WEB_MANIFEST_ROUTE, WPK_RobotRule, WPK_Robots, WPK_Seo, WPK_Sitemap, WPK_SitemapUrl, WPK_SitemapUrlImage, WP_CallOptions, WP_Client, WP_CommonErrorCode, WP_CurrencyFormat, WP_CustomFields, WP_CustomFieldsPath, WP_Endpoint, WP_EndpointData, WP_EndpointDefinition, WP_EndpointError, WP_EndpointInput, WP_EndpointPath, WP_EndpointResult, WP_Error, WP_ErrorData, WP_Failure, WP_List, WP_ListMetadata, WP_RequestBuild, WP_RequestContentType, WP_RequestInput, WP_RequestMethod, WP_RequestParts, WP_ResponseContentType, WP_Result, WP_Success, WP_TransportFailure, WP_TypedHeaders, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry, WordPressEnv, WordPressTransport, WordPressTransportOptions, WordPressTransportResult, altcha, arkose, assertIntegrationEndpoints, assertIntegrationEnv, authMock, buildProcedure, buildWebManifest, buildWordPressRequest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createGeoAdapter, createIntegration, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createResultClient, createSitemapRedirectRoute, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, createWordPressClient, customFieldsSchema, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, integrationEnv, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, mergeServiceAdapters, missingEndpoints, missingEnv, noopAdapter, parseIdentifier, parseSitemapSlug, readEnv, recaptcha, renderJsonLd, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, resolveWordPressConnection, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, sortIntegrations, toKizloError, turnstile, wordPressConnectionComplete, wpEndpoint, xmlResponse };
package/dist/index.js CHANGED
@@ -32,10 +32,10 @@ import { PageCustomFieldsSchema } from "./page/schema.js";
32
32
  import { PostCustomFieldsSchema } from "./post/schema.js";
33
33
  import { TagCustomFieldsSchema } from "./tag/schema.js";
34
34
  import { CORE_PROCEDURES } from "./procedures.js";
35
- import { assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv } from "./shared/integration.js";
35
+ import { assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv, sortIntegrations } from "./shared/integration.js";
36
36
  import { createEventHandler, createWebhookRouter } from "./webhook/index.js";
37
37
  import { Kizlo, createKizlo, integrationEnv, resolveKizloConfig, resolveWordPressConnection, wordPressConnectionComplete } from "./kizlo.js";
38
38
  import { SITEMAP_BASE, SITEMAP_INDEX_SLUG, createSitemapRedirectRoute, createSitemapRoute } from "./seo/sitemap.js";
39
39
  import { createMiddleware } from "./shared/middleware.js";
40
40
 
41
- export { COMMON_ERRORS, CONTENT_TYPES, CORE_PROCEDURES, CategoryCustomFieldsSchema, ContentType, Context, CookiesStorage, CurrencyFormat, IdentifierInput, Kizlo, KizloClient, KizloError, LIST_ORDER, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, PageCustomFieldsSchema, PostCustomFieldsSchema, PreviewTokenData, PreviewTokenPayload, Robots, RobotsRule, SITEMAP_BASE, SITEMAP_INDEX_SLUG, Seo, SeoHead, SeoSchema, SettingsService, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList, TagCustomFieldsSchema, WEB_MANIFEST_ROUTE, WP_Error, WordPressTransport, altcha, arkose, assertIntegrationEndpoints, assertIntegrationEnv, authMock, buildProcedure, buildWebManifest, buildWordPressRequest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createGeoAdapter, createIntegration, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createResultClient, createSitemapRedirectRoute, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, createWordPressClient, customFieldsSchema, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, integrationEnv, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, mergeServiceAdapters, missingEndpoints, missingEnv, noopAdapter, parseIdentifier, parseSitemapSlug, readEnv, recaptcha, renderJsonLd, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, resolveWordPressConnection, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, toKizloError, turnstile, wordPressConnectionComplete, wpEndpoint, xmlResponse };
41
+ export { COMMON_ERRORS, CONTENT_TYPES, CORE_PROCEDURES, CategoryCustomFieldsSchema, ContentType, Context, CookiesStorage, CurrencyFormat, IdentifierInput, Kizlo, KizloClient, KizloError, LIST_ORDER, ListMetadata, ListOrder, ListSitemapUrlInput, ListSitemapUrlInputBase, PageCustomFieldsSchema, PostCustomFieldsSchema, PreviewTokenData, PreviewTokenPayload, Robots, RobotsRule, SITEMAP_BASE, SITEMAP_INDEX_SLUG, Seo, SeoHead, SeoSchema, SettingsService, Sitemap, SitemapIndex, SitemapList, SitemapUrl, SitemapUrlImage, SitemapUrlList, TagCustomFieldsSchema, WEB_MANIFEST_ROUTE, WP_Error, WordPressTransport, altcha, arkose, assertIntegrationEndpoints, assertIntegrationEnv, authMock, buildProcedure, buildWebManifest, buildWordPressRequest, combineDetailed, compare, consoleLog, createAuthAdapter, createCaptchaAdapter, createCookiesAdapter, createEventHandler, createGeoAdapter, createIntegration, createKizlo, createKizloClient, createLoggerAdapter, createManifestRoute, createMiddleware, createOrpcRouter, createProcedure, createResultClient, createSitemapRedirectRoute, createSitemapRoute, createThrowableErrorMap, createWebhookRouter, createWordPressClient, customFieldsSchema, defineErrorMap, defineFixture, deserializeCurrencyFormat, deserializeListMetadata, deserializeSeo, emptyList, friendlyCaptcha, generateContract, geoMock, geoVercelNext, handleUnexpectedError, hash, hcaptcha, hmac, integrationEnv, isContractProcedure, isKizloError, isLocalPlugin, isWordPressResourceError, mergeServiceAdapters, missingEndpoints, missingEnv, noopAdapter, parseIdentifier, parseSitemapSlug, readEnv, recaptcha, renderJsonLd, renderSitemapIndex, renderUrlSet, resolveIcons, resolveKizloConfig, resolveWordPressConnection, restoreContract, schemaType, serializeCurrencyFormat, sitemapEntryPath, sortIntegrations, toKizloError, turnstile, wordPressConnectionComplete, wpEndpoint, xmlResponse };
@@ -1,3 +1,4 @@
1
+ import { FRAMEWORK_INTEGRATION_ORDER } from "../../shared/constants.js";
1
2
  import { createIntegration } from "../../shared/integration.js";
2
3
  import { runtimeEnv } from "../runtime-env.js";
3
4
 
@@ -6,6 +7,7 @@ import { runtimeEnv } from "../runtime-env.js";
6
7
  function astro(options) {
7
8
  return createIntegration({
8
9
  id: "astro",
10
+ order: FRAMEWORK_INTEGRATION_ORDER,
9
11
  env: runtimeEnv(options.env, "PUBLIC_KIZLO_BASE_URL")
10
12
  });
11
13
  }
@@ -1,3 +1,4 @@
1
+ import { FRAMEWORK_INTEGRATION_ORDER } from "../../shared/constants.js";
1
2
  import { createIntegration } from "../../shared/integration.js";
2
3
  import { runtimeEnv } from "../runtime-env.js";
3
4
  import { nextRevalidation } from "./revalidate.js";
@@ -9,6 +10,7 @@ function nextjs(options = {}) {
9
10
  const revalidation = options.revalidate;
10
11
  return createIntegration({
11
12
  id: "nextjs",
13
+ order: FRAMEWORK_INTEGRATION_ORDER,
12
14
  env: runtimeEnv(source, "NEXT_PUBLIC_KIZLO_BASE_URL"),
13
15
  events: revalidation === false ? void 0 : nextRevalidation(typeof revalidation === "object" ? revalidation : void 0).events
14
16
  });
@@ -1,3 +1,4 @@
1
+ import { FRAMEWORK_INTEGRATION_ORDER } from "../../shared/constants.js";
1
2
  import { createIntegration } from "../../shared/integration.js";
2
3
  import { runtimeEnv } from "../runtime-env.js";
3
4
 
@@ -6,6 +7,7 @@ import { runtimeEnv } from "../runtime-env.js";
6
7
  function node(options = {}) {
7
8
  return createIntegration({
8
9
  id: "node",
10
+ order: FRAMEWORK_INTEGRATION_ORDER,
9
11
  env: runtimeEnv(options.env ?? process.env, "KIZLO_BASE_URL")
10
12
  });
11
13
  }
@@ -1,3 +1,4 @@
1
+ import { FRAMEWORK_INTEGRATION_ORDER } from "../../shared/constants.js";
1
2
  import { createIntegration } from "../../shared/integration.js";
2
3
  import { runtimeEnv } from "../runtime-env.js";
3
4
 
@@ -6,6 +7,7 @@ import { runtimeEnv } from "../runtime-env.js";
6
7
  function tanstackStart(options = {}) {
7
8
  return createIntegration({
8
9
  id: "tanstack-start",
10
+ order: FRAMEWORK_INTEGRATION_ORDER,
9
11
  env: runtimeEnv(options.env ?? process.env, "VITE_KIZLO_BASE_URL")
10
12
  });
11
13
  }
package/dist/kizlo.js CHANGED
@@ -8,7 +8,7 @@ import { isTypescriptObject } from "./shared/utils.js";
8
8
  import { Context } from "./context.js";
9
9
  import { CORE_PROCEDURES } from "./procedures.js";
10
10
  import { isContractGeneration } from "./shared/contract-generation.js";
11
- import { assertIntegrationEndpoints, assertIntegrationEnv, missingEnv, readEnv } from "./shared/integration.js";
11
+ import { assertIntegrationEndpoints, assertIntegrationEnv, missingEnv, readEnv, sortIntegrations } from "./shared/integration.js";
12
12
  import { createWebhookRouter } from "./webhook/index.js";
13
13
  import { tryCatch } from "@kizlo/shared";
14
14
  import { ORPCError, createRouterClient } from "@orpc/server";
@@ -101,7 +101,7 @@ var Kizlo = class {
101
101
  const reservedIds = new Set([...Object.keys(CORE_PROCEDURES), "webhooks"]);
102
102
  const integrationIds = /* @__PURE__ */ new Set();
103
103
  const generating = isContractGeneration();
104
- for (const integration of this.config.integrations ?? []) {
104
+ for (const integration of sortIntegrations(this.config.integrations ?? [])) {
105
105
  if (reservedIds.has(integration.id)) throw new KizloError("INTEGRATION_ID_CONFLICT", { message: `The integration id "${integration.id}" is reserved by Kizlo. Choose a different integration id.` });
106
106
  if (integrationIds.has(integration.id)) throw new KizloError("INTEGRATION_ID_CONFLICT", { message: `The integration id "${integration.id}" is registered more than once. Give every integration a unique id.` });
107
107
  integrationIds.add(integration.id);
@@ -130,9 +130,10 @@ const WORDPRESS_ENV_VALUES = new Set([
130
130
  * Kizlo's active WordPress connection from the canonical `mode` value.
131
131
  */
132
132
  function integrationEnv(integrations) {
133
+ const mounted = sortIntegrations(integrations);
133
134
  const composed = (name) => {
134
135
  let value;
135
- for (const integration of integrations) {
136
+ for (const integration of mounted) {
136
137
  if (!integration.env) continue;
137
138
  const contribution = readEnv(integration.env, name);
138
139
  if (contribution !== void 0) value = contribution;
@@ -3,7 +3,7 @@ import { listed, stringifiedMetaRecord } from "@kizlo/shared";
3
3
  //#region src/menu/utils.ts
4
4
  function deserializeListMenuInput(input) {
5
5
  const orderby = input?.orderby === "relevance" && !input?.search || input?.orderby === "include" && input?.include === void 0 || input?.orderby === "include_slugs" && input?.slug === void 0 ? void 0 : input?.orderby;
6
- return {
6
+ return { query: {
7
7
  after: input?.after,
8
8
  before: input?.before,
9
9
  exclude: listed(input?.exclude),
@@ -21,7 +21,7 @@ function deserializeListMenuInput(input) {
21
21
  tax_relation: input?.taxRelation,
22
22
  search_columns: input?.searchColumns,
23
23
  status: ["publish"]
24
- };
24
+ } };
25
25
  }
26
26
  /**
27
27
  * The `href` a headless frontend links to. WP builds a non-custom item's `url` as an absolute same-site
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.20.2";
2
+ var version = "0.22.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };