@appwarden/middleware 3.14.0 → 3.15.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
  [![GitHub](https://img.shields.io/badge/GitHub-appwarden%2Fmiddleware-181717?logo=github&logoColor=white)](https://github.com/appwarden/middleware)
5
5
  [![npm version](https://img.shields.io/npm/v/@appwarden/middleware.svg)](https://www.npmjs.com/package/@appwarden/middleware)
6
6
  [![npm provenance](https://img.shields.io/badge/npm-provenance-green)](https://docs.npmjs.com/generating-provenance-statements)
7
- ![Test Coverage](https://img.shields.io/badge/coverage-93.71%25-brightgreen)
7
+ ![Test Coverage](https://img.shields.io/badge/coverage-93.34%25-brightgreen)
8
8
  [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)
9
9
 
10
10
  ## Core Features
@@ -11,10 +11,18 @@ import {
11
11
  LOCKDOWN_TEST_EXPIRY_MS,
12
12
  MIDDLEWARE_VERSION,
13
13
  validateHeartbeatResponseBody
14
- } from "./chunk-FE7E5Q5F.js";
14
+ } from "./chunk-4U4OJ6SP.js";
15
15
 
16
16
  // src/utils/build-lock-page-url.ts
17
+ function isValidLockPageSlug(lockPageSlug) {
18
+ return !lockPageSlug.includes("://") && !lockPageSlug.startsWith("//") && !lockPageSlug.includes("\\");
19
+ }
17
20
  function normalizeLockPageSlug(lockPageSlug) {
21
+ if (!isValidLockPageSlug(lockPageSlug)) {
22
+ throw new Error(
23
+ `Invalid lockPageSlug: "${lockPageSlug}". Absolute or protocol-relative URLs are not allowed.`
24
+ );
25
+ }
18
26
  return lockPageSlug.startsWith("/") ? lockPageSlug : `/${lockPageSlug}`;
19
27
  }
20
28
  function buildLockPageUrl(lockPageSlug, requestUrl) {
@@ -468,6 +476,45 @@ var makeCSPHeader = (cspNonce, directives, mode) => {
468
476
  ];
469
477
  };
470
478
 
479
+ // src/utils/get-appwarden-configuration.ts
480
+ function toDirectiveRecord(value) {
481
+ if (typeof value === "string") {
482
+ try {
483
+ const parsed = JSON.parse(value);
484
+ return parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {};
485
+ } catch {
486
+ throw new Error("contentSecurityPolicy.directives must be valid JSON");
487
+ }
488
+ }
489
+ return value && typeof value === "object" && !Array.isArray(value) ? value : {};
490
+ }
491
+ function mergeAdapterConfig(generated, callSite) {
492
+ const merged = { ...generated };
493
+ for (const key of Object.keys(callSite)) {
494
+ if (key === "contentSecurityPolicy") {
495
+ if (callSite[key] === void 0) {
496
+ continue;
497
+ }
498
+ const genCsp = generated[key] || {};
499
+ const siteCsp = callSite[key] || {};
500
+ merged[key] = {
501
+ mode: siteCsp.mode ?? genCsp.mode ?? void 0,
502
+ directives: {
503
+ ...toDirectiveRecord(genCsp.directives),
504
+ ...toDirectiveRecord(siteCsp.directives)
505
+ }
506
+ };
507
+ } else if (callSite[key] !== void 0) {
508
+ merged[key] = callSite[key];
509
+ }
510
+ }
511
+ return merged;
512
+ }
513
+ function parseMergedConfig(generatedConfig, callSiteConfig, parseSchema) {
514
+ const merged = mergeAdapterConfig(generatedConfig, callSiteConfig);
515
+ return parseSchema(merged);
516
+ }
517
+
471
518
  export {
472
519
  buildLockPageUrl,
473
520
  isOnLockPage,
@@ -482,5 +529,6 @@ export {
482
529
  handleHeartbeatRequest,
483
530
  isHTMLResponse,
484
531
  isHTMLRequest,
485
- makeCSPHeader
532
+ makeCSPHeader,
533
+ parseMergedConfig
486
534
  };
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  isHTMLResponse,
3
3
  makeCSPHeader
4
- } from "./chunk-NC2TN3D5.js";
4
+ } from "./chunk-2R3NOSYY.js";
5
5
  import {
6
6
  UseCSPInputSchema
7
- } from "./chunk-FE7E5Q5F.js";
7
+ } from "./chunk-4U4OJ6SP.js";
8
8
 
9
9
  // src/middlewares/use-content-security-policy.ts
10
10
  var AppendAttribute = (attribute, nonce) => ({
@@ -1,5 +1,5 @@
1
1
  // src/version.ts
2
- var MIDDLEWARE_VERSION = "3.13.4";
2
+ var MIDDLEWARE_VERSION = "3.14.1";
3
3
 
4
4
  // src/constants.ts
5
5
  var LOCKDOWN_TEST_EXPIRY_MS = 5 * 60 * 1e3;
@@ -160,12 +160,30 @@ var AppwardenApiHostnameSchema = z3.string().url({
160
160
  message: "Invalid `appwardenApiHostname`. Please provide an absolute URL (e.g. https://api.appwarden.io)."
161
161
  }).refine((value) => value.startsWith("https://"), {
162
162
  message: "`appwardenApiHostname` must use the https:// scheme (e.g. https://api.appwarden.io)."
163
- });
163
+ }).refine(
164
+ (value) => {
165
+ try {
166
+ const hostname = new URL(value).hostname;
167
+ return hostname === "api.appwarden.io" || hostname === "staging-api.appwarden.io";
168
+ } catch {
169
+ return false;
170
+ }
171
+ },
172
+ {
173
+ message: "`appwardenApiHostname` must be https://api.appwarden.io or https://staging-api.appwarden.io."
174
+ }
175
+ );
164
176
  var LockValue = z3.object({
165
177
  isLocked: z3.number(),
166
178
  isLockedTest: z3.number(),
167
179
  lastCheck: z3.number()
168
180
  });
181
+ var ValidLockPageSlugSchema = z3.string().refine(
182
+ (val) => !val.includes("://") && !val.startsWith("//") && !val.includes("\\"),
183
+ {
184
+ message: "lockPageSlug must be a relative path"
185
+ }
186
+ );
169
187
 
170
188
  // src/schemas/use-content-security-policy.ts
171
189
  var CSPDirectivesSchema = z4.union([
@@ -221,6 +239,7 @@ export {
221
239
  AppwardenApiTokenSchema,
222
240
  AppwardenApiHostnameSchema,
223
241
  LockValue,
242
+ ValidLockPageSlugSchema,
224
243
  HeartbeatConfigErrorSchema,
225
244
  HeartbeatResponseBodySchema,
226
245
  validateHeartbeatResponseBody,
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  useContentSecurityPolicy
3
- } from "./chunk-YPF5MTU3.js";
3
+ } from "./chunk-3CC6CMAB.js";
4
4
 
5
5
  // src/utils/apply-content-security-policy-to-response.ts
6
6
  var applyContentSecurityPolicyToResponse = async ({
@@ -2,22 +2,23 @@ import {
2
2
  AppwardenApiHostnameSchema,
3
3
  AppwardenApiTokenSchema,
4
4
  BooleanSchema,
5
- UseCSPInputSchema
6
- } from "./chunk-FE7E5Q5F.js";
5
+ UseCSPInputSchema,
6
+ ValidLockPageSlugSchema
7
+ } from "./chunk-4U4OJ6SP.js";
7
8
 
8
9
  // src/schemas/use-appwarden.ts
9
10
  import { z } from "zod";
10
11
  var AppwardenMultidomainConfigSchema = z.record(
11
12
  z.string(),
12
13
  z.object({
13
- lockPageSlug: z.string(),
14
+ lockPageSlug: ValidLockPageSlugSchema,
14
15
  contentSecurityPolicy: z.lazy(() => UseCSPInputSchema).optional(),
15
16
  debug: BooleanSchema.optional()
16
17
  })
17
18
  );
18
19
  var UseAppwardenInputSchema = z.object({
19
20
  debug: BooleanSchema.default(false),
20
- lockPageSlug: z.string().optional(),
21
+ lockPageSlug: ValidLockPageSlugSchema.optional(),
21
22
  contentSecurityPolicy: z.lazy(() => UseCSPInputSchema).optional(),
22
23
  multidomainConfig: AppwardenMultidomainConfigSchema.optional(),
23
24
  appwardenApiToken: AppwardenApiTokenSchema,
@@ -2,13 +2,14 @@ import {
2
2
  MemoryCache,
3
3
  debug,
4
4
  printMessage
5
- } from "./chunk-NC2TN3D5.js";
5
+ } from "./chunk-2R3NOSYY.js";
6
6
  import {
7
7
  APPWARDEN_CACHE_KEY,
8
8
  APPWARDEN_MIDDLEWARE_USER_AGENT,
9
9
  APPWARDEN_TEST_ROUTE,
10
+ AppwardenApiHostnameSchema,
10
11
  LockValue
11
- } from "./chunk-FE7E5Q5F.js";
12
+ } from "./chunk-4U4OJ6SP.js";
12
13
 
13
14
  // src/utils/cloudflare/cloudflare-cache.ts
14
15
  var store = {
@@ -122,9 +123,18 @@ var APIError = class extends Error {
122
123
  }
123
124
  };
124
125
  var DEFAULT_API_HOSTNAME = "https://api.appwarden.io";
126
+ var API_TIMEOUT_MS = 1e4;
127
+ function resolveApiHostname(hostname) {
128
+ if (!hostname) return DEFAULT_API_HOSTNAME;
129
+ const parsed = AppwardenApiHostnameSchema.safeParse(hostname);
130
+ if (!parsed.success) return DEFAULT_API_HOSTNAME;
131
+ return parsed.data;
132
+ }
125
133
  var syncEdgeValue = async (context) => {
126
- const apiHostname = context.appwardenApiHostname ?? DEFAULT_API_HOSTNAME;
134
+ const apiHostname = resolveApiHostname(context.appwardenApiHostname);
127
135
  context.debug(`GET ${apiHostname}`);
136
+ const controller = new AbortController();
137
+ const timeout = setTimeout(() => controller.abort(), API_TIMEOUT_MS);
128
138
  try {
129
139
  const response = await fetch(new URL("/v1/appwarden/status", apiHostname), {
130
140
  method: "POST",
@@ -137,7 +147,8 @@ var syncEdgeValue = async (context) => {
137
147
  provider: context.provider,
138
148
  fqdn: context.requestUrl.hostname,
139
149
  appwardenApiToken: context.appwardenApiToken
140
- })
150
+ }),
151
+ signal: controller.signal
141
152
  });
142
153
  if (response.status === 403) {
143
154
  console.log(
@@ -177,6 +188,8 @@ var syncEdgeValue = async (context) => {
177
188
  e instanceof APIError ? e.message : e instanceof Error ? `${message}: ${e.message}` : message
178
189
  )
179
190
  );
191
+ } finally {
192
+ clearTimeout(timeout);
180
193
  }
181
194
  };
182
195
 
@@ -1,4 +1,4 @@
1
- import { MiddlewareHandler } from 'astro';
1
+ import { APIContext } from 'astro';
2
2
  import { z } from 'zod';
3
3
 
4
4
  /**
@@ -7,11 +7,11 @@ import { z } from 'zod';
7
7
  */
8
8
  declare const AstroCloudflareConfigSchema: z.ZodObject<{
9
9
  /** The slug/path of the lock page to redirect to when the site is locked */
10
- lockPageSlug: z.ZodString;
10
+ lockPageSlug: z.ZodEffects<z.ZodString, string, string>;
11
11
  /** The Appwarden API token for authentication */
12
12
  appwardenApiToken: z.ZodEffects<z.ZodString, string, string>;
13
13
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
14
- appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
14
+ appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
15
15
  /** Enable debug logging */
16
16
  debug: z.ZodDefault<z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>, boolean, string | boolean | undefined>>;
17
17
  /** Optional Content Security Policy configuration */
@@ -350,6 +350,13 @@ type AstroCloudflareConfig = z.infer<typeof AstroCloudflareConfigSchema>;
350
350
  */
351
351
  type AstroCloudflareConfigInput = z.input<typeof AstroCloudflareConfigSchema>;
352
352
 
353
+ /**
354
+ * Build-time helper that merges generated config with call-site overrides.
355
+ *
356
+ * Call-site config has highest priority, followed by framework headers,
357
+ * then remote Appwarden configuration.
358
+ */
359
+ declare function getAppwardenConfiguration(generatedConfig: Record<string, unknown>, config: Partial<AstroCloudflareConfigInput>): AstroCloudflareConfig;
353
360
  /**
354
361
  * Normalized Cloudflare runtime context exposed to Appwarden config functions.
355
362
  *
@@ -378,7 +385,7 @@ type AstroAppwardenConfig = AstroCloudflareConfig;
378
385
  * This allows dynamic configuration based on environment variables.
379
386
  * Accepts pre-transformation input types (e.g., string | boolean for debug, string | object for CSP directives).
380
387
  */
381
- type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroCloudflareConfigInput;
388
+ type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroCloudflareConfigInput | AstroCloudflareConfig;
382
389
  /**
383
390
  * Creates an Appwarden middleware function for Astro.
384
391
  *
@@ -402,6 +409,6 @@ type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroCloudflareConfigI
402
409
  * @param configFn - A function that receives the Cloudflare runtime and returns the config
403
410
  * @returns An Astro middleware function
404
411
  */
405
- declare function createAppwardenMiddleware(configFn: AstroConfigFn): MiddlewareHandler;
412
+ declare function createAppwardenMiddleware(configFn: AstroConfigFn): (context: APIContext, next: () => Promise<Response>) => Promise<Response>;
406
413
 
407
- export { type AstroAppwardenConfig, type AstroCloudflareConfig, type AstroCloudflareConfigInput, type AstroCloudflareRuntime, type AstroConfigFn, createAppwardenMiddleware };
414
+ export { type AstroAppwardenConfig, type AstroCloudflareConfig, type AstroCloudflareConfigInput, type AstroCloudflareRuntime, type AstroConfigFn, createAppwardenMiddleware, getAppwardenConfiguration };
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  applyContentSecurityPolicyToResponse,
3
3
  isResponseLike
4
- } from "../chunk-VVE7MFVZ.js";
5
- import "../chunk-YPF5MTU3.js";
4
+ } from "../chunk-55QG265Y.js";
5
+ import "../chunk-3CC6CMAB.js";
6
6
  import {
7
7
  getNowMs,
8
8
  logElapsed
9
9
  } from "../chunk-G6BMPIYD.js";
10
10
  import {
11
11
  checkLockStatus
12
- } from "../chunk-GMWSGC6T.js";
12
+ } from "../chunk-PZ3M7SYD.js";
13
13
  import {
14
14
  TEMPORARY_REDIRECT_STATUS,
15
15
  buildLockPageUrl,
@@ -20,16 +20,18 @@ import {
20
20
  isHTMLRequest,
21
21
  isHeartbeatRequest,
22
22
  isOnLockPage,
23
+ parseMergedConfig,
23
24
  printMessage,
24
25
  sanitizeConfigErrors
25
- } from "../chunk-NC2TN3D5.js";
26
+ } from "../chunk-2R3NOSYY.js";
26
27
  import {
27
28
  AppwardenApiHostnameSchema,
28
29
  AppwardenApiTokenSchema,
29
30
  BooleanSchema,
30
31
  HEARTBEAT_SERVICES,
31
- UseCSPInputSchema
32
- } from "../chunk-FE7E5Q5F.js";
32
+ UseCSPInputSchema,
33
+ ValidLockPageSlugSchema
34
+ } from "../chunk-4U4OJ6SP.js";
33
35
 
34
36
  // src/adapters/astro-cloudflare.ts
35
37
  import { env as cloudflareEnv, waitUntil } from "cloudflare:workers";
@@ -38,7 +40,7 @@ import { env as cloudflareEnv, waitUntil } from "cloudflare:workers";
38
40
  import { z } from "zod";
39
41
  var AstroCloudflareConfigSchema = z.object({
40
42
  /** The slug/path of the lock page to redirect to when the site is locked */
41
- lockPageSlug: z.string(),
43
+ lockPageSlug: ValidLockPageSlugSchema,
42
44
  /** The Appwarden API token for authentication */
43
45
  appwardenApiToken: AppwardenApiTokenSchema,
44
46
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
@@ -50,6 +52,13 @@ var AstroCloudflareConfigSchema = z.object({
50
52
  });
51
53
 
52
54
  // src/adapters/astro-cloudflare.ts
55
+ function getAppwardenConfiguration(generatedConfig, config) {
56
+ return parseMergedConfig(
57
+ generatedConfig,
58
+ config,
59
+ AstroCloudflareConfigSchema.parse
60
+ );
61
+ }
53
62
  var createAstroHeartbeatResponse = (request, runtime, configFn) => {
54
63
  if (!runtime) {
55
64
  return handleHeartbeatRequest(
@@ -202,5 +211,6 @@ function createAppwardenMiddleware(configFn) {
202
211
  };
203
212
  }
204
213
  export {
205
- createAppwardenMiddleware
214
+ createAppwardenMiddleware,
215
+ getAppwardenConfiguration
206
216
  };
@@ -7,11 +7,11 @@ import { z } from 'zod';
7
7
  */
8
8
  declare const NextJsCloudflareConfigSchema: z.ZodObject<{
9
9
  /** The slug/path of the lock page to redirect to when the site is locked */
10
- lockPageSlug: z.ZodString;
10
+ lockPageSlug: z.ZodEffects<z.ZodString, string, string>;
11
11
  /** The Appwarden API token for authentication */
12
12
  appwardenApiToken: z.ZodEffects<z.ZodString, string, string>;
13
13
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
14
- appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
14
+ appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
15
15
  /** Enable debug logging */
16
16
  debug: z.ZodDefault<z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>, boolean, string | boolean | undefined>>;
17
17
  /** Optional Content Security Policy configuration (headers only, no HTML rewriting; '{{nonce}}' is not supported) */
@@ -410,6 +410,7 @@ type NextJsCloudflareConfig = z.infer<typeof NextJsCloudflareConfigSchema>;
410
410
  */
411
411
  type NextJsCloudflareConfigInput = z.input<typeof NextJsCloudflareConfigSchema>;
412
412
 
413
+ declare function getAppwardenConfiguration(generatedConfig: Record<string, unknown>, config: Partial<NextJsCloudflareConfigInput>): NextJsCloudflareConfig;
413
414
  /**
414
415
  * Cloudflare runtime context provided by @opennextjs/cloudflare.
415
416
  * This is the shape of the context returned by getCloudflareContext().
@@ -432,7 +433,7 @@ type NextJsCloudflareAppwardenConfig = NextJsCloudflareConfig;
432
433
  * This allows dynamic configuration based on environment variables.
433
434
  * Accepts pre-transformation input types (e.g., string | boolean for debug, string | object for CSP directives).
434
435
  */
435
- type NextJsCloudflareConfigFn = (runtime: NextJsCloudflareRuntime) => NextJsCloudflareConfigInput;
436
+ type NextJsCloudflareConfigFn = (runtime: NextJsCloudflareRuntime) => NextJsCloudflareConfigInput | NextJsCloudflareConfig;
436
437
  /**
437
438
  * Next.js middleware function signature.
438
439
  * Compatible with both middleware.ts and proxy.ts (Next.js 16+).
@@ -464,4 +465,4 @@ type NextJsMiddlewareFunction = (request: NextRequest, event?: NextFetchEvent) =
464
465
  */
465
466
  declare function createAppwardenMiddleware(configFn: NextJsCloudflareConfigFn): NextJsMiddlewareFunction;
466
467
 
467
- export { type NextJsCloudflareAppwardenConfig, type NextJsCloudflareConfig, type NextJsCloudflareConfigFn, type NextJsCloudflareConfigInput, type NextJsCloudflareRuntime, type NextJsMiddlewareFunction, createAppwardenMiddleware };
468
+ export { type NextJsCloudflareAppwardenConfig, type NextJsCloudflareConfig, type NextJsCloudflareConfigFn, type NextJsCloudflareConfigInput, type NextJsCloudflareRuntime, type NextJsMiddlewareFunction, createAppwardenMiddleware, getAppwardenConfiguration };
@@ -7,7 +7,7 @@ import {
7
7
  } from "../chunk-G6BMPIYD.js";
8
8
  import {
9
9
  checkLockStatus
10
- } from "../chunk-GMWSGC6T.js";
10
+ } from "../chunk-PZ3M7SYD.js";
11
11
  import {
12
12
  TEMPORARY_REDIRECT_STATUS,
13
13
  buildLockPageUrl,
@@ -18,16 +18,18 @@ import {
18
18
  isHeartbeatRequest,
19
19
  isOnLockPage,
20
20
  makeCSPHeader,
21
+ parseMergedConfig,
21
22
  printMessage,
22
23
  sanitizeConfigErrors
23
- } from "../chunk-NC2TN3D5.js";
24
+ } from "../chunk-2R3NOSYY.js";
24
25
  import {
25
26
  AppwardenApiHostnameSchema,
26
27
  AppwardenApiTokenSchema,
27
28
  BooleanSchema,
28
29
  HEARTBEAT_SERVICES,
29
- UseCSPInputSchema
30
- } from "../chunk-FE7E5Q5F.js";
30
+ UseCSPInputSchema,
31
+ ValidLockPageSlugSchema
32
+ } from "../chunk-4U4OJ6SP.js";
31
33
 
32
34
  // src/adapters/nextjs-cloudflare.ts
33
35
  import { getCloudflareContext } from "@opennextjs/cloudflare";
@@ -50,7 +52,7 @@ var NextJsCloudflareCSPInputSchema = UseCSPInputSchema.refine(
50
52
  );
51
53
  var NextJsCloudflareConfigSchema = z.object({
52
54
  /** The slug/path of the lock page to redirect to when the site is locked */
53
- lockPageSlug: z.string(),
55
+ lockPageSlug: ValidLockPageSlugSchema,
54
56
  /** The Appwarden API token for authentication */
55
57
  appwardenApiToken: AppwardenApiTokenSchema,
56
58
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
@@ -62,6 +64,13 @@ var NextJsCloudflareConfigSchema = z.object({
62
64
  });
63
65
 
64
66
  // src/adapters/nextjs-cloudflare.ts
67
+ function getAppwardenConfiguration(generatedConfig, config) {
68
+ return parseMergedConfig(
69
+ generatedConfig,
70
+ config,
71
+ NextJsCloudflareConfigSchema.parse
72
+ );
73
+ }
65
74
  var createNextJsHeartbeatResponse = (request, configFn) => {
66
75
  let runtime;
67
76
  try {
@@ -174,5 +183,6 @@ function createAppwardenMiddleware(configFn) {
174
183
  };
175
184
  }
176
185
  export {
177
- createAppwardenMiddleware
186
+ createAppwardenMiddleware,
187
+ getAppwardenConfiguration
178
188
  };
@@ -6,11 +6,11 @@ import { z } from 'zod';
6
6
  */
7
7
  declare const ReactRouterCloudflareConfigSchema: z.ZodObject<{
8
8
  /** The slug/path of the lock page to redirect to when the site is locked */
9
- lockPageSlug: z.ZodString;
9
+ lockPageSlug: z.ZodEffects<z.ZodString, string, string>;
10
10
  /** The Appwarden API token for authentication */
11
11
  appwardenApiToken: z.ZodEffects<z.ZodString, string, string>;
12
12
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
13
- appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
13
+ appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
14
14
  /** Enable debug logging */
15
15
  debug: z.ZodDefault<z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>, boolean, string | boolean | undefined>>;
16
16
  /** Optional Content Security Policy configuration */
@@ -349,6 +349,7 @@ type ReactRouterCloudflareConfig = z.infer<typeof ReactRouterCloudflareConfigSch
349
349
  */
350
350
  type ReactRouterAppwardenConfigInput = z.input<typeof ReactRouterCloudflareConfigSchema>;
351
351
 
352
+ declare function getAppwardenConfiguration(generatedConfig: Record<string, unknown>, config: Partial<ReactRouterAppwardenConfigInput>): ReactRouterCloudflareConfig;
352
353
  /**
353
354
  * Configuration function that returns the config.
354
355
  * This allows dynamic configuration based on environment variables from cloudflare:workers.
@@ -357,7 +358,7 @@ type ReactRouterAppwardenConfigInput = z.input<typeof ReactRouterCloudflareConfi
357
358
  *
358
359
  * @param runtime - Optional runtime context (for backward compatibility)
359
360
  */
360
- type ReactRouterConfigFn = (runtime?: unknown) => ReactRouterAppwardenConfigInput;
361
+ type ReactRouterConfigFn = (runtime?: unknown) => ReactRouterAppwardenConfigInput | ReactRouterCloudflareConfig;
361
362
  /**
362
363
  * React Router middleware function signature.
363
364
  * This matches the unstable_middleware export type in React Router v7.
@@ -392,4 +393,4 @@ type ReactRouterMiddlewareFunction = (args: ReactRouterMiddlewareArgs, next: ()
392
393
  */
393
394
  declare function createAppwardenMiddleware(configFn: ReactRouterConfigFn): ReactRouterMiddlewareFunction;
394
395
 
395
- export { type ReactRouterAppwardenConfigInput, type ReactRouterCloudflareConfig, type ReactRouterConfigFn, type ReactRouterMiddlewareArgs, type ReactRouterMiddlewareFunction, createAppwardenMiddleware };
396
+ export { type ReactRouterAppwardenConfigInput, type ReactRouterCloudflareConfig, type ReactRouterConfigFn, type ReactRouterMiddlewareArgs, type ReactRouterMiddlewareFunction, createAppwardenMiddleware, getAppwardenConfiguration };
@@ -1,15 +1,15 @@
1
1
  import {
2
2
  applyContentSecurityPolicyToResponse,
3
3
  isResponseLike
4
- } from "../chunk-VVE7MFVZ.js";
5
- import "../chunk-YPF5MTU3.js";
4
+ } from "../chunk-55QG265Y.js";
5
+ import "../chunk-3CC6CMAB.js";
6
6
  import {
7
7
  getNowMs,
8
8
  logElapsed
9
9
  } from "../chunk-G6BMPIYD.js";
10
10
  import {
11
11
  checkLockStatus
12
- } from "../chunk-GMWSGC6T.js";
12
+ } from "../chunk-PZ3M7SYD.js";
13
13
  import {
14
14
  buildLockPageUrl,
15
15
  createHeartbeatConfigError,
@@ -19,16 +19,18 @@ import {
19
19
  isHTMLRequest,
20
20
  isHeartbeatRequest,
21
21
  isOnLockPage,
22
+ parseMergedConfig,
22
23
  printMessage,
23
24
  sanitizeConfigErrors
24
- } from "../chunk-NC2TN3D5.js";
25
+ } from "../chunk-2R3NOSYY.js";
25
26
  import {
26
27
  AppwardenApiHostnameSchema,
27
28
  AppwardenApiTokenSchema,
28
29
  BooleanSchema,
29
30
  HEARTBEAT_SERVICES,
30
- UseCSPInputSchema
31
- } from "../chunk-FE7E5Q5F.js";
31
+ UseCSPInputSchema,
32
+ ValidLockPageSlugSchema
33
+ } from "../chunk-4U4OJ6SP.js";
32
34
 
33
35
  // src/adapters/react-router-cloudflare.ts
34
36
  import { waitUntil } from "cloudflare:workers";
@@ -37,7 +39,7 @@ import { waitUntil } from "cloudflare:workers";
37
39
  import { z } from "zod";
38
40
  var ReactRouterCloudflareConfigSchema = z.object({
39
41
  /** The slug/path of the lock page to redirect to when the site is locked */
40
- lockPageSlug: z.string(),
42
+ lockPageSlug: ValidLockPageSlugSchema,
41
43
  /** The Appwarden API token for authentication */
42
44
  appwardenApiToken: AppwardenApiTokenSchema,
43
45
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
@@ -49,6 +51,13 @@ var ReactRouterCloudflareConfigSchema = z.object({
49
51
  });
50
52
 
51
53
  // src/adapters/react-router-cloudflare.ts
54
+ function getAppwardenConfiguration(generatedConfig, config) {
55
+ return parseMergedConfig(
56
+ generatedConfig,
57
+ config,
58
+ ReactRouterCloudflareConfigSchema.parse
59
+ );
60
+ }
52
61
  var createConfigEvaluationHeartbeatResponse = (request) => {
53
62
  return handleHeartbeatRequest(
54
63
  request,
@@ -163,5 +172,6 @@ function createAppwardenMiddleware(configFn) {
163
172
  };
164
173
  }
165
174
  export {
166
- createAppwardenMiddleware
175
+ createAppwardenMiddleware,
176
+ getAppwardenConfiguration
167
177
  };
@@ -6,11 +6,11 @@ import { z } from 'zod';
6
6
  */
7
7
  declare const TanStackStartCloudflareConfigSchema: z.ZodObject<{
8
8
  /** The slug/path of the lock page to redirect to when the site is locked */
9
- lockPageSlug: z.ZodString;
9
+ lockPageSlug: z.ZodEffects<z.ZodString, string, string>;
10
10
  /** The Appwarden API token for authentication */
11
11
  appwardenApiToken: z.ZodEffects<z.ZodString, string, string>;
12
12
  /** Optional custom API hostname (defaults to https://api.appwarden.io) */
13
- appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodString, string, string>>;
13
+ appwardenApiHostname: z.ZodOptional<z.ZodEffects<z.ZodEffects<z.ZodString, string, string>, string, string>>;
14
14
  /** Enable debug logging */
15
15
  debug: z.ZodDefault<z.ZodEffects<z.ZodOptional<z.ZodUnion<[z.ZodString, z.ZodBoolean]>>, boolean, string | boolean | undefined>>;
16
16
  /** Optional Content Security Policy configuration */
@@ -343,12 +343,14 @@ declare const TanStackStartCloudflareConfigSchema: z.ZodObject<{
343
343
  type TanStackStartCloudflareConfig = z.infer<typeof TanStackStartCloudflareConfigSchema>;
344
344
  type TanStackStartCloudflareConfigInput = z.input<typeof TanStackStartCloudflareConfigSchema>;
345
345
 
346
+ declare function getAppwardenConfiguration(generatedConfig: Record<string, unknown>, config: Partial<TanStackStartCloudflareConfigInput>): TanStackStartCloudflareConfig;
347
+
346
348
  /**
347
349
  * Configuration function that returns the config.
348
350
  * This allows dynamic configuration based on environment variables from cloudflare:workers.
349
351
  * Accepts pre-transformation input types (e.g., string | boolean for debug, string | object for CSP directives).
350
352
  */
351
- type TanStackStartConfigFn = () => TanStackStartCloudflareConfigInput;
353
+ type TanStackStartConfigFn = () => TanStackStartCloudflareConfigInput | TanStackStartCloudflareConfig;
352
354
  /**
353
355
  * The result returned by the `next()` function in TanStack Start request middleware.
354
356
  *
@@ -418,4 +420,4 @@ type TanStackStartMiddlewareFunction = (args: TanStackStartMiddlewareArgs) => Pr
418
420
  */
419
421
  declare function createAppwardenMiddleware(configFn: TanStackStartConfigFn): TanStackStartMiddlewareFunction;
420
422
 
421
- export { type TanStackStartCloudflareConfig, type TanStackStartCloudflareConfigInput, type TanStackStartConfigFn, type TanStackStartMiddlewareArgs, type TanStackStartMiddlewareFunction, type TanStackStartNextFn, type TanStackStartNextResult, createAppwardenMiddleware };
423
+ export { type TanStackStartCloudflareConfig, type TanStackStartCloudflareConfigInput, type TanStackStartConfigFn, type TanStackStartMiddlewareArgs, type TanStackStartMiddlewareFunction, type TanStackStartNextFn, type TanStackStartNextResult, createAppwardenMiddleware, getAppwardenConfiguration };