@kensio/yulin 1.20.17 → 1.21.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/dist/service/athena/engine/sim-athena-comparison-shims.d.ts +13 -0
- package/dist/service/athena/engine/sim-athena-comparison-shims.js +68 -0
- package/dist/service/athena/engine/sim-athena-shims.js +2 -0
- package/dist/service/cloudformation/resource/cfn/cloudfront/sim-cloudfront-cfn-value-adapter.js +8 -0
- package/dist/service/cloudformation/resource/cfn/cloudfront/sim-cloudfront-orp-cfn.d.ts +24 -0
- package/dist/service/cloudformation/resource/cfn/cloudfront/sim-cloudfront-orp-cfn.js +31 -0
- package/dist/service/cloudfront/behaviour/sim-cloud-front-behavior.d.ts +12 -1
- package/dist/service/cloudfront/cache/sim-cf-accept-encoding.d.ts +11 -0
- package/dist/service/cloudfront/cache/sim-cf-accept-encoding.js +27 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-control.d.ts +28 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-control.js +49 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-entry-key-path.d.ts +11 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-entry-key-path.js +22 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-entry-key.d.ts +32 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-entry-key.js +112 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-status.d.ts +27 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-status.js +53 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-ttl.d.ts +28 -0
- package/dist/service/cloudfront/cache/sim-cf-cache-ttl.js +50 -0
- package/dist/service/cloudfront/cache/sim-cf-cacheable-request.d.ts +35 -0
- package/dist/service/cloudfront/cache/sim-cf-cacheable-request.js +32 -0
- package/dist/service/cloudfront/cache/sim-cf-distribution-cache.d.ts +57 -0
- package/dist/service/cloudfront/cache/sim-cf-distribution-cache.js +115 -0
- package/dist/service/cloudfront/cache/sim-cf-edge.d.ts +37 -0
- package/dist/service/cloudfront/cache/sim-cf-edge.js +34 -0
- package/dist/service/cloudfront/cache/sim-cf-error-cache-ttl.d.ts +36 -0
- package/dist/service/cloudfront/cache/sim-cf-error-cache-ttl.js +28 -0
- package/dist/service/cloudfront/cache/sim-cf-http-date.d.ts +15 -0
- package/dist/service/cloudfront/cache/sim-cf-http-date.js +40 -0
- package/dist/service/cloudfront/cache-policy/sim-cf-cache-key.d.ts +63 -0
- package/dist/service/cloudfront/cache-policy/sim-cf-cache-key.js +70 -0
- package/dist/service/cloudfront/cache-policy/sim-cf-cache-policy.d.ts +13 -3
- package/dist/service/cloudfront/cache-policy/sim-cf-cache-policy.js +31 -3
- package/dist/service/cloudfront/cache-policy/sim-cf-managed-cache-policies.d.ts +8 -3
- package/dist/service/cloudfront/cache-policy/sim-cf-managed-cache-policies.js +96 -12
- package/dist/service/cloudfront/cff/sim-cff-search-distribution.fixture.js +4 -0
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-config.d.ts +9 -8
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-config.js +40 -11
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-key.d.ts +10 -0
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-key.js +50 -0
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-section.d.ts +28 -0
- package/dist/service/cloudfront/cfn/cache-policy/sim-cfn-cf-cache-policy-section.js +29 -0
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-behavior-policy-kinds.d.ts +16 -0
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-behavior-policy-kinds.js +23 -0
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-distro-behavior-policies.d.ts +3 -2
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-distro-behavior-policies.js +3 -2
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-distro-creator.d.ts +6 -6
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-distro-creator.js +6 -6
- package/dist/service/cloudfront/cfn/distro/sim-cfn-cf-distro-policy-drops.js +8 -23
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-config.d.ts +28 -0
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-config.js +46 -0
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-creator.d.ts +24 -0
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-creator.js +32 -0
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-forwarding.d.ts +10 -0
- package/dist/service/cloudfront/cfn/origin-request-policy/sim-cfn-cf-orp-forwarding.js +51 -0
- package/dist/service/cloudfront/cfn/policy/sim-cfn-cf-policy-section.d.ts +22 -0
- package/dist/service/cloudfront/cfn/policy/sim-cfn-cf-policy-section.js +54 -0
- package/dist/service/cloudfront/cfn/sim-cfn-cloudfront-resource-factory.d.ts +1 -0
- package/dist/service/cloudfront/cfn/sim-cfn-cloudfront-resource-factory.js +12 -0
- package/dist/service/cloudfront/command/create-distribution/create-distribution.command.d.ts +1 -0
- package/dist/service/cloudfront/command/create-distribution/create-distribution.handler.d.ts +2 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-create-invalidation.d.ts +28 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-create-invalidation.js +59 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-get-invalidation.d.ts +19 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-get-invalidation.js +32 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-access.d.ts +36 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-access.js +45 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-command.types.d.ts +80 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-command.types.js +1 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-commands.d.ts +39 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-invalidation-commands.js +35 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-list-invalidations.d.ts +23 -0
- package/dist/service/cloudfront/command/invalidation/sim-cf-list-invalidations.js +39 -0
- package/dist/service/cloudfront/command/update-distribution/update-distribution.handler.d.ts +2 -0
- package/dist/service/cloudfront/controller/content/sim-cf-content-stage.d.ts +51 -0
- package/dist/service/cloudfront/controller/content/sim-cf-content-stage.js +65 -0
- package/dist/service/cloudfront/controller/dependency/sim-cf-controller-dependency.d.ts +2 -3
- package/dist/service/cloudfront/controller/dependency/sim-cf-controller-dependency.js +4 -4
- package/dist/service/cloudfront/controller/error/sim-cf-custom-error-responder.d.ts +4 -0
- package/dist/service/cloudfront/controller/error/sim-cf-custom-error-responder.js +12 -8
- package/dist/service/cloudfront/controller/origin/sim-cf-origin-stage.d.ts +2 -2
- package/dist/service/cloudfront/controller/origin/sim-cf-origin-stage.js +2 -2
- package/dist/service/cloudfront/controller/sim-cloudfront-request-pipeline.d.ts +6 -6
- package/dist/service/cloudfront/controller/sim-cloudfront-request-pipeline.js +35 -20
- package/dist/service/cloudfront/custom-error/sim-cloudfront-custom-error-response.d.ts +23 -5
- package/dist/service/cloudfront/custom-error/sim-cloudfront-custom-error-response.js +8 -0
- package/dist/service/cloudfront/distribution/configurator/sim-cf-behavior-origin-request-policy.d.ts +18 -0
- package/dist/service/cloudfront/distribution/configurator/sim-cf-behavior-origin-request-policy.js +30 -0
- package/dist/service/cloudfront/distribution/configurator/sim-cf-behavior-policies.d.ts +7 -5
- package/dist/service/cloudfront/distribution/configurator/sim-cf-behavior-policies.js +8 -5
- package/dist/service/cloudfront/distribution/configurator/sim-cf-behavior-properties.js +4 -1
- package/dist/service/cloudfront/distribution/configurator/sim-cf-distribution-configurator.factory.d.ts +2 -0
- package/dist/service/cloudfront/distribution/configurator/sim-cf-distribution-configurator.factory.js +6 -2
- package/dist/service/cloudfront/distribution/configurator/sim-cloud-front-custom-error-configurator.d.ts +13 -3
- package/dist/service/cloudfront/distribution/configurator/sim-cloud-front-custom-error-configurator.js +27 -6
- package/dist/service/cloudfront/distribution/configurator/sim-cloud-front-origin-configurator.d.ts +3 -1
- package/dist/service/cloudfront/distribution/configurator/sim-cloud-front-origin-configurator.js +4 -1
- package/dist/service/cloudfront/distribution/sim-cf-distribution-configuration-state.d.ts +5 -3
- package/dist/service/cloudfront/distribution/sim-cf-distribution-reconfigurer.d.ts +2 -0
- package/dist/service/cloudfront/distribution/sim-cf-distribution-view.js +1 -1
- package/dist/service/cloudfront/distribution/sim-cloudfront-distribution.d.ts +25 -2
- package/dist/service/cloudfront/distribution/sim-cloudfront-distribution.js +24 -0
- package/dist/service/cloudfront/error/sim-cf-invalidation.error.d.ts +22 -0
- package/dist/service/cloudfront/error/sim-cf-invalidation.error.js +26 -0
- package/dist/service/cloudfront/error/sim-cf-origin-request-policy.error.d.ts +22 -0
- package/dist/service/cloudfront/error/sim-cf-origin-request-policy.error.js +26 -0
- package/dist/service/cloudfront/index.d.ts +2 -0
- package/dist/service/cloudfront/index.js +1 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation-path.d.ts +22 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation-path.js +32 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation-view.d.ts +43 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation-view.js +33 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation.d.ts +55 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidation.js +56 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidations.d.ts +41 -0
- package/dist/service/cloudfront/invalidation/sim-cf-invalidations.js +58 -0
- package/dist/service/cloudfront/invalidation/sim-cf-repeated-invalidation.d.ts +15 -0
- package/dist/service/cloudfront/invalidation/sim-cf-repeated-invalidation.js +23 -0
- package/dist/service/cloudfront/origin/custom/sim-cf-custom-origin-forwarding.d.ts +19 -0
- package/dist/service/cloudfront/origin/custom/sim-cf-custom-origin-forwarding.js +116 -0
- package/dist/service/cloudfront/origin/custom/sim-cf-custom-origin-request.d.ts +15 -5
- package/dist/service/cloudfront/origin/custom/sim-cf-custom-origin-request.js +13 -8
- package/dist/service/cloudfront/origin/custom/sim-cf-custom-origin-signer.js +8 -5
- package/dist/service/cloudfront/origin/custom/sim-cloudfront-custom-origin.d.ts +13 -0
- package/dist/service/cloudfront/origin/custom/sim-cloudfront-custom-origin.js +8 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-behavior-forwarded.d.ts +24 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-behavior-forwarded.js +21 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-forwarded-to-origin.d.ts +57 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-forwarded-to-origin.js +129 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-managed-origin-request-policies.d.ts +30 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-managed-origin-request-policies.js +121 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-forwarding.d.ts +56 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-forwarding.js +67 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-policy-registry.d.ts +38 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-policy-registry.js +51 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-policy.d.ts +32 -0
- package/dist/service/cloudfront/origin-request-policy/sim-cf-origin-request-policy.js +30 -0
- package/dist/service/cloudfront/registry/sim-cloud-front-registry.d.ts +25 -0
- package/dist/service/cloudfront/registry/sim-cloud-front-registry.js +23 -0
- package/dist/service/cloudfront/sdk/sim-cloudfront-sdk-command-router.js +12 -0
- package/dist/service/cloudfront/sim-cloudfront-caching.d.ts +31 -0
- package/dist/service/cloudfront/sim-cloudfront-caching.js +38 -0
- package/dist/service/cloudfront/sim-cloudfront-commands.d.ts +12 -0
- package/dist/service/cloudfront/sim-cloudfront-commands.js +12 -0
- package/dist/service/cloudfront/sim-cloudfront-distributions.d.ts +21 -0
- package/dist/service/cloudfront/sim-cloudfront-distributions.js +23 -0
- package/dist/service/cloudfront/sim-cloudfront-origin-access-controls.d.ts +30 -0
- package/dist/service/cloudfront/sim-cloudfront-origin-access-controls.js +35 -0
- package/dist/service/cloudfront/sim-cloudfront-policies.d.ts +22 -5
- package/dist/service/cloudfront/sim-cloudfront-policies.js +27 -5
- package/dist/service/cloudfront/sim-cloudfront.d.ts +15 -31
- package/dist/service/cloudfront/sim-cloudfront.js +23 -41
- package/dist/service/iam/authorize/allow/sim-iam-allow-requirement.d.ts +6 -5
- package/dist/service/iam/authorize/allow/sim-iam-allow-requirement.js +6 -5
- package/dist/service/iam/authorize/context/sim-iam-auth-z-input.d.ts +6 -4
- package/dist/service/kms/command/sim-kms-request-options.d.ts +9 -5
- package/dist/service/logs/command/delivery/sim-logs-delivery-source-commands.d.ts +6 -4
- package/dist/service/logs/command/delivery/sim-logs-delivery-source-commands.js +13 -4
- package/dist/service/logs/delivery/cloudfront/sim-logs-vended-log-delivery.d.ts +23 -0
- package/dist/service/logs/delivery/cloudfront/sim-logs-vended-log-delivery.js +28 -0
- package/dist/service/ssm/parameter/sim-ssm-kms-crypto.d.ts +7 -10
- package/dist/service/ssm/parameter/sim-ssm-parameter-kms.d.ts +10 -11
- package/dist/service/ssm/parameter/sim-ssm-parameter-kms.js +11 -16
- package/docs/services/athena/README.md +7 -1
- package/docs/services/cloudformation/README.md +2 -1
- package/docs/services/cloudfront/README.md +903 -25
- package/docs/services/ecs/README.md +5 -2
- package/docs/services/kms/README.md +9 -5
- package/docs/services/logs/README.md +6 -0
- package/docs/services/ssm/README.md +26 -33
- package/package.json +1 -1
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { DatabaseSync } from "node:sqlite";
|
|
2
|
+
/**
|
|
3
|
+
* Trino's `least` and `greatest`.
|
|
4
|
+
*
|
|
5
|
+
* SQLite carries both already, as the two argument and wider forms of `min`
|
|
6
|
+
* and `max`. A rewrite renaming the call would reach the same words written
|
|
7
|
+
* inside a string literal. SQLite resolves a shim by the name the statement
|
|
8
|
+
* wrote, and the ordering is done here.
|
|
9
|
+
*
|
|
10
|
+
* Trino answers null where any argument is null, and SQLite's own `min` and
|
|
11
|
+
* `max` answer the same way.
|
|
12
|
+
*/
|
|
13
|
+
export declare function simAthenaInstallComparisonShims(database: DatabaseSync): void;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { SimAthenaSetUpError } from "../error/sim-athena.error.js";
|
|
2
|
+
import { simAthenaScalarShim } from "./sim-athena-shim-registry.js";
|
|
3
|
+
/**
|
|
4
|
+
* Trino's `least` and `greatest`.
|
|
5
|
+
*
|
|
6
|
+
* SQLite carries both already, as the two argument and wider forms of `min`
|
|
7
|
+
* and `max`. A rewrite renaming the call would reach the same words written
|
|
8
|
+
* inside a string literal. SQLite resolves a shim by the name the statement
|
|
9
|
+
* wrote, and the ordering is done here.
|
|
10
|
+
*
|
|
11
|
+
* Trino answers null where any argument is null, and SQLite's own `min` and
|
|
12
|
+
* `max` answer the same way.
|
|
13
|
+
*/
|
|
14
|
+
export function simAthenaInstallComparisonShims(database) {
|
|
15
|
+
simAthenaScalarShim(database, "least", (...values) => extremeOf(values, -1));
|
|
16
|
+
simAthenaScalarShim(database, "greatest", (...values) => extremeOf(values, 1));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The argument at one end of the ordering, taking -1 for the low end.
|
|
20
|
+
*
|
|
21
|
+
* Trino takes two arguments at least. SQLite hands over whatever the call
|
|
22
|
+
* wrote, and a call carrying none of them answers null.
|
|
23
|
+
*/
|
|
24
|
+
function extremeOf(values, wanted) {
|
|
25
|
+
if (values.length === 0 || values.includes(null)) {
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
return values.reduce((held, value) => ordering(value, held) === wanted ? value : held);
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* How two arguments order, as -1, 0 or 1.
|
|
32
|
+
*
|
|
33
|
+
* Numbers order numerically and everything else orders by its text. SQLite's
|
|
34
|
+
* own `min` and `max` order the same pair the same way. Trino refuses a call
|
|
35
|
+
* mixing types. None of the shims here check types, and a mixed call is
|
|
36
|
+
* ordered as text.
|
|
37
|
+
*/
|
|
38
|
+
function ordering(one, other) {
|
|
39
|
+
if (isNumeric(one) && isNumeric(other)) {
|
|
40
|
+
return signOf(one < other, one > other);
|
|
41
|
+
}
|
|
42
|
+
const left = comparableText(one);
|
|
43
|
+
const right = comparableText(other);
|
|
44
|
+
return signOf(left < right, left > right);
|
|
45
|
+
}
|
|
46
|
+
/** One comparison read back as -1, 0 or 1. */
|
|
47
|
+
function signOf(below, above) {
|
|
48
|
+
if (below) {
|
|
49
|
+
return -1;
|
|
50
|
+
}
|
|
51
|
+
return above ? 1 : 0;
|
|
52
|
+
}
|
|
53
|
+
function isNumeric(value) {
|
|
54
|
+
return typeof value === "number" || typeof value === "bigint";
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* One argument as the text it orders by.
|
|
58
|
+
*
|
|
59
|
+
* A `varbinary` orders by its bytes in Trino, and nothing written out here
|
|
60
|
+
* orders the same way. A call over one raises and the query falls back to its
|
|
61
|
+
* declared result.
|
|
62
|
+
*/
|
|
63
|
+
function comparableText(value) {
|
|
64
|
+
if (value instanceof Uint8Array) {
|
|
65
|
+
throw new SimAthenaSetUpError("least and greatest take numbers or text rather than a varbinary");
|
|
66
|
+
}
|
|
67
|
+
return String(value);
|
|
68
|
+
}
|
|
@@ -2,6 +2,7 @@ import { simAthenaInstallAggregateShims } from "./sim-athena-aggregate-shims.js"
|
|
|
2
2
|
import { simAthenaInstallArrayShims } from "./sim-athena-array-shims.js";
|
|
3
3
|
import { simAthenaInstallBinaryShims } from "./sim-athena-binary-shims.js";
|
|
4
4
|
import { simAthenaInstallClockShims } from "./sim-athena-clock-shims.js";
|
|
5
|
+
import { simAthenaInstallComparisonShims } from "./sim-athena-comparison-shims.js";
|
|
5
6
|
import { simAthenaInstallDateArithmeticShims } from "./sim-athena-date-arithmetic-shims.js";
|
|
6
7
|
import { simAthenaInstallDateShims } from "./sim-athena-date-shims.js";
|
|
7
8
|
import { simAthenaInstallJsonDocumentShims } from "./sim-athena-json-document-shims.js";
|
|
@@ -29,4 +30,5 @@ export function simAthenaInstallShims(database, startedAt) {
|
|
|
29
30
|
simAthenaInstallRegexpShims(database);
|
|
30
31
|
simAthenaInstallUrlShims(database);
|
|
31
32
|
simAthenaInstallAggregateShims(database);
|
|
33
|
+
simAthenaInstallComparisonShims(database);
|
|
32
34
|
}
|
package/dist/service/cloudformation/resource/cfn/cloudfront/sim-cloudfront-cfn-value-adapter.js
CHANGED
|
@@ -6,6 +6,8 @@ import { SimCloudFrontResponseHeadersPolicy } from "../../../../cloudfront/respo
|
|
|
6
6
|
import { SimCloudFrontResponseHeadersPolicyCfn } from "./sim-cloudfront-rh-policy-cfn.js";
|
|
7
7
|
import { SimCloudFrontCachePolicy } from "../../../../cloudfront/cache-policy/sim-cf-cache-policy.js";
|
|
8
8
|
import { SimCloudFrontCachePolicyCfn } from "./sim-cloudfront-cache-policy-cfn.js";
|
|
9
|
+
import { SimCloudFrontOriginRequestPolicy } from "../../../../cloudfront/origin-request-policy/sim-cf-origin-request-policy.js";
|
|
10
|
+
import { SimCloudFrontOriginRequestPolicyCfn } from "./sim-cloudfront-orp-cfn.js";
|
|
9
11
|
import { SimCloudFrontOriginAccessControl } from "../../../../cloudfront/origin-access-control/sim-cf-origin-access-control.js";
|
|
10
12
|
import { SimCloudFrontOriginAccessControlCfn } from "./sim-cloudfront-oac-cfn.js";
|
|
11
13
|
import { SimCloudFrontKeyValueStore } from "../../../../cloudfront/key-value-store/sim-cf-key-value-store.js";
|
|
@@ -36,6 +38,12 @@ export function cloudFrontValueAdapter(properties) {
|
|
|
36
38
|
policy: properties.simResource,
|
|
37
39
|
});
|
|
38
40
|
}
|
|
41
|
+
if (properties.type === "AWS::CloudFront::OriginRequestPolicy" &&
|
|
42
|
+
properties.simResource instanceof SimCloudFrontOriginRequestPolicy) {
|
|
43
|
+
return new SimCloudFrontOriginRequestPolicyCfn({
|
|
44
|
+
policy: properties.simResource,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
39
47
|
if (properties.type === "AWS::CloudFront::OriginAccessControl" &&
|
|
40
48
|
properties.simResource instanceof SimCloudFrontOriginAccessControl) {
|
|
41
49
|
return new SimCloudFrontOriginAccessControlCfn({
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { SimCfnTemplateValue } from "../../../template/value/sim-cfn-template-value.js";
|
|
2
|
+
import type { SimCloudFrontOriginRequestPolicy } from "../../../../cloudfront/origin-request-policy/sim-cf-origin-request-policy.js";
|
|
3
|
+
import type { SimCfnResourceValueAdapter } from "../sim-cfn-resource-value-adapter.js";
|
|
4
|
+
interface SimCloudFrontOriginRequestPolicyCfnProperties {
|
|
5
|
+
readonly policy: SimCloudFrontOriginRequestPolicy;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* CloudFormation-facing behavior for an AWS::CloudFront::OriginRequestPolicy
|
|
9
|
+
* Resource.
|
|
10
|
+
*/
|
|
11
|
+
export declare class SimCloudFrontOriginRequestPolicyCfn implements SimCfnResourceValueAdapter {
|
|
12
|
+
private readonly policy;
|
|
13
|
+
constructor(properties: SimCloudFrontOriginRequestPolicyCfnProperties);
|
|
14
|
+
/**
|
|
15
|
+
* CloudFormation Ref for AWS::CloudFront::OriginRequestPolicy returns the
|
|
16
|
+
* policy ID, which is what a Cache Behavior's OriginRequestPolicyId wants.
|
|
17
|
+
*/
|
|
18
|
+
refValue(): SimCfnTemplateValue;
|
|
19
|
+
/**
|
|
20
|
+
* CloudFormation attributes for AWS::CloudFront::OriginRequestPolicy.
|
|
21
|
+
*/
|
|
22
|
+
attributeValue(attributeName: string): SimCfnTemplateValue;
|
|
23
|
+
}
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CloudFormation-facing behavior for an AWS::CloudFront::OriginRequestPolicy
|
|
3
|
+
* Resource.
|
|
4
|
+
*/
|
|
5
|
+
export class SimCloudFrontOriginRequestPolicyCfn {
|
|
6
|
+
policy;
|
|
7
|
+
constructor(properties) {
|
|
8
|
+
this.policy = properties.policy;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* CloudFormation Ref for AWS::CloudFront::OriginRequestPolicy returns the
|
|
12
|
+
* policy ID, which is what a Cache Behavior's OriginRequestPolicyId wants.
|
|
13
|
+
*/
|
|
14
|
+
refValue() {
|
|
15
|
+
return this.policy.id;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* CloudFormation attributes for AWS::CloudFront::OriginRequestPolicy.
|
|
19
|
+
*/
|
|
20
|
+
attributeValue(attributeName) {
|
|
21
|
+
switch (attributeName) {
|
|
22
|
+
case "Id": {
|
|
23
|
+
return this.policy.id;
|
|
24
|
+
}
|
|
25
|
+
default: {
|
|
26
|
+
/* v8 ignore next */
|
|
27
|
+
return `${this.policy.id}.${attributeName}`;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
@@ -5,6 +5,10 @@ export interface SimCloudFrontBehavior {
|
|
|
5
5
|
pathPattern?: string;
|
|
6
6
|
targetOriginName: string;
|
|
7
7
|
allowedMethods: Set<string>;
|
|
8
|
+
/**
|
|
9
|
+
* The methods this Behavior caches a response for. A request made with any
|
|
10
|
+
* other method reaches the Origin every time.
|
|
11
|
+
*/
|
|
8
12
|
cachedMethods: Set<string>;
|
|
9
13
|
viewerProtocolPolicy?: "allow-all" | "redirect-to-https" | "https-only";
|
|
10
14
|
originPath?: string;
|
|
@@ -14,9 +18,16 @@ export interface SimCloudFrontBehavior {
|
|
|
14
18
|
responseHeadersPolicyId?: string | undefined;
|
|
15
19
|
/**
|
|
16
20
|
* The cache policy this Behavior was given, whether a template created it or
|
|
17
|
-
* AWS manages it.
|
|
21
|
+
* AWS manages it. It decides what the Distribution's cache keys on, and a
|
|
22
|
+
* Behavior naming no policy this simulation holds caches nothing.
|
|
18
23
|
*/
|
|
19
24
|
cachePolicyId?: string | undefined;
|
|
25
|
+
/**
|
|
26
|
+
* The origin request policy this Behavior was given, whether a template
|
|
27
|
+
* created it or AWS manages it. What reaches the Origin does not read it
|
|
28
|
+
* yet.
|
|
29
|
+
*/
|
|
30
|
+
originRequestPolicyId?: string | undefined;
|
|
20
31
|
functionAssociations?: undefined | {
|
|
21
32
|
viewerRequest?: SimArn;
|
|
22
33
|
viewerResponse?: SimArn;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { SimCloudFrontCacheKey } from "../cache-policy/sim-cf-cache-key.js";
|
|
2
|
+
/**
|
|
3
|
+
* The compression the policy keys on, as CloudFront's normalized
|
|
4
|
+
* `Accept-Encoding`.
|
|
5
|
+
*
|
|
6
|
+
* This is what caches one object twice, once compressed and once not, without
|
|
7
|
+
* the header being in the policy's whitelist. An encoding the viewer accepts
|
|
8
|
+
* but the policy does not enable is left out, since CloudFront would not have
|
|
9
|
+
* asked the Origin for it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function simCfNormalizedAcceptEncoding(headers: Headers, cacheKey: SimCloudFrontCacheKey): string[];
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The compression the policy keys on, as CloudFront's normalized
|
|
3
|
+
* `Accept-Encoding`.
|
|
4
|
+
*
|
|
5
|
+
* This is what caches one object twice, once compressed and once not, without
|
|
6
|
+
* the header being in the policy's whitelist. An encoding the viewer accepts
|
|
7
|
+
* but the policy does not enable is left out, since CloudFront would not have
|
|
8
|
+
* asked the Origin for it.
|
|
9
|
+
*/
|
|
10
|
+
export function simCfNormalizedAcceptEncoding(headers, cacheKey) {
|
|
11
|
+
const enabled = [
|
|
12
|
+
...(cacheKey.enableAcceptEncodingBrotli ? ["br"] : []),
|
|
13
|
+
...(cacheKey.enableAcceptEncodingGzip ? ["gzip"] : []),
|
|
14
|
+
];
|
|
15
|
+
const accepted = acceptedEncodings(headers.get("accept-encoding"));
|
|
16
|
+
return enabled.filter((encoding) => accepted.has(encoding));
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* The encodings a viewer said it accepts, by name alone. A quality value is
|
|
20
|
+
* ignored, so a viewer that sent `gzip;q=0` is taken to accept gzip.
|
|
21
|
+
*/
|
|
22
|
+
function acceptedEncodings(headerValue) {
|
|
23
|
+
return new Set((headerValue ?? "").split(",").map((encoding) => {
|
|
24
|
+
const [name = ""] = encoding.split(";", 1);
|
|
25
|
+
return name.trim().toLowerCase();
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What an Origin's `Cache-Control` header says about holding the object at an
|
|
3
|
+
* edge.
|
|
4
|
+
*
|
|
5
|
+
* Only the directives that move CloudFront's own cache duration are read.
|
|
6
|
+
* `stale-while-revalidate` and `stale-if-error` are left out, because serving
|
|
7
|
+
* a stale object is a behaviour of its own that this simulation does not have.
|
|
8
|
+
*
|
|
9
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html
|
|
10
|
+
*/
|
|
11
|
+
export interface SimCfCacheControl {
|
|
12
|
+
/**
|
|
13
|
+
* Whether the Origin asked for the object to stay out of a shared cache,
|
|
14
|
+
* through `no-store`, `no-cache` or `private`.
|
|
15
|
+
*/
|
|
16
|
+
readonly uncacheable: boolean;
|
|
17
|
+
/** The seconds `s-maxage` names, where it names a usable number of them. */
|
|
18
|
+
readonly sharedMaxAgeSec: number | undefined;
|
|
19
|
+
/** The seconds `max-age` names, where it names a usable number of them. */
|
|
20
|
+
readonly maxAgeSec: number | undefined;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Read the `Cache-Control` directives a response carries.
|
|
24
|
+
*
|
|
25
|
+
* A directive naming something other than a whole number of seconds is read as
|
|
26
|
+
* absent. `max-age=soon` falls through to whatever the response says next.
|
|
27
|
+
*/
|
|
28
|
+
export declare function simCfCacheControl(header: string | null): SimCfCacheControl;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The three directives CloudFront and a browser both respect as a refusal.
|
|
3
|
+
*/
|
|
4
|
+
const uncacheableDirectives = ["no-store", "no-cache", "private"];
|
|
5
|
+
/**
|
|
6
|
+
* Read the `Cache-Control` directives a response carries.
|
|
7
|
+
*
|
|
8
|
+
* A directive naming something other than a whole number of seconds is read as
|
|
9
|
+
* absent. `max-age=soon` falls through to whatever the response says next.
|
|
10
|
+
*/
|
|
11
|
+
export function simCfCacheControl(header) {
|
|
12
|
+
const directives = cacheControlDirectives(header);
|
|
13
|
+
return {
|
|
14
|
+
uncacheable: uncacheableDirectives.some((directive) => directives.has(directive)),
|
|
15
|
+
sharedMaxAgeSec: directiveSeconds(directives.get("s-maxage")),
|
|
16
|
+
maxAgeSec: directiveSeconds(directives.get("max-age")),
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Split a header into its directives, by lower-cased name.
|
|
21
|
+
*
|
|
22
|
+
* A directive carrying no value is held under an empty string, which is what
|
|
23
|
+
* makes `no-store` findable the same way as `max-age=60`.
|
|
24
|
+
*/
|
|
25
|
+
function cacheControlDirectives(header) {
|
|
26
|
+
const directives = new Map();
|
|
27
|
+
const parts = (header ?? "").split(",");
|
|
28
|
+
for (const part of parts) {
|
|
29
|
+
const trimmed = part.trim();
|
|
30
|
+
if (trimmed.length === 0) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const separator = trimmed.indexOf("=");
|
|
34
|
+
const name = separator === -1 ? trimmed : trimmed.slice(0, Math.max(0, separator));
|
|
35
|
+
directives.set(name.trim().toLowerCase(), separator === -1 ? "" : trimmed.slice(separator + 1).trim());
|
|
36
|
+
}
|
|
37
|
+
return directives;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* The seconds a directive's value names, or none where it names no whole
|
|
41
|
+
* number of them.
|
|
42
|
+
*/
|
|
43
|
+
function directiveSeconds(value) {
|
|
44
|
+
if (value === undefined) {
|
|
45
|
+
return undefined;
|
|
46
|
+
}
|
|
47
|
+
const seconds = value.replace(/^"(.*)"$/, "$1");
|
|
48
|
+
return /^\d+$/.test(seconds) ? Number(seconds) : undefined;
|
|
49
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The request path one cache entry was keyed under.
|
|
3
|
+
*
|
|
4
|
+
* `simCfCacheEntryKey` builds the key as a JSON array with the path third in
|
|
5
|
+
* it, and this reads that element back out. An invalidation matches entries by
|
|
6
|
+
* path this way, and the cache keeps its one map keyed on the whole key.
|
|
7
|
+
*
|
|
8
|
+
* A key of another shape answers with nothing. An invalidation then leaves the
|
|
9
|
+
* entry where it is.
|
|
10
|
+
*/
|
|
11
|
+
export declare function simCfCacheEntryKeyPath(key: string): string | undefined;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Where the request path sits in a cache entry key.
|
|
3
|
+
*/
|
|
4
|
+
const cacheEntryKeyPathIndex = 2;
|
|
5
|
+
/**
|
|
6
|
+
* The request path one cache entry was keyed under.
|
|
7
|
+
*
|
|
8
|
+
* `simCfCacheEntryKey` builds the key as a JSON array with the path third in
|
|
9
|
+
* it, and this reads that element back out. An invalidation matches entries by
|
|
10
|
+
* path this way, and the cache keeps its one map keyed on the whole key.
|
|
11
|
+
*
|
|
12
|
+
* A key of another shape answers with nothing. An invalidation then leaves the
|
|
13
|
+
* entry where it is.
|
|
14
|
+
*/
|
|
15
|
+
export function simCfCacheEntryKeyPath(key) {
|
|
16
|
+
const parts = JSON.parse(key);
|
|
17
|
+
if (!Array.isArray(parts)) {
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
const path = parts.at(cacheEntryKeyPathIndex);
|
|
21
|
+
return typeof path === "string" ? path : undefined;
|
|
22
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { SimCloudFrontCacheKey } from "../cache-policy/sim-cf-cache-key.js";
|
|
2
|
+
interface SimCfCacheEntryKeyProperties {
|
|
3
|
+
readonly request: Request;
|
|
4
|
+
/**
|
|
5
|
+
* What the Behavior's cache policy keys on.
|
|
6
|
+
*/
|
|
7
|
+
readonly cacheKey: SimCloudFrontCacheKey;
|
|
8
|
+
/**
|
|
9
|
+
* The edge the request arrived at, which caches apart from every other edge.
|
|
10
|
+
*/
|
|
11
|
+
readonly edgeId: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The key one request is cached under.
|
|
15
|
+
*
|
|
16
|
+
* CloudFront keys on the request path plus whatever the cache policy names:
|
|
17
|
+
* the query strings, the headers and the cookies it lists, and the normalized
|
|
18
|
+
* `Accept-Encoding` where it enables gzip or brotli. Two requests differing
|
|
19
|
+
* only in something the policy leaves out share one entry, which is the whole
|
|
20
|
+
* point of a cache key.
|
|
21
|
+
*
|
|
22
|
+
* The path sits third in the key, which `simCfCacheEntryKeyPath` reads it back
|
|
23
|
+
* out of when an invalidation matches an entry.
|
|
24
|
+
*
|
|
25
|
+
* The method is part of the key here because a HEAD response carries no body
|
|
26
|
+
* and a GET response does, so serving one from the other would answer with the
|
|
27
|
+
* wrong thing.
|
|
28
|
+
*
|
|
29
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/understanding-the-cache-key.html
|
|
30
|
+
*/
|
|
31
|
+
export declare function simCfCacheEntryKey(properties: SimCfCacheEntryKeyProperties): string;
|
|
32
|
+
export {};
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { jsonStringify } from "../../../util/type-guard/json.js";
|
|
2
|
+
import { simCfNormalizedAcceptEncoding } from "./sim-cf-accept-encoding.js";
|
|
3
|
+
/**
|
|
4
|
+
* The key one request is cached under.
|
|
5
|
+
*
|
|
6
|
+
* CloudFront keys on the request path plus whatever the cache policy names:
|
|
7
|
+
* the query strings, the headers and the cookies it lists, and the normalized
|
|
8
|
+
* `Accept-Encoding` where it enables gzip or brotli. Two requests differing
|
|
9
|
+
* only in something the policy leaves out share one entry, which is the whole
|
|
10
|
+
* point of a cache key.
|
|
11
|
+
*
|
|
12
|
+
* The path sits third in the key, which `simCfCacheEntryKeyPath` reads it back
|
|
13
|
+
* out of when an invalidation matches an entry.
|
|
14
|
+
*
|
|
15
|
+
* The method is part of the key here because a HEAD response carries no body
|
|
16
|
+
* and a GET response does, so serving one from the other would answer with the
|
|
17
|
+
* wrong thing.
|
|
18
|
+
*
|
|
19
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/understanding-the-cache-key.html
|
|
20
|
+
*/
|
|
21
|
+
export function simCfCacheEntryKey(properties) {
|
|
22
|
+
const { request, cacheKey, edgeId } = properties;
|
|
23
|
+
const url = new URL(request.url);
|
|
24
|
+
return jsonStringify([
|
|
25
|
+
edgeId,
|
|
26
|
+
request.method.toUpperCase(),
|
|
27
|
+
url.pathname,
|
|
28
|
+
keyedQueryStrings(url.searchParams, cacheKey),
|
|
29
|
+
keyedHeaders(request.headers, cacheKey),
|
|
30
|
+
keyedCookies(request.headers, cacheKey),
|
|
31
|
+
simCfNormalizedAcceptEncoding(request.headers, cacheKey),
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The query strings the policy keys on, in an order two requests sending them
|
|
36
|
+
* differently still agree on.
|
|
37
|
+
*/
|
|
38
|
+
function keyedQueryStrings(searchParameters, cacheKey) {
|
|
39
|
+
return [...searchParameters]
|
|
40
|
+
.filter(([name]) => isKeyedOn(cacheKey.queryStringBehavior, cacheKey.queryStrings, name))
|
|
41
|
+
.map(([name, value]) => `${name}=${value}`)
|
|
42
|
+
.toSorted(byCodePoint);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* The headers the policy keys on, by lower-case name since a header name is
|
|
46
|
+
* case insensitive.
|
|
47
|
+
*
|
|
48
|
+
* A header the policy names and the viewer did not send keys as an empty
|
|
49
|
+
* value, so a request sending it and one leaving it out are kept apart.
|
|
50
|
+
*/
|
|
51
|
+
function keyedHeaders(headers, cacheKey) {
|
|
52
|
+
if (cacheKey.headerBehavior === "none") {
|
|
53
|
+
return [];
|
|
54
|
+
}
|
|
55
|
+
return cacheKey.headers
|
|
56
|
+
.map((name) => `${name.toLowerCase()}=${headers.get(name) ?? ""}`)
|
|
57
|
+
.toSorted(byCodePoint);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The cookies the policy keys on, read out of the one `Cookie` header a
|
|
61
|
+
* request sends them all in.
|
|
62
|
+
*/
|
|
63
|
+
function keyedCookies(headers, cacheKey) {
|
|
64
|
+
return (headers.get("cookie") ?? "")
|
|
65
|
+
.split(";")
|
|
66
|
+
.map((cookie) => cookie.trim())
|
|
67
|
+
.filter((cookie) => cookie.length > 0)
|
|
68
|
+
.filter((cookie) => isKeyedOn(cacheKey.cookieBehavior, cacheKey.cookies, cookieName(cookie)))
|
|
69
|
+
.toSorted(byCodePoint);
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Order two parts of a key the same way whatever the host's locale is, which a
|
|
73
|
+
* key two requests have to agree on cannot be left to `localeCompare`.
|
|
74
|
+
*/
|
|
75
|
+
function byCodePoint(one, other) {
|
|
76
|
+
if (one === other) {
|
|
77
|
+
return 0;
|
|
78
|
+
}
|
|
79
|
+
return one < other ? -1 : 1;
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The name half of one `name=value` cookie.
|
|
83
|
+
*/
|
|
84
|
+
function cookieName(cookie) {
|
|
85
|
+
const [name = ""] = cookie.split("=", 1);
|
|
86
|
+
return name;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Whether one name is in the cache key, under the behaviour its section names.
|
|
90
|
+
*
|
|
91
|
+
* A `whitelist` keys on the names listed and an `allExcept` keys on everything
|
|
92
|
+
* but them, which is the same list read two ways.
|
|
93
|
+
*
|
|
94
|
+
* The cookie behaviours and the query string behaviours are the same four
|
|
95
|
+
* values, so one function reads both.
|
|
96
|
+
*/
|
|
97
|
+
function isKeyedOn(behavior, names, name) {
|
|
98
|
+
switch (behavior) {
|
|
99
|
+
case "all": {
|
|
100
|
+
return true;
|
|
101
|
+
}
|
|
102
|
+
case "whitelist": {
|
|
103
|
+
return names.includes(name);
|
|
104
|
+
}
|
|
105
|
+
case "allExcept": {
|
|
106
|
+
return !names.includes(name);
|
|
107
|
+
}
|
|
108
|
+
case "none": {
|
|
109
|
+
return false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The header a hit carries its age in, in seconds.
|
|
3
|
+
*/
|
|
4
|
+
export declare const simCfAgeHeaderName = "age";
|
|
5
|
+
/**
|
|
6
|
+
* What `X-Cache` reads when the Distribution's cache answered.
|
|
7
|
+
*/
|
|
8
|
+
export declare const simCfCacheHit = "Hit from cloudfront";
|
|
9
|
+
/**
|
|
10
|
+
* What `X-Cache` reads when the Origin answered.
|
|
11
|
+
*/
|
|
12
|
+
export declare const simCfCacheMiss = "Miss from cloudfront";
|
|
13
|
+
/**
|
|
14
|
+
* The response with `X-Cache` saying which of the two answered it.
|
|
15
|
+
*
|
|
16
|
+
* An `X-Cache` an Origin sent is replaced, the way CloudFront replaces one.
|
|
17
|
+
*/
|
|
18
|
+
export declare function simCfCacheStatusResponse(response: Response, hit: boolean): Response;
|
|
19
|
+
/**
|
|
20
|
+
* How long an entry stored at one instant has been held at another, in whole
|
|
21
|
+
* seconds.
|
|
22
|
+
*
|
|
23
|
+
* Both instants come off the simulation's clock. A test reaches any age it
|
|
24
|
+
* wants by advancing simulated time. A clock wound backwards would give a
|
|
25
|
+
* negative age, and HTTP has no such thing, so zero is the floor.
|
|
26
|
+
*/
|
|
27
|
+
export declare function simCfCacheAgeSec(storedAt: Date, now: Date): number;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What CloudFront tells the viewer about the cache that answered.
|
|
3
|
+
*
|
|
4
|
+
* `X-Cache` says whether the Distribution held the object, and `Age` says how
|
|
5
|
+
* long it has held it. Both go on ahead of the Behavior's response headers
|
|
6
|
+
* policy and the viewer-response event. A policy can take either off, and a
|
|
7
|
+
* viewer-response function sees them.
|
|
8
|
+
*
|
|
9
|
+
* Real CloudFront writes several other values into `X-Cache` (`RefreshHit` and
|
|
10
|
+
* `LambdaGeneratedResponse` among them). A hit and a miss are the two this
|
|
11
|
+
* simulation reaches, and a response answered before the cache was consulted
|
|
12
|
+
* carries no `X-Cache` at all.
|
|
13
|
+
*
|
|
14
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/RequestAndResponseBehaviorCustomOrigin.html
|
|
15
|
+
*/
|
|
16
|
+
const xCacheHeaderName = "x-cache";
|
|
17
|
+
/**
|
|
18
|
+
* The header a hit carries its age in, in seconds.
|
|
19
|
+
*/
|
|
20
|
+
export const simCfAgeHeaderName = "age";
|
|
21
|
+
/**
|
|
22
|
+
* What `X-Cache` reads when the Distribution's cache answered.
|
|
23
|
+
*/
|
|
24
|
+
export const simCfCacheHit = "Hit from cloudfront";
|
|
25
|
+
/**
|
|
26
|
+
* What `X-Cache` reads when the Origin answered.
|
|
27
|
+
*/
|
|
28
|
+
export const simCfCacheMiss = "Miss from cloudfront";
|
|
29
|
+
/**
|
|
30
|
+
* The response with `X-Cache` saying which of the two answered it.
|
|
31
|
+
*
|
|
32
|
+
* An `X-Cache` an Origin sent is replaced, the way CloudFront replaces one.
|
|
33
|
+
*/
|
|
34
|
+
export function simCfCacheStatusResponse(response, hit) {
|
|
35
|
+
const headers = new Headers(response.headers);
|
|
36
|
+
headers.set(xCacheHeaderName, hit ? simCfCacheHit : simCfCacheMiss);
|
|
37
|
+
return new Response(response.body, {
|
|
38
|
+
status: response.status,
|
|
39
|
+
statusText: response.statusText,
|
|
40
|
+
headers,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* How long an entry stored at one instant has been held at another, in whole
|
|
45
|
+
* seconds.
|
|
46
|
+
*
|
|
47
|
+
* Both instants come off the simulation's clock. A test reaches any age it
|
|
48
|
+
* wants by advancing simulated time. A clock wound backwards would give a
|
|
49
|
+
* negative age, and HTTP has no such thing, so zero is the floor.
|
|
50
|
+
*/
|
|
51
|
+
export function simCfCacheAgeSec(storedAt, now) {
|
|
52
|
+
return Math.max(0, Math.floor((now.getTime() - storedAt.getTime()) / 1000));
|
|
53
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { SimCloudFrontCachePolicy } from "../cache-policy/sim-cf-cache-policy.js";
|
|
2
|
+
interface SimCfCacheTtlProperties {
|
|
3
|
+
/** The response the Origin answered with, whose headers carry the ask. */
|
|
4
|
+
readonly response: Response;
|
|
5
|
+
/** The Behavior's cache policy, whose three TTLs decide the answer. */
|
|
6
|
+
readonly policy: SimCloudFrontCachePolicy;
|
|
7
|
+
/** Now, off the simulation's clock, which `Expires` is measured from. */
|
|
8
|
+
readonly now: Date;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* How many seconds a Distribution holds this response for. Zero says it holds
|
|
12
|
+
* it not at all.
|
|
13
|
+
*
|
|
14
|
+
* The Origin asks and the policy decides how much of the ask to grant. An
|
|
15
|
+
* Origin naming a duration gets it held between the policy's `MinTTL` and
|
|
16
|
+
* `MaxTTL`, and one naming none gets the greater of `MinTTL` and `DefaultTTL`.
|
|
17
|
+
* `s-maxage` is preferred to `max-age`, and `max-age` to `Expires`, which is
|
|
18
|
+
* the order CloudFront reads them in.
|
|
19
|
+
*
|
|
20
|
+
* `no-store`, `no-cache` and `private` are respected where `MinTTL` is 0, and
|
|
21
|
+
* held for `MinTTL` where it is higher. That last one is CloudFront's own
|
|
22
|
+
* surprise. A policy with a floor overrides an Origin that asked for nothing to
|
|
23
|
+
* be stored.
|
|
24
|
+
*
|
|
25
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html
|
|
26
|
+
*/
|
|
27
|
+
export declare function simCfCacheTtlSec(properties: SimCfCacheTtlProperties): number;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { simCfCacheControl } from "./sim-cf-cache-control.js";
|
|
2
|
+
import { simCfHttpDateInstant } from "./sim-cf-http-date.js";
|
|
3
|
+
/**
|
|
4
|
+
* How many seconds a Distribution holds this response for. Zero says it holds
|
|
5
|
+
* it not at all.
|
|
6
|
+
*
|
|
7
|
+
* The Origin asks and the policy decides how much of the ask to grant. An
|
|
8
|
+
* Origin naming a duration gets it held between the policy's `MinTTL` and
|
|
9
|
+
* `MaxTTL`, and one naming none gets the greater of `MinTTL` and `DefaultTTL`.
|
|
10
|
+
* `s-maxage` is preferred to `max-age`, and `max-age` to `Expires`, which is
|
|
11
|
+
* the order CloudFront reads them in.
|
|
12
|
+
*
|
|
13
|
+
* `no-store`, `no-cache` and `private` are respected where `MinTTL` is 0, and
|
|
14
|
+
* held for `MinTTL` where it is higher. That last one is CloudFront's own
|
|
15
|
+
* surprise. A policy with a floor overrides an Origin that asked for nothing to
|
|
16
|
+
* be stored.
|
|
17
|
+
*
|
|
18
|
+
* https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Expiration.html
|
|
19
|
+
*/
|
|
20
|
+
export function simCfCacheTtlSec(properties) {
|
|
21
|
+
const { response, policy, now } = properties;
|
|
22
|
+
const control = simCfCacheControl(response.headers.get("cache-control"));
|
|
23
|
+
if (control.uncacheable) {
|
|
24
|
+
return policy.minTtlSec;
|
|
25
|
+
}
|
|
26
|
+
const asked = control.sharedMaxAgeSec ??
|
|
27
|
+
control.maxAgeSec ??
|
|
28
|
+
expiresTtlSec(response, now);
|
|
29
|
+
if (asked === undefined) {
|
|
30
|
+
return Math.max(policy.minTtlSec, policy.defaultTtlSec);
|
|
31
|
+
}
|
|
32
|
+
return Math.min(Math.max(asked, policy.minTtlSec), policy.maxTtlSec);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* The seconds left until the `Expires` header's instant, or none where the
|
|
36
|
+
* response carries no such header.
|
|
37
|
+
*
|
|
38
|
+
* A date already gone by counts as no seconds, which the policy's `MinTTL`
|
|
39
|
+
* then raises where it has one. A value that is not an HTTP date counts the
|
|
40
|
+
* same way, following RFC 9111, which reads an unparsable `Expires` as an
|
|
41
|
+
* object that has already expired.
|
|
42
|
+
*/
|
|
43
|
+
function expiresTtlSec(response, now) {
|
|
44
|
+
const expires = response.headers.get("expires");
|
|
45
|
+
if (expires === null) {
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
const instant = simCfHttpDateInstant(expires.trim());
|
|
49
|
+
return instant === undefined ? 0 : (instant - now.getTime()) / 1000;
|
|
50
|
+
}
|