@reventlessdev/reventless-aws 3.0.0-alpha.258 → 3.0.0-alpha.260
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/CHANGELOG.md +20 -0
- package/package.json +8 -8
- package/src/Platform.res +79 -4
- package/src/Platform.res.mjs +24 -8
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Backend.res +77 -0
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Backend.res.mjs +87 -0
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res +42 -36
- package/src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res.mjs +24 -6
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +20 -0
- package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +7 -0
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res +3 -16
- package/src/adapter/Runtime/RuntimeEnvironment_Lambda.res.mjs +4 -19
- package/src/components/OutboundTranslationSlice_Builder.res +2 -2
- package/src/components/OutboundTranslationSlice_Builder.res.mjs +3 -2
- package/src/plugin/runtime/PluginRuntime_Builder.res +31 -0
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +13 -0
- package/src/util/Util_DcbMetrics.res +48 -0
- package/src/util/Util_DcbMetrics.res.mjs +37 -0
- package/src/util/Util_ShellConfig.res +72 -0
- package/src/util/Util_ShellConfig.res.mjs +60 -0
- package/tests/Geocoder_AwsLocation_OpsTest.res +78 -0
- package/tests/Geocoder_AwsLocation_OpsTest.res.mjs +71 -0
- package/tests/Util_DcbMetricsTest.res +35 -0
- package/tests/Util_DcbMetricsTest.res.mjs +29 -0
- package/tests/Util_ShellConfigTest.res +78 -0
- package/tests/Util_ShellConfigTest.res.mjs +113 -0
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Stdlib_Dict from "@rescript/runtime/lib/es6/Stdlib_Dict.js";
|
|
4
|
+
import * as Geocoder_AwsLocation_Ops$ReventlessAws from "../src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res.mjs";
|
|
5
|
+
|
|
6
|
+
function setIndex(v) {
|
|
7
|
+
process.env["PLACE_INDEX_NAME"] = v;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function clearIndex() {
|
|
11
|
+
Stdlib_Dict.$$delete(process.env, "PLACE_INDEX_NAME");
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
globalThis.describe("Geocoder_AwsLocation_Ops.handler status contract", () => {
|
|
15
|
+
globalThis.test("an unset PLACE_INDEX_NAME is a service failure, not a verdict", async () => {
|
|
16
|
+
Stdlib_Dict.$$delete(process.env, "PLACE_INDEX_NAME");
|
|
17
|
+
let resp = await Geocoder_AwsLocation_Ops$ReventlessAws.handler({
|
|
18
|
+
queryStringParameters: Object.fromEntries([[
|
|
19
|
+
"q",
|
|
20
|
+
"10 Downing Street"
|
|
21
|
+
]])
|
|
22
|
+
});
|
|
23
|
+
globalThis.expect(resp.statusCode).toBe(502);
|
|
24
|
+
globalThis.expect(resp.body).toBe("[]");
|
|
25
|
+
});
|
|
26
|
+
globalThis.test("an empty query is an answer — nothing was asked", async () => {
|
|
27
|
+
setIndex("some-index");
|
|
28
|
+
let resp = await Geocoder_AwsLocation_Ops$ReventlessAws.handler({
|
|
29
|
+
queryStringParameters: Object.fromEntries([[
|
|
30
|
+
"q",
|
|
31
|
+
""
|
|
32
|
+
]])
|
|
33
|
+
});
|
|
34
|
+
globalThis.expect(resp.statusCode).toBe(200);
|
|
35
|
+
globalThis.expect(resp.body).toBe("[]");
|
|
36
|
+
return Stdlib_Dict.$$delete(process.env, "PLACE_INDEX_NAME");
|
|
37
|
+
});
|
|
38
|
+
globalThis.test("a missing q param is treated as an empty one", async () => {
|
|
39
|
+
setIndex("some-index");
|
|
40
|
+
let resp = await Geocoder_AwsLocation_Ops$ReventlessAws.handler({});
|
|
41
|
+
globalThis.expect(resp.statusCode).toBe(200);
|
|
42
|
+
return Stdlib_Dict.$$delete(process.env, "PLACE_INDEX_NAME");
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
globalThis.describe("Geocoder_AwsLocation_Ops.readQueryParam", () => {
|
|
47
|
+
globalThis.test("prefers the parsed params", () => {
|
|
48
|
+
globalThis.expect(Geocoder_AwsLocation_Ops$ReventlessAws.readQueryParam({
|
|
49
|
+
queryStringParameters: Object.fromEntries([[
|
|
50
|
+
"q",
|
|
51
|
+
"Berlin"
|
|
52
|
+
]])
|
|
53
|
+
})).toEqual("Berlin");
|
|
54
|
+
});
|
|
55
|
+
globalThis.test("falls back to the raw query string, percent-decoded", () => {
|
|
56
|
+
globalThis.expect(Geocoder_AwsLocation_Ops$ReventlessAws.readQueryParam({
|
|
57
|
+
rawQueryString: "lang=en&q=10%20Downing%20Street"
|
|
58
|
+
})).toEqual("10 Downing Street");
|
|
59
|
+
});
|
|
60
|
+
globalThis.test("no q anywhere is None", () => {
|
|
61
|
+
globalThis.expect(Geocoder_AwsLocation_Ops$ReventlessAws.readQueryParam({
|
|
62
|
+
rawQueryString: "lang=en"
|
|
63
|
+
})).toEqual(undefined);
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
export {
|
|
68
|
+
setIndex,
|
|
69
|
+
clearIndex,
|
|
70
|
+
}
|
|
71
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
open JestGlobals
|
|
2
|
+
|
|
3
|
+
// The rule that matters is CloudWatch's, not ours: a metric transformation may carry
|
|
4
|
+
// `dimensions` OR `defaultValue`, never both. Violating it is not caught at compile
|
|
5
|
+
// time — both fields are optional in the binding — and not caught at deploy time
|
|
6
|
+
// either unless the stack happens to have a managed log group for the filter to
|
|
7
|
+
// attach to. So it is asserted here.
|
|
8
|
+
|
|
9
|
+
describe("Util_DcbMetrics.transformationFor", () => {
|
|
10
|
+
testSync("never sets defaultValue — it is mutually exclusive with dimensions", () =>
|
|
11
|
+
Util_DcbMetrics.metricNames->Array.forEach(m =>
|
|
12
|
+
expect(Util_DcbMetrics.transformationFor(m).defaultValue)->toBe(None)
|
|
13
|
+
)
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
testSync("dimensions the metric by slice", () =>
|
|
17
|
+
expect(
|
|
18
|
+
Util_DcbMetrics.transformationFor("AppendRetry").dimensions->Option.isSome,
|
|
19
|
+
)->toBe(true)
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
testSync("counts into the DCB namespace", () =>
|
|
23
|
+
expect(Util_DcbMetrics.transformationFor("AppendRetry").namespace)->toBe("Reventless/DCB")
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
testSync("names the metric after the emitted marker", () =>
|
|
27
|
+
expect(Util_DcbMetrics.transformationFor("AppendConflict").name)->toBe("AppendConflict")
|
|
28
|
+
)
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
describe("Util_DcbMetrics.patternFor", () => {
|
|
32
|
+
testSync("selects one metric's lines by its marker", () =>
|
|
33
|
+
expect(Util_DcbMetrics.patternFor("AppendRetry"))->toBe(`{ $.reventlessMetric = "AppendRetry" }`)
|
|
34
|
+
)
|
|
35
|
+
})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
4
|
+
import * as Util_DcbMetrics$ReventlessAws from "../src/util/Util_DcbMetrics.res.mjs";
|
|
5
|
+
|
|
6
|
+
globalThis.describe("Util_DcbMetrics.transformationFor", () => {
|
|
7
|
+
globalThis.test("never sets defaultValue — it is mutually exclusive with dimensions", () => {
|
|
8
|
+
Util_DcbMetrics$ReventlessAws.metricNames.forEach(m => {
|
|
9
|
+
globalThis.expect(Util_DcbMetrics$ReventlessAws.transformationFor(m).defaultValue).toBe(undefined);
|
|
10
|
+
});
|
|
11
|
+
});
|
|
12
|
+
globalThis.test("dimensions the metric by slice", () => {
|
|
13
|
+
globalThis.expect(Stdlib_Option.isSome(Util_DcbMetrics$ReventlessAws.transformationFor("AppendRetry").dimensions)).toBe(true);
|
|
14
|
+
});
|
|
15
|
+
globalThis.test("counts into the DCB namespace", () => {
|
|
16
|
+
globalThis.expect(Util_DcbMetrics$ReventlessAws.transformationFor("AppendRetry").namespace).toBe("Reventless/DCB");
|
|
17
|
+
});
|
|
18
|
+
globalThis.test("names the metric after the emitted marker", () => {
|
|
19
|
+
globalThis.expect(Util_DcbMetrics$ReventlessAws.transformationFor("AppendConflict").name).toBe("AppendConflict");
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
globalThis.describe("Util_DcbMetrics.patternFor", () => {
|
|
24
|
+
globalThis.test("selects one metric's lines by its marker", () => {
|
|
25
|
+
globalThis.expect(Util_DcbMetrics$ReventlessAws.patternFor("AppendRetry")).toBe(`{ $.reventlessMetric = "AppendRetry" }`);
|
|
26
|
+
});
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
/* Not a pure module */
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
open JestGlobals
|
|
2
|
+
|
|
3
|
+
// The host shell reads config.json by key name, and every failure here is a
|
|
4
|
+
// silent one: a missing key deletes a feature with nothing in any log, and a
|
|
5
|
+
// key overwritten by a passthrough points the app at the wrong API. Both are
|
|
6
|
+
// only assertable because `fields` is pure.
|
|
7
|
+
|
|
8
|
+
let computed = [
|
|
9
|
+
("apiEndpoint", JSON.Encode.string("https://domain.example/graphql")),
|
|
10
|
+
("region", JSON.Encode.string("eu-west-1")),
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
let get = (out, key) => out->Dict.get(key)->Option.getOr(JSON.Encode.null)
|
|
14
|
+
|
|
15
|
+
describe("Util_ShellConfig.fields — viewModes", () => {
|
|
16
|
+
testSync("unset ⇒ no viewModes key and the computed set is untouched", () => {
|
|
17
|
+
let out = Util_ShellConfig.fields(~computed)
|
|
18
|
+
expect(out->Dict.keysToArray)->toEqual(["apiEndpoint", "region"])
|
|
19
|
+
expect(out->Dict.get("viewModes")->Option.isNone)->toBe(true)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
testSync("Map with defaults ⇒ the mode, and no mapStyle key", () => {
|
|
23
|
+
let out = Util_ShellConfig.fields(~computed, ~viewModes=[Map({})])
|
|
24
|
+
expect(out->get("viewModes"))->toEqual(JSON.Encode.array([JSON.Encode.string("map")]))
|
|
25
|
+
expect(out->Dict.get("mapStyle")->Option.isNone)->toBe(true)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
testSync("per-mode options flatten beside the mode", () => {
|
|
29
|
+
let out = Util_ShellConfig.fields(
|
|
30
|
+
~computed,
|
|
31
|
+
~viewModes=[Map({style: "https://tiles.example/style.json"}), Graph({layout: "dagre"})],
|
|
32
|
+
)
|
|
33
|
+
expect(out->get("viewModes"))->toEqual(
|
|
34
|
+
JSON.Encode.array([JSON.Encode.string("map"), JSON.Encode.string("graph")]),
|
|
35
|
+
)
|
|
36
|
+
expect(out->get("mapStyle"))->toEqual(
|
|
37
|
+
JSON.Encode.string("https://tiles.example/style.json"),
|
|
38
|
+
)
|
|
39
|
+
expect(out->get("graphLayout"))->toEqual(JSON.Encode.string("dagre"))
|
|
40
|
+
})
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
describe("Util_ShellConfig.fields — shellConfig passthrough", () => {
|
|
44
|
+
testSync("shell-owned keys land verbatim, under the computed ones", () => {
|
|
45
|
+
let out = Util_ShellConfig.fields(
|
|
46
|
+
~computed,
|
|
47
|
+
~shellConfig=Dict.fromArray([
|
|
48
|
+
("platformName", JSON.Encode.string("Online Shop")),
|
|
49
|
+
("accessTiers", JSON.Encode.array([JSON.Encode.string("public")])),
|
|
50
|
+
]),
|
|
51
|
+
)
|
|
52
|
+
expect(out->Dict.keysToArray)->toEqual([
|
|
53
|
+
"apiEndpoint",
|
|
54
|
+
"region",
|
|
55
|
+
"platformName",
|
|
56
|
+
"accessTiers",
|
|
57
|
+
])
|
|
58
|
+
expect(out->get("platformName"))->toEqual(JSON.Encode.string("Online Shop"))
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
testSync("a key the deploy computes fails the deploy, naming it", () => {
|
|
62
|
+
let failure = try {
|
|
63
|
+
let _ = Util_ShellConfig.fields(
|
|
64
|
+
~computed,
|
|
65
|
+
~shellConfig=Dict.fromArray([
|
|
66
|
+
("apiEndpoint", JSON.Encode.string("https://wrong.example/graphql")),
|
|
67
|
+
]),
|
|
68
|
+
)
|
|
69
|
+
None
|
|
70
|
+
} catch {
|
|
71
|
+
| Failure(message) => Some(message)
|
|
72
|
+
}
|
|
73
|
+
switch failure {
|
|
74
|
+
| Some(message) => expect(message->String.includes("apiEndpoint"))->toBe(true)
|
|
75
|
+
| None => fail("a shellConfig key colliding with a computed one must fail the deploy")
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
})
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as JestGlobals from "@reventlessdev/rescript-jest/src/JestGlobals.res.mjs";
|
|
4
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
|
+
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
6
|
+
import * as Util_ShellConfig$ReventlessAws from "../src/util/Util_ShellConfig.res.mjs";
|
|
7
|
+
|
|
8
|
+
let computed = [
|
|
9
|
+
[
|
|
10
|
+
"apiEndpoint",
|
|
11
|
+
"https://domain.example/graphql"
|
|
12
|
+
],
|
|
13
|
+
[
|
|
14
|
+
"region",
|
|
15
|
+
"eu-west-1"
|
|
16
|
+
]
|
|
17
|
+
];
|
|
18
|
+
|
|
19
|
+
function get(out, key) {
|
|
20
|
+
return Stdlib_Option.getOr(out[key], null);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
globalThis.describe("Util_ShellConfig.fields — viewModes", () => {
|
|
24
|
+
globalThis.test("unset ⇒ no viewModes key and the computed set is untouched", () => {
|
|
25
|
+
let out = Util_ShellConfig$ReventlessAws.fields(computed, undefined, undefined);
|
|
26
|
+
globalThis.expect(Object.keys(out)).toEqual([
|
|
27
|
+
"apiEndpoint",
|
|
28
|
+
"region"
|
|
29
|
+
]);
|
|
30
|
+
globalThis.expect(Stdlib_Option.isNone(out["viewModes"])).toBe(true);
|
|
31
|
+
});
|
|
32
|
+
globalThis.test("Map with defaults ⇒ the mode, and no mapStyle key", () => {
|
|
33
|
+
let out = Util_ShellConfig$ReventlessAws.fields(computed, [{
|
|
34
|
+
TAG: "Map",
|
|
35
|
+
_0: {}
|
|
36
|
+
}], undefined);
|
|
37
|
+
globalThis.expect(get(out, "viewModes")).toEqual(["map"]);
|
|
38
|
+
globalThis.expect(Stdlib_Option.isNone(out["mapStyle"])).toBe(true);
|
|
39
|
+
});
|
|
40
|
+
globalThis.test("per-mode options flatten beside the mode", () => {
|
|
41
|
+
let out = Util_ShellConfig$ReventlessAws.fields(computed, [
|
|
42
|
+
{
|
|
43
|
+
TAG: "Map",
|
|
44
|
+
_0: {
|
|
45
|
+
style: "https://tiles.example/style.json"
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
TAG: "Graph",
|
|
50
|
+
_0: {
|
|
51
|
+
layout: "dagre"
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
], undefined);
|
|
55
|
+
globalThis.expect(get(out, "viewModes")).toEqual([
|
|
56
|
+
"map",
|
|
57
|
+
"graph"
|
|
58
|
+
]);
|
|
59
|
+
globalThis.expect(get(out, "mapStyle")).toEqual("https://tiles.example/style.json");
|
|
60
|
+
globalThis.expect(get(out, "graphLayout")).toEqual("dagre");
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
globalThis.describe("Util_ShellConfig.fields — shellConfig passthrough", () => {
|
|
65
|
+
globalThis.test("shell-owned keys land verbatim, under the computed ones", () => {
|
|
66
|
+
let out = Util_ShellConfig$ReventlessAws.fields(computed, undefined, Object.fromEntries([
|
|
67
|
+
[
|
|
68
|
+
"platformName",
|
|
69
|
+
"Online Shop"
|
|
70
|
+
],
|
|
71
|
+
[
|
|
72
|
+
"accessTiers",
|
|
73
|
+
["public"]
|
|
74
|
+
]
|
|
75
|
+
]));
|
|
76
|
+
globalThis.expect(Object.keys(out)).toEqual([
|
|
77
|
+
"apiEndpoint",
|
|
78
|
+
"region",
|
|
79
|
+
"platformName",
|
|
80
|
+
"accessTiers"
|
|
81
|
+
]);
|
|
82
|
+
globalThis.expect(get(out, "platformName")).toEqual("Online Shop");
|
|
83
|
+
});
|
|
84
|
+
globalThis.test("a key the deploy computes fails the deploy, naming it", () => {
|
|
85
|
+
let failure;
|
|
86
|
+
try {
|
|
87
|
+
Util_ShellConfig$ReventlessAws.fields(computed, undefined, Object.fromEntries([[
|
|
88
|
+
"apiEndpoint",
|
|
89
|
+
"https://wrong.example/graphql"
|
|
90
|
+
]]));
|
|
91
|
+
failure = undefined;
|
|
92
|
+
} catch (raw_message) {
|
|
93
|
+
let message = Primitive_exceptions.internalToException(raw_message);
|
|
94
|
+
if (message.RE_EXN_ID === "Failure") {
|
|
95
|
+
failure = message._1;
|
|
96
|
+
} else {
|
|
97
|
+
throw message;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
if (failure !== undefined) {
|
|
101
|
+
globalThis.expect(failure.includes("apiEndpoint")).toBe(true);
|
|
102
|
+
return;
|
|
103
|
+
} else {
|
|
104
|
+
return JestGlobals.fail("a shellConfig key colliding with a computed one must fail the deploy");
|
|
105
|
+
}
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
export {
|
|
110
|
+
computed,
|
|
111
|
+
get,
|
|
112
|
+
}
|
|
113
|
+
/* Not a pure module */
|