@rayselfs/cf-rule-engine 1.7.0 → 1.8.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
@@ -29,12 +29,12 @@ export default defineViewerRequest([
29
29
  **viewer-response** — security and CORS headers:
30
30
 
31
31
  ```typescript
32
- import { setSecurityHeaders, setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors/index'
32
+ import { setSecurityHeaders, setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors/index'
33
33
  import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
34
34
 
35
35
  export default defineViewerResponse([
36
36
  setSecurityHeaders(),
37
- setCorsHeaders({ allowedOrigins: ['https://www.example.com'] }),
37
+ setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
38
38
  ])
39
39
  ```
40
40
 
@@ -113,6 +113,31 @@ Use `chain()` when one behavior must see the request mutations (URI rewrite, hea
113
113
  | `imageOptimize(options)` | ✅ | ✅ |
114
114
  | `verifyToken(options)` | ❌ | ✅ |
115
115
 
116
+ ### setCorsHeaders — OriginPolicy
117
+
118
+ `allowedOrigins` accepts an `OriginPolicy` that controls how `Access-Control-Allow-Origin` is set:
119
+
120
+ | Value | Behavior |
121
+ |---|---|
122
+ | `ORIGIN_WILDCARD` (`'*'`) | Static `Access-Control-Allow-Origin: *` — for fully public APIs |
123
+ | `Origin[]` | Compare request `Origin` against the list; echo if matched, skip if not. Supports wildcard subdomains (`https://*.example.com`). |
124
+ | `ORIGIN_ECHO` (`'echo'`) | Echo any request `Origin` if present, skip if none — use with `allowCredentials: true` |
125
+
126
+ ```typescript
127
+ import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/index'
128
+
129
+ // Public API
130
+ setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD })
131
+
132
+ // Restricted — echo only listed origins
133
+ setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] })
134
+
135
+ // Echo any origin (required when allowCredentials: true)
136
+ setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true })
137
+ ```
138
+
139
+ `allowedMethods` and `allowedHeaders` are optional — omit to exclude those headers from the response.
140
+
116
141
  ## Helpers (`@rayselfs/cf-rule-engine/helpers/index`)
117
142
 
118
143
  Helpers are pre-configured rule factories that combine multiple criteria and behaviors for common use cases.
@@ -134,9 +159,10 @@ Adds `x-cf-distribution: staging` to the response when the request carries `aws-
134
159
 
135
160
  ```typescript
136
161
  import { stagingIndicator } from '@rayselfs/cf-rule-engine/helpers/index'
162
+ import { setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors/index'
137
163
 
138
164
  defineViewerResponse([
139
- setCorsHeaders({ allowedOrigins: ['https://www.example.com'] }),
165
+ setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
140
166
  stagingIndicator(),
141
167
  ])
142
168
  ```
@@ -1,2 +1,2 @@
1
1
  import '../core/types.cjs';
2
- export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-9xiONGmR.cjs';
2
+ export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-D1NHYwvA.cjs';
@@ -1,2 +1,2 @@
1
1
  import '../core/types.js';
2
- export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-BK3-bFx8.js';
2
+ export { d as defineViewerRequest, a as defineViewerResponse } from '../lambda-edge-DnIvWFGe.js';
@@ -27,7 +27,7 @@ var _chunkMRPTC74Icjs = require('../chunk-MRPTC74I.cjs');
27
27
  var _chunkCV234DQTcjs = require('../chunk-CV234DQT.cjs');
28
28
 
29
29
 
30
- var _chunkGK5JX7OMcjs = require('../chunk-GK5JX7OM.cjs');
30
+ var _chunkWAKA4OJDcjs = require('../chunk-WAKA4OJD.cjs');
31
31
 
32
32
 
33
33
  var _chunkZXS23HXAcjs = require('../chunk-ZXS23HXA.cjs');
@@ -123,4 +123,4 @@ function verifyToken(options) {
123
123
 
124
124
 
125
125
 
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 = _chunkGK5JX7OMcjs.setCorsHeaders; exports.setCsp = _chunkZXS23HXAcjs.setCsp; exports.setRequestHeader = _chunkPPUHEL4Hcjs.setRequestHeader; exports.setResponseHeader = _chunkB4WEJSEZcjs.setResponseHeader; exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders; exports.stripQueryParams = _chunkMSES76XKcjs.stripQueryParams; exports.verifyToken = verifyToken;
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 = _chunkWAKA4OJDcjs.setCorsHeaders; exports.setCsp = _chunkZXS23HXAcjs.setCsp; exports.setRequestHeader = _chunkPPUHEL4Hcjs.setRequestHeader; exports.setResponseHeader = _chunkB4WEJSEZcjs.setResponseHeader; exports.setSecurityHeaders = _chunk3UXNXJ6Ncjs.setSecurityHeaders; exports.stripQueryParams = _chunkMSES76XKcjs.stripQueryParams; exports.verifyToken = verifyToken;
@@ -27,7 +27,7 @@ import {
27
27
  } from "../chunk-ZTMSH34E.js";
28
28
  import {
29
29
  setCorsHeaders
30
- } from "../chunk-SOBTD7AD.js";
30
+ } from "../chunk-SRA2DFKG.js";
31
31
  import {
32
32
  setCsp
33
33
  } from "../chunk-XUI4Y22M.js";
@@ -1,7 +1,11 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkGK5JX7OMcjs = require('../chunk-GK5JX7OM.cjs');
3
+
4
+
5
+ var _chunkWAKA4OJDcjs = require('../chunk-WAKA4OJD.cjs');
4
6
  require('../chunk-75ZPJI57.cjs');
5
7
 
6
8
 
7
- exports.setCorsHeaders = _chunkGK5JX7OMcjs.setCorsHeaders;
9
+
10
+
11
+ exports.ORIGIN_ECHO = _chunkWAKA4OJDcjs.ORIGIN_ECHO; exports.ORIGIN_WILDCARD = _chunkWAKA4OJDcjs.ORIGIN_WILDCARD; exports.setCorsHeaders = _chunkWAKA4OJDcjs.setCorsHeaders;
@@ -1,38 +1,42 @@
1
1
  import { ResponseBehaviorFn } from '../core/types.cjs';
2
2
 
3
+ declare const ORIGIN_WILDCARD: "*";
4
+ type OriginWildcard = typeof ORIGIN_WILDCARD;
5
+ declare const ORIGIN_ECHO: "echo";
6
+ type OriginEcho = typeof ORIGIN_ECHO;
3
7
  /**
4
- * CORS configuration options for the `setCorsHeaders` behavior.
8
+ * A valid HTTP origin must start with `https://` or `http://`.
9
+ * Supports wildcard subdomains (e.g. `https://*.viverse.com`).
10
+ */
11
+ type Origin = `https://${string}` | `http://${string}`;
12
+ /**
13
+ * Controls how `Access-Control-Allow-Origin` is set:
14
+ * - `ORIGIN_WILDCARD` (`'*'`) — static `*`, allows all origins without inspection
15
+ * - `Origin[]` — compare request `Origin` header against the list; echo if matched, skip if not
16
+ * - `ORIGIN_ECHO` (`'echo'`) — echo any request `Origin` if present, skip if none
17
+ */
18
+ type OriginPolicy = OriginWildcard | Origin[] | OriginEcho;
19
+ /**
20
+ * CORS configuration options for `setCorsHeaders` and `preflightRequest`.
5
21
  */
6
22
  interface CorsOptions {
7
23
  /**
8
- * List of allowed origin patterns. Supports exact strings and wildcard `*` patterns
9
- * (e.g. `'https://*.example.com'`). Use `['*']` to allow all origins.
10
- * Default: `['*']`
24
+ * Origin policy. See `OriginPolicy` for details.
11
25
  */
12
- allowedOrigins?: string[];
13
- /**
14
- * When `true`, reflects the incoming `Origin` request header as the
15
- * `Access-Control-Allow-Origin` response value, provided it matches one of
16
- * `allowedOrigins`. Required when `allowCredentials` is `true` (browsers reject
17
- * `Access-Control-Allow-Origin: *` with credentials).
18
- * Default: `false`
19
- */
20
- allowOriginEcho?: boolean;
26
+ allowedOrigins: OriginPolicy;
21
27
  /**
22
28
  * Value for the `Access-Control-Allow-Methods` header.
23
- * Default: `'GET, POST, OPTIONS'`
29
+ * Omit to exclude the header.
24
30
  */
25
31
  allowedMethods?: string;
26
32
  /**
27
33
  * Value for the `Access-Control-Allow-Headers` header.
28
- * Default: `'Content-Type, Cache-Control, Pragma, Range'`
34
+ * Omit to exclude the header.
29
35
  */
30
36
  allowedHeaders?: string;
31
37
  /**
32
38
  * When `true`, sets `Access-Control-Allow-Credentials: true`.
33
- * Must be used together with `allowOriginEcho: true`; browsers reject
34
- * wildcard origins when credentials are present.
35
- * Default: `false`
39
+ * Use with `ORIGIN_ECHO` or `Origin[]` browsers reject `*` with credentials.
36
40
  */
37
41
  allowCredentials?: boolean;
38
42
  /**
@@ -42,35 +46,32 @@ interface CorsOptions {
42
46
  maxAge?: number;
43
47
  }
44
48
  /**
45
- * Sets CORS response headers with configurable origin matching, methods, headers,
46
- * credentials, and preflight cache duration.
47
- *
48
- * Akamai equivalent: typically implemented via `modifyOutgoingResponseHeader` rules
49
- * for each CORS header individually.
49
+ * Sets CORS response headers with configurable origin policy.
50
50
  *
51
- * @param options - CORS configuration. All fields are optional with safe defaults.
51
+ * @param options - CORS configuration. `allowedOrigins` is required.
52
52
  * @returns A `ResponseBehaviorFn` to use directly in `defineViewerResponse` or wrapped in a `ResponseRule`.
53
53
  *
54
54
  * @example
55
55
  * ```ts
56
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
57
- * import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
56
+ * import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/set-cors-headers'
57
+ * import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
58
58
  *
59
- * // Allow all origins (default)
60
- * export default defineViewerResponse([setCorsHeaders()])
59
+ * // Public API static Access-Control-Allow-Origin: *
60
+ * export default defineViewerResponse([
61
+ * setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
62
+ * ])
63
+ *
64
+ * // Restricted — echo only listed origins (supports wildcard subdomains)
65
+ * export default defineViewerResponse([
66
+ * setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] }),
67
+ * ])
61
68
  *
62
- * // Echo origin with credentials (e.g. for authenticated API endpoints)
69
+ * // Echo any origin (e.g. for credentialed requests)
63
70
  * export default defineViewerResponse([
64
- * setCorsHeaders({
65
- * allowedOrigins: ['https://www.example.com', 'https://*.example.com'],
66
- * allowOriginEcho: true,
67
- * allowCredentials: true,
68
- * allowedMethods: 'GET, POST, PUT, DELETE, OPTIONS',
69
- * maxAge: 86400,
70
- * }),
71
+ * setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
71
72
  * ])
72
73
  * ```
73
74
  */
74
- declare function setCorsHeaders(options?: CorsOptions): ResponseBehaviorFn;
75
+ declare function setCorsHeaders(options: CorsOptions): ResponseBehaviorFn;
75
76
 
76
- export { type CorsOptions, setCorsHeaders };
77
+ export { type CorsOptions, ORIGIN_ECHO, ORIGIN_WILDCARD, type Origin, type OriginEcho, type OriginPolicy, type OriginWildcard, setCorsHeaders };
@@ -1,38 +1,42 @@
1
1
  import { ResponseBehaviorFn } from '../core/types.js';
2
2
 
3
+ declare const ORIGIN_WILDCARD: "*";
4
+ type OriginWildcard = typeof ORIGIN_WILDCARD;
5
+ declare const ORIGIN_ECHO: "echo";
6
+ type OriginEcho = typeof ORIGIN_ECHO;
3
7
  /**
4
- * CORS configuration options for the `setCorsHeaders` behavior.
8
+ * A valid HTTP origin must start with `https://` or `http://`.
9
+ * Supports wildcard subdomains (e.g. `https://*.viverse.com`).
10
+ */
11
+ type Origin = `https://${string}` | `http://${string}`;
12
+ /**
13
+ * Controls how `Access-Control-Allow-Origin` is set:
14
+ * - `ORIGIN_WILDCARD` (`'*'`) — static `*`, allows all origins without inspection
15
+ * - `Origin[]` — compare request `Origin` header against the list; echo if matched, skip if not
16
+ * - `ORIGIN_ECHO` (`'echo'`) — echo any request `Origin` if present, skip if none
17
+ */
18
+ type OriginPolicy = OriginWildcard | Origin[] | OriginEcho;
19
+ /**
20
+ * CORS configuration options for `setCorsHeaders` and `preflightRequest`.
5
21
  */
6
22
  interface CorsOptions {
7
23
  /**
8
- * List of allowed origin patterns. Supports exact strings and wildcard `*` patterns
9
- * (e.g. `'https://*.example.com'`). Use `['*']` to allow all origins.
10
- * Default: `['*']`
24
+ * Origin policy. See `OriginPolicy` for details.
11
25
  */
12
- allowedOrigins?: string[];
13
- /**
14
- * When `true`, reflects the incoming `Origin` request header as the
15
- * `Access-Control-Allow-Origin` response value, provided it matches one of
16
- * `allowedOrigins`. Required when `allowCredentials` is `true` (browsers reject
17
- * `Access-Control-Allow-Origin: *` with credentials).
18
- * Default: `false`
19
- */
20
- allowOriginEcho?: boolean;
26
+ allowedOrigins: OriginPolicy;
21
27
  /**
22
28
  * Value for the `Access-Control-Allow-Methods` header.
23
- * Default: `'GET, POST, OPTIONS'`
29
+ * Omit to exclude the header.
24
30
  */
25
31
  allowedMethods?: string;
26
32
  /**
27
33
  * Value for the `Access-Control-Allow-Headers` header.
28
- * Default: `'Content-Type, Cache-Control, Pragma, Range'`
34
+ * Omit to exclude the header.
29
35
  */
30
36
  allowedHeaders?: string;
31
37
  /**
32
38
  * When `true`, sets `Access-Control-Allow-Credentials: true`.
33
- * Must be used together with `allowOriginEcho: true`; browsers reject
34
- * wildcard origins when credentials are present.
35
- * Default: `false`
39
+ * Use with `ORIGIN_ECHO` or `Origin[]` browsers reject `*` with credentials.
36
40
  */
37
41
  allowCredentials?: boolean;
38
42
  /**
@@ -42,35 +46,32 @@ interface CorsOptions {
42
46
  maxAge?: number;
43
47
  }
44
48
  /**
45
- * Sets CORS response headers with configurable origin matching, methods, headers,
46
- * credentials, and preflight cache duration.
47
- *
48
- * Akamai equivalent: typically implemented via `modifyOutgoingResponseHeader` rules
49
- * for each CORS header individually.
49
+ * Sets CORS response headers with configurable origin policy.
50
50
  *
51
- * @param options - CORS configuration. All fields are optional with safe defaults.
51
+ * @param options - CORS configuration. `allowedOrigins` is required.
52
52
  * @returns A `ResponseBehaviorFn` to use directly in `defineViewerResponse` or wrapped in a `ResponseRule`.
53
53
  *
54
54
  * @example
55
55
  * ```ts
56
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
57
- * import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
56
+ * import { setCorsHeaders, ORIGIN_WILDCARD, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors/set-cors-headers'
57
+ * import { defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/viewer-response'
58
58
  *
59
- * // Allow all origins (default)
60
- * export default defineViewerResponse([setCorsHeaders()])
59
+ * // Public API static Access-Control-Allow-Origin: *
60
+ * export default defineViewerResponse([
61
+ * setCorsHeaders({ allowedOrigins: ORIGIN_WILDCARD }),
62
+ * ])
63
+ *
64
+ * // Restricted — echo only listed origins (supports wildcard subdomains)
65
+ * export default defineViewerResponse([
66
+ * setCorsHeaders({ allowedOrigins: ['https://*.viverse.com', 'https://sdk-api.viverse.com'] }),
67
+ * ])
61
68
  *
62
- * // Echo origin with credentials (e.g. for authenticated API endpoints)
69
+ * // Echo any origin (e.g. for credentialed requests)
63
70
  * export default defineViewerResponse([
64
- * setCorsHeaders({
65
- * allowedOrigins: ['https://www.example.com', 'https://*.example.com'],
66
- * allowOriginEcho: true,
67
- * allowCredentials: true,
68
- * allowedMethods: 'GET, POST, PUT, DELETE, OPTIONS',
69
- * maxAge: 86400,
70
- * }),
71
+ * setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
71
72
  * ])
72
73
  * ```
73
74
  */
74
- declare function setCorsHeaders(options?: CorsOptions): ResponseBehaviorFn;
75
+ declare function setCorsHeaders(options: CorsOptions): ResponseBehaviorFn;
75
76
 
76
- export { type CorsOptions, setCorsHeaders };
77
+ export { type CorsOptions, ORIGIN_ECHO, ORIGIN_WILDCARD, type Origin, type OriginEcho, type OriginPolicy, type OriginWildcard, setCorsHeaders };
@@ -1,7 +1,11 @@
1
1
  import {
2
+ ORIGIN_ECHO,
3
+ ORIGIN_WILDCARD,
2
4
  setCorsHeaders
3
- } from "../chunk-SOBTD7AD.js";
5
+ } from "../chunk-SRA2DFKG.js";
4
6
  import "../chunk-MLKGABMK.js";
5
7
  export {
8
+ ORIGIN_ECHO,
9
+ ORIGIN_WILDCARD,
6
10
  setCorsHeaders
7
11
  };
@@ -1,6 +1,10 @@
1
1
  import {
2
2
  methodIs
3
3
  } from "./chunk-PY3JMRDG.js";
4
+ import {
5
+ ORIGIN_ECHO,
6
+ ORIGIN_WILDCARD
7
+ } from "./chunk-SRA2DFKG.js";
4
8
 
5
9
  // src/helpers/preflight-request.ts
6
10
  function matchesOriginPattern(origin, pattern) {
@@ -10,27 +14,33 @@ function matchesOriginPattern(origin, pattern) {
10
14
  return new RegExp(`^${escaped}$`).test(origin);
11
15
  }
12
16
  function preflightRequest(options) {
13
- const allowedOrigins = options?.allowedOrigins ?? ["*"];
14
- const allowedMethods = options?.allowedMethods ?? "GET, POST, OPTIONS";
15
- const allowedHeaders = options?.allowedHeaders ?? "Content-Type, Cache-Control, Pragma, Range";
16
- const allowCredentials = options?.allowCredentials ?? false;
17
- const maxAge = options?.maxAge;
17
+ const { allowedOrigins } = options;
18
+ const allowedMethods = options.allowedMethods ?? "GET, POST, OPTIONS";
19
+ const allowedHeaders = options.allowedHeaders ?? "Content-Type, Cache-Control, Pragma, Range";
20
+ const allowCredentials = options.allowCredentials ?? false;
21
+ const maxAge = options.maxAge;
18
22
  return {
19
23
  criteria: methodIs(["OPTIONS"]),
20
24
  behavior: (request) => {
21
25
  let allowOrigin;
22
- if (options?.allowOriginEcho) {
23
- const originHeader = request.headers["origin"]?.value;
24
- allowOrigin = originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p)) ? originHeader : allowedOrigins[0] ?? "*";
26
+ if (allowedOrigins === ORIGIN_WILDCARD) {
27
+ allowOrigin = "*";
28
+ } else if (allowedOrigins === ORIGIN_ECHO) {
29
+ allowOrigin = request.headers["origin"]?.value;
25
30
  } else {
26
- allowOrigin = allowedOrigins.includes("*") ? "*" : allowedOrigins[0] ?? "*";
31
+ const originHeader = request.headers["origin"]?.value;
32
+ if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
33
+ allowOrigin = originHeader;
34
+ }
27
35
  }
28
36
  const headers = {
29
37
  "cache-control": { value: "no-store" },
30
- "access-control-allow-origin": { value: allowOrigin },
31
38
  "access-control-allow-methods": { value: allowedMethods },
32
39
  "access-control-allow-headers": { value: allowedHeaders }
33
40
  };
41
+ if (allowOrigin !== void 0) {
42
+ headers["access-control-allow-origin"] = { value: allowOrigin };
43
+ }
34
44
  if (allowCredentials) {
35
45
  headers["access-control-allow-credentials"] = { value: "true" };
36
46
  }
@@ -2,6 +2,10 @@
2
2
 
3
3
  var _chunkOTFDML3Kcjs = require('./chunk-OTFDML3K.cjs');
4
4
 
5
+
6
+
7
+ var _chunkWAKA4OJDcjs = require('./chunk-WAKA4OJD.cjs');
8
+
5
9
  // src/helpers/preflight-request.ts
6
10
  function matchesOriginPattern(origin, pattern) {
7
11
  if (pattern === "*") return true;
@@ -10,27 +14,33 @@ function matchesOriginPattern(origin, pattern) {
10
14
  return new RegExp(`^${escaped}$`).test(origin);
11
15
  }
12
16
  function preflightRequest(options) {
13
- const allowedOrigins = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.allowedOrigins]), () => ( ["*"]));
14
- const allowedMethods = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.allowedMethods]), () => ( "GET, POST, OPTIONS"));
15
- const allowedHeaders = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.allowedHeaders]), () => ( "Content-Type, Cache-Control, Pragma, Range"));
16
- const allowCredentials = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _4 => _4.allowCredentials]), () => ( false));
17
- const maxAge = _optionalChain([options, 'optionalAccess', _5 => _5.maxAge]);
17
+ const { allowedOrigins } = options;
18
+ const allowedMethods = _nullishCoalesce(options.allowedMethods, () => ( "GET, POST, OPTIONS"));
19
+ const allowedHeaders = _nullishCoalesce(options.allowedHeaders, () => ( "Content-Type, Cache-Control, Pragma, Range"));
20
+ const allowCredentials = _nullishCoalesce(options.allowCredentials, () => ( false));
21
+ const maxAge = options.maxAge;
18
22
  return {
19
23
  criteria: _chunkOTFDML3Kcjs.methodIs.call(void 0, ["OPTIONS"]),
20
24
  behavior: (request) => {
21
25
  let allowOrigin;
22
- if (_optionalChain([options, 'optionalAccess', _6 => _6.allowOriginEcho])) {
23
- const originHeader = _optionalChain([request, 'access', _7 => _7.headers, 'access', _8 => _8["origin"], 'optionalAccess', _9 => _9.value]);
24
- allowOrigin = originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p)) ? originHeader : _nullishCoalesce(allowedOrigins[0], () => ( "*"));
26
+ if (allowedOrigins === _chunkWAKA4OJDcjs.ORIGIN_WILDCARD) {
27
+ allowOrigin = "*";
28
+ } else if (allowedOrigins === _chunkWAKA4OJDcjs.ORIGIN_ECHO) {
29
+ allowOrigin = _optionalChain([request, 'access', _ => _.headers, 'access', _2 => _2["origin"], 'optionalAccess', _3 => _3.value]);
25
30
  } else {
26
- allowOrigin = allowedOrigins.includes("*") ? "*" : _nullishCoalesce(allowedOrigins[0], () => ( "*"));
31
+ const originHeader = _optionalChain([request, 'access', _4 => _4.headers, 'access', _5 => _5["origin"], 'optionalAccess', _6 => _6.value]);
32
+ if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
33
+ allowOrigin = originHeader;
34
+ }
27
35
  }
28
36
  const headers = {
29
37
  "cache-control": { value: "no-store" },
30
- "access-control-allow-origin": { value: allowOrigin },
31
38
  "access-control-allow-methods": { value: allowedMethods },
32
39
  "access-control-allow-headers": { value: allowedHeaders }
33
40
  };
41
+ if (allowOrigin !== void 0) {
42
+ headers["access-control-allow-origin"] = { value: allowOrigin };
43
+ }
34
44
  if (allowCredentials) {
35
45
  headers["access-control-allow-credentials"] = { value: "true" };
36
46
  }
@@ -1,4 +1,6 @@
1
1
  // src/behaviors/set-cors-headers.ts
2
+ var ORIGIN_WILDCARD = "*";
3
+ var ORIGIN_ECHO = "echo";
2
4
  function matchesOriginPattern(origin, pattern) {
3
5
  if (pattern === "*") return true;
4
6
  if (!pattern.includes("*")) return origin === pattern;
@@ -6,26 +8,33 @@ function matchesOriginPattern(origin, pattern) {
6
8
  return new RegExp(`^${escaped}$`).test(origin);
7
9
  }
8
10
  function setCorsHeaders(options) {
9
- const allowedOrigins = options?.allowedOrigins ?? ["*"];
10
- const allowedMethods = options?.allowedMethods ?? "GET, POST, OPTIONS";
11
- const allowedHeaders = options?.allowedHeaders ?? "Content-Type, Cache-Control, Pragma, Range";
11
+ const { allowedOrigins } = options;
12
12
  return (request, response) => {
13
- let allowOrigin = allowedOrigins[0] ?? "*";
14
- if (options?.allowOriginEcho) {
13
+ let allowOrigin;
14
+ if (allowedOrigins === ORIGIN_WILDCARD) {
15
+ allowOrigin = "*";
16
+ } else if (allowedOrigins === ORIGIN_ECHO) {
17
+ allowOrigin = request.headers["origin"]?.value;
18
+ } else {
15
19
  const originHeader = request.headers["origin"]?.value;
16
20
  if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
17
21
  allowOrigin = originHeader;
18
22
  }
19
23
  }
24
+ if (allowOrigin === void 0) return response;
20
25
  const corsHeaders = {
21
- "access-control-allow-origin": { value: allowOrigin },
22
- "access-control-allow-methods": { value: allowedMethods },
23
- "access-control-allow-headers": { value: allowedHeaders }
26
+ "access-control-allow-origin": { value: allowOrigin }
24
27
  };
25
- if (options?.allowCredentials) {
28
+ if (options.allowedMethods !== void 0) {
29
+ corsHeaders["access-control-allow-methods"] = { value: options.allowedMethods };
30
+ }
31
+ if (options.allowedHeaders !== void 0) {
32
+ corsHeaders["access-control-allow-headers"] = { value: options.allowedHeaders };
33
+ }
34
+ if (options.allowCredentials) {
26
35
  corsHeaders["access-control-allow-credentials"] = { value: "true" };
27
36
  }
28
- if (options?.maxAge !== void 0) {
37
+ if (options.maxAge !== void 0) {
29
38
  corsHeaders["access-control-max-age"] = { value: String(options.maxAge) };
30
39
  }
31
40
  return Object.assign({}, response, {
@@ -35,5 +44,7 @@ function setCorsHeaders(options) {
35
44
  }
36
45
 
37
46
  export {
47
+ ORIGIN_WILDCARD,
48
+ ORIGIN_ECHO,
38
49
  setCorsHeaders
39
50
  };
@@ -0,0 +1,50 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true}); 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; }// src/behaviors/set-cors-headers.ts
2
+ var ORIGIN_WILDCARD = "*";
3
+ var ORIGIN_ECHO = "echo";
4
+ function matchesOriginPattern(origin, pattern) {
5
+ if (pattern === "*") return true;
6
+ if (!pattern.includes("*")) return origin === pattern;
7
+ const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
8
+ return new RegExp(`^${escaped}$`).test(origin);
9
+ }
10
+ function setCorsHeaders(options) {
11
+ const { allowedOrigins } = options;
12
+ return (request, response) => {
13
+ let allowOrigin;
14
+ if (allowedOrigins === ORIGIN_WILDCARD) {
15
+ allowOrigin = "*";
16
+ } else if (allowedOrigins === ORIGIN_ECHO) {
17
+ allowOrigin = _optionalChain([request, 'access', _ => _.headers, 'access', _2 => _2["origin"], 'optionalAccess', _3 => _3.value]);
18
+ } else {
19
+ const originHeader = _optionalChain([request, 'access', _4 => _4.headers, 'access', _5 => _5["origin"], 'optionalAccess', _6 => _6.value]);
20
+ if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
21
+ allowOrigin = originHeader;
22
+ }
23
+ }
24
+ if (allowOrigin === void 0) return response;
25
+ const corsHeaders = {
26
+ "access-control-allow-origin": { value: allowOrigin }
27
+ };
28
+ if (options.allowedMethods !== void 0) {
29
+ corsHeaders["access-control-allow-methods"] = { value: options.allowedMethods };
30
+ }
31
+ if (options.allowedHeaders !== void 0) {
32
+ corsHeaders["access-control-allow-headers"] = { value: options.allowedHeaders };
33
+ }
34
+ if (options.allowCredentials) {
35
+ corsHeaders["access-control-allow-credentials"] = { value: "true" };
36
+ }
37
+ if (options.maxAge !== void 0) {
38
+ corsHeaders["access-control-max-age"] = { value: String(options.maxAge) };
39
+ }
40
+ return Object.assign({}, response, {
41
+ headers: Object.assign({}, response.headers, corsHeaders)
42
+ });
43
+ };
44
+ }
45
+
46
+
47
+
48
+
49
+
50
+ exports.ORIGIN_WILDCARD = ORIGIN_WILDCARD; exports.ORIGIN_ECHO = ORIGIN_ECHO; exports.setCorsHeaders = setCorsHeaders;
@@ -17,12 +17,12 @@ import { CriteriaFn } from '../core/types.cjs';
17
17
  * ```typescript
18
18
  * import { rule } from '@rayselfs/cf-rule-engine'
19
19
  * import { headerEquals } from '@rayselfs/cf-rule-engine/criteria'
20
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
20
+ * import { setCorsHeaders, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors'
21
21
  *
22
22
  * // Apply CORS headers only for requests from known origins
23
23
  * rule(
24
24
  * headerEquals('origin', ['https://www.example.com', 'https://store.example.com']),
25
- * setCorsHeaders({ allowOriginEcho: true, allowCredentials: true }),
25
+ * setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
26
26
  * )
27
27
  * ```
28
28
  */
@@ -17,12 +17,12 @@ import { CriteriaFn } from '../core/types.js';
17
17
  * ```typescript
18
18
  * import { rule } from '@rayselfs/cf-rule-engine'
19
19
  * import { headerEquals } from '@rayselfs/cf-rule-engine/criteria'
20
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
20
+ * import { setCorsHeaders, ORIGIN_ECHO } from '@rayselfs/cf-rule-engine/behaviors'
21
21
  *
22
22
  * // Apply CORS headers only for requests from known origins
23
23
  * rule(
24
24
  * headerEquals('origin', ['https://www.example.com', 'https://store.example.com']),
25
- * setCorsHeaders({ allowOriginEcho: true, allowCredentials: true }),
25
+ * setCorsHeaders({ allowedOrigins: ORIGIN_ECHO, allowCredentials: true }),
26
26
  * )
27
27
  * ```
28
28
  */
@@ -1,6 +1,6 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk63WIEBQBcjs = require('../chunk-63WIEBQB.cjs');
3
+ var _chunk45SNLNLRcjs = require('../chunk-45SNLNLR.cjs');
4
4
 
5
5
 
6
6
  var _chunkLSCC62CZcjs = require('../chunk-LSCC62CZ.cjs');
@@ -20,6 +20,7 @@ var _chunkL7NBJ4JAcjs = require('../chunk-L7NBJ4JA.cjs');
20
20
 
21
21
  var _chunkB4WEJSEZcjs = require('../chunk-B4WEJSEZ.cjs');
22
22
  require('../chunk-WWSRNCUP.cjs');
23
+ require('../chunk-WAKA4OJD.cjs');
23
24
  require('../chunk-WKYMSRCD.cjs');
24
25
  require('../chunk-JU5WX5RU.cjs');
25
26
  require('../chunk-75ZPJI57.cjs');
@@ -39,4 +40,4 @@ function stagingIndicator() {
39
40
 
40
41
 
41
42
 
42
- exports.preflightRequest = _chunk63WIEBQBcjs.preflightRequest; exports.sendCountryCode = _chunkLSCC62CZcjs.sendCountryCode; exports.stagingIndicator = stagingIndicator; exports.whitelist = _chunkMO7HW25Rcjs.whitelist;
43
+ exports.preflightRequest = _chunk45SNLNLRcjs.preflightRequest; exports.sendCountryCode = _chunkLSCC62CZcjs.sendCountryCode; exports.stagingIndicator = stagingIndicator; exports.whitelist = _chunkMO7HW25Rcjs.whitelist;
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  preflightRequest
3
- } from "../chunk-H2LO6MQG.js";
3
+ } from "../chunk-3VYYXEER.js";
4
4
  import {
5
5
  sendCountryCode
6
6
  } from "../chunk-C32DL3EP.js";
@@ -20,6 +20,7 @@ import {
20
20
  setResponseHeader
21
21
  } from "../chunk-RBBKFG5J.js";
22
22
  import "../chunk-DSSFFJWL.js";
23
+ import "../chunk-SRA2DFKG.js";
23
24
  import "../chunk-Q4NP4C3B.js";
24
25
  import "../chunk-BDNPQ7AU.js";
25
26
  import "../chunk-MLKGABMK.js";
@@ -1,8 +1,9 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunk63WIEBQBcjs = require('../chunk-63WIEBQB.cjs');
3
+ var _chunk45SNLNLRcjs = require('../chunk-45SNLNLR.cjs');
4
4
  require('../chunk-OTFDML3K.cjs');
5
+ require('../chunk-WAKA4OJD.cjs');
5
6
  require('../chunk-75ZPJI57.cjs');
6
7
 
7
8
 
8
- exports.preflightRequest = _chunk63WIEBQBcjs.preflightRequest;
9
+ exports.preflightRequest = _chunk45SNLNLRcjs.preflightRequest;
@@ -5,17 +5,18 @@ import { CorsOptions } from '../behaviors/set-cors-headers.cjs';
5
5
  * Returns a `Rule` that responds 204 to OPTIONS preflight requests with CORS headers.
6
6
  *
7
7
  * Accepts the same `CorsOptions` as `setCorsHeaders` — pass the same object to both
8
- * to define CORS config in one place.
8
+ * to define CORS config in one place. `allowedMethods` and `allowedHeaders` default to
9
+ * permissive values if omitted.
9
10
  *
10
11
  * @example
11
12
  * ```ts
12
13
  * import { preflightRequest } from '@rayselfs/cf-rule-engine/helpers'
13
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
14
+ * import { setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors'
14
15
  * import { defineViewerRequest, defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
15
16
  * import type { CorsOptions } from '@rayselfs/cf-rule-engine/behaviors'
16
17
  *
17
18
  * const CORS: CorsOptions = {
18
- * allowedOrigins: ['*'],
19
+ * allowedOrigins: ORIGIN_WILDCARD,
19
20
  * allowedMethods: 'GET, POST, OPTIONS',
20
21
  * allowedHeaders: 'Content-Type, Cache-Control, Pragma, Range',
21
22
  * }
@@ -33,6 +34,6 @@ import { CorsOptions } from '../behaviors/set-cors-headers.cjs';
33
34
  *
34
35
  * @returns A `Rule` ready to pass into `defineViewerRequest`.
35
36
  */
36
- declare function preflightRequest(options?: CorsOptions): Rule;
37
+ declare function preflightRequest(options: CorsOptions): Rule;
37
38
 
38
39
  export { preflightRequest };
@@ -5,17 +5,18 @@ import { CorsOptions } from '../behaviors/set-cors-headers.js';
5
5
  * Returns a `Rule` that responds 204 to OPTIONS preflight requests with CORS headers.
6
6
  *
7
7
  * Accepts the same `CorsOptions` as `setCorsHeaders` — pass the same object to both
8
- * to define CORS config in one place.
8
+ * to define CORS config in one place. `allowedMethods` and `allowedHeaders` default to
9
+ * permissive values if omitted.
9
10
  *
10
11
  * @example
11
12
  * ```ts
12
13
  * import { preflightRequest } from '@rayselfs/cf-rule-engine/helpers'
13
- * import { setCorsHeaders } from '@rayselfs/cf-rule-engine/behaviors'
14
+ * import { setCorsHeaders, ORIGIN_WILDCARD } from '@rayselfs/cf-rule-engine/behaviors'
14
15
  * import { defineViewerRequest, defineViewerResponse } from '@rayselfs/cf-rule-engine/adapters/cf-function'
15
16
  * import type { CorsOptions } from '@rayselfs/cf-rule-engine/behaviors'
16
17
  *
17
18
  * const CORS: CorsOptions = {
18
- * allowedOrigins: ['*'],
19
+ * allowedOrigins: ORIGIN_WILDCARD,
19
20
  * allowedMethods: 'GET, POST, OPTIONS',
20
21
  * allowedHeaders: 'Content-Type, Cache-Control, Pragma, Range',
21
22
  * }
@@ -33,6 +34,6 @@ import { CorsOptions } from '../behaviors/set-cors-headers.js';
33
34
  *
34
35
  * @returns A `Rule` ready to pass into `defineViewerRequest`.
35
36
  */
36
- declare function preflightRequest(options?: CorsOptions): Rule;
37
+ declare function preflightRequest(options: CorsOptions): Rule;
37
38
 
38
39
  export { preflightRequest };
@@ -1,7 +1,8 @@
1
1
  import {
2
2
  preflightRequest
3
- } from "../chunk-H2LO6MQG.js";
3
+ } from "../chunk-3VYYXEER.js";
4
4
  import "../chunk-PY3JMRDG.js";
5
+ import "../chunk-SRA2DFKG.js";
5
6
  import "../chunk-MLKGABMK.js";
6
7
  export {
7
8
  preflightRequest
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { BehaviorFn, BehaviorResult, CriteriaFn, HttpRequest, HttpResponse, ResponseBehaviorFn, ResponseRule, Rule, ViewerRequestHandler, ViewerResponseHandler } from './core/types.cjs';
2
2
  export { all, any, chain, not, rule, runRules } from './core/rule.cjs';
3
3
  export { c as cfFunction } from './cf-function-BkfWpTfl.cjs';
4
- export { l as lambdaEdge } from './lambda-edge-9xiONGmR.cjs';
4
+ export { l as lambdaEdge } from './lambda-edge-D1NHYwvA.cjs';
5
5
  import './adapters/viewer-request.cjs';
6
6
  import './adapters/viewer-response.cjs';
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  export { BehaviorFn, BehaviorResult, CriteriaFn, HttpRequest, HttpResponse, ResponseBehaviorFn, ResponseRule, Rule, ViewerRequestHandler, ViewerResponseHandler } from './core/types.js';
2
2
  export { all, any, chain, not, rule, runRules } from './core/rule.js';
3
3
  export { c as cfFunction } from './cf-function-CZwCWch-.js';
4
- export { l as lambdaEdge } from './lambda-edge-BK3-bFx8.js';
4
+ export { l as lambdaEdge } from './lambda-edge-DnIvWFGe.js';
5
5
  import './adapters/viewer-request.js';
6
6
  import './adapters/viewer-response.js';
@@ -51,7 +51,7 @@ declare function defineViewerRequest(rules: Rule[]): (event: unknown) => unknown
51
51
  *
52
52
  * export const handler = defineViewerResponse([
53
53
  * setSecurityHeaders(),
54
- * setCorsHeaders({ allowedOrigins: ['https://www.example.com'], allowOriginEcho: true }),
54
+ * setCorsHeaders({ allowedOrigins: ['https://www.example.com'] }),
55
55
  * ])
56
56
  * ```
57
57
  */
@@ -51,7 +51,7 @@ declare function defineViewerRequest(rules: Rule[]): (event: unknown) => unknown
51
51
  *
52
52
  * export const handler = defineViewerResponse([
53
53
  * setSecurityHeaders(),
54
- * setCorsHeaders({ allowedOrigins: ['https://www.example.com'], allowOriginEcho: true }),
54
+ * setCorsHeaders({ allowedOrigins: ['https://www.example.com'] }),
55
55
  * ])
56
56
  * ```
57
57
  */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rayselfs/cf-rule-engine",
3
- "version": "1.7.0",
3
+ "version": "1.8.0",
4
4
  "description": "Composable, tree-shakeable CloudFront Function rules",
5
5
  "license": "MIT",
6
6
  "sideEffects": false,
@@ -1,39 +0,0 @@
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; }// src/behaviors/set-cors-headers.ts
2
- function matchesOriginPattern(origin, pattern) {
3
- if (pattern === "*") return true;
4
- if (!pattern.includes("*")) return origin === pattern;
5
- const escaped = pattern.replace(/[.+^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*");
6
- return new RegExp(`^${escaped}$`).test(origin);
7
- }
8
- function setCorsHeaders(options) {
9
- const allowedOrigins = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.allowedOrigins]), () => ( ["*"]));
10
- const allowedMethods = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.allowedMethods]), () => ( "GET, POST, OPTIONS"));
11
- const allowedHeaders = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.allowedHeaders]), () => ( "Content-Type, Cache-Control, Pragma, Range"));
12
- return (request, response) => {
13
- let allowOrigin = _nullishCoalesce(allowedOrigins[0], () => ( "*"));
14
- if (_optionalChain([options, 'optionalAccess', _4 => _4.allowOriginEcho])) {
15
- const originHeader = _optionalChain([request, 'access', _5 => _5.headers, 'access', _6 => _6["origin"], 'optionalAccess', _7 => _7.value]);
16
- if (originHeader && allowedOrigins.some((p) => matchesOriginPattern(originHeader, p))) {
17
- allowOrigin = originHeader;
18
- }
19
- }
20
- const corsHeaders = {
21
- "access-control-allow-origin": { value: allowOrigin },
22
- "access-control-allow-methods": { value: allowedMethods },
23
- "access-control-allow-headers": { value: allowedHeaders }
24
- };
25
- if (_optionalChain([options, 'optionalAccess', _8 => _8.allowCredentials])) {
26
- corsHeaders["access-control-allow-credentials"] = { value: "true" };
27
- }
28
- if (_optionalChain([options, 'optionalAccess', _9 => _9.maxAge]) !== void 0) {
29
- corsHeaders["access-control-max-age"] = { value: String(options.maxAge) };
30
- }
31
- return Object.assign({}, response, {
32
- headers: Object.assign({}, response.headers, corsHeaders)
33
- });
34
- };
35
- }
36
-
37
-
38
-
39
- exports.setCorsHeaders = setCorsHeaders;