kizlo 0.26.1 → 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.
@@ -15,7 +15,7 @@ interface AuthUser {
15
15
  }
16
16
  type AuthGetSession = (request: Request | null) => Promisify<AuthUser | null>;
17
17
  interface AuthAdapter {
18
- /** Resolve the authenticated session from the request, or `null` when there is no session. Receives `null` for server-side (non-HTTP) invocations. */
18
+ /** Resolve the session from an HTTP request, a cookie-derived server request, or `null` when neither is available. */
19
19
  getSession: AuthGetSession;
20
20
  }
21
21
  /** Author a custom auth adapter, typed against the {@link AuthAdapter} contract. */
@@ -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
@@ -13,6 +13,8 @@ import { IntegrationPluginRequirement } from "@kizlo/shared";
13
13
 
14
14
  //#region src/context.d.ts
15
15
  interface ContextConfig {
16
+ /** Public Kizlo URL used to resolve cookie-based authentication for direct server calls. */
17
+ baseUrl?: string;
16
18
  siteSecret: string;
17
19
  adapters?: ServiceAdapters;
18
20
  credentials: WordPressCredentials;
@@ -64,6 +66,7 @@ declare class Context {
64
66
  private readonly settings;
65
67
  private readonly email;
66
68
  constructor(config: ContextConfig);
69
+ private createServices;
67
70
  /**
68
71
  * Report a request that did not reach Kizlo WordPress, or a WordPress side older than the client
69
72
  * needs. The transport supplies the URL and status even when fetch itself failed; a Kizlo response
@@ -75,34 +78,34 @@ declare class Context {
75
78
  /** Bold yellow, boxed in dashes so it stands out in a busy dev console. */
76
79
  private warn;
77
80
  createRestContext(request: Request): {
78
- headers: Headers;
79
- request: Request;
80
- config: ContextConfig;
81
- logger: Logger;
82
- wordpress: WordPressTransport;
83
- settings: SettingsService;
84
- email: EmailService;
85
81
  getConnInfo: ConnInfoFn;
86
82
  verifyCaptcha: VerifyCaptchaFn;
87
83
  getSession: SessionFn;
88
84
  verifyPreviewToken: VerifyPreviewTokenFn;
89
85
  cookies: CookiesStorage;
90
86
  invokedBy: "client";
91
- };
92
- createServerContext(): {
93
- cookies: CookiesStorage;
94
- headers: null;
95
- request: null;
96
- config: ContextConfig;
97
- logger: Logger;
98
87
  wordpress: WordPressTransport;
99
88
  settings: SettingsService;
100
89
  email: EmailService;
90
+ headers: Headers;
91
+ request: Request;
92
+ config: ContextConfig;
93
+ logger: Logger;
94
+ };
95
+ createServerContext(): {
101
96
  getSession: SessionFn;
102
97
  getConnInfo: ConnInfoFn;
103
98
  verifyCaptcha: VerifyCaptchaFn;
104
99
  verifyPreviewToken: VerifyPreviewTokenFn;
105
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;
106
109
  };
107
110
  private createRestCookieStorage;
108
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),
@@ -109,16 +123,19 @@ var Context = class {
109
123
  };
110
124
  }
111
125
  createServerContext() {
126
+ const cookies = new CookiesStorage(this.config.adapters?.cookies);
112
127
  return {
113
- cookies: new CookiesStorage(this.config.adapters?.cookies),
128
+ cookies,
114
129
  headers: null,
115
130
  request: null,
116
131
  config: this.config,
117
132
  logger: this.logger,
118
- wordpress: this.wordpress,
119
- settings: this.settings,
120
- email: this.email,
121
- getSession: this.createGetSessionFn(null),
133
+ ...this.config.adapters?.geo ? this.createServices(null) : {
134
+ wordpress: this.wordpress,
135
+ settings: this.settings,
136
+ email: this.email
137
+ },
138
+ getSession: this.createGetSessionFn(null, cookies),
122
139
  getConnInfo: this.createConnInfoFn(null),
123
140
  verifyCaptcha: this.createVerifyCaptchaFn(null),
124
141
  verifyPreviewToken: this.createVerifyPreviewTokenFn(),
@@ -176,9 +193,19 @@ var Context = class {
176
193
  return await this.config.adapters?.geo?.getConnInfo?.(request) ?? null;
177
194
  };
178
195
  }
179
- createGetSessionFn(request) {
196
+ createGetSessionFn(request, cookies) {
180
197
  return async () => {
181
- return await Promise.resolve(this.config.adapters?.auth?.getSession?.(request)) ?? null;
198
+ const auth = this.config.adapters?.auth;
199
+ if (!auth) return null;
200
+ let authRequest = request;
201
+ if (!authRequest && this.config.baseUrl && cookies) {
202
+ const cookieHeader = (await cookies.get()).map(({ name, value }) => stringifySetCookie({
203
+ name,
204
+ value
205
+ })).join("; ");
206
+ if (cookieHeader) authRequest = new Request(this.config.baseUrl, { headers: { cookie: cookieHeader } });
207
+ }
208
+ return await auth.getSession(authRequest) ?? null;
182
209
  };
183
210
  }
184
211
  createVerifyPreviewTokenFn() {
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 };
@@ -1,6 +1,7 @@
1
1
  import { FRAMEWORK_INTEGRATION_ORDER } from "../../shared/constants.js";
2
2
  import { createIntegration } from "../../shared/integration.js";
3
3
  import { runtimeEnv } from "../runtime-env.js";
4
+ import { createNextCookiesInterface } from "./utils.js";
4
5
  import { nextRevalidation } from "./revalidate.js";
5
6
 
6
7
  //#region src/integrations/nextjs/integration.ts
@@ -11,6 +12,7 @@ function nextjs(options = {}) {
11
12
  return createIntegration({
12
13
  id: "nextjs",
13
14
  order: FRAMEWORK_INTEGRATION_ORDER,
15
+ adapters: { cookies: createNextCookiesInterface() },
14
16
  env: runtimeEnv(source, "NEXT_PUBLIC_KIZLO_BASE_URL"),
15
17
  events: revalidation === false ? void 0 : nextRevalidation(typeof revalidation === "object" ? revalidation : void 0).events
16
18
  });
package/dist/kizlo.js CHANGED
@@ -27,6 +27,7 @@ var Kizlo = class {
27
27
  this.config = config;
28
28
  const integrations = this.registerIntegrations();
29
29
  this.context = new Context({
30
+ baseUrl: config.baseUrl,
30
31
  adapters: integrations.adapters,
31
32
  siteSecret: config.siteSecret,
32
33
  credentials: config.credentials,
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.26.1";
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.1",
3
+ "version": "0.27.0",
4
4
  "type": "module",
5
5
  "description": "A headless WordPress framework for TypeScript.",
6
6
  "keywords": [