@appwarden/middleware 3.4.2 → 3.5.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-91.49%25-brightgreen)
7
+ ![Test Coverage](https://img.shields.io/badge/coverage-91.55%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
@@ -0,0 +1,6 @@
1
+ // src/utils/get-now.ts
2
+ var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
3
+
4
+ export {
5
+ getNowMs
6
+ };
@@ -3,7 +3,7 @@ var isResponseLike = (value) => {
3
3
  if (!value || typeof value !== "object") return false;
4
4
  const candidate = value;
5
5
  const headers = candidate.headers;
6
- return !!(headers && typeof headers === "object" && typeof headers.has === "function" && typeof headers.set === "function" && typeof headers.get === "function" && "body" in candidate);
6
+ return !!(headers && typeof headers === "object" && typeof headers.has === "function" && typeof headers.set === "function" && typeof headers.get === "function");
7
7
  };
8
8
 
9
9
  export {
@@ -1,5 +1,5 @@
1
1
  import { Runtime } from '@astrojs/cloudflare';
2
- import { APIContext, MiddlewareHandler } from 'astro';
2
+ import { MiddlewareHandler } from 'astro';
3
3
  import { U as UseCSPInput } from '../use-content-security-policy-DUYpyUPy.js';
4
4
  import 'zod';
5
5
 
@@ -30,20 +30,6 @@ interface AstroAppwardenConfig {
30
30
  * This allows dynamic configuration based on environment variables.
31
31
  */
32
32
  type AstroConfigFn = (runtime: AstroCloudflareRuntime) => AstroAppwardenConfig;
33
- /**
34
- * Astro middleware context type.
35
- * Re-exported from Astro's official APIContext type for type compatibility.
36
- *
37
- * @deprecated Use `APIContext` from 'astro' directly. This alias is kept for backward compatibility.
38
- */
39
- type AstroMiddlewareContext = APIContext;
40
- /**
41
- * Astro middleware function signature.
42
- * This is an alias for Astro's official MiddlewareHandler type for type compatibility.
43
- *
44
- * @deprecated Use `MiddlewareHandler` from 'astro' directly. This alias is kept for backward compatibility.
45
- */
46
- type AstroMiddlewareFunction = MiddlewareHandler;
47
33
  /**
48
34
  * Creates an Appwarden middleware function for Astro.
49
35
  *
@@ -69,4 +55,4 @@ type AstroMiddlewareFunction = MiddlewareHandler;
69
55
  */
70
56
  declare function createAppwardenMiddleware(configFn: AstroConfigFn): MiddlewareHandler;
71
57
 
72
- export { type AstroAppwardenConfig, type AstroCloudflareRuntime, type AstroConfigFn, type AstroMiddlewareContext, type AstroMiddlewareFunction, createAppwardenMiddleware };
58
+ export { createAppwardenMiddleware };
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  isResponseLike
3
- } from "../chunk-24CQJ54X.js";
3
+ } from "../chunk-XFG6SUSV.js";
4
4
  import {
5
5
  useContentSecurityPolicy
6
6
  } from "../chunk-AXWJZE7U.js";
7
+ import {
8
+ getNowMs
9
+ } from "../chunk-X7WZVYQS.js";
7
10
  import {
8
11
  validateConfig
9
12
  } from "../chunk-MNGMTDH3.js";
@@ -43,7 +46,6 @@ var AstroCloudflareConfigSchema = z.object({
43
46
  });
44
47
 
45
48
  // src/adapters/astro-cloudflare.ts
46
- var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
47
49
  function createAppwardenMiddleware(configFn) {
48
50
  return async (context, next) => {
49
51
  const startTime = getNowMs();
@@ -61,4 +61,4 @@ type NextJsMiddlewareFunction = (request: NextRequest, event?: NextFetchEvent) =
61
61
  */
62
62
  declare function createAppwardenMiddleware(configFn: NextJsCloudflareConfigFn): NextJsMiddlewareFunction;
63
63
 
64
- export { type NextJsCloudflareAppwardenConfig, type NextJsCloudflareConfigFn, type NextJsCloudflareRuntime, type NextJsMiddlewareFunction, createAppwardenMiddleware };
64
+ export { createAppwardenMiddleware };
@@ -1,3 +1,6 @@
1
+ import {
2
+ getNowMs
3
+ } from "../chunk-X7WZVYQS.js";
1
4
  import {
2
5
  validateConfig
3
6
  } from "../chunk-MNGMTDH3.js";
@@ -52,7 +55,6 @@ var NextJsCloudflareConfigSchema = z.object({
52
55
  });
53
56
 
54
57
  // src/adapters/nextjs-cloudflare.ts
55
- var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
56
58
  function createAppwardenMiddleware(configFn) {
57
59
  return async (request, _event) => {
58
60
  const startTime = getNowMs();
@@ -76,4 +76,4 @@ type ReactRouterMiddlewareFunction = (args: ReactRouterMiddlewareArgs, next: ()
76
76
  */
77
77
  declare function createAppwardenMiddleware(configFn: ReactRouterConfigFn): ReactRouterMiddlewareFunction;
78
78
 
79
- export { type CloudflareContext, type ReactRouterAppwardenConfig, type ReactRouterConfigFn, type ReactRouterMiddlewareArgs, type ReactRouterMiddlewareFunction, cloudflareContextSymbol, createAppwardenMiddleware };
79
+ export { type CloudflareContext, cloudflareContextSymbol, createAppwardenMiddleware };
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  isResponseLike
3
- } from "../chunk-24CQJ54X.js";
3
+ } from "../chunk-XFG6SUSV.js";
4
4
  import {
5
5
  useContentSecurityPolicy
6
6
  } from "../chunk-AXWJZE7U.js";
7
+ import {
8
+ getNowMs
9
+ } from "../chunk-X7WZVYQS.js";
7
10
  import {
8
11
  validateConfig
9
12
  } from "../chunk-MNGMTDH3.js";
@@ -45,7 +48,6 @@ var ReactRouterCloudflareConfigSchema = z.object({
45
48
  var cloudflareContextSymbol = /* @__PURE__ */ Symbol.for(
46
49
  "@appwarden/middleware:cloudflare"
47
50
  );
48
- var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
49
51
  function getCloudflareContext(context) {
50
52
  if (context?.cloudflare) {
51
53
  return context.cloudflare;
@@ -29,48 +29,55 @@ interface TanStackStartAppwardenConfig {
29
29
  * This allows dynamic configuration based on environment variables.
30
30
  */
31
31
  type TanStackStartConfigFn = (cloudflare: TanStackStartCloudflareContext) => TanStackStartAppwardenConfig;
32
+ /**
33
+ * The result returned by the `next()` function in TanStack Start request middleware.
34
+ *
35
+ * Mirrors the internal `RequestServerResult` interface from `@tanstack/start-client-core`
36
+ * without importing from an unstable internal package path.
37
+ */
38
+ interface TanStackStartNextResult {
39
+ request: Request;
40
+ pathname: string;
41
+ context: Record<string, unknown>;
42
+ response: Response;
43
+ }
44
+ /**
45
+ * The `next()` function passed to TanStack Start request middleware.
46
+ *
47
+ * Mirrors the internal `RequestServerNextFn` signature.
48
+ */
49
+ type TanStackStartNextFn = (options?: {
50
+ context?: Record<string, unknown>;
51
+ }) => Promise<TanStackStartNextResult>;
32
52
  /**
33
53
  * TanStack Start middleware server callback arguments.
34
- * This matches the shape of arguments passed to createMiddleware().server().
54
+ *
55
+ * Mirrors the official TanStack Start `RequestServerOptions` interface, with
56
+ * an additional optional `cloudflare` context property for Cloudflare
57
+ * Workers deployments.
35
58
  */
36
59
  interface TanStackStartMiddlewareArgs {
37
60
  request: Request;
38
- next: () => Promise<unknown>;
61
+ pathname: string;
39
62
  context: {
40
63
  cloudflare?: TanStackStartCloudflareContext;
41
64
  [key: string]: unknown;
42
65
  };
66
+ next: TanStackStartNextFn;
67
+ serverFnMeta?: unknown;
43
68
  }
44
69
  /**
45
70
  * TanStack Start middleware function signature.
46
- * This matches the return type of createMiddleware().server().
71
+ *
72
+ * Mirrors the official TanStack Start `RequestServerFn` type used for
73
+ * request middleware server functions.
47
74
  */
48
- type TanStackStartMiddlewareFunction = (args: TanStackStartMiddlewareArgs) => Promise<unknown>;
75
+ type TanStackStartMiddlewareFunction = (args: TanStackStartMiddlewareArgs) => Promise<TanStackStartNextResult | Response>;
49
76
  /**
50
- * Creates an Appwarden middleware function for TanStack Start.
51
- *
52
- * This middleware checks if the site is locked and throws a redirect to the lock page if so.
53
- * It should be added to the `requestMiddleware` array in your `src/start.ts` file.
54
- *
55
- * @example
56
- * ```typescript
57
- * // src/start.ts
58
- * import { createStart } from "@tanstack/react-start"
59
- * import { createAppwardenMiddleware } from "@appwarden/middleware/tanstack-start"
60
- *
61
- * const appwardenMiddleware = createAppwardenMiddleware(({ env }) => ({
62
- * lockPageSlug: env.APPWARDEN_LOCK_PAGE_SLUG,
63
- * appwardenApiToken: env.APPWARDEN_API_TOKEN,
64
- * }))
65
- *
66
- * export const startInstance = createStart(() => ({
67
- * requestMiddleware: [appwardenMiddleware],
68
- * }))
69
- * ```
70
77
  *
71
78
  * @param configFn - A function that receives the Cloudflare context and returns the config
72
79
  * @returns A TanStack Start middleware function
73
80
  */
74
81
  declare function createAppwardenMiddleware(configFn: TanStackStartConfigFn): TanStackStartMiddlewareFunction;
75
82
 
76
- export { type TanStackStartAppwardenConfig, type TanStackStartCloudflareContext, type TanStackStartConfigFn, type TanStackStartMiddlewareArgs, type TanStackStartMiddlewareFunction, createAppwardenMiddleware };
83
+ export { type TanStackStartCloudflareContext, createAppwardenMiddleware };
@@ -1,9 +1,12 @@
1
1
  import {
2
2
  isResponseLike
3
- } from "../chunk-24CQJ54X.js";
3
+ } from "../chunk-XFG6SUSV.js";
4
4
  import {
5
5
  useContentSecurityPolicy
6
6
  } from "../chunk-AXWJZE7U.js";
7
+ import {
8
+ getNowMs
9
+ } from "../chunk-X7WZVYQS.js";
7
10
  import {
8
11
  validateConfig
9
12
  } from "../chunk-MNGMTDH3.js";
@@ -42,9 +45,8 @@ var TanStackStartCloudflareConfigSchema = z.object({
42
45
  });
43
46
 
44
47
  // src/adapters/tanstack-start-cloudflare.ts
45
- var getNowMs = () => typeof performance !== "undefined" && typeof performance.now === "function" ? performance.now() : Date.now();
46
48
  function createAppwardenMiddleware(configFn) {
47
- return async (args) => {
49
+ const middleware = async (args) => {
48
50
  const startTime = getNowMs();
49
51
  const { request, next, context } = args;
50
52
  try {
@@ -52,7 +54,7 @@ function createAppwardenMiddleware(configFn) {
52
54
  if (!cloudflare) {
53
55
  console.error(
54
56
  printMessage(
55
- "Cloudflare context not found. Ensure running on Cloudflare Workers with proper context setup."
57
+ "Cloudflare context not found in TanStack Start context. Ensure your Register type includes the cloudflare context, or pass it manually in the middleware wrapper."
56
58
  )
57
59
  );
58
60
  return next();
@@ -79,7 +81,7 @@ function createAppwardenMiddleware(configFn) {
79
81
  debugFn("Already on lock page - skipping");
80
82
  return next();
81
83
  }
82
- const result = await checkLockStatus({
84
+ const lockStatus = await checkLockStatus({
83
85
  request,
84
86
  appwardenApiToken: config.appwardenApiToken,
85
87
  appwardenApiHostname: config.appwardenApiHostname,
@@ -87,13 +89,14 @@ function createAppwardenMiddleware(configFn) {
87
89
  lockPageSlug: config.lockPageSlug,
88
90
  waitUntil: (fn) => cloudflare.ctx.waitUntil(fn)
89
91
  });
90
- if (result.isLocked) {
92
+ if (lockStatus.isLocked) {
91
93
  const lockPageUrl = buildLockPageUrl(config.lockPageSlug, request.url);
92
94
  debugFn(`Website is locked - redirecting to ${lockPageUrl.pathname}`);
93
95
  throw createRedirect(lockPageUrl);
94
96
  }
95
97
  debugFn("Website is unlocked");
96
- const response = await next();
98
+ const result = await next();
99
+ const { response } = result;
97
100
  if (config.contentSecurityPolicy && isResponseLike(response)) {
98
101
  debugFn("Applying CSP middleware");
99
102
  const cspContext = {
@@ -111,11 +114,14 @@ function createAppwardenMiddleware(configFn) {
111
114
  );
112
115
  const elapsed2 = Math.round(getNowMs() - startTime);
113
116
  debugFn(`Middleware executed in ${elapsed2}ms`);
114
- return cspContext.response;
117
+ return {
118
+ ...result,
119
+ response: cspContext.response
120
+ };
115
121
  }
116
122
  const elapsed = Math.round(getNowMs() - startTime);
117
123
  debugFn(`Middleware executed in ${elapsed}ms`);
118
- return response;
124
+ return result;
119
125
  } catch (error) {
120
126
  if (isResponseLike(error)) {
121
127
  throw error;
@@ -128,6 +134,7 @@ function createAppwardenMiddleware(configFn) {
128
134
  return next();
129
135
  }
130
136
  };
137
+ return middleware;
131
138
  }
132
139
  export {
133
140
  createAppwardenMiddleware
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@appwarden/middleware",
3
- "version": "3.4.2",
3
+ "version": "3.5.0",
4
4
  "description": "Instantly shut off access your app deployed on Cloudflare or Vercel",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -65,6 +65,7 @@
65
65
  "peerDependencies": {
66
66
  "@astrojs/cloudflare": ">=11.0.0",
67
67
  "@opennextjs/cloudflare": ">=1.16.6",
68
+ "@tanstack/start": "^1.120.20",
68
69
  "@vercel/functions": ">=1.0.0",
69
70
  "astro": ">=4.0.0",
70
71
  "next": ">=14"
@@ -82,6 +83,9 @@
82
83
  "@opennextjs/cloudflare": {
83
84
  "optional": true
84
85
  },
86
+ "@tanstack/start": {
87
+ "optional": true
88
+ },
85
89
  "@vercel/functions": {
86
90
  "optional": true
87
91
  }
@@ -106,10 +110,13 @@
106
110
  "wrangler@>=4.0.0 <4.59.1": ">=4.59.1",
107
111
  "qs@>=6.7.0 <=6.14.1": ">=6.14.2",
108
112
  "devalue@<=5.6.2": ">=5.6.3",
109
- "minimatch@<10.2.1": ">=10.2.1",
113
+ "minimatch@<10.2.1": ">=10.2.3",
110
114
  "tar@<7.5.8": ">=7.5.8",
111
115
  "ajv@>=7.0.0-alpha.0 <8.18.0": ">=8.18.0",
112
- "rollup@>=4.0.0 <4.59.0": ">=4.59.0"
116
+ "rollup@>=4.0.0 <4.59.0": ">=4.59.0",
117
+ "h3@<=1.15.4": ">=1.15.5",
118
+ "js-yaml@<3.14.2": ">=3.14.2",
119
+ "fast-xml-parser@<5.3.8": ">=5.3.8"
113
120
  }
114
121
  }
115
122
  }
package/vercel.d.ts CHANGED
@@ -749,4 +749,4 @@ type VercelAppwardenConfig = z.input<typeof AppwardenConfigSchema>;
749
749
  type VercelMiddlewareFunction = (request: Request) => Promise<Response>;
750
750
  declare function createAppwardenMiddleware(config: VercelAppwardenConfig): VercelMiddlewareFunction;
751
751
 
752
- export { AppwardenConfigSchema, type VercelAppwardenConfig, type VercelMiddlewareFunction, createAppwardenMiddleware };
752
+ export { type VercelMiddlewareFunction, createAppwardenMiddleware };
package/vercel.js CHANGED
@@ -330,6 +330,5 @@ function createAppwardenMiddleware(config) {
330
330
  };
331
331
  }
332
332
  export {
333
- AppwardenConfigSchema,
334
333
  createAppwardenMiddleware
335
334
  };