@rayselfs/cf-rule-engine 1.8.2 → 1.9.1

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.
Files changed (91) hide show
  1. package/dist/adapters/lambda-edge.cjs +2 -2
  2. package/dist/adapters/lambda-edge.js +1 -1
  3. package/dist/adapters/viewer-request-async.cjs +26 -0
  4. package/dist/adapters/viewer-request-async.d.cts +28 -0
  5. package/dist/adapters/viewer-request-async.d.ts +28 -0
  6. package/dist/adapters/viewer-request-async.js +26 -0
  7. package/dist/behaviors/construct-response.d.cts +2 -2
  8. package/dist/behaviors/construct-response.d.ts +2 -2
  9. package/dist/behaviors/image-optimize.d.cts +24 -13
  10. package/dist/behaviors/image-optimize.d.ts +24 -13
  11. package/dist/behaviors/index.cjs +12 -11
  12. package/dist/behaviors/index.d.cts +2 -2
  13. package/dist/behaviors/index.d.ts +2 -2
  14. package/dist/behaviors/index.js +11 -10
  15. package/dist/behaviors/kvs.cjs +24 -0
  16. package/dist/behaviors/kvs.d.cts +34 -0
  17. package/dist/behaviors/kvs.d.ts +34 -0
  18. package/dist/behaviors/kvs.js +24 -0
  19. package/dist/behaviors/redirect.d.cts +2 -2
  20. package/dist/behaviors/redirect.d.ts +2 -2
  21. package/dist/behaviors/rewrite-uri.cjs +2 -2
  22. package/dist/behaviors/rewrite-uri.js +1 -1
  23. package/dist/behaviors/set-cors-headers.cjs +3 -2
  24. package/dist/behaviors/set-cors-headers.d.cts +5 -22
  25. package/dist/behaviors/set-cors-headers.d.ts +5 -22
  26. package/dist/behaviors/set-cors-headers.js +2 -1
  27. package/dist/behaviors/set-csp.d.cts +2 -2
  28. package/dist/behaviors/set-csp.d.ts +2 -2
  29. package/dist/behaviors/set-security-headers.d.cts +2 -2
  30. package/dist/behaviors/set-security-headers.d.ts +2 -2
  31. package/dist/{chunk-ORW3KDO5.js → chunk-7EA7GFWX.js} +4 -7
  32. package/dist/{chunk-MRPTC74I.cjs → chunk-BSH5JZBL.cjs} +4 -2
  33. package/dist/{chunk-2DE6WPPL.js → chunk-EEZ7NUJG.js} +12 -1
  34. package/dist/{chunk-PBR6AREG.cjs → chunk-EMDI676G.cjs} +7 -10
  35. package/dist/{chunk-3BBLG4IX.cjs → chunk-G4JEAL6L.cjs} +11 -8
  36. package/dist/{chunk-CQA2DCVF.js → chunk-H3RK4USR.js} +4 -6
  37. package/dist/{chunk-RL7ZETZR.js → chunk-IHDSTTO2.js} +5 -5
  38. package/dist/{chunk-AEZDDJEW.cjs → chunk-IHVOAORH.cjs} +6 -8
  39. package/dist/{chunk-T5EXFHVA.cjs → chunk-ISXKMJCN.cjs} +5 -5
  40. package/dist/{chunk-MVGYPBYB.cjs → chunk-LVOM5GJ6.cjs} +2 -2
  41. package/dist/{chunk-D47P7HVZ.cjs → chunk-MK4QBCD5.cjs} +2 -2
  42. package/dist/chunk-NWRGD3AH.js +71 -0
  43. package/dist/{chunk-FTP7NLKX.js → chunk-QVY6REMD.js} +4 -2
  44. package/dist/{chunk-IBXAK2A4.cjs → chunk-ULICUDDH.cjs} +12 -1
  45. package/dist/{chunk-WEBU4R5C.js → chunk-ULR7EP5D.js} +11 -8
  46. package/dist/{chunk-S2AAATFN.js → chunk-VQGBRWJK.js} +1 -1
  47. package/dist/chunk-WZKRNMF2.cjs +71 -0
  48. package/dist/{chunk-LO2BO3RU.js → chunk-Y7TIDVVC.js} +1 -1
  49. package/dist/{chunk-KW5YBTSD.js → chunk-YHTUV2SA.js} +1 -1
  50. package/dist/{chunk-CF5PWWTF.cjs → chunk-ZEFLAOTL.cjs} +2 -2
  51. package/dist/core/types.d.cts +8 -8
  52. package/dist/core/types.d.ts +8 -8
  53. package/dist/criteria/file-extension.d.cts +3 -3
  54. package/dist/criteria/file-extension.d.ts +3 -3
  55. package/dist/criteria/index.cjs +8 -8
  56. package/dist/criteria/index.js +7 -7
  57. package/dist/criteria/ip-cidr.cjs +3 -3
  58. package/dist/criteria/ip-cidr.js +2 -2
  59. package/dist/criteria/kvs.cjs +14 -0
  60. package/dist/criteria/kvs.d.cts +34 -0
  61. package/dist/criteria/kvs.d.ts +34 -0
  62. package/dist/criteria/kvs.js +14 -0
  63. package/dist/criteria/path-matches.cjs +3 -3
  64. package/dist/criteria/path-matches.js +2 -2
  65. package/dist/criteria/user-agent-matches.cjs +3 -3
  66. package/dist/criteria/user-agent-matches.js +2 -2
  67. package/dist/helpers/index.cjs +10 -10
  68. package/dist/helpers/index.js +10 -10
  69. package/dist/helpers/preflight-request.cjs +4 -3
  70. package/dist/helpers/preflight-request.js +3 -2
  71. package/dist/helpers/whitelist.cjs +7 -7
  72. package/dist/helpers/whitelist.d.cts +2 -2
  73. package/dist/helpers/whitelist.d.ts +2 -2
  74. package/dist/helpers/whitelist.js +6 -6
  75. package/dist/index.cjs +2 -2
  76. package/dist/index.js +1 -1
  77. package/dist/shared/cidr.cjs +2 -2
  78. package/dist/shared/cidr.d.cts +2 -2
  79. package/dist/shared/cidr.d.ts +2 -2
  80. package/dist/shared/cidr.js +1 -1
  81. package/dist/shared/kvs.cjs +1 -0
  82. package/dist/shared/kvs.d.cts +10 -0
  83. package/dist/shared/kvs.d.ts +10 -0
  84. package/dist/shared/kvs.js +0 -0
  85. package/dist/shared/wildcard.cjs +4 -2
  86. package/dist/shared/wildcard.d.cts +10 -1
  87. package/dist/shared/wildcard.d.ts +10 -1
  88. package/dist/shared/wildcard.js +3 -1
  89. package/package.json +1 -1
  90. package/dist/chunk-LNQPYKGG.js +0 -20
  91. package/dist/chunk-YVUR35RN.cjs +0 -20
@@ -1,10 +1,10 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
3
 
4
- var _chunk3BBLG4IXcjs = require('../chunk-3BBLG4IX.cjs');
4
+ var _chunkG4JEAL6Lcjs = require('../chunk-G4JEAL6L.cjs');
5
5
  require('../chunk-WKYMSRCD.cjs');
6
6
  require('../chunk-75ZPJI57.cjs');
7
7
 
8
8
 
9
9
 
10
- exports.defineViewerRequest = _chunk3BBLG4IXcjs.defineViewerRequest; exports.defineViewerResponse = _chunk3BBLG4IXcjs.defineViewerResponse;
10
+ exports.defineViewerRequest = _chunkG4JEAL6Lcjs.defineViewerRequest; exports.defineViewerResponse = _chunkG4JEAL6Lcjs.defineViewerResponse;
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  defineViewerRequest,
3
3
  defineViewerResponse
4
- } from "../chunk-WEBU4R5C.js";
4
+ } from "../chunk-ULR7EP5D.js";
5
5
  import "../chunk-Q4NP4C3B.js";
6
6
  import "../chunk-MLKGABMK.js";
7
7
  export {
@@ -0,0 +1,26 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } }
2
+
3
+ var _chunkWKYMSRCDcjs = require('../chunk-WKYMSRCD.cjs');
4
+
5
+
6
+
7
+
8
+ var _chunk6NFAPLQ7cjs = require('../chunk-6NFAPLQ7.cjs');
9
+ require('../chunk-75ZPJI57.cjs');
10
+
11
+ // src/adapters/viewer-request-async.ts
12
+ function defineViewerRequestAsync(setup) {
13
+ return async (event) => {
14
+ const ev = event;
15
+ const evReq = ev.request;
16
+ const originalCookies = _nullishCoalesce(evReq.cookies, () => ( {}));
17
+ const req = _chunk6NFAPLQ7cjs.normalizeRequest.call(void 0, event);
18
+ const rules = await setup(event);
19
+ const result = _chunkWKYMSRCDcjs.runRules.call(void 0, rules, req);
20
+ if (result.action === "respond") return _chunk6NFAPLQ7cjs.denormalizeResponse.call(void 0, result.response);
21
+ return _chunk6NFAPLQ7cjs.denormalizeRequest.call(void 0, result.request, originalCookies);
22
+ };
23
+ }
24
+
25
+
26
+ exports.defineViewerRequestAsync = defineViewerRequestAsync;
@@ -0,0 +1,28 @@
1
+ import { Rule } from '../core/types.cjs';
2
+
3
+ /**
4
+ * Creates a CloudFront Function viewer-request handler where rules are resolved
5
+ * asynchronously before each request — for example, loading redirect maps or
6
+ * CIDR lists from CloudFront KeyValueStore at startup.
7
+ *
8
+ * The `setup` function receives the raw CF event and returns a `Rule[]`. It is
9
+ * called once per invocation, so any async initialization (e.g. KVS reads)
10
+ * should be cached outside the handler when possible.
11
+ *
12
+ * @param setup - Async factory that receives the CF event and returns the ordered rule list.
13
+ * @returns An async CloudFront Function handler `async (event) => request | response`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { rule } from '@rayselfs/cf-rule-engine'
18
+ * import { kvsRedirect } from '@rayselfs/cf-rule-engine/behaviors/kvs'
19
+ * import { defineViewerRequestAsync } from '@rayselfs/cf-rule-engine/adapters/viewer-request'
20
+ *
21
+ * export default defineViewerRequestAsync(async () => [
22
+ * await kvsRedirect(handle, 'redirects'),
23
+ * ])
24
+ * ```
25
+ */
26
+ declare function defineViewerRequestAsync(setup: (event: unknown) => Promise<Rule[]>): (event: unknown) => Promise<unknown>;
27
+
28
+ export { defineViewerRequestAsync };
@@ -0,0 +1,28 @@
1
+ import { Rule } from '../core/types.js';
2
+
3
+ /**
4
+ * Creates a CloudFront Function viewer-request handler where rules are resolved
5
+ * asynchronously before each request — for example, loading redirect maps or
6
+ * CIDR lists from CloudFront KeyValueStore at startup.
7
+ *
8
+ * The `setup` function receives the raw CF event and returns a `Rule[]`. It is
9
+ * called once per invocation, so any async initialization (e.g. KVS reads)
10
+ * should be cached outside the handler when possible.
11
+ *
12
+ * @param setup - Async factory that receives the CF event and returns the ordered rule list.
13
+ * @returns An async CloudFront Function handler `async (event) => request | response`.
14
+ *
15
+ * @example
16
+ * ```ts
17
+ * import { rule } from '@rayselfs/cf-rule-engine'
18
+ * import { kvsRedirect } from '@rayselfs/cf-rule-engine/behaviors/kvs'
19
+ * import { defineViewerRequestAsync } from '@rayselfs/cf-rule-engine/adapters/viewer-request'
20
+ *
21
+ * export default defineViewerRequestAsync(async () => [
22
+ * await kvsRedirect(handle, 'redirects'),
23
+ * ])
24
+ * ```
25
+ */
26
+ declare function defineViewerRequestAsync(setup: (event: unknown) => Promise<Rule[]>): (event: unknown) => Promise<unknown>;
27
+
28
+ export { defineViewerRequestAsync };
@@ -0,0 +1,26 @@
1
+ import {
2
+ runRules
3
+ } from "../chunk-Q4NP4C3B.js";
4
+ import {
5
+ denormalizeRequest,
6
+ denormalizeResponse,
7
+ normalizeRequest
8
+ } from "../chunk-CQ7YZ3AR.js";
9
+ import "../chunk-MLKGABMK.js";
10
+
11
+ // src/adapters/viewer-request-async.ts
12
+ function defineViewerRequestAsync(setup) {
13
+ return async (event) => {
14
+ const ev = event;
15
+ const evReq = ev.request;
16
+ const originalCookies = evReq.cookies ?? {};
17
+ const req = normalizeRequest(event);
18
+ const rules = await setup(event);
19
+ const result = runRules(rules, req);
20
+ if (result.action === "respond") return denormalizeResponse(result.response);
21
+ return denormalizeRequest(result.request, originalCookies);
22
+ };
23
+ }
24
+ export {
25
+ defineViewerRequestAsync
26
+ };
@@ -3,7 +3,7 @@ import { BehaviorFn } from '../core/types.cjs';
3
3
  /**
4
4
  * Options for constructing a synthetic HTTP response at the edge.
5
5
  */
6
- interface ConstructResponseOptions {
6
+ type ConstructResponseOptions = {
7
7
  /**
8
8
  * The HTTP status code for the response (e.g. `200`, `403`, `404`).
9
9
  */
@@ -24,7 +24,7 @@ interface ConstructResponseOptions {
24
24
  * @example `{ 'x-request-id': '123', 'retry-after': '60' }`
25
25
  */
26
26
  headers?: Record<string, string>;
27
- }
27
+ };
28
28
  /**
29
29
  * Constructs and returns a synthetic HTTP response directly from the edge,
30
30
  * without forwarding the request to the origin.
@@ -3,7 +3,7 @@ import { BehaviorFn } from '../core/types.js';
3
3
  /**
4
4
  * Options for constructing a synthetic HTTP response at the edge.
5
5
  */
6
- interface ConstructResponseOptions {
6
+ type ConstructResponseOptions = {
7
7
  /**
8
8
  * The HTTP status code for the response (e.g. `200`, `403`, `404`).
9
9
  */
@@ -24,7 +24,7 @@ interface ConstructResponseOptions {
24
24
  * @example `{ 'x-request-id': '123', 'retry-after': '60' }`
25
25
  */
26
26
  headers?: Record<string, string>;
27
- }
27
+ };
28
28
  /**
29
29
  * Constructs and returns a synthetic HTTP response directly from the edge,
30
30
  * without forwarding the request to the origin.
@@ -5,8 +5,13 @@ import { HttpRequest, BehaviorFn } from '../core/types.cjs';
5
5
  *
6
6
  * Determines which request headers are injected so the proxy knows where to
7
7
  * fetch the source image:
8
- * - gateway: injects X-Img-Source-Type=gateway and X-Img-Upstream-Gateway
9
- * - s3: injects X-Img-Source-Type=s3 and X-Img-Source-Bucket
8
+ * - `s3`: injects `X-Img-Source-Type: s3` and `X-Img-Source-Bucket`
9
+ * - `gateway`: injects `X-Img-Source-Type: gateway` and `X-Img-Upstream-Gateway`
10
+ * (proxy treats any non-`s3` value as a gateway fallback)
11
+ *
12
+ * **Required for all requests** — the proxy always resolves the upstream source,
13
+ * even when no optimization params are present (pass-through mode). If origin
14
+ * headers are missing, the proxy returns an error.
10
15
  */
11
16
  type ImageOriginConfig = {
12
17
  type: 'gateway';
@@ -32,7 +37,7 @@ type ImageOriginResolver = ImageOriginConfig | ((request: HttpRequest) => ImageO
32
37
  * the normalized `imwidth`, `f`, and `q` params to drive imgproxy transformation
33
38
  * and S3 caching.
34
39
  */
35
- interface ImageOptimizeOptions {
40
+ type ImageOptimizeOptions = {
36
41
  /** Ordered list of breakpoint widths (px). Request widths snap to the nearest ceiling breakpoint. */
37
42
  breakpoints: number[];
38
43
  /** Preferred format priority. Defaults to ['avif', 'webp', 'jpeg']. */
@@ -45,13 +50,13 @@ interface ImageOptimizeOptions {
45
50
  imformatParam?: string;
46
51
  /**
47
52
  * Origin configuration for image-optimize-proxy.
48
- * When provided, injects the corresponding X-Img-* request headers so the
49
- * proxy knows how to resolve the source image. This removes the need to
50
- * configure CloudFront origin custom headers separately in Terraform.
51
- *
52
- * Accepts either a static config object or a resolver function that receives
53
- * the request and returns the appropriate origin (or undefined to skip).
54
- */
53
+ * When provided, injects the corresponding X-Img-* request headers so the
54
+ * proxy knows how to resolve the source image. This removes the need to
55
+ * configure CloudFront origin custom headers separately in Terraform.
56
+ *
57
+ * Accepts either a static config object or a resolver function that receives
58
+ * the request and returns the appropriate origin (or undefined to skip).
59
+ */
55
60
  origin?: ImageOriginResolver;
56
61
  /**
57
62
  * CloudFront origin verification secret.
@@ -59,16 +64,16 @@ interface ImageOptimizeOptions {
59
64
  * The proxy validates this header to ensure requests originate from CloudFront.
60
65
  */
61
66
  originSecret?: string;
62
- }
67
+ };
63
68
  /** Resolved normalized image parameters. */
64
- interface ResolvedImageParams {
69
+ type ResolvedImageParams = {
65
70
  /** Width snapped to nearest ceiling breakpoint. */
66
71
  breakpoint: number;
67
72
  /** Resolved output format. */
68
73
  format: 'avif' | 'webp' | 'jpeg';
69
74
  /** Quality value (1-100). */
70
75
  quality: number;
71
- }
76
+ };
72
77
  /**
73
78
  * Resolves normalized image parameters (breakpoint, format, quality) from a request.
74
79
  *
@@ -101,6 +106,12 @@ declare function resolveImageParams(request: Pick<HttpRequest, 'querystring' | '
101
106
  * or X-Img-Source-Bucket headers (eliminates need for Terraform origin custom headers)
102
107
  * - When `originSecret` is set, injects X-Origin-Verify header
103
108
  *
109
+ * ⚠️ **Origin headers are required even for pass-through requests.** The proxy
110
+ * always resolves the upstream source regardless of whether optimization params
111
+ * are present. If `origin` is not configured here, set `X-Img-Upstream-Gateway`
112
+ * or `X-Img-Source-Type` / `X-Img-Source-Bucket` as CloudFront origin custom
113
+ * headers in Terraform — otherwise the proxy returns an error for every request.
114
+ *
104
115
  * Architecture:
105
116
  * CF Function (viewer-request): imageOptimize — normalize querystring + inject origin headers
106
117
  * image-optimize-proxy (origin): reads imwidth/f/q + X-Img-* headers, calls imgproxy sidecar, caches to S3
@@ -5,8 +5,13 @@ import { HttpRequest, BehaviorFn } from '../core/types.js';
5
5
  *
6
6
  * Determines which request headers are injected so the proxy knows where to
7
7
  * fetch the source image:
8
- * - gateway: injects X-Img-Source-Type=gateway and X-Img-Upstream-Gateway
9
- * - s3: injects X-Img-Source-Type=s3 and X-Img-Source-Bucket
8
+ * - `s3`: injects `X-Img-Source-Type: s3` and `X-Img-Source-Bucket`
9
+ * - `gateway`: injects `X-Img-Source-Type: gateway` and `X-Img-Upstream-Gateway`
10
+ * (proxy treats any non-`s3` value as a gateway fallback)
11
+ *
12
+ * **Required for all requests** — the proxy always resolves the upstream source,
13
+ * even when no optimization params are present (pass-through mode). If origin
14
+ * headers are missing, the proxy returns an error.
10
15
  */
11
16
  type ImageOriginConfig = {
12
17
  type: 'gateway';
@@ -32,7 +37,7 @@ type ImageOriginResolver = ImageOriginConfig | ((request: HttpRequest) => ImageO
32
37
  * the normalized `imwidth`, `f`, and `q` params to drive imgproxy transformation
33
38
  * and S3 caching.
34
39
  */
35
- interface ImageOptimizeOptions {
40
+ type ImageOptimizeOptions = {
36
41
  /** Ordered list of breakpoint widths (px). Request widths snap to the nearest ceiling breakpoint. */
37
42
  breakpoints: number[];
38
43
  /** Preferred format priority. Defaults to ['avif', 'webp', 'jpeg']. */
@@ -45,13 +50,13 @@ interface ImageOptimizeOptions {
45
50
  imformatParam?: string;
46
51
  /**
47
52
  * Origin configuration for image-optimize-proxy.
48
- * When provided, injects the corresponding X-Img-* request headers so the
49
- * proxy knows how to resolve the source image. This removes the need to
50
- * configure CloudFront origin custom headers separately in Terraform.
51
- *
52
- * Accepts either a static config object or a resolver function that receives
53
- * the request and returns the appropriate origin (or undefined to skip).
54
- */
53
+ * When provided, injects the corresponding X-Img-* request headers so the
54
+ * proxy knows how to resolve the source image. This removes the need to
55
+ * configure CloudFront origin custom headers separately in Terraform.
56
+ *
57
+ * Accepts either a static config object or a resolver function that receives
58
+ * the request and returns the appropriate origin (or undefined to skip).
59
+ */
55
60
  origin?: ImageOriginResolver;
56
61
  /**
57
62
  * CloudFront origin verification secret.
@@ -59,16 +64,16 @@ interface ImageOptimizeOptions {
59
64
  * The proxy validates this header to ensure requests originate from CloudFront.
60
65
  */
61
66
  originSecret?: string;
62
- }
67
+ };
63
68
  /** Resolved normalized image parameters. */
64
- interface ResolvedImageParams {
69
+ type ResolvedImageParams = {
65
70
  /** Width snapped to nearest ceiling breakpoint. */
66
71
  breakpoint: number;
67
72
  /** Resolved output format. */
68
73
  format: 'avif' | 'webp' | 'jpeg';
69
74
  /** Quality value (1-100). */
70
75
  quality: number;
71
- }
76
+ };
72
77
  /**
73
78
  * Resolves normalized image parameters (breakpoint, format, quality) from a request.
74
79
  *
@@ -101,6 +106,12 @@ declare function resolveImageParams(request: Pick<HttpRequest, 'querystring' | '
101
106
  * or X-Img-Source-Bucket headers (eliminates need for Terraform origin custom headers)
102
107
  * - When `originSecret` is set, injects X-Origin-Verify header
103
108
  *
109
+ * ⚠️ **Origin headers are required even for pass-through requests.** The proxy
110
+ * always resolves the upstream source regardless of whether optimization params
111
+ * are present. If `origin` is not configured here, set `X-Img-Upstream-Gateway`
112
+ * or `X-Img-Source-Type` / `X-Img-Source-Bucket` as CloudFront origin custom
113
+ * headers in Terraform — otherwise the proxy returns an error for every request.
114
+ *
104
115
  * Architecture:
105
116
  * CF Function (viewer-request): imageOptimize — normalize querystring + inject origin headers
106
117
  * image-optimize-proxy (origin): reads imwidth/f/q + X-Img-* headers, calls imgproxy sidecar, caches to S3
@@ -1,5 +1,12 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }
2
2
 
3
+ var _chunkIHVOAORHcjs = require('../chunk-IHVOAORH.cjs');
4
+ require('../chunk-ULICUDDH.cjs');
5
+
6
+
7
+ var _chunkZXS23HXAcjs = require('../chunk-ZXS23HXA.cjs');
8
+
9
+
3
10
  var _chunkPPUHEL4Hcjs = require('../chunk-PPUHEL4H.cjs');
4
11
 
5
12
 
@@ -12,6 +19,9 @@ var _chunk3UXNXJ6Ncjs = require('../chunk-3UXNXJ6N.cjs');
12
19
  var _chunkMSES76XKcjs = require('../chunk-MSES76XK.cjs');
13
20
 
14
21
 
22
+ var _chunkLTLBEBKLcjs = require('../chunk-LTLBEBKL.cjs');
23
+
24
+
15
25
  var _chunkKXC6ES3Bcjs = require('../chunk-KXC6ES3B.cjs');
16
26
 
17
27
 
@@ -21,25 +31,16 @@ var _chunkWWSRNCUPcjs = require('../chunk-WWSRNCUP.cjs');
21
31
  var _chunkSGEBNQR2cjs = require('../chunk-SGEBNQR2.cjs');
22
32
 
23
33
 
24
- var _chunkMRPTC74Icjs = require('../chunk-MRPTC74I.cjs');
34
+ var _chunkBSH5JZBLcjs = require('../chunk-BSH5JZBL.cjs');
25
35
 
26
36
 
27
37
  var _chunkCV234DQTcjs = require('../chunk-CV234DQT.cjs');
28
38
 
29
39
 
30
- var _chunkAEZDDJEWcjs = require('../chunk-AEZDDJEW.cjs');
31
-
32
-
33
- var _chunkZXS23HXAcjs = require('../chunk-ZXS23HXA.cjs');
34
-
35
-
36
40
  var _chunkOSGZTNTScjs = require('../chunk-OSGZTNTS.cjs');
37
41
 
38
42
 
39
43
  var _chunkJU5WX5RUcjs = require('../chunk-JU5WX5RU.cjs');
40
-
41
-
42
- var _chunkLTLBEBKLcjs = require('../chunk-LTLBEBKL.cjs');
43
44
  require('../chunk-75ZPJI57.cjs');
44
45
 
45
46
  // src/behaviors/verify-token.ts
@@ -123,4 +124,4 @@ function verifyToken(options) {
123
124
 
124
125
 
125
126
 
126
- exports.constructResponse = _chunkOSGZTNTScjs.constructResponse; exports.copyHeader = _chunkJU5WX5RUcjs.copyHeader; exports.directoryIndex = _chunkLTLBEBKLcjs.directoryIndex; exports.imageOptimize = _chunkKXC6ES3Bcjs.imageOptimize; exports.redirect = _chunkWWSRNCUPcjs.redirect; exports.removeResponseHeaders = _chunkSGEBNQR2cjs.removeResponseHeaders; exports.rewriteUri = _chunkMRPTC74Icjs.rewriteUri; exports.setCacheControl = _chunkCV234DQTcjs.setCacheControl; exports.setCorsHeaders = _chunkAEZDDJEWcjs.setCorsHeaders; exports.setCsp = _chunkZXS23HXAcjs.setCsp; exports.setRequestHeader = _chunkPPUHEL4Hcjs.setRequestHeader; exports.setResponseHeader = _chunkB4WEJSEZcjs.setResponseHeader; exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders; exports.stripQueryParams = _chunkMSES76XKcjs.stripQueryParams; exports.verifyToken = verifyToken;
127
+ exports.constructResponse = _chunkOSGZTNTScjs.constructResponse; exports.copyHeader = _chunkJU5WX5RUcjs.copyHeader; exports.directoryIndex = _chunkLTLBEBKLcjs.directoryIndex; exports.imageOptimize = _chunkKXC6ES3Bcjs.imageOptimize; exports.redirect = _chunkWWSRNCUPcjs.redirect; exports.removeResponseHeaders = _chunkSGEBNQR2cjs.removeResponseHeaders; exports.rewriteUri = _chunkBSH5JZBLcjs.rewriteUri; exports.setCacheControl = _chunkCV234DQTcjs.setCacheControl; exports.setCorsHeaders = _chunkIHVOAORHcjs.setCorsHeaders; exports.setCsp = _chunkZXS23HXAcjs.setCsp; exports.setRequestHeader = _chunkPPUHEL4Hcjs.setRequestHeader; exports.setResponseHeader = _chunkB4WEJSEZcjs.setResponseHeader; exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders; exports.stripQueryParams = _chunkMSES76XKcjs.stripQueryParams; exports.verifyToken = verifyToken;
@@ -21,11 +21,11 @@ export { ResponseBehaviorFn, ResponseRule } from '../core/types.cjs';
21
21
  * Token format: `exp=<unix>~acl=<path>~hmac=<hex>`
22
22
  * The `key` is the hex-encoded HMAC-SHA256 secret (Akamai `verifyTokenAuthorization.key`).
23
23
  */
24
- interface VerifyTokenOptions {
24
+ type VerifyTokenOptions = {
25
25
  key: string;
26
26
  param?: string;
27
27
  failureStatus?: 401 | 403;
28
- }
28
+ };
29
29
  /**
30
30
  * Validates an Akamai Edge Auth Token 2.0 (HMAC-SHA256) from the request querystring.
31
31
  * Returns 403 on missing / expired / invalid token; continues on success.
@@ -21,11 +21,11 @@ export { ResponseBehaviorFn, ResponseRule } from '../core/types.js';
21
21
  * Token format: `exp=<unix>~acl=<path>~hmac=<hex>`
22
22
  * The `key` is the hex-encoded HMAC-SHA256 secret (Akamai `verifyTokenAuthorization.key`).
23
23
  */
24
- interface VerifyTokenOptions {
24
+ type VerifyTokenOptions = {
25
25
  key: string;
26
26
  param?: string;
27
27
  failureStatus?: 401 | 403;
28
- }
28
+ };
29
29
  /**
30
30
  * Validates an Akamai Edge Auth Token 2.0 (HMAC-SHA256) from the request querystring.
31
31
  * Returns 403 on missing / expired / invalid token; continues on success.
@@ -1,3 +1,10 @@
1
+ import {
2
+ setCorsHeaders
3
+ } from "../chunk-H3RK4USR.js";
4
+ import "../chunk-EEZ7NUJG.js";
5
+ import {
6
+ setCsp
7
+ } from "../chunk-XUI4Y22M.js";
1
8
  import {
2
9
  setRequestHeader
3
10
  } from "../chunk-M5KUQBDW.js";
@@ -10,6 +17,9 @@ import {
10
17
  import {
11
18
  stripQueryParams
12
19
  } from "../chunk-XPQG5IML.js";
20
+ import {
21
+ directoryIndex
22
+ } from "../chunk-R7WXS7BI.js";
13
23
  import {
14
24
  imageOptimize
15
25
  } from "../chunk-LQRLWDQQ.js";
@@ -21,25 +31,16 @@ import {
21
31
  } from "../chunk-BUAIBB3N.js";
22
32
  import {
23
33
  rewriteUri
24
- } from "../chunk-FTP7NLKX.js";
34
+ } from "../chunk-QVY6REMD.js";
25
35
  import {
26
36
  setCacheControl
27
37
  } from "../chunk-ZTMSH34E.js";
28
- import {
29
- setCorsHeaders
30
- } from "../chunk-CQA2DCVF.js";
31
- import {
32
- setCsp
33
- } from "../chunk-XUI4Y22M.js";
34
38
  import {
35
39
  constructResponse
36
40
  } from "../chunk-6DBZBV2M.js";
37
41
  import {
38
42
  copyHeader
39
43
  } from "../chunk-BDNPQ7AU.js";
40
- import {
41
- directoryIndex
42
- } from "../chunk-R7WXS7BI.js";
43
44
  import "../chunk-MLKGABMK.js";
44
45
 
45
46
  // src/behaviors/verify-token.ts
@@ -0,0 +1,24 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});require('../chunk-75ZPJI57.cjs');
2
+
3
+ // src/behaviors/kvs.ts
4
+ async function kvsRedirect(handle, key, statusCode) {
5
+ const raw = await handle.get(key);
6
+ const map = raw ? JSON.parse(raw) : {};
7
+ const code = statusCode !== void 0 ? statusCode : 301;
8
+ const desc = code === 302 ? "Found" : "Moved Permanently";
9
+ return (request) => {
10
+ const dest = map[request.uri];
11
+ if (!dest) return { action: "continue", request };
12
+ return {
13
+ action: "respond",
14
+ response: {
15
+ statusCode: code,
16
+ statusDescription: desc,
17
+ headers: { location: { value: dest } }
18
+ }
19
+ };
20
+ };
21
+ }
22
+
23
+
24
+ exports.kvsRedirect = kvsRedirect;
@@ -0,0 +1,34 @@
1
+ import { BehaviorFn } from '../core/types.cjs';
2
+ import { KvsHandle } from '../shared/kvs.cjs';
3
+
4
+ /**
5
+ * Loads a redirect map from CloudFront KeyValueStore and returns a `BehaviorFn`
6
+ * that performs 301/302 redirects based on exact URI matches.
7
+ *
8
+ * The KVS value at `key` must be a JSON-encoded `Record<string, string>` mapping
9
+ * source URIs to destination URLs (e.g. `{ "/old": "https://example.com/new" }`).
10
+ * Requests whose URI does not appear in the map are passed through unchanged.
11
+ *
12
+ * Intended for use with `defineViewerRequestAsync` — the KVS read happens once
13
+ * at setup time and the resulting map is captured in the returned closure.
14
+ *
15
+ * @param handle - KVS handle (from `@aws-sdk/cloudfront-keyvaluestore` or equivalent).
16
+ * @param key - The KVS key whose value is a JSON redirect map.
17
+ * @param statusCode - HTTP redirect status code. Defaults to `301`.
18
+ * @returns A `BehaviorFn` to pass to `rule()`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { defineViewerRequestAsync } from '@rayselfs/cf-rule-engine/adapters/viewer-request'
23
+ * import { rule } from '@rayselfs/cf-rule-engine'
24
+ * import { kvsRedirect } from '@rayselfs/cf-rule-engine/behaviors/kvs'
25
+ *
26
+ * export default defineViewerRequestAsync(async (event) => {
27
+ * const handle = CloudFront.createKeyValueStore(event)
28
+ * return [rule(await kvsRedirect(handle, 'redirects'))]
29
+ * })
30
+ * ```
31
+ */
32
+ declare function kvsRedirect(handle: KvsHandle, key: string, statusCode?: number): Promise<BehaviorFn>;
33
+
34
+ export { kvsRedirect };
@@ -0,0 +1,34 @@
1
+ import { BehaviorFn } from '../core/types.js';
2
+ import { KvsHandle } from '../shared/kvs.js';
3
+
4
+ /**
5
+ * Loads a redirect map from CloudFront KeyValueStore and returns a `BehaviorFn`
6
+ * that performs 301/302 redirects based on exact URI matches.
7
+ *
8
+ * The KVS value at `key` must be a JSON-encoded `Record<string, string>` mapping
9
+ * source URIs to destination URLs (e.g. `{ "/old": "https://example.com/new" }`).
10
+ * Requests whose URI does not appear in the map are passed through unchanged.
11
+ *
12
+ * Intended for use with `defineViewerRequestAsync` — the KVS read happens once
13
+ * at setup time and the resulting map is captured in the returned closure.
14
+ *
15
+ * @param handle - KVS handle (from `@aws-sdk/cloudfront-keyvaluestore` or equivalent).
16
+ * @param key - The KVS key whose value is a JSON redirect map.
17
+ * @param statusCode - HTTP redirect status code. Defaults to `301`.
18
+ * @returns A `BehaviorFn` to pass to `rule()`.
19
+ *
20
+ * @example
21
+ * ```ts
22
+ * import { defineViewerRequestAsync } from '@rayselfs/cf-rule-engine/adapters/viewer-request'
23
+ * import { rule } from '@rayselfs/cf-rule-engine'
24
+ * import { kvsRedirect } from '@rayselfs/cf-rule-engine/behaviors/kvs'
25
+ *
26
+ * export default defineViewerRequestAsync(async (event) => {
27
+ * const handle = CloudFront.createKeyValueStore(event)
28
+ * return [rule(await kvsRedirect(handle, 'redirects'))]
29
+ * })
30
+ * ```
31
+ */
32
+ declare function kvsRedirect(handle: KvsHandle, key: string, statusCode?: number): Promise<BehaviorFn>;
33
+
34
+ export { kvsRedirect };
@@ -0,0 +1,24 @@
1
+ import "../chunk-MLKGABMK.js";
2
+
3
+ // src/behaviors/kvs.ts
4
+ async function kvsRedirect(handle, key, statusCode) {
5
+ const raw = await handle.get(key);
6
+ const map = raw ? JSON.parse(raw) : {};
7
+ const code = statusCode !== void 0 ? statusCode : 301;
8
+ const desc = code === 302 ? "Found" : "Moved Permanently";
9
+ return (request) => {
10
+ const dest = map[request.uri];
11
+ if (!dest) return { action: "continue", request };
12
+ return {
13
+ action: "respond",
14
+ response: {
15
+ statusCode: code,
16
+ statusDescription: desc,
17
+ headers: { location: { value: dest } }
18
+ }
19
+ };
20
+ };
21
+ }
22
+ export {
23
+ kvsRedirect
24
+ };
@@ -3,14 +3,14 @@ import { BehaviorFn } from '../core/types.cjs';
3
3
  /**
4
4
  * Options for configuring redirect behavior.
5
5
  */
6
- interface RedirectOptions {
6
+ type RedirectOptions = {
7
7
  /**
8
8
  * When `true`, the original request's query string is appended to the redirect
9
9
  * `location` URL. Useful for preserving search params during path migrations.
10
10
  * Default: `false`.
11
11
  */
12
12
  preserveQuerystring?: boolean;
13
- }
13
+ };
14
14
  /**
15
15
  * Redirects the request to the specified URL with the given HTTP status code.
16
16
  *
@@ -3,14 +3,14 @@ import { BehaviorFn } from '../core/types.js';
3
3
  /**
4
4
  * Options for configuring redirect behavior.
5
5
  */
6
- interface RedirectOptions {
6
+ type RedirectOptions = {
7
7
  /**
8
8
  * When `true`, the original request's query string is appended to the redirect
9
9
  * `location` URL. Useful for preserving search params during path migrations.
10
10
  * Default: `false`.
11
11
  */
12
12
  preserveQuerystring?: boolean;
13
- }
13
+ };
14
14
  /**
15
15
  * Redirects the request to the specified URL with the given HTTP status code.
16
16
  *
@@ -1,7 +1,7 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkMRPTC74Icjs = require('../chunk-MRPTC74I.cjs');
3
+ var _chunkBSH5JZBLcjs = require('../chunk-BSH5JZBL.cjs');
4
4
  require('../chunk-75ZPJI57.cjs');
5
5
 
6
6
 
7
- exports.rewriteUri = _chunkMRPTC74Icjs.rewriteUri;
7
+ exports.rewriteUri = _chunkBSH5JZBLcjs.rewriteUri;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  rewriteUri
3
- } from "../chunk-FTP7NLKX.js";
3
+ } from "../chunk-QVY6REMD.js";
4
4
  import "../chunk-MLKGABMK.js";
5
5
  export {
6
6
  rewriteUri
@@ -2,10 +2,11 @@
2
2
 
3
3
 
4
4
 
5
- var _chunkAEZDDJEWcjs = require('../chunk-AEZDDJEW.cjs');
5
+ var _chunkIHVOAORHcjs = require('../chunk-IHVOAORH.cjs');
6
+ require('../chunk-ULICUDDH.cjs');
6
7
  require('../chunk-75ZPJI57.cjs');
7
8
 
8
9
 
9
10
 
10
11
 
11
- exports.ORIGIN_ECHO = _chunkAEZDDJEWcjs.ORIGIN_ECHO; exports.ORIGIN_WILDCARD = _chunkAEZDDJEWcjs.ORIGIN_WILDCARD; exports.setCorsHeaders = _chunkAEZDDJEWcjs.setCorsHeaders;
12
+ exports.ORIGIN_ECHO = _chunkIHVOAORHcjs.ORIGIN_ECHO; exports.ORIGIN_WILDCARD = _chunkIHVOAORHcjs.ORIGIN_WILDCARD; exports.setCorsHeaders = _chunkIHVOAORHcjs.setCorsHeaders;