@rayselfs/cf-rule-engine 1.6.2 → 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.
Files changed (41) hide show
  1. package/README.md +29 -3
  2. package/dist/adapters/lambda-edge.d.cts +1 -1
  3. package/dist/adapters/lambda-edge.d.ts +1 -1
  4. package/dist/behaviors/index.cjs +3 -3
  5. package/dist/behaviors/index.js +2 -2
  6. package/dist/behaviors/set-cors-headers.cjs +6 -2
  7. package/dist/behaviors/set-cors-headers.d.cts +39 -38
  8. package/dist/behaviors/set-cors-headers.d.ts +39 -38
  9. package/dist/behaviors/set-cors-headers.js +5 -1
  10. package/dist/behaviors/set-security-headers.cjs +2 -2
  11. package/dist/behaviors/set-security-headers.d.cts +35 -19
  12. package/dist/behaviors/set-security-headers.d.ts +35 -19
  13. package/dist/behaviors/set-security-headers.js +1 -1
  14. package/dist/chunk-3UXNXJ6N.cjs +21 -0
  15. package/dist/{chunk-H2LO6MQG.js → chunk-3VYYXEER.js} +20 -10
  16. package/dist/{chunk-63WIEBQB.cjs → chunk-45SNLNLR.cjs} +20 -10
  17. package/dist/chunk-O4SOSGAP.js +21 -0
  18. package/dist/{chunk-SOBTD7AD.js → chunk-SRA2DFKG.js} +21 -10
  19. package/dist/chunk-WAKA4OJD.cjs +50 -0
  20. package/dist/criteria/header-equals.d.cts +2 -2
  21. package/dist/criteria/header-equals.d.ts +2 -2
  22. package/dist/criteria/index.cjs +12 -12
  23. package/dist/criteria/index.js +12 -12
  24. package/dist/helpers/index.cjs +8 -7
  25. package/dist/helpers/index.js +7 -6
  26. package/dist/helpers/preflight-request.cjs +3 -2
  27. package/dist/helpers/preflight-request.d.cts +5 -4
  28. package/dist/helpers/preflight-request.d.ts +5 -4
  29. package/dist/helpers/preflight-request.js +2 -1
  30. package/dist/helpers/whitelist.cjs +3 -3
  31. package/dist/helpers/whitelist.js +2 -2
  32. package/dist/index.d.cts +1 -1
  33. package/dist/index.d.ts +1 -1
  34. package/dist/{lambda-edge-9xiONGmR.d.cts → lambda-edge-D1NHYwvA.d.cts} +1 -1
  35. package/dist/{lambda-edge-BK3-bFx8.d.ts → lambda-edge-DnIvWFGe.d.ts} +1 -1
  36. package/package.json +1 -1
  37. package/dist/chunk-GK5JX7OM.cjs +0 -39
  38. package/dist/chunk-UI6LKDJI.cjs +0 -19
  39. package/dist/chunk-VQCRSBWL.js +0 -19
  40. package/dist/{chunk-RL7ZETZR.js → chunk-ER2YEZZO.js} +3 -3
  41. package/dist/{chunk-T5EXFHVA.cjs → chunk-MO7HW25R.cjs} +3 -3
@@ -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
  }
@@ -0,0 +1,21 @@
1
+ // src/behaviors/set-security-headers.ts
2
+ function setSecurityHeaders(options) {
3
+ return (_request, response) => {
4
+ const extra = {};
5
+ if (options.hsts !== void 0)
6
+ extra["strict-transport-security"] = { value: options.hsts };
7
+ if (options.xFrameOptions !== void 0)
8
+ extra["x-frame-options"] = { value: options.xFrameOptions };
9
+ if (options.xContentTypeOptions !== void 0)
10
+ extra["x-content-type-options"] = { value: options.xContentTypeOptions };
11
+ if (options.xXssProtection !== void 0)
12
+ extra["x-xss-protection"] = { value: options.xXssProtection };
13
+ return Object.assign({}, response, {
14
+ headers: Object.assign({}, response.headers, extra)
15
+ });
16
+ };
17
+ }
18
+
19
+ export {
20
+ setSecurityHeaders
21
+ };
@@ -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,17 +1,5 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkG7JGTBTTcjs = require('../chunk-G7JGTBTT.cjs');
4
-
5
-
6
- var _chunkMVGYPBYBcjs = require('../chunk-MVGYPBYB.cjs');
7
-
8
-
9
- var _chunk32SMWYAFcjs = require('../chunk-32SMWYAF.cjs');
10
-
11
-
12
- var _chunkL7NBJ4JAcjs = require('../chunk-L7NBJ4JA.cjs');
13
-
14
-
15
3
  var _chunkJGJW7D2Ncjs = require('../chunk-JGJW7D2N.cjs');
16
4
 
17
5
 
@@ -26,6 +14,12 @@ var _chunkVEEOQ7TScjs = require('../chunk-VEEOQ7TS.cjs');
26
14
 
27
15
 
28
16
  var _chunkCF5PWWTFcjs = require('../chunk-CF5PWWTF.cjs');
17
+
18
+
19
+ var _chunkG7JGTBTTcjs = require('../chunk-G7JGTBTT.cjs');
20
+
21
+
22
+ var _chunkMVGYPBYBcjs = require('../chunk-MVGYPBYB.cjs');
29
23
  require('../chunk-IBXAK2A4.cjs');
30
24
 
31
25
 
@@ -33,6 +27,12 @@ var _chunkOSZWDCTScjs = require('../chunk-OSZWDCTS.cjs');
33
27
 
34
28
 
35
29
  var _chunkU54FZCOHcjs = require('../chunk-U54FZCOH.cjs');
30
+
31
+
32
+ var _chunk32SMWYAFcjs = require('../chunk-32SMWYAF.cjs');
33
+
34
+
35
+ var _chunkL7NBJ4JAcjs = require('../chunk-L7NBJ4JA.cjs');
36
36
  require('../chunk-75ZPJI57.cjs');
37
37
 
38
38
 
@@ -1,15 +1,3 @@
1
- import {
2
- pathPrefix
3
- } from "../chunk-XLSZ5RB7.js";
4
- import {
5
- userAgentMatches
6
- } from "../chunk-S2AAATFN.js";
7
- import {
8
- headerContains
9
- } from "../chunk-SRQF5UEJ.js";
10
- import {
11
- headerEquals
12
- } from "../chunk-BZQJYOU2.js";
13
1
  import {
14
2
  hostnameIs
15
3
  } from "../chunk-3PVDUC5M.js";
@@ -26,6 +14,12 @@ import {
26
14
  import {
27
15
  pathMatches
28
16
  } from "../chunk-LO2BO3RU.js";
17
+ import {
18
+ pathPrefix
19
+ } from "../chunk-XLSZ5RB7.js";
20
+ import {
21
+ userAgentMatches
22
+ } from "../chunk-S2AAATFN.js";
29
23
  import "../chunk-2DE6WPPL.js";
30
24
  import {
31
25
  countryIs
@@ -33,6 +27,12 @@ import {
33
27
  import {
34
28
  fileExtension
35
29
  } from "../chunk-LBJUCJF2.js";
30
+ import {
31
+ headerContains
32
+ } from "../chunk-SRQF5UEJ.js";
33
+ import {
34
+ headerEquals
35
+ } from "../chunk-BZQJYOU2.js";
36
36
  import "../chunk-MLKGABMK.js";
37
37
  export {
38
38
  countryIs,
@@ -1,25 +1,26 @@
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');
7
7
 
8
8
 
9
- var _chunkT5EXFHVAcjs = require('../chunk-T5EXFHVA.cjs');
10
- require('../chunk-MVGYPBYB.cjs');
11
-
12
-
13
- var _chunkL7NBJ4JAcjs = require('../chunk-L7NBJ4JA.cjs');
9
+ var _chunkMO7HW25Rcjs = require('../chunk-MO7HW25R.cjs');
14
10
  require('../chunk-D47P7HVZ.cjs');
15
11
  require('../chunk-YVUR35RN.cjs');
16
12
  require('../chunk-OTFDML3K.cjs');
17
13
  require('../chunk-CF5PWWTF.cjs');
14
+ require('../chunk-MVGYPBYB.cjs');
18
15
  require('../chunk-IBXAK2A4.cjs');
19
16
 
20
17
 
18
+ var _chunkL7NBJ4JAcjs = require('../chunk-L7NBJ4JA.cjs');
19
+
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 = _chunkT5EXFHVAcjs.whitelist;
43
+ exports.preflightRequest = _chunk45SNLNLRcjs.preflightRequest; exports.sendCountryCode = _chunkLSCC62CZcjs.sendCountryCode; exports.stagingIndicator = stagingIndicator; exports.whitelist = _chunkMO7HW25Rcjs.whitelist;
@@ -1,25 +1,26 @@
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";
7
7
  import {
8
8
  whitelist
9
- } from "../chunk-RL7ZETZR.js";
10
- import "../chunk-S2AAATFN.js";
11
- import {
12
- headerEquals
13
- } from "../chunk-BZQJYOU2.js";
9
+ } from "../chunk-ER2YEZZO.js";
14
10
  import "../chunk-KW5YBTSD.js";
15
11
  import "../chunk-LNQPYKGG.js";
16
12
  import "../chunk-PY3JMRDG.js";
17
13
  import "../chunk-LO2BO3RU.js";
14
+ import "../chunk-S2AAATFN.js";
18
15
  import "../chunk-2DE6WPPL.js";
16
+ import {
17
+ headerEquals
18
+ } from "../chunk-BZQJYOU2.js";
19
19
  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
@@ -1,14 +1,14 @@
1
1
  "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
2
 
3
- var _chunkT5EXFHVAcjs = require('../chunk-T5EXFHVA.cjs');
4
- require('../chunk-MVGYPBYB.cjs');
3
+ var _chunkMO7HW25Rcjs = require('../chunk-MO7HW25R.cjs');
5
4
  require('../chunk-D47P7HVZ.cjs');
6
5
  require('../chunk-YVUR35RN.cjs');
7
6
  require('../chunk-CF5PWWTF.cjs');
7
+ require('../chunk-MVGYPBYB.cjs');
8
8
  require('../chunk-IBXAK2A4.cjs');
9
9
  require('../chunk-WWSRNCUP.cjs');
10
10
  require('../chunk-WKYMSRCD.cjs');
11
11
  require('../chunk-75ZPJI57.cjs');
12
12
 
13
13
 
14
- exports.whitelist = _chunkT5EXFHVAcjs.whitelist;
14
+ exports.whitelist = _chunkMO7HW25Rcjs.whitelist;
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  whitelist
3
- } from "../chunk-RL7ZETZR.js";
4
- import "../chunk-S2AAATFN.js";
3
+ } from "../chunk-ER2YEZZO.js";
5
4
  import "../chunk-KW5YBTSD.js";
6
5
  import "../chunk-LNQPYKGG.js";
7
6
  import "../chunk-LO2BO3RU.js";
7
+ import "../chunk-S2AAATFN.js";
8
8
  import "../chunk-2DE6WPPL.js";
9
9
  import "../chunk-DSSFFJWL.js";
10
10
  import "../chunk-Q4NP4C3B.js";
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.6.2",
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;
@@ -1,19 +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-security-headers.ts
2
- function setSecurityHeaders(options) {
3
- const hsts = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _ => _.hsts]), () => ( "max-age=31536000; includeSubDomains"));
4
- const xFrameOptions = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _2 => _2.xFrameOptions]), () => ( "SAMEORIGIN"));
5
- const xContentTypeOptions = _nullishCoalesce(_optionalChain([options, 'optionalAccess', _3 => _3.xContentTypeOptions]), () => ( "nosniff"));
6
- return (_request, response) => {
7
- return Object.assign({}, response, {
8
- headers: Object.assign({}, response.headers, {
9
- "strict-transport-security": { value: hsts },
10
- "x-frame-options": { value: xFrameOptions },
11
- "x-content-type-options": { value: xContentTypeOptions }
12
- })
13
- });
14
- };
15
- }
16
-
17
-
18
-
19
- exports.setSecurityHeaders = setSecurityHeaders;
@@ -1,19 +0,0 @@
1
- // src/behaviors/set-security-headers.ts
2
- function setSecurityHeaders(options) {
3
- const hsts = options?.hsts ?? "max-age=31536000; includeSubDomains";
4
- const xFrameOptions = options?.xFrameOptions ?? "SAMEORIGIN";
5
- const xContentTypeOptions = options?.xContentTypeOptions ?? "nosniff";
6
- return (_request, response) => {
7
- return Object.assign({}, response, {
8
- headers: Object.assign({}, response.headers, {
9
- "strict-transport-security": { value: hsts },
10
- "x-frame-options": { value: xFrameOptions },
11
- "x-content-type-options": { value: xContentTypeOptions }
12
- })
13
- });
14
- };
15
- }
16
-
17
- export {
18
- setSecurityHeaders
19
- };
@@ -1,12 +1,12 @@
1
- import {
2
- userAgentMatches
3
- } from "./chunk-S2AAATFN.js";
4
1
  import {
5
2
  ipCidr
6
3
  } from "./chunk-KW5YBTSD.js";
7
4
  import {
8
5
  pathMatches
9
6
  } from "./chunk-LO2BO3RU.js";
7
+ import {
8
+ userAgentMatches
9
+ } from "./chunk-S2AAATFN.js";
10
10
  import {
11
11
  redirect
12
12
  } from "./chunk-DSSFFJWL.js";