kizlo 0.20.2 → 0.21.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.
@@ -69,11 +69,19 @@ interface Integration<TId extends string, TProcedures extends AnyProcedureTree =
69
69
  env?: EnvSource;
70
70
  /** Environment, endpoint, and WordPress plugin requirements checked at their documented lifecycle points. */
71
71
  requires?: IntegrationRequirements;
72
+ /**
73
+ * Mount position, ascending, defaulting to `0`. Mounting first means supplying the baseline a later
74
+ * integration overrides, so a framework integration declares a negative order to land ahead of app
75
+ * integrations however the `integrations` array is written.
76
+ */
77
+ order?: number;
72
78
  }
73
79
  type AnyIntegration = Integration<any, AnyProcedureTree>;
74
80
  type ExtractIntegrationProcedures<TIntegration extends AnyIntegration> = TIntegration extends Integration<infer Name, infer Procedures> ? [keyof Procedures] extends [never] ? never : string extends keyof Procedures ? never : Record<Name, Procedures> : never;
75
81
  type InferIntegrationProcedures<TIntegrations extends readonly AnyIntegration[]> = TIntegrations extends readonly [] ? Record<never, never> : ExtractIntegrationProcedures<TIntegrations[number]> extends infer R ? [R] extends [never] ? Record<never, never> : UnionToIntersection<R> : never;
76
82
  declare function createIntegration<TId extends string, TProcedures extends AnyProcedureTree = Record<never, never>>(integration: Integration<TId, TProcedures>): Integration<TId, TProcedures>;
83
+ /** Integrations in mount order. `sort` is stable, so integrations sharing an `order` keep their declared order. */
84
+ declare function sortIntegrations<TIntegration extends AnyIntegration>(integrations: readonly TIntegration[]): TIntegration[];
77
85
  /** The declared subtrees the generated tree does not have. */
78
86
  declare function missingEndpoints(endpoints: object, required: readonly string[]): string[];
79
87
  /**
@@ -88,4 +96,4 @@ declare function assertIntegrationEndpoints(integration: AnyIntegration, endpoin
88
96
  /** Fail at startup when an integration's required environment values are absent. */
89
97
  declare function assertIntegrationEnv(integration: AnyIntegration, env: EnvSource): void;
90
98
  //#endregion
91
- export { AnyIntegration, EnvReader, EnvRecord, EnvSource, ExtractIntegrationProcedures, InferIntegrationProcedures, Integration, IntegrationRequirements, KizloEnv, WordPressEnv, assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv };
99
+ export { AnyIntegration, EnvReader, EnvRecord, EnvSource, ExtractIntegrationProcedures, InferIntegrationProcedures, Integration, IntegrationRequirements, KizloEnv, WordPressEnv, assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv, sortIntegrations };
@@ -18,6 +18,10 @@ function missingEnv(source, required) {
18
18
  function createIntegration(integration) {
19
19
  return integration;
20
20
  }
21
+ /** Integrations in mount order. `sort` is stable, so integrations sharing an `order` keep their declared order. */
22
+ function sortIntegrations(integrations) {
23
+ return [...integrations].sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
24
+ }
21
25
  /** The declared subtrees the generated tree does not have. */
22
26
  function missingEndpoints(endpoints, required) {
23
27
  return required.filter((path) => {
@@ -43,8 +47,7 @@ function assertIntegrationEndpoints(integration, endpoints) {
43
47
  const missing = missingEndpoints(endpoints, required);
44
48
  if (missing.length === 0) return;
45
49
  const plugins = integration.requires?.plugins;
46
- const remedy = plugins?.length ? `Install or update the required WordPress plugins (${plugins.map((plugin) => `${plugin.name} ${plugin.version}+`).join(", ")}), then run \`kizlo generate\`.` : "Run `kizlo generate` against a WordPress that serves them.";
47
- throw new KizloError("MISSING_WORDPRESS_ENDPOINTS", { message: `The "${integration.id}" integration needs WordPress endpoints your generated client does not have: ${missing.join(", ")}. ${remedy}` });
50
+ throw new KizloError("MISSING_WORDPRESS_ENDPOINTS", { message: `${plugins?.length ? `The "${integration.id}" integration plugin is outdated. Update ${plugins.map((plugin) => `${plugin.name} to ${plugin.version} or newer`).join(" and ")}, then run \`kizlo generate\` to refresh introspection.ts.` : `The "${integration.id}" integration is missing routes in your introspection. Run \`kizlo generate\` against a WordPress that serves them to refresh introspection.ts.`}\n\nMissing routes:\n${missing.map((route) => ` - ${route}`).join("\n")}\n\n${`Download the latest version: https://kizlo.io/integrations/${integration.id}`}` });
48
51
  }
49
52
  /** Fail at startup when an integration's required environment values are absent. */
50
53
  function assertIntegrationEnv(integration, env) {
@@ -56,4 +59,4 @@ function assertIntegrationEnv(integration, env) {
56
59
  }
57
60
 
58
61
  //#endregion
59
- export { assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv };
62
+ export { assertIntegrationEndpoints, assertIntegrationEnv, createIntegration, missingEndpoints, missingEnv, readEnv, sortIntegrations };
@@ -257,6 +257,11 @@ function sortedChildren(node) {
257
257
  function sortedEndpoints(node) {
258
258
  return [...node.endpoints].sort((left, right) => left.member.localeCompare(right.member));
259
259
  }
260
+ /**
261
+ * The runtime descriptor for one operation: what the generated client emits, and what anything calling
262
+ * a route straight off the introspection document needs to build its request. Exported because the
263
+ * CLI's MCP server dispatches routes the client never generated a member for.
264
+ */
260
265
  function endpointDefinition(entry) {
261
266
  const pathParameters = sortedEntries(entry.operation.input.properties ?? {}).filter(([, schema]) => schema.in === "path").map(([name]) => name);
262
267
  const responseContentTypes = Object.fromEntries(sortedEntries(entry.operation.responses).map(([status, response]) => [status, response.content_type]));
@@ -454,4 +459,4 @@ function generateWordPressModule(document) {
454
459
  }
455
460
 
456
461
  //#endregion
457
- export { generateWordPressModule };
462
+ export { camel, endpointDefinition, generateWordPressModule };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kizlo",
3
- "version": "0.20.2",
3
+ "version": "0.21.0",
4
4
  "type": "module",
5
5
  "description": "A headless WordPress framework for TypeScript.",
6
6
  "keywords": [
@@ -107,6 +107,7 @@
107
107
  "dependencies": {
108
108
  "@clack/prompts": "^1.5.1",
109
109
  "@kizlo/shared": "0.9.0",
110
+ "@modelcontextprotocol/sdk": "^1.29.0",
110
111
  "@orpc/client": "^1.14.3",
111
112
  "@orpc/contract": "^1.14.3",
112
113
  "@orpc/openapi": "^1.14.3",