kizlo 0.29.0 → 0.31.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.
- package/dist/adapters/geo.cloudflare.d.ts +1 -1
- package/dist/adapters/geo.cloudflare.js +1 -1
- package/dist/adapters/request-context.d.ts +12 -0
- package/dist/adapters/types.d.ts +2 -0
- package/dist/adapters/types.js +1 -0
- package/dist/context.d.ts +13 -30
- package/dist/context.js +15 -6
- package/dist/index.d.ts +4 -4
- package/dist/integrations/nextjs/api.d.ts +13 -0
- package/dist/integrations/nextjs/api.js +17 -0
- package/dist/integrations/tanstack-start/cloudflare/cache-policy.js +14 -0
- package/dist/integrations/tanstack-start/cloudflare/cache.d.ts +40 -0
- package/dist/integrations/tanstack-start/cloudflare/cache.js +112 -0
- package/dist/integrations/tanstack-start/cloudflare/revalidator.d.ts +35 -0
- package/dist/integrations/tanstack-start/cloudflare/revalidator.js +130 -0
- package/dist/integrations/tanstack-start/react/cookies.js +20 -0
- package/dist/integrations/tanstack-start/react/integration.d.ts +25 -0
- package/dist/integrations/tanstack-start/react/integration.js +18 -0
- package/dist/integrations/tanstack-start/react/middleware.d.ts +9 -0
- package/dist/integrations/tanstack-start/react/middleware.js +32 -0
- package/dist/integrations/tanstack-start/request-context.d.ts +8 -0
- package/dist/integrations/tanstack-start/request-context.js +24 -0
- package/dist/kizlo.d.ts +2 -1
- package/dist/kizlo.js +24 -16
- package/dist/nextjs/server.d.ts +2 -1
- package/dist/nextjs/server.js +2 -1
- package/dist/package.js +1 -1
- package/dist/tanstack-start/cloudflare.d.ts +28 -0
- package/dist/tanstack-start/cloudflare.js +34 -0
- package/dist/tanstack-start/react/server.d.ts +14 -0
- package/dist/tanstack-start/react/server.js +13 -0
- package/dist/webhook/index.d.ts +2 -0
- package/dist/webhook/index.js +9 -2
- package/dist/webhook/schema.d.ts +36 -1
- package/dist/webhook/schema.js +7 -3
- package/dist/webhook/utils.js +11 -1
- package/package.json +24 -20
- package/dist/cloudflare/vinext.d.ts +0 -7
- package/dist/cloudflare/vinext.js +0 -44
- package/dist/cloudflare.d.ts +0 -3
- package/dist/cloudflare.js +0 -4
- package/dist/integrations/cloudflare/integration.d.ts +0 -8
- package/dist/integrations/cloudflare/integration.js +0 -16
- package/dist/integrations/cloudflare/request-context.d.ts +0 -9
- package/dist/integrations/cloudflare/request-context.js +0 -58
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { GeoAdapter } from "./geo.js";
|
|
2
2
|
|
|
3
3
|
//#region src/adapters/geo.cloudflare.d.ts
|
|
4
|
-
/** Read trusted Cloudflare connection headers in Next.js
|
|
4
|
+
/** Read trusted Cloudflare connection headers in Next.js. Only use behind Cloudflare ingress. */
|
|
5
5
|
declare function geoCloudflareNext(): GeoAdapter;
|
|
6
6
|
//#endregion
|
|
7
7
|
export { geoCloudflareNext };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { cloudflareConnInfo } from "./cloudflare-connection.js";
|
|
2
2
|
|
|
3
3
|
//#region src/adapters/geo.cloudflare.ts
|
|
4
|
-
/** Read trusted Cloudflare connection headers in Next.js
|
|
4
|
+
/** Read trusted Cloudflare connection headers in Next.js. Only use behind Cloudflare ingress. */
|
|
5
5
|
function geoCloudflareNext() {
|
|
6
6
|
return { getConnInfo: async (request) => {
|
|
7
7
|
let headers = request?.headers;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
//#region src/adapters/request-context.d.ts
|
|
2
|
+
/** Request-local values supplied by a runtime integration, never by global core state. */
|
|
3
|
+
interface RequestContextAdapter {
|
|
4
|
+
get(): {
|
|
5
|
+
request: Request;
|
|
6
|
+
values: object;
|
|
7
|
+
} | undefined;
|
|
8
|
+
/** Optional when the framework already owns request scoping. */
|
|
9
|
+
run?(request: Request, values: object | undefined, handle: () => Promise<Response>): Promise<Response>;
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { RequestContextAdapter };
|
package/dist/adapters/types.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { CaptchaAdapter } from "./captcha.js";
|
|
|
3
3
|
import { CookiesAdapter } from "../shared/types.js";
|
|
4
4
|
import { GeoAdapter } from "./geo.js";
|
|
5
5
|
import { LoggerAdapter } from "./logger.js";
|
|
6
|
+
import { RequestContextAdapter } from "./request-context.js";
|
|
6
7
|
|
|
7
8
|
//#region src/adapters/types.d.ts
|
|
8
9
|
/** The service contracts Kizlo integrations can provide at runtime. */
|
|
@@ -12,6 +13,7 @@ interface ServiceAdapters {
|
|
|
12
13
|
geo?: GeoAdapter;
|
|
13
14
|
logger?: LoggerAdapter;
|
|
14
15
|
cookies?: CookiesAdapter;
|
|
16
|
+
requestContext?: RequestContextAdapter;
|
|
15
17
|
}
|
|
16
18
|
/** Merge adapter contributions in order without letting `undefined` erase an earlier value. */
|
|
17
19
|
declare function mergeServiceAdapters(...contributions: (ServiceAdapters | undefined)[]): ServiceAdapters;
|
package/dist/adapters/types.js
CHANGED
|
@@ -9,6 +9,7 @@ function mergeServiceAdapters(...contributions) {
|
|
|
9
9
|
if (contribution.geo !== void 0) adapters.geo = contribution.geo;
|
|
10
10
|
if (contribution.logger !== void 0) adapters.logger = contribution.logger;
|
|
11
11
|
if (contribution.cookies !== void 0) adapters.cookies = contribution.cookies;
|
|
12
|
+
if (contribution.requestContext !== void 0) adapters.requestContext = contribution.requestContext;
|
|
12
13
|
}
|
|
13
14
|
return adapters;
|
|
14
15
|
}
|
package/dist/context.d.ts
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { ActiveWordPressClient, WordPressCredentials } from "./wordpress/types.js";
|
|
2
|
-
import { WordPressTransport } from "./wordpress/transport.js";
|
|
3
2
|
import "./wordpress/index.js";
|
|
4
3
|
import { AuthUser } from "./adapters/auth.js";
|
|
5
4
|
import { PreviewTokenPayload } from "./shared/schema.js";
|
|
@@ -31,8 +30,8 @@ type VerifyPreviewTokenFn = (token: string) => Promise<PreviewTokenPayload | nul
|
|
|
31
30
|
* the server builds. A procedure's handler receives this base plus whatever its middleware injected
|
|
32
31
|
* via `next({ context })`.
|
|
33
32
|
*/
|
|
34
|
-
interface
|
|
35
|
-
/** The
|
|
33
|
+
interface BuiltinProcedureContext {
|
|
34
|
+
/** The active HTTP `Request`, or `null` outside a request scope. */
|
|
36
35
|
request: Request | null;
|
|
37
36
|
/** Response headers to be sent (e.g. `Set-Cookie`), or `null` server-side. */
|
|
38
37
|
headers: Headers | null;
|
|
@@ -59,6 +58,10 @@ interface ProcedureContext {
|
|
|
59
58
|
/** How the procedure was called: `"client"` (over HTTP) or `"server"` (direct server invocation). */
|
|
60
59
|
invokedBy: "client" | "server";
|
|
61
60
|
}
|
|
61
|
+
/** Augment in the application to add typed, server-supplied request fields. */
|
|
62
|
+
interface ProcedureContext extends BuiltinProcedureContext {}
|
|
63
|
+
/** The application fields accepted by handler(request, values), excluding Kizlo-owned fields. */
|
|
64
|
+
type PlatformRequestCtx = Omit<ProcedureContext, keyof BuiltinProcedureContext> & object;
|
|
62
65
|
declare class Context {
|
|
63
66
|
private readonly config;
|
|
64
67
|
private readonly logger;
|
|
@@ -77,35 +80,15 @@ declare class Context {
|
|
|
77
80
|
private warnIfOutdated;
|
|
78
81
|
/** Bold yellow, boxed in dashes so it stands out in a busy dev console. */
|
|
79
82
|
private warn;
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
verifyCaptcha: VerifyCaptchaFn;
|
|
83
|
-
getSession: SessionFn;
|
|
84
|
-
verifyPreviewToken: VerifyPreviewTokenFn;
|
|
85
|
-
cookies: CookiesStorage;
|
|
86
|
-
invokedBy: "client";
|
|
87
|
-
wordpress: WordPressTransport;
|
|
88
|
-
settings: SettingsService;
|
|
89
|
-
email: EmailService;
|
|
90
|
-
headers: Headers;
|
|
83
|
+
withRequestContext(request: Request, values: PlatformRequestCtx | undefined, handle: () => Promise<Response>): Promise<Response>;
|
|
84
|
+
createRestContext(request: Request, values?: PlatformRequestCtx): ProcedureContext & {
|
|
91
85
|
request: Request;
|
|
92
|
-
|
|
93
|
-
|
|
86
|
+
headers: Headers;
|
|
87
|
+
invokedBy: "client";
|
|
94
88
|
};
|
|
95
|
-
createServerContext(): {
|
|
96
|
-
getSession: SessionFn;
|
|
97
|
-
getConnInfo: ConnInfoFn;
|
|
98
|
-
verifyCaptcha: VerifyCaptchaFn;
|
|
99
|
-
verifyPreviewToken: VerifyPreviewTokenFn;
|
|
100
|
-
invokedBy: "server";
|
|
101
|
-
wordpress: WordPressTransport;
|
|
102
|
-
settings: SettingsService;
|
|
103
|
-
email: EmailService;
|
|
104
|
-
cookies: CookiesStorage;
|
|
89
|
+
createServerContext(): ProcedureContext & {
|
|
105
90
|
headers: null;
|
|
106
|
-
|
|
107
|
-
config: ContextConfig;
|
|
108
|
-
logger: Logger;
|
|
91
|
+
invokedBy: "server";
|
|
109
92
|
};
|
|
110
93
|
private createRestCookieStorage;
|
|
111
94
|
private createVerifyCaptchaFn;
|
|
@@ -115,4 +98,4 @@ declare class Context {
|
|
|
115
98
|
private createLogger;
|
|
116
99
|
}
|
|
117
100
|
//#endregion
|
|
118
|
-
export { ConnInfoFn, Context, ContextConfig, ProcedureContext, SessionFn, VerifyCaptchaFn, VerifyPreviewTokenFn };
|
|
101
|
+
export { ConnInfoFn, Context, ContextConfig, PlatformRequestCtx, ProcedureContext, SessionFn, VerifyCaptchaFn, VerifyPreviewTokenFn };
|
package/dist/context.js
CHANGED
|
@@ -102,9 +102,15 @@ var Context = class {
|
|
|
102
102
|
const border = "-".repeat(inner.length + 2);
|
|
103
103
|
console.warn(`\n\x1b[1m\x1b[33m${border}\n|${inner}|\n${border}\x1b[0m\n`);
|
|
104
104
|
}
|
|
105
|
-
|
|
105
|
+
withRequestContext(request, values, handle) {
|
|
106
|
+
if (values !== void 0 && (values === null || typeof values !== "object" || Array.isArray(values))) throw new TypeError("Request context must be an object.");
|
|
107
|
+
return this.config.adapters?.requestContext?.run?.(request, values, handle) ?? handle();
|
|
108
|
+
}
|
|
109
|
+
createRestContext(request, values) {
|
|
106
110
|
const headers = new Headers();
|
|
107
111
|
return {
|
|
112
|
+
...this.config.adapters?.requestContext?.get()?.values,
|
|
113
|
+
...values,
|
|
108
114
|
headers,
|
|
109
115
|
request: request.clone(),
|
|
110
116
|
config: this.config,
|
|
@@ -123,21 +129,24 @@ var Context = class {
|
|
|
123
129
|
};
|
|
124
130
|
}
|
|
125
131
|
createServerContext() {
|
|
132
|
+
const scope = this.config.adapters?.requestContext?.get();
|
|
133
|
+
const request = scope?.request ?? null;
|
|
126
134
|
const cookies = new CookiesStorage(this.config.adapters?.cookies);
|
|
127
135
|
return {
|
|
136
|
+
...scope?.values,
|
|
128
137
|
cookies,
|
|
129
138
|
headers: null,
|
|
130
|
-
request
|
|
139
|
+
request,
|
|
131
140
|
config: this.config,
|
|
132
141
|
logger: this.logger,
|
|
133
|
-
...this.config.adapters?.geo ? this.createServices(
|
|
142
|
+
...this.config.adapters?.geo ? this.createServices(request) : {
|
|
134
143
|
wordpress: this.wordpress,
|
|
135
144
|
settings: this.settings,
|
|
136
145
|
email: this.email
|
|
137
146
|
},
|
|
138
|
-
getSession: this.createGetSessionFn(
|
|
139
|
-
getConnInfo: this.createConnInfoFn(
|
|
140
|
-
verifyCaptcha: this.createVerifyCaptchaFn(
|
|
147
|
+
getSession: this.createGetSessionFn(request, cookies),
|
|
148
|
+
getConnInfo: this.createConnInfoFn(request),
|
|
149
|
+
verifyCaptcha: this.createVerifyCaptchaFn(request),
|
|
141
150
|
verifyPreviewToken: this.createVerifyPreviewTokenFn(),
|
|
142
151
|
invokedBy: "server"
|
|
143
152
|
};
|
package/dist/index.d.ts
CHANGED
|
@@ -17,14 +17,14 @@ import { ConsoleLogAdapterOptions, LogLevel, LogPayload, Logger, LoggerAdapter,
|
|
|
17
17
|
import { ServiceAdapters, mergeServiceAdapters } from "./adapters/types.js";
|
|
18
18
|
import { AuthorsSettings, AuthorsSettingsInput, BrandSettings, BrandSettingsInput, CrawlingSettings, CrawlingSettingsInput, HeadlessSettings, HeadlessSettingsInput, IdentitySettings, IdentitySettingsInput, OrganizationFounder, OrganizationSettings, OrganizationSettingsInput, PersonSettings, PersonSettingsInput, PostStatusDefinition, PostTypeSettings, PostTypeSettingsInput, Settings, SiteSettings, SiteSettingsInput, SocialProfile, TaxonomySettings, TaxonomySettingsInput, UploadsSettings, UploadsSettingsInput, WebhookSettings, WebhookSettingsInput } from "./settings/service.interface.js";
|
|
19
19
|
import { IconDescriptor, ManifestIcon, ResolvedIcons, resolveIcons } from "./brand/icons.js";
|
|
20
|
+
import { CookiesStorage } from "./cookie.js";
|
|
21
|
+
import { SettingsService } from "./settings/service.js";
|
|
22
|
+
import { ConnInfoFn, Context, ContextConfig, PlatformRequestCtx, ProcedureContext, SessionFn, VerifyCaptchaFn, VerifyPreviewTokenFn } from "./context.js";
|
|
20
23
|
import { Post, PostCustomFields, PostCustomFieldsSchema } from "./post/schema.js";
|
|
21
24
|
import { Page, PageCustomFields, PageCustomFieldsSchema } from "./page/schema.js";
|
|
22
25
|
import { Category, CategoryCustomFields, CategoryCustomFieldsSchema } from "./category/schema.js";
|
|
23
26
|
import { Tag, TagCustomFields, TagCustomFieldsSchema } from "./tag/schema.js";
|
|
24
27
|
import { CORE_PROCEDURES, CoreProcedures } from "./procedures.js";
|
|
25
|
-
import { CookiesStorage } from "./cookie.js";
|
|
26
|
-
import { SettingsService } from "./settings/service.js";
|
|
27
|
-
import { ConnInfoFn, Context, ContextConfig, ProcedureContext, SessionFn, VerifyCaptchaFn, VerifyPreviewTokenFn } from "./context.js";
|
|
28
28
|
import { AnyEventSchema, AnyEvents, EventHandler, EventHandlerFn, InferEventUnion, WebhookOptions, createEventHandler, createWebhookRouter } from "./webhook/index.js";
|
|
29
29
|
import { COMMON_ERRORS, CommonErrorCode, CommonErrorLiteral, CommonErrorMap, DefinedErrorMapLike, ErrorDefinition, KizloError, KizloErrorOptions, ThrowableErrorFn, ThrowableErrorMap, WithCommonErrorMap, createThrowableErrorMap, defineErrorMap, isKizloError, toKizloError } from "./shared/error.js";
|
|
30
30
|
import { AnyMiddleware, ExtractMiddlewareContextOutput, InferMiddlewares, Middleware, MiddlewareHandler, MiddlewareNextFn, MiddlewareOptions, MiddlewareResult, createMiddleware } from "./shared/middleware.js";
|
|
@@ -44,4 +44,4 @@ import { ShaAlgorithm, compare, hash, hmac } from "./shared/crypto.js";
|
|
|
44
44
|
import { Identifier, parseIdentifier } from "./shared/identifier.js";
|
|
45
45
|
import { createOrpcRouter } from "./shared/router.js";
|
|
46
46
|
import { deserializeCurrencyFormat, deserializeListMetadata, emptyList, serializeCurrencyFormat } from "./shared/serialize.js";
|
|
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, 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 };
|
|
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, PlatformRequestCtx, 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, 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 };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/integrations/nextjs/api.d.ts
|
|
2
|
+
/** Map framework route methods to Kizlo without passing Next.js params as platform context. */
|
|
3
|
+
declare function toNextJsHandler(handler: (request: Request) => Response | Promise<Response>): {
|
|
4
|
+
GET: (request: Request) => Response | Promise<Response>;
|
|
5
|
+
POST: (request: Request) => Response | Promise<Response>;
|
|
6
|
+
PUT: (request: Request) => Response | Promise<Response>;
|
|
7
|
+
PATCH: (request: Request) => Response | Promise<Response>;
|
|
8
|
+
DELETE: (request: Request) => Response | Promise<Response>;
|
|
9
|
+
OPTIONS: (request: Request) => Response | Promise<Response>;
|
|
10
|
+
HEAD: (request: Request) => Response | Promise<Response>;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { toNextJsHandler };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
//#region src/integrations/nextjs/api.ts
|
|
2
|
+
/** Map framework route methods to Kizlo without passing Next.js params as platform context. */
|
|
3
|
+
function toNextJsHandler(handler) {
|
|
4
|
+
const route = (request) => handler(request);
|
|
5
|
+
return {
|
|
6
|
+
GET: route,
|
|
7
|
+
POST: route,
|
|
8
|
+
PUT: route,
|
|
9
|
+
PATCH: route,
|
|
10
|
+
DELETE: route,
|
|
11
|
+
OPTIONS: route,
|
|
12
|
+
HEAD: route
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
//#endregion
|
|
17
|
+
export { toNextJsHandler };
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
//#region src/integrations/tanstack-start/cloudflare/cache-policy.ts
|
|
2
|
+
const EDGE_HEADERS = [
|
|
3
|
+
"Cloudflare-CDN-Cache-Control",
|
|
4
|
+
"CDN-Cache-Control",
|
|
5
|
+
"Cache-Control"
|
|
6
|
+
];
|
|
7
|
+
function validateTags(tags) {
|
|
8
|
+
if (!Array.isArray(tags)) throw new TypeError("CDN tags must be an array of strings.");
|
|
9
|
+
for (const tag of tags) if (typeof tag !== "string" || !tag.length || tag.length > 1024 || /[^\x21-\x2b\x2d-\x7e]/.test(tag)) throw new TypeError("CDN tags must contain 1-1024 printable ASCII characters without spaces or commas.");
|
|
10
|
+
return [...new Set(tags)];
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
//#endregion
|
|
14
|
+
export { EDGE_HEADERS, validateTags };
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Duration } from "@kizlo/shared";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/tanstack-start/cloudflare/cache.d.ts
|
|
4
|
+
|
|
5
|
+
interface CloudflareCacheResult {
|
|
6
|
+
success: boolean;
|
|
7
|
+
errors?: {
|
|
8
|
+
code: number;
|
|
9
|
+
message: string;
|
|
10
|
+
}[];
|
|
11
|
+
}
|
|
12
|
+
/** Native Workers Cache control surface, not the separate caches.default API. */
|
|
13
|
+
interface CloudflareCacheBinding {
|
|
14
|
+
invalidate?(options: {
|
|
15
|
+
tags?: string[];
|
|
16
|
+
pathPrefixes?: string[];
|
|
17
|
+
}): Promise<CloudflareCacheResult>;
|
|
18
|
+
purge?(options: {
|
|
19
|
+
purgeEverything: true;
|
|
20
|
+
}): Promise<CloudflareCacheResult>;
|
|
21
|
+
}
|
|
22
|
+
interface CdnHeadersOptions {
|
|
23
|
+
/** Freshness in seconds at the edge. Browser reuse requires revalidation. */
|
|
24
|
+
maxAge: Duration;
|
|
25
|
+
staleWhileRevalidate?: Duration;
|
|
26
|
+
/** Defaults to zero so a failing origin cannot keep stale pages indefinitely. */
|
|
27
|
+
staleIfError?: Duration;
|
|
28
|
+
tags?: readonly string[];
|
|
29
|
+
/** Request headers that select separate cached responses. No variance is added automatically. */
|
|
30
|
+
vary?: readonly string[];
|
|
31
|
+
}
|
|
32
|
+
declare function createCdnHeaders(options: CdnHeadersOptions): Record<string, string>;
|
|
33
|
+
/** Mark the native pathname prefix stale, including its query variants and longer paths. */
|
|
34
|
+
declare function revalidateUrl(url: string | URL): Promise<void>;
|
|
35
|
+
/** Mark responses carrying this host-scoped tag stale under their stored cache policy. */
|
|
36
|
+
declare function revalidateTag(tag: string): Promise<void>;
|
|
37
|
+
/** Remove every cached response owned by the calling Worker entrypoint. */
|
|
38
|
+
declare function purgeCache(): Promise<void>;
|
|
39
|
+
//#endregion
|
|
40
|
+
export { CdnHeadersOptions, CloudflareCacheBinding, CloudflareCacheResult, createCdnHeaders, purgeCache, revalidateTag, revalidateUrl };
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { getStartRequestContext } from "../request-context.js";
|
|
2
|
+
import { EDGE_HEADERS, validateTags } from "./cache-policy.js";
|
|
3
|
+
import { seconds } from "@kizlo/shared";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
|
|
6
|
+
//#region src/integrations/tanstack-start/cloudflare/cache.ts
|
|
7
|
+
function getCacheContext() {
|
|
8
|
+
const context = getStartRequestContext();
|
|
9
|
+
const cache = (context?.values)?.executionCtx?.cache;
|
|
10
|
+
if (!context || !cache) throw new Error("CDN revalidation requires a TanStack Start request with executionCtx.cache. Use withCloudflare at the Worker entrypoint.");
|
|
11
|
+
return {
|
|
12
|
+
url: new URL(context.request.url),
|
|
13
|
+
cache
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const MAX_TAG_HEADER_BYTES = 16384;
|
|
17
|
+
const digest = (value) => createHash("sha256").update(value).digest("hex");
|
|
18
|
+
const resourceTag = (url, tag) => `kizlo:t:${digest(`${url.host}\0${tag}`)}`;
|
|
19
|
+
function seconds$1(value, name) {
|
|
20
|
+
value = typeof value === "number" ? value : seconds(value);
|
|
21
|
+
if (!Number.isSafeInteger(value) || value < 0) throw new RangeError(`${name} must be a nonnegative integer number of seconds.`);
|
|
22
|
+
return value;
|
|
23
|
+
}
|
|
24
|
+
function createCdnHeaders(options) {
|
|
25
|
+
const directives = [`public`, `max-age=${seconds$1(options.maxAge, "maxAge")}`];
|
|
26
|
+
if (options.staleWhileRevalidate !== void 0) directives.push(`stale-while-revalidate=${seconds$1(options.staleWhileRevalidate, "staleWhileRevalidate")}`);
|
|
27
|
+
directives.push(`stale-if-error=${seconds$1(options.staleIfError ?? 0, "staleIfError")}`);
|
|
28
|
+
const tags = validateTags(options.tags ?? []).join(",");
|
|
29
|
+
const vary = options.vary ?? [];
|
|
30
|
+
if (!Array.isArray(vary) || vary.some((name) => typeof name !== "string" || !name.length || /[^!#$%&'*+.^_`|~0-9a-z-]/i.test(name))) throw new TypeError("Vary must be an array of HTTP header names.");
|
|
31
|
+
const names = [...new Map(vary.map((name) => [name.toLowerCase(), name])).values()];
|
|
32
|
+
return {
|
|
33
|
+
"Cache-Control": "no-cache",
|
|
34
|
+
"Cloudflare-CDN-Cache-Control": directives.join(", "),
|
|
35
|
+
...tags ? { "Cache-Tag": tags } : {},
|
|
36
|
+
...names.length ? { Vary: names.includes("*") ? "*" : names.join(", ") } : {}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Mark the native pathname prefix stale, including its query variants and longer paths. */
|
|
40
|
+
async function revalidateUrl(url) {
|
|
41
|
+
const state = getCacheContext();
|
|
42
|
+
const value = url instanceof URL ? url.href : url;
|
|
43
|
+
if (typeof value !== "string" || !/^(?:\/(?!\/)|https?:\/\/)/i.test(value) || /[\s\p{Cc}\\]/u.test(value)) throw new TypeError("CDN URLs must be absolute pathnames or same-origin HTTP(S) URLs without whitespace or backslashes.");
|
|
44
|
+
const target = new URL(value, state.url);
|
|
45
|
+
if (target.origin !== state.url.origin || target.username || target.password) throw new TypeError("CDN URLs must belong to the current origin and cannot contain credentials.");
|
|
46
|
+
await invalidate(state.cache, { pathPrefixes: [target.pathname] });
|
|
47
|
+
}
|
|
48
|
+
/** Mark responses carrying this host-scoped tag stale under their stored cache policy. */
|
|
49
|
+
async function revalidateTag(tag) {
|
|
50
|
+
await revalidateTags([tag]);
|
|
51
|
+
}
|
|
52
|
+
/** Submit every dependency, independently of the response storage budget. */
|
|
53
|
+
async function revalidateTags(tags) {
|
|
54
|
+
const unique = validateTags(tags);
|
|
55
|
+
const state = getCacheContext();
|
|
56
|
+
for (let index = 0; index < unique.length; index += 100) await invalidate(state.cache, { tags: unique.slice(index, index + 100).map((tag) => resourceTag(state.url, tag)) });
|
|
57
|
+
}
|
|
58
|
+
/** Remove every cached response owned by the calling Worker entrypoint. */
|
|
59
|
+
async function purgeCache() {
|
|
60
|
+
const { cache } = getCacheContext();
|
|
61
|
+
if (typeof cache.purge !== "function") throw new Error("The Worker runtime does not support cache.purge().");
|
|
62
|
+
assertCacheResult(await cache.purge({ purgeEverything: true }));
|
|
63
|
+
}
|
|
64
|
+
async function invalidate(cache, targets) {
|
|
65
|
+
if (typeof cache.invalidate !== "function") throw new Error("The Worker runtime does not support cache.invalidate().");
|
|
66
|
+
assertCacheResult(await cache.invalidate(targets));
|
|
67
|
+
}
|
|
68
|
+
function assertCacheResult(result) {
|
|
69
|
+
if (result?.success !== true) {
|
|
70
|
+
const detail = result?.errors?.map(({ code, message }) => `${code}: ${message}`).join("; ");
|
|
71
|
+
throw new Error(`Cloudflare CDN revalidation failed${detail ? `: ${detail}` : "."}`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/** Default to no caching and encode only authored resource tags. */
|
|
75
|
+
function applyCloudflareHeaders(request, response) {
|
|
76
|
+
if (response.status === 101) return response;
|
|
77
|
+
const result = new Headers(response.headers);
|
|
78
|
+
if (!EDGE_HEADERS.some((name) => result.has(name))) result.set("Cache-Control", "no-store");
|
|
79
|
+
const authoredTags = result.get("Cache-Tag");
|
|
80
|
+
if (authoredTags !== null) {
|
|
81
|
+
const url = new URL(request.url);
|
|
82
|
+
const resources = validateTags(authoredTags.split(",").map((tag) => tag.trim()));
|
|
83
|
+
const encoded = resources.map((tag) => resourceTag(url, tag));
|
|
84
|
+
const retained = [];
|
|
85
|
+
let bytes = 0;
|
|
86
|
+
for (const tag of encoded) {
|
|
87
|
+
const next = bytes + tag.length + (retained.length ? 1 : 0);
|
|
88
|
+
if (retained.length === 1e3 || next > MAX_TAG_HEADER_BYTES) break;
|
|
89
|
+
retained.push(tag);
|
|
90
|
+
bytes = next;
|
|
91
|
+
}
|
|
92
|
+
if (retained.length < resources.length) console.warn({
|
|
93
|
+
code: "KIZLO_CDN_TAGS_TRIMMED",
|
|
94
|
+
pathname: url.pathname,
|
|
95
|
+
requested: resources.length,
|
|
96
|
+
retained: retained.length,
|
|
97
|
+
dropped: resources.length - retained.length,
|
|
98
|
+
maxBytes: MAX_TAG_HEADER_BYTES,
|
|
99
|
+
maxTags: 1e3
|
|
100
|
+
});
|
|
101
|
+
const tagHeader = retained.join(",");
|
|
102
|
+
result.set("Cache-Tag", tagHeader);
|
|
103
|
+
}
|
|
104
|
+
return new Response(response.body, {
|
|
105
|
+
status: response.status,
|
|
106
|
+
statusText: response.statusText,
|
|
107
|
+
headers: result
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
//#endregion
|
|
112
|
+
export { applyCloudflareHeaders, createCdnHeaders, getCacheContext, purgeCache, revalidateTag, revalidateTags, revalidateUrl };
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { PostEventData, SETTINGS_INDEXED_EVENT_TYPES, SettingsEventType, TermDependencies, TermEventData } from "../../../webhook/schema.js";
|
|
2
|
+
import { Integration } from "../../../shared/integration.js";
|
|
3
|
+
import "../../../index.js";
|
|
4
|
+
import z from "zod/v4";
|
|
5
|
+
|
|
6
|
+
//#region src/integrations/tanstack-start/cloudflare/revalidator.d.ts
|
|
7
|
+
type RevalidationPostData = z.output<typeof PostEventData> & {
|
|
8
|
+
affected_terms: TermDependencies;
|
|
9
|
+
};
|
|
10
|
+
type RevalidationTermData = z.output<typeof TermEventData> & {
|
|
11
|
+
affected_terms: TermDependencies;
|
|
12
|
+
};
|
|
13
|
+
interface RevalidationPostRule {
|
|
14
|
+
resourceTag(id: number): string;
|
|
15
|
+
collectionTags?(data: RevalidationPostData): readonly string[];
|
|
16
|
+
}
|
|
17
|
+
interface RevalidationTaxonomyRule {
|
|
18
|
+
resourceTag(id: number): string;
|
|
19
|
+
collectionTags?(id: number, data: RevalidationTermData): readonly string[];
|
|
20
|
+
}
|
|
21
|
+
type RevalidationSettingsEvent<K$1 extends SettingsEventType> = {
|
|
22
|
+
type: K$1;
|
|
23
|
+
data: K$1 extends (typeof SETTINGS_INDEXED_EVENT_TYPES)[number] ? {
|
|
24
|
+
key: string;
|
|
25
|
+
} : null;
|
|
26
|
+
};
|
|
27
|
+
interface RevalidatorOptions {
|
|
28
|
+
postTypes?: Record<string, RevalidationPostRule>;
|
|
29
|
+
taxonomies?: Record<string, RevalidationTaxonomyRule>;
|
|
30
|
+
settings?: "purge" | { [K in SettingsEventType]?: (event: RevalidationSettingsEvent<K>) => readonly string[] };
|
|
31
|
+
}
|
|
32
|
+
/** Optional content-change rules; does not install a response caching policy. */
|
|
33
|
+
declare function revalidator(options?: RevalidatorOptions): Integration<"revalidator", Record<never, never>>;
|
|
34
|
+
//#endregion
|
|
35
|
+
export { RevalidationPostData, RevalidationPostRule, RevalidationSettingsEvent, RevalidationTaxonomyRule, RevalidationTermData, RevalidatorOptions, revalidator };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { KizloError } from "../../../shared/error.js";
|
|
2
|
+
import { createIntegration } from "../../../shared/integration.js";
|
|
3
|
+
import { POST_EVENT_TYPES, PostEventData, SETTINGS_EVENT_TYPES, SETTINGS_INDEXED_EVENT_TYPES, SettingsIndexedEventData, SettingsSimpleEventData, TERM_EVENT_TYPES, TermDependencies, TermEventData } from "../../../webhook/schema.js";
|
|
4
|
+
import { createEventHandler } from "../../../webhook/index.js";
|
|
5
|
+
import { validateTags } from "./cache-policy.js";
|
|
6
|
+
import { getCacheContext, purgeCache, revalidateTags } from "./cache.js";
|
|
7
|
+
import z from "zod/v4";
|
|
8
|
+
|
|
9
|
+
//#region src/integrations/tanstack-start/cloudflare/revalidator.ts
|
|
10
|
+
const rule = z.object({
|
|
11
|
+
resourceTag: z.custom((value) => typeof value === "function"),
|
|
12
|
+
collectionTags: z.custom((value) => typeof value === "function").optional()
|
|
13
|
+
}).strict();
|
|
14
|
+
const rules = z.record(z.string().regex(/^[a-zA-Z0-9_-]+$/), rule);
|
|
15
|
+
const optionsSchema = z.object({
|
|
16
|
+
postTypes: rules.optional(),
|
|
17
|
+
taxonomies: rules.optional(),
|
|
18
|
+
settings: z.union([z.literal("purge"), z.partialRecord(z.enum(SETTINGS_EVENT_TYPES), z.custom((value) => typeof value === "function"))]).optional()
|
|
19
|
+
}).strict();
|
|
20
|
+
/** Optional content-change rules; does not install a response caching policy. */
|
|
21
|
+
function revalidator(options = {}) {
|
|
22
|
+
optionsSchema.parse(options);
|
|
23
|
+
const purgeSettings = options.settings === "purge";
|
|
24
|
+
const settings = typeof options.settings === "object" ? options.settings : {};
|
|
25
|
+
const postSchema = z.unknown().transform((data, ctx) => {
|
|
26
|
+
if (!(data !== null && typeof data === "object" && "post_type" in data && typeof data.post_type === "string" && Object.hasOwn(options.postTypes ?? {}, data.post_type))) {
|
|
27
|
+
if (Object.keys(options.postTypes ?? {}).length && (data === null || typeof data !== "object" || !("post_type" in data) || typeof data.post_type !== "string" || !data.post_type.length)) {
|
|
28
|
+
ctx.addIssue({
|
|
29
|
+
code: "custom",
|
|
30
|
+
message: "A post_type is required to select configured rules"
|
|
31
|
+
});
|
|
32
|
+
return z.NEVER;
|
|
33
|
+
}
|
|
34
|
+
return data;
|
|
35
|
+
}
|
|
36
|
+
const result = PostEventData.extend({ affected_terms: TermDependencies }).safeParse(data);
|
|
37
|
+
if (!result.success) {
|
|
38
|
+
ctx.addIssue({
|
|
39
|
+
code: "custom",
|
|
40
|
+
message: "Complete affected_terms is required for configured post types"
|
|
41
|
+
});
|
|
42
|
+
return z.NEVER;
|
|
43
|
+
}
|
|
44
|
+
return result.data;
|
|
45
|
+
});
|
|
46
|
+
const termSchema = z.unknown().transform((data, ctx) => {
|
|
47
|
+
if (!(data !== null && typeof data === "object" && "taxonomy" in data && typeof data.taxonomy === "string" && Object.hasOwn(options.taxonomies ?? {}, data.taxonomy))) {
|
|
48
|
+
if (Object.keys(options.taxonomies ?? {}).length && (data === null || typeof data !== "object" || !("taxonomy" in data) || typeof data.taxonomy !== "string" || !data.taxonomy.length)) {
|
|
49
|
+
ctx.addIssue({
|
|
50
|
+
code: "custom",
|
|
51
|
+
message: "A taxonomy is required to select configured rules"
|
|
52
|
+
});
|
|
53
|
+
return z.NEVER;
|
|
54
|
+
}
|
|
55
|
+
return data;
|
|
56
|
+
}
|
|
57
|
+
const result = TermEventData.extend({ affected_terms: TermDependencies }).safeParse(data);
|
|
58
|
+
if (!result.success) {
|
|
59
|
+
ctx.addIssue({
|
|
60
|
+
code: "custom",
|
|
61
|
+
message: "Complete affected_terms is required for configured taxonomies"
|
|
62
|
+
});
|
|
63
|
+
return z.NEVER;
|
|
64
|
+
}
|
|
65
|
+
return result.data;
|
|
66
|
+
});
|
|
67
|
+
return createIntegration({
|
|
68
|
+
id: "revalidator",
|
|
69
|
+
events: [{
|
|
70
|
+
...createEventHandler([
|
|
71
|
+
{
|
|
72
|
+
types: [...POST_EVENT_TYPES],
|
|
73
|
+
data: postSchema
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
types: [...TERM_EVENT_TYPES],
|
|
77
|
+
data: termSchema
|
|
78
|
+
},
|
|
79
|
+
...(purgeSettings ? SETTINGS_EVENT_TYPES : Object.keys(settings)).map((type) => ({
|
|
80
|
+
types: [type],
|
|
81
|
+
data: SETTINGS_INDEXED_EVENT_TYPES.includes(type) ? SettingsIndexedEventData : SettingsSimpleEventData
|
|
82
|
+
}))
|
|
83
|
+
], async (event, context) => {
|
|
84
|
+
if (!event) return;
|
|
85
|
+
const selected = [];
|
|
86
|
+
const addResource = (tag) => {
|
|
87
|
+
selected.push(...validateTags([tag]));
|
|
88
|
+
};
|
|
89
|
+
const addCollection = (tags) => {
|
|
90
|
+
selected.push(...validateTags(tags));
|
|
91
|
+
};
|
|
92
|
+
if (POST_EVENT_TYPES.includes(event.type)) {
|
|
93
|
+
const data = event.data;
|
|
94
|
+
const rule$1 = data && typeof data.post_type === "string" && Object.hasOwn(options.postTypes ?? {}, data.post_type) ? options.postTypes?.[data.post_type] : void 0;
|
|
95
|
+
if (!rule$1 || !data) return;
|
|
96
|
+
addResource(rule$1.resourceTag(data.post_id));
|
|
97
|
+
if (rule$1.collectionTags) addCollection(rule$1.collectionTags(data));
|
|
98
|
+
} else if (TERM_EVENT_TYPES.includes(event.type)) {
|
|
99
|
+
const data = event.data;
|
|
100
|
+
const rule$1 = data && typeof data.taxonomy === "string" && Object.hasOwn(options.taxonomies ?? {}, data.taxonomy) ? options.taxonomies?.[data.taxonomy] : void 0;
|
|
101
|
+
if (!rule$1 || !data) return;
|
|
102
|
+
for (const id of new Set([data.term_id, ...data.affected_terms[data.taxonomy] ?? []])) {
|
|
103
|
+
addResource(rule$1.resourceTag(id));
|
|
104
|
+
if (rule$1.collectionTags) addCollection(rule$1.collectionTags(id, data));
|
|
105
|
+
}
|
|
106
|
+
} else if (!purgeSettings) {
|
|
107
|
+
const setting = settings[event.type];
|
|
108
|
+
if (!setting) return;
|
|
109
|
+
addCollection(setting(event));
|
|
110
|
+
}
|
|
111
|
+
const purge = purgeSettings && SETTINGS_EVENT_TYPES.includes(event.type);
|
|
112
|
+
if (!purge && !selected.length) return;
|
|
113
|
+
const active = getCacheContext();
|
|
114
|
+
const expected = new URL(context.config.baseUrl ?? "").origin;
|
|
115
|
+
if (active.url.origin !== expected || !context.request || new URL(context.request.url).origin !== expected) throw new KizloError("UNPROCESSABLE_CONTENT", { message: "Revalidation webhook must use the configured public origin and cache-owning Worker entrypoint." });
|
|
116
|
+
try {
|
|
117
|
+
if (purge) await purgeCache();
|
|
118
|
+
else await revalidateTags(selected);
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error !== null && typeof error === "object" && "status" in error && error.status === 429) throw new KizloError("TOO_MANY_REQUESTS", { cause: error });
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
}),
|
|
124
|
+
failureMode: "retry"
|
|
125
|
+
}]
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { revalidator };
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { deleteCookie, getCookies, setCookie } from "@tanstack/react-start/server";
|
|
2
|
+
|
|
3
|
+
//#region src/integrations/tanstack-start/react/cookies.ts
|
|
4
|
+
function startCookies() {
|
|
5
|
+
return {
|
|
6
|
+
getAll: () => Object.entries(getCookies()).flatMap(([name, value]) => value === void 0 ? [] : [{
|
|
7
|
+
name,
|
|
8
|
+
value
|
|
9
|
+
}]),
|
|
10
|
+
setAll: (cookies) => {
|
|
11
|
+
for (const { name, value, options } of cookies) setCookie(name, value, options);
|
|
12
|
+
},
|
|
13
|
+
deleteAll: (cookies) => {
|
|
14
|
+
for (const { name, options } of cookies) deleteCookie(name, options);
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
//#endregion
|
|
20
|
+
export { startCookies };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { CookiesAdapter } from "../../../shared/types.js";
|
|
2
|
+
import { EventHandler } from "../../../webhook/index.js";
|
|
3
|
+
import { EnvSource, IntegrationRequirements } from "../../../shared/integration.js";
|
|
4
|
+
import "../../../index.js";
|
|
5
|
+
import { TanstackStartOptions } from "../integration.js";
|
|
6
|
+
import { getStartRequestContext } from "../request-context.js";
|
|
7
|
+
|
|
8
|
+
//#region src/integrations/tanstack-start/react/integration.d.ts
|
|
9
|
+
/** Add React Start's native request context and cookies to the shared environment mapping. */
|
|
10
|
+
declare function tanstackStart(options?: TanstackStartOptions): {
|
|
11
|
+
adapters: {
|
|
12
|
+
cookies: CookiesAdapter;
|
|
13
|
+
requestContext: {
|
|
14
|
+
get: typeof getStartRequestContext;
|
|
15
|
+
};
|
|
16
|
+
};
|
|
17
|
+
id: "tanstack-start";
|
|
18
|
+
procedures?: Record<never, never> | undefined;
|
|
19
|
+
events?: EventHandler[];
|
|
20
|
+
env?: EnvSource;
|
|
21
|
+
requires?: IntegrationRequirements;
|
|
22
|
+
order?: number;
|
|
23
|
+
};
|
|
24
|
+
//#endregion
|
|
25
|
+
export { tanstackStart };
|