kizlo 0.26.2 → 0.27.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.
@@ -0,0 +1,7 @@
1
+ import { GeoAdapter } from "./geo.js";
2
+
3
+ //#region src/adapters/geo.cloudflare.d.ts
4
+ /** Read trusted Cloudflare connection headers in Next.js/vinext. Only use behind Cloudflare ingress. */
5
+ declare function geoCloudflareNext(): GeoAdapter;
6
+ //#endregion
7
+ export { geoCloudflareNext };
@@ -0,0 +1,23 @@
1
+ //#region src/adapters/geo.cloudflare.ts
2
+ /** Read trusted Cloudflare connection headers in Next.js/vinext. Only use behind Cloudflare ingress. */
3
+ function geoCloudflareNext() {
4
+ return { getConnInfo: async (request) => {
5
+ let headers = request?.headers;
6
+ if (!headers) try {
7
+ headers = await (await import("next/headers")).headers();
8
+ } catch {}
9
+ const country = headers?.get("cf-ipcountry") || null;
10
+ return {
11
+ ip: headers?.get("cf-connecting-ip") || null,
12
+ country: country === "XX" || country === "T1" ? null : country,
13
+ city: null,
14
+ state: null,
15
+ postcode: null,
16
+ timezone: null,
17
+ userAgent: headers?.get("user-agent") || null
18
+ };
19
+ } };
20
+ }
21
+
22
+ //#endregion
23
+ export { geoCloudflareNext };
@@ -2,7 +2,7 @@ import { Promisify } from "@kizlo/shared";
2
2
 
3
3
  //#region src/adapters/geo.d.ts
4
4
  interface ConnInfo {
5
- /** Client IP address, or `null` if unavailable. */
5
+ /** Trusted client IP forwarded to WordPress as x-real-ip, or `null` if unavailable. */
6
6
  ip: string | null;
7
7
  /** ISO country code, or `null`. */
8
8
  country: string | null;
@@ -5,8 +5,8 @@ function geoVercelNext() {
5
5
  let nextHeaders;
6
6
  try {
7
7
  nextHeaders = await (await import("next/headers")).headers();
8
- } catch (err) {
9
- throw new Error("geoVercelNext: no Request was provided and `next/headers` could not be loaded. Install `next` as a peer dependency, or pass a Request to the SDK.", { cause: err });
8
+ } catch {
9
+ return readVercelHeaders(new Headers());
10
10
  }
11
11
  return readVercelHeaders(nextHeaders);
12
12
  } };
package/dist/context.d.ts CHANGED
@@ -66,6 +66,7 @@ declare class Context {
66
66
  private readonly settings;
67
67
  private readonly email;
68
68
  constructor(config: ContextConfig);
69
+ private createServices;
69
70
  /**
70
71
  * Report a request that did not reach Kizlo WordPress, or a WordPress side older than the client
71
72
  * needs. The transport supplies the URL and status even when fetch itself failed; a Kizlo response
@@ -77,34 +78,34 @@ declare class Context {
77
78
  /** Bold yellow, boxed in dashes so it stands out in a busy dev console. */
78
79
  private warn;
79
80
  createRestContext(request: Request): {
80
- headers: Headers;
81
- request: Request;
82
- config: ContextConfig;
83
- logger: Logger;
84
- wordpress: WordPressTransport;
85
- settings: SettingsService;
86
- email: EmailService;
87
81
  getConnInfo: ConnInfoFn;
88
82
  verifyCaptcha: VerifyCaptchaFn;
89
83
  getSession: SessionFn;
90
84
  verifyPreviewToken: VerifyPreviewTokenFn;
91
85
  cookies: CookiesStorage;
92
86
  invokedBy: "client";
93
- };
94
- createServerContext(): {
95
- cookies: CookiesStorage;
96
- headers: null;
97
- request: null;
98
- config: ContextConfig;
99
- logger: Logger;
100
87
  wordpress: WordPressTransport;
101
88
  settings: SettingsService;
102
89
  email: EmailService;
90
+ headers: Headers;
91
+ request: Request;
92
+ config: ContextConfig;
93
+ logger: Logger;
94
+ };
95
+ createServerContext(): {
103
96
  getSession: SessionFn;
104
97
  getConnInfo: ConnInfoFn;
105
98
  verifyCaptcha: VerifyCaptchaFn;
106
99
  verifyPreviewToken: VerifyPreviewTokenFn;
107
100
  invokedBy: "server";
101
+ wordpress: WordPressTransport;
102
+ settings: SettingsService;
103
+ email: EmailService;
104
+ cookies: CookiesStorage;
105
+ headers: null;
106
+ request: null;
107
+ config: ContextConfig;
108
+ logger: Logger;
108
109
  };
109
110
  private createRestCookieStorage;
110
111
  private createVerifyCaptchaFn;
package/dist/context.js CHANGED
@@ -52,13 +52,25 @@ var Context = class {
52
52
  email;
53
53
  constructor(config) {
54
54
  this.config = config;
55
- this.wordpress = createWordPressClient(new WordPressTransport({
55
+ this.logger = this.createLogger();
56
+ const services = this.createServices(null);
57
+ this.wordpress = services.wordpress;
58
+ this.settings = services.settings;
59
+ this.email = services.email;
60
+ }
61
+ createServices(request) {
62
+ const config = this.config;
63
+ const geo = config.adapters?.geo;
64
+ const wordpress = createWordPressClient(new WordPressTransport({
56
65
  credentials: config.credentials,
57
- onResult: (result) => this.warnIfOutdated(result)
66
+ onResult: (result) => this.warnIfOutdated(result),
67
+ getClientIp: geo ? async () => (await geo.getConnInfo(request)).ip : void 0
58
68
  }), config.introspection ?? {});
59
- this.settings = new SettingsService(this.wordpress);
60
- this.email = new EmailService(this.wordpress);
61
- this.logger = this.createLogger();
69
+ return {
70
+ wordpress,
71
+ settings: new SettingsService(wordpress),
72
+ email: new EmailService(wordpress)
73
+ };
62
74
  }
63
75
  /**
64
76
  * Report a request that did not reach Kizlo WordPress, or a WordPress side older than the client
@@ -97,9 +109,11 @@ var Context = class {
97
109
  request: request.clone(),
98
110
  config: this.config,
99
111
  logger: this.logger,
100
- wordpress: this.wordpress,
101
- settings: this.settings,
102
- email: this.email,
112
+ ...this.config.adapters?.geo ? this.createServices(request) : {
113
+ wordpress: this.wordpress,
114
+ settings: this.settings,
115
+ email: this.email
116
+ },
103
117
  getConnInfo: this.createConnInfoFn(request),
104
118
  verifyCaptcha: this.createVerifyCaptchaFn(request),
105
119
  getSession: this.createGetSessionFn(request),
@@ -116,9 +130,11 @@ var Context = class {
116
130
  request: null,
117
131
  config: this.config,
118
132
  logger: this.logger,
119
- wordpress: this.wordpress,
120
- settings: this.settings,
121
- email: this.email,
133
+ ...this.config.adapters?.geo ? this.createServices(null) : {
134
+ wordpress: this.wordpress,
135
+ settings: this.settings,
136
+ email: this.email
137
+ },
122
138
  getSession: this.createGetSessionFn(null, cookies),
123
139
  getConnInfo: this.createConnInfoFn(null),
124
140
  verifyCaptcha: this.createVerifyCaptchaFn(null),
package/dist/index.d.ts CHANGED
@@ -11,6 +11,7 @@ import { CurrencyFormat, IdentifierInput, LIST_ORDER, ListMetadata, ListOrder, P
11
11
  import { AnyContext, AnyNestedClient, CookiesAdapter, CookiesDeleteAll, CookiesGetAll, CookiesSetAll, HTTPMethod, List, MaybeOptionalOptions, RedirectInput, RedirectStatus } from "./shared/types.js";
12
12
  import { createCookiesAdapter } from "./adapters/cookies.js";
13
13
  import { ConnInfo, GeoAdapter, GeoGetConnInfo, createGeoAdapter, geoMock } from "./adapters/geo.js";
14
+ import { geoCloudflareNext } from "./adapters/geo.cloudflare.js";
14
15
  import { geoVercelNext } from "./adapters/geo.vercel.js";
15
16
  import { ConsoleLogAdapterOptions, LogLevel, LogPayload, Logger, LoggerAdapter, consoleLog, createLoggerAdapter, noopAdapter } from "./adapters/logger.js";
16
17
  import { ServiceAdapters, mergeServiceAdapters } from "./adapters/types.js";
@@ -43,4 +44,4 @@ import { ShaAlgorithm, compare, hash, hmac } from "./shared/crypto.js";
43
44
  import { Identifier, parseIdentifier } from "./shared/identifier.js";
44
45
  import { createOrpcRouter } from "./shared/router.js";
45
46
  import { deserializeCurrencyFormat, deserializeListMetadata, emptyList, serializeCurrencyFormat } from "./shared/serialize.js";
46
- export { ActiveKizloClient, 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, InferClientData, InferClientError, InferClientInput, InferClientResult, InferEventUnion, InferIntegrationProcedures, InferMiddlewares, InferProcedureData, InferProcedureError, InferProcedureInput, InferProcedureResult, Integration, IntegrationRequirements, InvocationScope, JsonValue, Kizlo, KizloBrowserClient, KizloClient, KizloClientConfig, KizloConfig, KizloEnv, KizloError, KizloErrorOptions, KizloErrorUnion, KizloProcedureRegistry, 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_Schema, WP_Success, WP_TransportFailure, WP_TypedHeaders, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry, WordPressEnv, WordPressSchemaRegistry, 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 };
47
+ export { ActiveKizloClient, 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, InferClientData, InferClientError, InferClientInput, InferClientResult, InferEventUnion, InferIntegrationProcedures, InferMiddlewares, InferProcedureData, InferProcedureError, InferProcedureInput, InferProcedureResult, Integration, IntegrationRequirements, InvocationScope, JsonValue, Kizlo, KizloBrowserClient, KizloClient, KizloClientConfig, KizloConfig, KizloEnv, KizloError, KizloErrorOptions, KizloErrorUnion, KizloProcedureRegistry, 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_Schema, WP_Success, WP_TransportFailure, WP_TypedHeaders, WebManifest, WebhookOptions, WebhookSettings, WebhookSettingsInput, WithCommonErrorMap, WordPressClientRegistry, WordPressCredentials, WordPressCustomFieldsRegistry, WordPressEndpointRegistry, WordPressEnv, WordPressSchemaRegistry, 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, geoCloudflareNext, 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
@@ -3,6 +3,7 @@ import { compare, hash, hmac } from "./shared/crypto.js";
3
3
  import { altcha, arkose, createCaptchaAdapter, friendlyCaptcha, hcaptcha, recaptcha, turnstile } from "./adapters/captcha.js";
4
4
  import { createCookiesAdapter } from "./adapters/cookies.js";
5
5
  import { createGeoAdapter, geoMock } from "./adapters/geo.js";
6
+ import { geoCloudflareNext } from "./adapters/geo.cloudflare.js";
6
7
  import { geoVercelNext } from "./adapters/geo.vercel.js";
7
8
  import { consoleLog, createLoggerAdapter, noopAdapter } from "./adapters/logger.js";
8
9
  import { mergeServiceAdapters } from "./adapters/types.js";
@@ -38,4 +39,4 @@ import { Kizlo, createKizlo, integrationEnv, resolveKizloConfig, resolveWordPres
38
39
  import { SITEMAP_BASE, SITEMAP_INDEX_SLUG, createSitemapRedirectRoute, createSitemapRoute } from "./seo/sitemap.js";
39
40
  import { createMiddleware } from "./shared/middleware.js";
40
41
 
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 };
42
+ 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, geoCloudflareNext, 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/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.26.2";
2
+ var version = "0.27.0";
3
3
 
4
4
  //#endregion
5
5
  export { version };
@@ -3,7 +3,7 @@ import { createProcedure } from "../shared/procedure.js";
3
3
  import { AnyEvent } from "./schema.js";
4
4
  import { validateEvent } from "./utils.js";
5
5
  import { tryCatchSync, verifyWebhook } from "@kizlo/shared";
6
- import z from "zod";
6
+ import z$1 from "zod";
7
7
 
8
8
  //#region src/webhook/index.ts
9
9
  function createEventHandler(eventsOrHandler, maybeHandler) {
@@ -21,7 +21,7 @@ function createWebhookRouter(options) {
21
21
  method: "POST",
22
22
  body: AnyEvent,
23
23
  path: "/webhooks",
24
- output: z.void()
24
+ output: z$1.void()
25
25
  }, async ({ context, input }) => {
26
26
  const payload = await context.request?.text() ?? "";
27
27
  const headers = Object.fromEntries(context.request?.headers.entries() ?? []);
@@ -1,8 +1,10 @@
1
1
  import { WP_List, WP_ListMetadata, WP_RequestInput, WP_Result, WordPressCredentials } from "./types.js";
2
- import { Duration, SearchParamsLike } from "@kizlo/shared";
2
+ import { Duration, Promisify, SearchParamsLike } from "@kizlo/shared";
3
3
 
4
4
  //#region src/wordpress/transport.d.ts
5
5
  interface WordPressTransportOptions {
6
+ /** Resolve a trusted IP for this invocation. Missing or invalid IPs are omitted. */
7
+ getClientIp?: () => Promisify<string | null>;
6
8
  credentials: WordPressCredentials;
7
9
  timeout?: Duration;
8
10
  onResponse?: (headers: Headers) => void;
@@ -15,6 +17,7 @@ interface WordPressTransportResult {
15
17
  }
16
18
  declare class WordPressTransport {
17
19
  #private;
20
+ private readonly getClientIp?;
18
21
  private readonly siteBase;
19
22
  private readonly authHeader;
20
23
  private readonly defaultTimeout;
@@ -2,9 +2,12 @@ import { WP_Error } from "./error.js";
2
2
  import { SAFE_REQUEST_TIMEOUT, UNEXPECTED_BODY_SNIPPET_LENGTH, WP_AUTH_HEADER_KEY, WP_AUTH_TYPE } from "./constants.js";
3
3
  import { isWordPressResourceError } from "./utils.js";
4
4
  import { milliseconds, stringifyQueryString, trimLeadingTrailingSlashes, tryCatch, tryCatchSync } from "@kizlo/shared";
5
+ import { z } from "zod";
5
6
 
6
7
  //#region src/wordpress/transport.ts
8
+ const clientIpSchema = z.union([z.ipv4(), z.ipv6()]);
7
9
  var WordPressTransport = class {
10
+ getClientIp;
8
11
  siteBase;
9
12
  authHeader;
10
13
  defaultTimeout;
@@ -22,6 +25,7 @@ var WordPressTransport = class {
22
25
  this.defaultTimeout = context.timeout ?? SAFE_REQUEST_TIMEOUT;
23
26
  this.onResponse = context.onResponse;
24
27
  this.onResult = context.onResult;
28
+ this.getClientIp = context.getClientIp;
25
29
  }
26
30
  async post(path, input) {
27
31
  return this.request({
@@ -206,6 +210,24 @@ var WordPressTransport = class {
206
210
  ...input.headers,
207
211
  [WP_AUTH_HEADER_KEY]: this.authHeader
208
212
  };
213
+ const signal = this.#resolveSignal(input);
214
+ let clientIp;
215
+ if (this.getClientIp && url.origin === new URL(this.siteBase).origin) {
216
+ for (const name of Object.keys(headers)) if (name.toLowerCase() === "x-real-ip") delete headers[name];
217
+ let onAbort = () => {};
218
+ try {
219
+ signal.throwIfAborted();
220
+ const value = await Promise.race([Promise.resolve().then(() => this.getClientIp?.()), new Promise((_, reject) => {
221
+ onAbort = () => reject(signal.reason);
222
+ signal.addEventListener("abort", onAbort, { once: true });
223
+ })]);
224
+ const parsed = clientIpSchema.safeParse(value);
225
+ if (parsed.success) clientIp = parsed.data;
226
+ } finally {
227
+ signal.removeEventListener("abort", onAbort);
228
+ }
229
+ if (clientIp) headers["x-real-ip"] = clientIp;
230
+ }
209
231
  const hasBody = ![
210
232
  "GET",
211
233
  "DELETE",
@@ -215,7 +237,8 @@ var WordPressTransport = class {
215
237
  return fetch(url.toString(), {
216
238
  headers,
217
239
  method: input.method,
218
- signal: this.#resolveSignal(input),
240
+ signal,
241
+ ...clientIp ? { redirect: "error" } : {},
219
242
  ...hasBody && body !== void 0 ? { body } : {}
220
243
  });
221
244
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "kizlo",
3
- "version": "0.26.2",
3
+ "version": "0.27.0",
4
4
  "type": "module",
5
5
  "description": "A headless WordPress framework for TypeScript.",
6
6
  "keywords": [