kizlo 0.1.1 → 0.2.1

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 (73) hide show
  1. package/README.md +1 -1
  2. package/dist/adapters/auth.d.ts +11 -2
  3. package/dist/adapters/auth.js +5 -1
  4. package/dist/adapters/captcha.d.ts +3 -1
  5. package/dist/adapters/captcha.js +5 -1
  6. package/dist/adapters/cookies.d.ts +7 -0
  7. package/dist/adapters/cookies.js +8 -0
  8. package/dist/adapters/geo.d.ts +13 -2
  9. package/dist/adapters/geo.js +5 -1
  10. package/dist/adapters/logger.d.ts +8 -1
  11. package/dist/adapters/logger.js +5 -1
  12. package/dist/cli/banner.js +12 -1
  13. package/dist/cli/commands/dev.js +203 -20
  14. package/dist/cli/commands/init.js +240 -47
  15. package/dist/cli/commands/test.js +56 -19
  16. package/dist/cli/commands/watch.js +5 -23
  17. package/dist/cli/daemon/config.js +11 -5
  18. package/dist/cli/daemon/logger.js +1 -0
  19. package/dist/cli/daemon/watch.js +35 -2
  20. package/dist/cli/presets/base.js +8 -1
  21. package/dist/cli/presets/nextjs.js +1 -1
  22. package/dist/cli/utils.js +74 -5
  23. package/dist/cli/wp/compose/docker-compose.yml +12 -0
  24. package/dist/cli/wp/dev.js +4 -2
  25. package/dist/cli/wp/docker.d.ts +22 -4
  26. package/dist/cli/wp/docker.js +27 -5
  27. package/dist/cli/wp/ports.js +72 -0
  28. package/dist/cli/wp/session.js +150 -0
  29. package/dist/cli/wp/settings.js +73 -0
  30. package/dist/cli/wp/types.d.ts +5 -3
  31. package/dist/cli/wp/utils.d.ts +7 -1
  32. package/dist/cli/wp/utils.js +17 -1
  33. package/dist/cli/wp/watchdog.d.ts +1 -0
  34. package/dist/cli/wp/watchdog.js +45 -0
  35. package/dist/client.d.ts +1 -1
  36. package/dist/client.js +2 -2
  37. package/dist/context.d.ts +12 -1
  38. package/dist/context.js +1 -1
  39. package/dist/index.d.ts +16 -12
  40. package/dist/index.js +9 -6
  41. package/dist/integrations/nextjs/kizlo.server.d.ts +1 -1
  42. package/dist/integrations/nextjs/kizlo.server.js +2 -2
  43. package/dist/integrations/nextjs/utils.js +2 -2
  44. package/dist/kizlo.d.ts +27 -6
  45. package/dist/kizlo.js +24 -11
  46. package/dist/package.js +1 -1
  47. package/dist/router.d.ts +7 -7
  48. package/dist/service.d.ts +2 -0
  49. package/dist/service.js +3 -0
  50. package/dist/settings/service.d.ts +22 -0
  51. package/dist/settings/service.interface.d.ts +134 -0
  52. package/dist/settings/service.js +43 -0
  53. package/dist/shared/error.d.ts +16 -5
  54. package/dist/shared/error.js +4 -0
  55. package/dist/shared/extension.d.ts +2 -0
  56. package/dist/shared/middleware.d.ts +13 -10
  57. package/dist/shared/middleware.js +7 -0
  58. package/dist/shared/procedure.d.ts +34 -28
  59. package/dist/shared/procedure.js +3 -6
  60. package/dist/shared/types.d.ts +19 -13
  61. package/dist/test/client.d.ts +5 -0
  62. package/dist/test/client.js +5 -0
  63. package/dist/test/server.d.ts +6 -0
  64. package/dist/test/server.js +6 -0
  65. package/dist/test.d.ts +4 -4
  66. package/dist/test.js +3 -3
  67. package/dist/webhook/index.d.ts +14 -13
  68. package/dist/webhook/index.js +5 -5
  69. package/dist/webhook/schema.d.ts +3 -3
  70. package/dist/webhook/schema.js +37 -37
  71. package/dist/webhook/utils.js +4 -4
  72. package/dist/wordpress/service.js +6 -0
  73. package/package.json +1 -1
@@ -0,0 +1,134 @@
1
+ //#region src/settings/service.interface.d.ts
2
+ interface KizloMedia {
3
+ id: number;
4
+ url: string;
5
+ }
6
+ interface KizloSocialProfile {
7
+ url: string;
8
+ platform: string;
9
+ }
10
+ interface KizloSiteSettings {
11
+ url: string | null;
12
+ backend_url: string | null;
13
+ secret: string | null;
14
+ name: string | null;
15
+ alternate_name: string | null;
16
+ tagline: string | null;
17
+ title_separator: string;
18
+ fallback_image: KizloMedia | null;
19
+ search_action_structure: string | null;
20
+ }
21
+ interface KizloPersonSettings {
22
+ name: string;
23
+ image: KizloMedia | null;
24
+ social_profiles: KizloSocialProfile[];
25
+ }
26
+ interface KizloOrganizationFounder {
27
+ name: string;
28
+ social_profiles: KizloSocialProfile[];
29
+ }
30
+ interface KizloOrganizationSettings {
31
+ name: string;
32
+ alternate_name: string | null;
33
+ slogan: string | null;
34
+ description: string | null;
35
+ email: string | null;
36
+ phone: string | null;
37
+ legal_name: string | null;
38
+ founding_date: string | null;
39
+ founder: KizloOrganizationFounder | null;
40
+ employees: number | null;
41
+ logo: KizloMedia | null;
42
+ social_profiles: KizloSocialProfile[];
43
+ }
44
+ interface KizloIdentitySettings {
45
+ type: "person" | "organization";
46
+ person: KizloPersonSettings | null;
47
+ organization: KizloOrganizationSettings | null;
48
+ }
49
+ interface KizloBaseContentSettings {
50
+ title_structure: string | null;
51
+ description_structure: string | null;
52
+ search_engine_visibility: boolean | null;
53
+ webpage_type: string;
54
+ article_type: string | null;
55
+ }
56
+ interface KizloAuthorsSettings extends Omit<KizloBaseContentSettings, "webpage_type" | "article_type"> {
57
+ enabled: boolean;
58
+ pathname_structure: string | null;
59
+ }
60
+ interface KizloPostTypeSettings extends KizloBaseContentSettings {
61
+ name: string;
62
+ slug: string;
63
+ seo_enabled: boolean;
64
+ pathname_structure: string | null;
65
+ comment_action_structure: string | null;
66
+ rest_api_enabled: boolean;
67
+ internal: boolean;
68
+ publicly_queryable: boolean;
69
+ supports: Record<string, boolean>;
70
+ }
71
+ interface KizloTaxonomySettings extends Omit<KizloBaseContentSettings, "webpage_type" | "article_type"> {
72
+ name: string;
73
+ slug: string;
74
+ seo_enabled: boolean;
75
+ pathname_structure: string | null;
76
+ rest_api_enabled: boolean;
77
+ internal: boolean;
78
+ publicly_queryable: boolean;
79
+ }
80
+ interface KizloWebhookSettings {
81
+ post_types: string[];
82
+ taxonomies: string[];
83
+ webhook_urls: string[];
84
+ }
85
+ interface KizloCrawlingSettings {
86
+ sitemaps: {
87
+ pathname_structure: string;
88
+ };
89
+ robots: {
90
+ include_sitemap: boolean;
91
+ custom_rules: {
92
+ user_agent: string;
93
+ rule: "allow" | "disallow";
94
+ path: string;
95
+ }[];
96
+ };
97
+ }
98
+ interface KizloPostStatus {
99
+ label: string;
100
+ slug: string;
101
+ public: boolean;
102
+ }
103
+ interface KizloSettings {
104
+ site: KizloSiteSettings;
105
+ identity: KizloIdentitySettings;
106
+ authors: KizloAuthorsSettings;
107
+ post_types: KizloPostTypeSettings[];
108
+ taxonomies: KizloTaxonomySettings[];
109
+ crawling: KizloCrawlingSettings;
110
+ webhook: KizloWebhookSettings;
111
+ statuses: KizloPostStatus[];
112
+ plain_permalinks: boolean;
113
+ }
114
+ type KizloSiteSettingsInput = Partial<Omit<KizloSiteSettings, "fallback_image"> & {
115
+ fallback_image: number | null;
116
+ }>;
117
+ type KizloWebhookSettingsInput = Partial<KizloWebhookSettings>;
118
+ type KizloPersonSettingsInput = Partial<Omit<KizloPersonSettings, "image"> & {
119
+ image: number | null;
120
+ }>;
121
+ type KizloOrganizationSettingsInput = Partial<Omit<KizloOrganizationSettings, "logo"> & {
122
+ logo: number | null;
123
+ }>;
124
+ type KizloIdentitySettingsInput = Partial<{
125
+ type: "person" | "organization";
126
+ person: KizloPersonSettingsInput | null;
127
+ organization: KizloOrganizationSettingsInput | null;
128
+ }>;
129
+ type KizloAuthorsSettingsInput = Partial<KizloAuthorsSettings>;
130
+ type KizloCrawlingSettingsInput = Partial<KizloCrawlingSettings>;
131
+ type KizloPostTypeSettingsInput = Partial<Pick<KizloPostTypeSettings, "title_structure" | "description_structure" | "search_engine_visibility" | "webpage_type" | "article_type" | "seo_enabled" | "pathname_structure" | "comment_action_structure" | "rest_api_enabled" | "publicly_queryable">>;
132
+ type KizloTaxonomySettingsInput = Partial<Pick<KizloTaxonomySettings, "title_structure" | "description_structure" | "search_engine_visibility" | "seo_enabled" | "pathname_structure" | "rest_api_enabled" | "publicly_queryable">>;
133
+ //#endregion
134
+ export { KizloAuthorsSettings, KizloAuthorsSettingsInput, KizloCrawlingSettings, KizloCrawlingSettingsInput, KizloIdentitySettings, KizloIdentitySettingsInput, KizloMedia, KizloOrganizationFounder, KizloOrganizationSettings, KizloOrganizationSettingsInput, KizloPersonSettings, KizloPersonSettingsInput, KizloPostStatus, KizloPostTypeSettings, KizloPostTypeSettingsInput, KizloSettings, KizloSiteSettings, KizloSiteSettingsInput, KizloSocialProfile, KizloTaxonomySettings, KizloTaxonomySettingsInput, KizloWebhookSettings, KizloWebhookSettingsInput };
@@ -0,0 +1,43 @@
1
+ import { WP_KIZLO_BASE } from "../wordpress/constants.js";
2
+
3
+ //#region src/settings/service.ts
4
+ var KizloSettingsService = class {
5
+ service;
6
+ constructor(service) {
7
+ this.service = service;
8
+ }
9
+ /** Fetch every Kizlo settings section in one response. */
10
+ async get() {
11
+ return this.service.wordpress.get("/settings", { base: WP_KIZLO_BASE });
12
+ }
13
+ async updateSite(input) {
14
+ return this.update("/settings/site", input);
15
+ }
16
+ async updateWebhook(input) {
17
+ return this.update("/settings/webhook", input);
18
+ }
19
+ async updateIdentity(input) {
20
+ return this.update("/settings/identity", input);
21
+ }
22
+ async updateAuthors(input) {
23
+ return this.update("/settings/authors", input);
24
+ }
25
+ async updateCrawling(input) {
26
+ return this.update("/settings/crawling", input);
27
+ }
28
+ async updatePostType(slug, input) {
29
+ return this.update(`/settings/post_types/${slug}`, input);
30
+ }
31
+ async updateTaxonomy(slug, input) {
32
+ return this.update(`/settings/taxonomies/${slug}`, input);
33
+ }
34
+ async update(path, body) {
35
+ return this.service.wordpress.put(path, {
36
+ base: WP_KIZLO_BASE,
37
+ body
38
+ });
39
+ }
40
+ };
41
+
42
+ //#endregion
43
+ export { KizloSettingsService };
@@ -88,28 +88,39 @@ type CommonErrorCode = keyof CommonErrorMap;
88
88
  type CommonErrorLiteral = LiteralUnion<CommonErrorCode, string>;
89
89
  type WithCommonErrorMap<TErrors extends DefinedErrorMapLike> = CommonErrorMap & { [K in keyof TErrors as string extends K ? never : K]: TErrors[K] };
90
90
  interface KizloErrorOptions {
91
+ /** Human-readable message. Defaults to the matching common error's preset message, or the code itself. */
91
92
  message?: string;
93
+ /** HTTP status to send. Defaults to the matching common error's status, or `500`. */
92
94
  status?: number;
95
+ /** Arbitrary payload carried on the error and surfaced to the client. */
93
96
  data?: unknown;
97
+ /** Underlying error that triggered this one; set as the native `Error` `cause`. */
94
98
  cause?: unknown;
95
99
  }
96
100
  declare class KizloError<TCode extends CommonErrorLiteral = CommonErrorLiteral, TData = unknown> extends Error {
101
+ /** Always `"KizloError"` — the discriminator `isKizloError` checks. */
97
102
  readonly name = "KizloError";
103
+ /** The error code, e.g. `"NOT_FOUND"` or a custom code from your error map. */
98
104
  readonly code: TCode;
105
+ /** The payload passed when the error was thrown, or `null`. */
99
106
  readonly data: TData;
107
+ /** The HTTP status this error maps to. */
100
108
  readonly status: number;
101
109
  constructor(code: TCode, options?: KizloErrorOptions);
102
110
  }
103
111
  declare function isKizloError(value: unknown): value is KizloError;
104
112
  declare function toKizloError(e: unknown): KizloError;
105
- type DefinedErrorLike = {
113
+ type ErrorDefinition = {
114
+ /** HTTP status sent when this error is thrown. Defaults to the matching common error's status, or 500. */
106
115
  status?: number;
116
+ /** Human-readable message. Overridable per throw via `errors.CODE({ message })`. */
107
117
  message?: string;
118
+ /** Standard Schema for the error's `data` payload — validated and typed when you throw `errors.CODE({ data })`. */
108
119
  data?: AnySchema;
109
120
  };
110
- declare function defineErrorMap<const T extends Partial<Record<CommonErrorLiteral, DefinedErrorLike>>>(map: T): T;
111
- type DefinedErrorMapLike = Record<string, DefinedErrorLike>;
112
- type ThrowableErrorFn<TCode extends string, T extends DefinedErrorLike> = T["data"] extends AnySchema ? undefined extends SchemaInput<T["data"]> ? (options?: {
121
+ declare function defineErrorMap<const T extends Partial<Record<CommonErrorLiteral, ErrorDefinition>>>(map: T): T;
122
+ type DefinedErrorMapLike = Record<string, ErrorDefinition>;
123
+ type ThrowableErrorFn<TCode extends string, T extends ErrorDefinition> = T["data"] extends AnySchema ? undefined extends SchemaInput<T["data"]> ? (options?: {
113
124
  status?: number;
114
125
  message?: string;
115
126
  data?: SchemaInput<T["data"]>;
@@ -125,4 +136,4 @@ type ThrowableErrorFn<TCode extends string, T extends DefinedErrorLike> = T["dat
125
136
  type ThrowableErrorMap<T extends DefinedErrorMapLike> = { [K in Extract<keyof T, string>]: ThrowableErrorFn<K, T[K]> };
126
137
  declare function createThrowableErrorMap<TError extends DefinedErrorMapLike>(errors: TError): ThrowableErrorMap<WithCommonErrorMap<TError>>;
127
138
  //#endregion
128
- export { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorLike, DefinedErrorMapLike, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError };
139
+ export { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorMapLike, ErrorDefinition, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError };
@@ -82,9 +82,13 @@ const COMMON_ERRORS = {
82
82
  }
83
83
  };
84
84
  var KizloError = class extends Error {
85
+ /** Always `"KizloError"` — the discriminator `isKizloError` checks. */
85
86
  name = "KizloError";
87
+ /** The error code, e.g. `"NOT_FOUND"` or a custom code from your error map. */
86
88
  code;
89
+ /** The payload passed when the error was thrown, or `null`. */
87
90
  data;
91
+ /** The HTTP status this error maps to. */
88
92
  status;
89
93
  constructor(code, options) {
90
94
  const preset = COMMON_ERRORS[code];
@@ -9,7 +9,9 @@ interface ExtensionInitOptions {
9
9
  };
10
10
  }
11
11
  interface ExtensionInitResult<TRouter extends AnyProcedureRouter> {
12
+ /** Procedures the extension exposes, grouped by name. Each entry (or nested group) becomes a client method under the extension's `id`. */
12
13
  router?: TRouter;
14
+ /** Webhook event handlers, built with `createEventHandler`, run when WordPress emits a matching event. */
13
15
  events?: EventHandler[];
14
16
  }
15
17
  interface Extension<TId extends string, TRouter extends AnyProcedureRouter> {
@@ -1,29 +1,32 @@
1
1
  import { AnyContext } from "./types.js";
2
- import { DefinedErrorMapLike, ThrowableErrorMap } from "./error.js";
2
+ import { DefinedErrorMapLike } from "./error.js";
3
3
  import { ServerContext } from "../context.js";
4
+ import { BaseHandlerOptions } from "./procedure.js";
4
5
  import { UnionToIntersection } from "@kizlo/shared";
5
6
 
6
7
  //#region src/shared/middleware.d.ts
8
+ type InferUses<T extends readonly AnyMiddleware[] | undefined> = T extends readonly [] ? object : T extends readonly AnyMiddleware[] ? UnionToIntersection<ExtractMiddlewareContextOutput<T[number]>> : object;
7
9
  interface MiddlewareResult<TOutContext extends AnyContext, TOutput> {
10
+ /** The handler's return value, as it flows back up through any middleware that awaited `next()`. */
8
11
  output: TOutput;
12
+ /** The context after this point in the chain, including anything middleware added via `next({ context })`. */
9
13
  context: TOutContext;
10
14
  }
11
15
  type MiddlewareNextFn<TOutput> = {
12
16
  (): Promise<MiddlewareResult<AnyContext, TOutput>>;
13
17
  <UOutContext extends AnyContext>(options: {
18
+ /** Values to merge into the context for every middleware and the handler downstream — added to it, fully typed. */
14
19
  context: UOutContext;
15
20
  }): Promise<MiddlewareResult<UOutContext, TOutput>>;
16
21
  };
17
- type MiddlewareOptions<TInput, TOutput, TError extends DefinedErrorMapLike> = {
18
- input: TInput;
19
- context: ServerContext;
22
+ type MiddlewareOptions<TInput, TOutput, TError extends DefinedErrorMapLike> = BaseHandlerOptions<TInput, ServerContext, TError> & {
23
+ /** Run the next middleware (or the handler) and return its result; pass `{ context }` to extend the context for everything downstream. */
20
24
  next: MiddlewareNextFn<TOutput>;
21
- errors: ThrowableErrorMap<TError>;
22
25
  };
23
- type MiddlewareHandler<TOutContext extends AnyContext, TInput, TOutput, TError extends DefinedErrorMapLike> = (options: MiddlewareOptions<TInput, TOutput, TError>) => Promise<MiddlewareResult<TOutContext, TOutput>>;
24
- type Middleware<TOutContext extends AnyContext, TInput, TOutput, TError extends DefinedErrorMapLike> = MiddlewareHandler<TOutContext, TInput, TOutput, TError>;
26
+ type MiddlewareHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TOutContext extends AnyContext> = (options: MiddlewareOptions<TInput, TOutput, TError>) => Promise<MiddlewareResult<TOutContext, TOutput>>;
27
+ type Middleware<TInput, TOutput, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext> = MiddlewareHandler<TInput, TOutput, TError, TOutContext>;
25
28
  type AnyMiddleware = Middleware<any, any, any, any>;
26
- type ExtractMiddlewareContextOutput<M> = M extends Middleware<infer TOut, any, any, any> ? TOut : never;
27
- type InferUses<T extends readonly AnyMiddleware[] | undefined> = T extends readonly [] ? object : T extends readonly AnyMiddleware[] ? UnionToIntersection<ExtractMiddlewareContextOutput<T[number]>> : object;
29
+ type ExtractMiddlewareContextOutput<M> = M extends Middleware<any, any, any, infer TOut> ? TOut : never;
30
+ declare function createMiddleware<TInput = any, TOutput = any, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext>(handler: MiddlewareHandler<TInput, TOutput, TError, TOutContext>): Middleware<TInput, TOutput, TError, TOutContext>;
28
31
  //#endregion
29
- export { InferUses };
32
+ export { AnyMiddleware, ExtractMiddlewareContextOutput, InferUses, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, createMiddleware };
@@ -0,0 +1,7 @@
1
+ //#region src/shared/middleware.ts
2
+ function createMiddleware(handler) {
3
+ return handler;
4
+ }
5
+
6
+ //#endregion
7
+ export { createMiddleware };
@@ -1,7 +1,6 @@
1
- import { AnyContext } from "./types.js";
2
1
  import { DefinedErrorMapLike, ThrowableErrorMap, WithCommonErrorMap } from "./error.js";
3
2
  import { ServerContext } from "../context.js";
4
- import { InferUses } from "./middleware.js";
3
+ import { AnyMiddleware, InferUses, Middleware } from "./middleware.js";
5
4
  import * as _orpc_contract0 from "@orpc/contract";
6
5
  import { AnySchema, DeepMerge, Pathname, Prettify, Promisify, Schema, SchemaInput, SchemaOutput } from "@kizlo/shared";
7
6
  import * as _orpc_server0 from "@orpc/server";
@@ -14,33 +13,19 @@ type AnyProcedureRouter = {
14
13
  };
15
14
  type RouterDepthTuple = [never, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
16
15
  type ExtractProcedureByScope<TRouter extends AnyProcedureRouter, TScope extends InvocationScope, TDepth extends number = 10> = TDepth extends 0 ? TRouter : { [K in keyof TRouter as TRouter[K] extends Procedure<infer Scope, infer _Input, infer _Output, infer _Errors> ? Scope extends TScope ? K : never : TRouter[K] extends AnyProcedureRouter ? keyof ExtractProcedureByScope<TRouter[K], TScope, RouterDepthTuple[TDepth]> extends never ? never : K : never]: TRouter[K] extends AnyProcedure ? TRouter[K] : TRouter[K] extends AnyProcedureRouter ? ExtractProcedureByScope<TRouter[K], TScope, RouterDepthTuple[TDepth]> : never };
17
- interface MiddlewareResult<TOutContext extends AnyContext, TOutput> {
18
- output: TOutput;
19
- context: TOutContext;
20
- }
21
- type MiddlewareNextFn<TOutput> = {
22
- (): Promise<MiddlewareResult<AnyContext, TOutput>>;
23
- <UOutContext extends AnyContext>(options: {
24
- context: UOutContext;
25
- }): Promise<MiddlewareResult<UOutContext, TOutput>>;
26
- };
27
- type MiddlewareOptions<TInput, TOutput, TError extends DefinedErrorMapLike> = {
28
- input: TInput;
29
- context: ServerContext;
30
- next: MiddlewareNextFn<TOutput>;
31
- errors: ThrowableErrorMap<TError>;
32
- };
33
- type MiddlewareHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TOutContext extends AnyContext> = (options: MiddlewareOptions<TInput, TOutput, TError>) => Promise<MiddlewareResult<TOutContext, TOutput>>;
34
- type Middleware<TInput, TOutput, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext> = MiddlewareHandler<TInput, TOutput, TError, TOutContext>;
35
- type AnyMiddleware = Middleware<any, any, any, any>;
36
- type ExtractMiddlewareContextOutput<M> = M extends Middleware<infer TOut, any, any, any> ? TOut : never;
37
- declare function createMiddleware<TInput = any, TOutput = any, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TOutContext extends AnyContext = AnyContext>(handler: MiddlewareHandler<TInput, TOutput, TError, TOutContext>): Middleware<TInput, TOutput, TError, TOutContext>;
38
- type InvocationScope = "internal" | "remote" | "api";
39
- type ProcedureHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TContext extends ServerContext> = (ctx: {
16
+ /** The base options passed to every procedure handler and middleware. */
17
+ interface BaseHandlerOptions<TInput, TContext, TError extends DefinedErrorMapLike> {
18
+ /** The validated, typed request. For `api`, the merged `{ params, query, body, headers }`; for `remote`/`internal`, the `input` schema's type. */
40
19
  input: TInput;
20
+ /** Server-side services and adapters — the WordPress client, logger, cookies, auth, and more — plus anything middleware adds. */
41
21
  context: TContext;
42
- errors: ThrowableErrorMap<WithCommonErrorMap<TError>>;
43
- }) => Promisify<TOutput>;
22
+ /** Typed error map — throw `errors.SOME_CODE()` for a known failure. */
23
+ errors: ProcedureErrors<TError>;
24
+ }
25
+ type InvocationScope = "internal" | "remote" | "api";
26
+ /** Callable map of a procedure's declared error codes plus the built-in common HTTP errors. */
27
+ type ProcedureErrors<TError extends DefinedErrorMapLike = DefinedErrorMapLike> = ThrowableErrorMap<WithCommonErrorMap<TError>>;
28
+ type ProcedureHandler<TInput, TOutput, TError extends DefinedErrorMapLike, TContext extends ServerContext> = (options: BaseHandlerOptions<TInput, TContext, TError>) => Promisify<TOutput>;
44
29
  interface Procedure<TScope extends InvocationScope, TInput, TOutput, TError extends DefinedErrorMapLike = DefinedErrorMapLike> {
45
30
  "~kizlo": {
46
31
  uses: AnyMiddleware[];
@@ -86,23 +71,44 @@ type ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, TMap extends "o
86
71
  type ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders> = Prettify<TScope extends "api" ? ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, "output"> : [TInput] extends [Schema] ? SchemaOutput<TInput> : unknown>;
87
72
  type ResolvedSchemaInput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders> = Prettify<TScope extends "api" ? ResolveOpenapi<TPathname, TBody, TParams, TQuery, THeaders, "input"> : [TInput] extends [Schema] ? SchemaInput<TInput> : unknown>;
88
73
  type ProcedureOptions<TScope extends InvocationScope, TPathname extends Pathname, TInput extends Schema | undefined, TBody extends Schema | undefined, TParams extends Schema | undefined, TQuery extends Schema | undefined, THeaders extends Schema | undefined, TOutput extends Schema, TError extends DefinedErrorMapLike, TMiddlewares extends Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[]> = {
74
+ /** Where the procedure can be called from: `"api"` (HTTP REST endpoint), `"remote"` (RPC-style endpoint), or `"internal"` (server-only). */
89
75
  scope: TScope;
76
+ /** Error codes this procedure can throw, on top of the built-in common HTTP errors. An inline object or a `defineErrorMap`. */
90
77
  errors?: TError;
78
+ /** Schema that types — and, when `outputValidation` is on, validates — the handler's return value. */
91
79
  output: TOutput;
80
+ /** Middleware to run before the handler, in declaration order. */
92
81
  middlewares?: TMiddlewares;
82
+ /**
83
+ * Validate the incoming request against the input schemas.
84
+ * @default true
85
+ */
93
86
  inputValidation?: boolean;
87
+ /**
88
+ * Validate the return value against `output`.
89
+ * @default false
90
+ */
94
91
  outputValidation?: boolean;
95
92
  } & (TScope extends "api" ? {
93
+ /** HTTP method for the route, e.g. `"GET"` or `"POST"`. */
96
94
  method?: HTTPMethod;
95
+ /** REST path with `{param}` placeholders, e.g. `/featured/{id}`. */
97
96
  path?: TPathname;
97
+ /** Schema for the request body. */
98
98
  body?: TBody;
99
+ /** Schema for the query string. */
99
100
  query?: TQuery;
101
+ /** Schema for the path parameters. */
100
102
  params?: TParams;
103
+ /** Schema for the request headers. */
101
104
  headers?: THeaders;
102
105
  } : TScope extends "remote" ? {
106
+ /** Schema for the call's single input argument. */
103
107
  input?: TInput;
108
+ /** HTTP method for the underlying request. */
104
109
  method?: HTTPMethod;
105
110
  } : {
111
+ /** Schema for the call's single input argument. */
106
112
  input?: TInput;
107
113
  });
108
114
  declare function createProcedure<TScope extends InvocationScope, TPathname extends Pathname, TInput extends Schema | undefined = undefined, TBody extends Schema | undefined = undefined, TParams extends Schema | undefined = undefined, TQuery extends Schema | undefined = undefined, THeaders extends Schema | undefined = undefined, TOutput extends Schema = Schema, TError extends DefinedErrorMapLike = DefinedErrorMapLike, TMiddlewares extends Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[] = Middleware<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError>[], TContext extends ProcedureContext<TMiddlewares> = ProcedureContext<TMiddlewares>>(options: ProcedureOptions<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders, TOutput, TError, TMiddlewares>, handler: ProcedureHandler<ResolvedSchemaOutput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, SchemaOutput<TOutput>, TError, TContext>): Procedure<TScope, ResolvedSchemaInput<TScope, TPathname, TInput, TBody, TParams, TQuery, THeaders>, TScope extends "api" ? JsonifiedValue<SchemaOutput<TOutput>> : SchemaOutput<TOutput>, TError>;
@@ -111,4 +117,4 @@ declare function buildProcedure(procedure: AnyProcedure): _orpc_server0.Decorate
111
117
  declare function handleUnexpectedError(error: unknown, errors?: DefinedErrorMapLike): never;
112
118
  declare function combineDetailed(parts: Record<string, AnySchema>): AnySchema;
113
119
  //#endregion
114
- export { AnyMiddleware, AnyProcedure, AnyProcedureRouter, ExtractMiddlewareContextOutput, ExtractParams, ExtractProcedureByScope, InvocationScope, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, OpenapiPart, Procedure, ProcedureContext, ProcedureHandler, ProcedureOptions, ResolveParamsPart, ResolvedSchemaInput, ResolvedSchemaOutput, RouterDepthTuple, SchemaIO, buildProcedure, combineDetailed, createMiddleware, createProcedure, handleUnexpectedError, schemaType };
120
+ export { AnyProcedure, AnyProcedureRouter, BaseHandlerOptions, ExtractParams, ExtractProcedureByScope, InvocationScope, OpenapiPart, Procedure, ProcedureContext, ProcedureErrors, ProcedureHandler, ProcedureOptions, ResolveParamsPart, ResolvedSchemaInput, ResolvedSchemaOutput, RouterDepthTuple, SchemaIO, buildProcedure, combineDetailed, createProcedure, handleUnexpectedError, schemaType };
@@ -2,9 +2,6 @@ import { COMMON_ERRORS, KizloError, createThrowableErrorMap, isKizloError } from
2
2
  import { os } from "@orpc/server";
3
3
 
4
4
  //#region src/shared/procedure.ts
5
- function createMiddleware(handler) {
6
- return handler;
7
- }
8
5
  function createProcedure(options, handler) {
9
6
  return { "~kizlo": {
10
7
  options,
@@ -92,8 +89,8 @@ function combineDetailed(parts) {
92
89
  version: 1,
93
90
  vendor: "kizlo",
94
91
  validate: async (value) => {
95
- if (typeof value !== "object" || value === null) return { issues: [{ message: "Expected object" }] };
96
- const input = value;
92
+ if (value != null && typeof value !== "object") return { issues: [{ message: "Expected object" }] };
93
+ const input = value ?? {};
97
94
  const result = {};
98
95
  const issues = [];
99
96
  for (const [key, schema] of Object.entries(parts)) {
@@ -111,4 +108,4 @@ function combineDetailed(parts) {
111
108
  }
112
109
 
113
110
  //#endregion
114
- export { buildProcedure, combineDetailed, createMiddleware, createProcedure, handleUnexpectedError, schemaType };
111
+ export { buildProcedure, combineDetailed, createProcedure, handleUnexpectedError, schemaType };
@@ -17,19 +17,25 @@ interface RedirectInput {
17
17
  status?: RedirectStatus;
18
18
  searchParams?: Record<string, string>;
19
19
  }
20
+ type CookiesSetAll = (cookies: CookieWithOptions[]) => Promise<void> | void;
21
+ type CookiesGetAll = () => Promise<{
22
+ name: string;
23
+ value: string;
24
+ }[] | null> | {
25
+ name: string;
26
+ value: string;
27
+ }[] | null;
28
+ type CookiesDeleteAll = (cookies: {
29
+ name: string;
30
+ options?: CookieOptions;
31
+ }[]) => Promise<void> | void;
20
32
  interface CookiesAdapter {
21
- setAll(cookies: CookieWithOptions[]): Promise<void> | void;
22
- getAll(): Promise<{
23
- name: string;
24
- value: string;
25
- }[] | null> | {
26
- name: string;
27
- value: string;
28
- }[] | null;
29
- deleteAll(cookies: {
30
- name: string;
31
- options?: CookieOptions;
32
- }[]): Promise<void> | void;
33
+ /** Write the given cookies, each with its options. */
34
+ setAll: CookiesSetAll;
35
+ /** Read all cookies as name/value pairs, or `null` when none are available. */
36
+ getAll: CookiesGetAll;
37
+ /** Delete the named cookies, honoring each entry's options (e.g. `path`). */
38
+ deleteAll: CookiesDeleteAll;
33
39
  }
34
40
  //#endregion
35
- export { AnyContext, AnyNestedClient, CookiesAdapter, HTTPMethod, List, MaybeOptionalOptions, RedirectInput, RedirectStatus };
41
+ export { AnyContext, AnyNestedClient, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, HTTPMethod, List, MaybeOptionalOptions, RedirectInput, RedirectStatus };
@@ -5,6 +5,11 @@ import "../index.js";
5
5
  import { KizloTestInstance } from "./server.js";
6
6
 
7
7
  //#region src/test/client.d.ts
8
+ /**
9
+ * Wraps a test instance with the real browser client, routing its requests through the instance's `handler`. Use
10
+ * it for end-to-end tests: calls go through serialization and the same scope rules as production (internal
11
+ * procedures never leave the server), returning the `{ success, data, error }` envelope your frontend sees.
12
+ */
8
13
  declare function getKizloClientTestInstance(kizlo: KizloTestInstance): Promise<KizloClient<RootRouter<readonly AnyExtension[]>>>;
9
14
  type KizloClientTestInstance = Awaited<ReturnType<typeof getKizloClientTestInstance>>;
10
15
  //#endregion
@@ -2,6 +2,11 @@ import { generateContract } from "../shared/contract.js";
2
2
  import { KizloClient } from "../client.js";
3
3
 
4
4
  //#region src/test/client.ts
5
+ /**
6
+ * Wraps a test instance with the real browser client, routing its requests through the instance's `handler`. Use
7
+ * it for end-to-end tests: calls go through serialization and the same scope rules as production (internal
8
+ * procedures never leave the server), returning the `{ success, data, error }` envelope your frontend sees.
9
+ */
5
10
  async function getKizloClientTestInstance(kizlo) {
6
11
  return new KizloClient({
7
12
  url: "http://test.local",
@@ -2,6 +2,12 @@ import { AnyExtension } from "../shared/extension.js";
2
2
  import { Kizlo } from "../kizlo.js";
3
3
 
4
4
  //#region src/test/server.d.ts
5
+
6
+ /**
7
+ * Wires a Kizlo instance against the seeded test stack: admin credentials read from
8
+ * the test-credentials artifact, with mock geo, auth, and captcha adapters and a
9
+ * warn/error logger. Call procedures directly through its `client` in integration tests.
10
+ */
5
11
  declare function getKizloTestInstance<TExts extends readonly AnyExtension[] = []>(options?: {
6
12
  extensions?: TExts;
7
13
  }): Kizlo<TExts>;
@@ -7,12 +7,18 @@ import { captchaMock } from "./captcha.js";
7
7
  import { toTestUser } from "./users.js";
8
8
 
9
9
  //#region src/test/server.ts
10
+ /**
11
+ * Wires a Kizlo instance against the seeded test stack: admin credentials read from
12
+ * the test-credentials artifact, with mock geo, auth, and captcha adapters and a
13
+ * warn/error logger. Call procedures directly through its `client` in integration tests.
14
+ */
10
15
  function getKizloTestInstance(options) {
11
16
  const creds = getTestCredentials();
12
17
  return new Kizlo({
13
18
  baseUrl: "http://test.local",
14
19
  siteSecret: "test-secret",
15
20
  environment: "test",
21
+ target: "production",
16
22
  credentials: {
17
23
  url: creds.url,
18
24
  username: creds.users.admin.username,
package/dist/test.d.ts CHANGED
@@ -1,6 +1,6 @@
1
- import { DockerStack, RunResult, Stack, compose, composeDown, composeStop, composeUp, createStack, wpCli } from "./cli/wp/docker.js";
2
- import { DevPluginSource, Fixture, 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, resolvePluginSource } from "./cli/wp/utils.js";
1
+ import { DockerStack, RunResult, Stack, compose, composeDown, composeStop, composeUp, createStack, dockerAvailable, wpCli } from "./cli/wp/docker.js";
2
+ 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";
4
4
  import { TestAuthAdapterUser, toTestUser } from "./test/users.js";
5
5
  import { testAuthAdapter } from "./test/auth.js";
6
6
  import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
@@ -9,4 +9,4 @@ import { KizloClientTestInstance, getKizloClientTestInstance } from "./test/clie
9
9
  import { menuFixture } from "./menu/fixture.js";
10
10
  import { postFixture } from "./post/fixture.js";
11
11
  import { coreFixtures } from "./test/fixtures.js";
12
- export { CAPTCHA_TEST_TOKEN_PASS, DevPluginSource, DockerStack, Fixture, JsonValue, KizloClientTestInstance, KizloTestInstance, LocalPlugin, PluginSource, RunResult, SeedContext, Stack, TestAdminUser, TestAuthAdapterUser, TestCredentials, TestUser, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
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 };
package/dist/test.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { defineFixture, isLocalPlugin } from "./cli/wp/types.js";
2
- import { compose, composeDown, composeStop, composeUp, createStack, wpCli } from "./cli/wp/docker.js";
3
- import { activateLocalPlugin, credentialsPath, ensurePlugin, ensurePlugins, findConfigDir, getTestCredentials, githubRelease, isSeeded, kizloRelease, resolvePluginSource } from "./cli/wp/utils.js";
2
+ 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
4
  import { testAuthAdapter } from "./test/auth.js";
5
5
  import { CAPTCHA_TEST_TOKEN_PASS, captchaMock } from "./test/captcha.js";
6
6
  import { getKizloClientTestInstance } from "./test/client.js";
@@ -10,4 +10,4 @@ import { coreFixtures } from "./test/fixtures.js";
10
10
  import { toTestUser } from "./test/users.js";
11
11
  import { getKizloTestInstance } from "./test/server.js";
12
12
 
13
- export { CAPTCHA_TEST_TOKEN_PASS, activateLocalPlugin, captchaMock, compose, composeDown, composeStop, composeUp, coreFixtures, createStack, credentialsPath, defineFixture, ensurePlugin, ensurePlugins, findConfigDir, getKizloClientTestInstance, getKizloTestInstance, getTestCredentials, githubRelease, isLocalPlugin, isSeeded, kizloRelease, menuFixture, postFixture, resolvePluginSource, testAuthAdapter, toTestUser, wpCli };
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 };
@@ -1,31 +1,32 @@
1
- import { WebhookEvent } from "./schema.js";
1
+ import { KizloEvent } from "./schema.js";
2
2
  import { DefinedErrorMapLike } from "../shared/error.js";
3
3
  import { ServerContext } from "../context.js";
4
4
  import { Procedure } from "../shared/procedure.js";
5
5
  import "../index.js";
6
- import { Pathname, Schema, SchemaOutput } from "@kizlo/shared";
6
+ import { Schema, SchemaOutput } from "@kizlo/shared";
7
7
 
8
8
  //#region src/webhook/index.d.ts
9
- type AnyWebhookEventSchema<TData = unknown> = Schema<unknown, TData>;
10
- type AnyWebhookEvents = {
9
+ type AnyEventSchema<TData = unknown> = Schema<unknown, TData>;
10
+ type AnyEvents = {
11
+ /** Event type strings this entry matches, e.g. `["review.created"]`. The handler's `event.type` is narrowed to this union. */
11
12
  types: string[];
12
- data: AnyWebhookEventSchema;
13
+ /** Standard Schema that validates and types each matched event's `data` payload. */
14
+ data: AnyEventSchema;
13
15
  }[];
14
- type InferWebhookEventUnion<T extends AnyWebhookEvents> = { [K in keyof T]: {
16
+ type InferEventUnion<T extends AnyEvents> = { [K in keyof T]: {
15
17
  type: T[K]["types"][number];
16
18
  data: SchemaOutput<T[K]["data"]>;
17
19
  } }[number];
18
- type WebhookHandlerFn<T extends AnyWebhookEvents> = (event: InferWebhookEventUnion<T> | WebhookEvent | null, context: ServerContext) => Promise<void> | void;
20
+ type EventHandlerFn<T extends AnyEvents> = (event: InferEventUnion<T> | KizloEvent | null, context: ServerContext) => Promise<void> | void;
19
21
  interface WebhookOptions {
20
- path?: Pathname;
21
22
  events?: EventHandler[];
22
23
  }
23
24
  interface EventHandler {
24
- events?: AnyWebhookEvents;
25
- handler: WebhookHandlerFn<AnyWebhookEvents>;
25
+ events?: AnyEvents;
26
+ handler: EventHandlerFn<AnyEvents>;
26
27
  }
27
- declare function createEventHandler<const T extends AnyWebhookEvents = never>(handler: WebhookHandlerFn<T>): EventHandler;
28
- declare function createEventHandler<const T extends AnyWebhookEvents = never>(events: T, handler: WebhookHandlerFn<T>): EventHandler;
28
+ declare function createEventHandler<const T extends AnyEvents = never>(handler: EventHandlerFn<T>): EventHandler;
29
+ declare function createEventHandler<const T extends AnyEvents = never>(events: T, handler: EventHandlerFn<T>): EventHandler;
29
30
  declare function createWebhookRouter(options?: WebhookOptions): {
30
31
  webhooks: Procedure<"api", {
31
32
  body: {
@@ -35,4 +36,4 @@ declare function createWebhookRouter(options?: WebhookOptions): {
35
36
  }, unknown, DefinedErrorMapLike>;
36
37
  };
37
38
  //#endregion
38
- export { AnyWebhookEventSchema, AnyWebhookEvents, EventHandler, InferWebhookEventUnion, WebhookHandlerFn, WebhookOptions, createEventHandler, createWebhookRouter };
39
+ export { AnyEventSchema, AnyEvents, EventHandler, EventHandlerFn, InferEventUnion, WebhookOptions, createEventHandler, createWebhookRouter };