@reventlessdev/reventless-aws 3.0.0-alpha.264 → 3.0.0-alpha.266

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 (27) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/package.json +7 -7
  3. package/src/Platform.res +66 -45
  4. package/src/Platform.res.mjs +31 -35
  5. package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver.res +227 -0
  6. package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver.res.mjs +127 -0
  7. package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver_Ops.res +55 -0
  8. package/src/adapter/Geocoder/Geocoder_AwsLocation_Resolver_Ops.res.mjs +48 -0
  9. package/src/adapter/Runtime/AutomationSliceEntryPoint.mjs +21 -3
  10. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res +219 -27
  11. package/src/adapter/Runtime/AutomationSliceEntryPoint_Ops.res.mjs +121 -7
  12. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res +118 -0
  13. package/src/adapter/Runtime/AutomationSliceRuntime_Builder_Single.res.mjs +61 -0
  14. package/src/components/OutboundTranslationSlice_Builder.res +15 -0
  15. package/src/components/OutboundTranslationSlice_Builder.res.mjs +11 -1
  16. package/src/plugin/runtime/PluginRuntime_Builder.res +26 -0
  17. package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +26 -0
  18. package/tests/AutomationSliceEntryPoint_OpsTest.res +44 -3
  19. package/tests/AutomationSliceEntryPoint_OpsTest.res.mjs +65 -1
  20. package/tests/Geocoder_AwsLocation_Resolver_OpsTest.res +53 -0
  21. package/tests/Geocoder_AwsLocation_Resolver_OpsTest.res.mjs +55 -0
  22. package/src/adapter/Geocoder/Geocoder_AwsLocation.res +0 -166
  23. package/src/adapter/Geocoder/Geocoder_AwsLocation.res.mjs +0 -105
  24. package/src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res +0 -144
  25. package/src/adapter/Geocoder/Geocoder_AwsLocation_Ops.res.mjs +0 -137
  26. package/tests/Geocoder_AwsLocation_OpsTest.res +0 -78
  27. package/tests/Geocoder_AwsLocation_OpsTest.res.mjs +0 -71
@@ -1,137 +0,0 @@
1
- // Generated by ReScript, PLEASE EDIT WITH CARE
2
-
3
- import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
4
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
- import * as Location$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/Location.res.mjs";
6
- import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
7
- import * as ClientLocation from "@aws-sdk/client-location";
8
-
9
- function getEnv(k) {
10
- let v = process.env[k];
11
- if (v !== undefined && v !== "") {
12
- return v;
13
- }
14
- }
15
-
16
- function jsonHeaders() {
17
- return Object.fromEntries([[
18
- "content-type",
19
- "application/json"
20
- ]]);
21
- }
22
-
23
- function readQueryParam(event) {
24
- let q = Stdlib_Option.flatMap(event.queryStringParameters, p => p["q"]);
25
- if (q !== undefined) {
26
- return q;
27
- } else {
28
- return Stdlib_Option.flatMap(event.rawQueryString, raw => Stdlib_Array.findMap(raw.split("&"), pair => {
29
- let match = pair.split("=");
30
- if (match.length !== 2) {
31
- return;
32
- }
33
- let k = match[0];
34
- let v = match[1];
35
- if (k === "q") {
36
- return decodeURIComponent(v);
37
- }
38
- }));
39
- }
40
- }
41
-
42
- async function handler(event) {
43
- try {
44
- let indexName = Stdlib_Option.getOr(getEnv("PLACE_INDEX_NAME"), "");
45
- let q = Stdlib_Option.getOr(readQueryParam(event), "");
46
- if (indexName === "") {
47
- console.error("Geocoder: PLACE_INDEX_NAME is unset");
48
- return {
49
- statusCode: 502,
50
- headers: Object.fromEntries([[
51
- "content-type",
52
- "application/json"
53
- ]]),
54
- body: "[]"
55
- };
56
- }
57
- if (q === "") {
58
- return {
59
- statusCode: 200,
60
- headers: Object.fromEntries([[
61
- "content-type",
62
- "application/json"
63
- ]]),
64
- body: "[]"
65
- };
66
- }
67
- let resp = await Location$AwsSdk.SearchPlaceIndexForTextCommand.send(new ClientLocation.SearchPlaceIndexForTextCommand({
68
- IndexName: indexName,
69
- Text: q,
70
- MaxResults: 5
71
- }));
72
- let results = Stdlib_Array.filterMap(Stdlib_Option.getOr(resp.Results, []), r => {
73
- let place = r.Place;
74
- if (place === undefined) {
75
- return;
76
- }
77
- let label = Stdlib_Option.getOr(place.Label, "");
78
- let pt = Stdlib_Option.flatMap(place.Geometry, g => g.Point);
79
- if (pt === undefined) {
80
- return;
81
- }
82
- if (pt.length < 2) {
83
- return;
84
- }
85
- let lng = pt[0];
86
- let lat = pt[1];
87
- let rel = r.Relevance;
88
- return Object.fromEntries([
89
- [
90
- "label",
91
- label
92
- ],
93
- [
94
- "lat",
95
- lat
96
- ],
97
- [
98
- "lng",
99
- lng
100
- ]
101
- ].concat(rel !== undefined ? [[
102
- "relevance",
103
- rel
104
- ]] : []));
105
- });
106
- return {
107
- statusCode: 200,
108
- headers: Object.fromEntries([[
109
- "content-type",
110
- "application/json"
111
- ]]),
112
- body: JSON.stringify(results)
113
- };
114
- } catch (raw_exn) {
115
- let exn = Primitive_exceptions.internalToException(raw_exn);
116
- console.error("Geocoder: search failed", exn);
117
- return {
118
- statusCode: 502,
119
- headers: Object.fromEntries([[
120
- "content-type",
121
- "application/json"
122
- ]]),
123
- body: "[]"
124
- };
125
- }
126
- }
127
-
128
- let Search;
129
-
130
- export {
131
- Search,
132
- getEnv,
133
- jsonHeaders,
134
- readQueryParam,
135
- handler,
136
- }
137
- /* Location-AwsSdk Not a pure module */
@@ -1,78 +0,0 @@
1
- // Guards the geocoder Function URL's *status* contract, which is the whole
2
- // reason one endpoint can serve two callers that want opposite things from it.
3
- //
4
- // A browser search box reads the body and must degrade quietly: never an error,
5
- // just no results. An unattended translator reads the status, because it has to
6
- // tell "there is no such address" (write a verdict, do not retry) from "the
7
- // service cannot answer" (retry). The two only ever disagree about which half of
8
- // the response they read, so:
9
- //
10
- // 200 + a possibly-empty array — an answer
11
- // anything else — no answer
12
- //
13
- // The arms below are the ones reachable without a live AWS Location call. The
14
- // success path and the thrown-error path both need the SDK and stay unasserted
15
- // here — see the plan's Verification note.
16
-
17
- open JestGlobals
18
-
19
- let setIndex = v => NodeProcess.env->Dict.set("PLACE_INDEX_NAME", v)
20
- let clearIndex = () => NodeProcess.env->Dict.delete("PLACE_INDEX_NAME")
21
-
22
- describe("Geocoder_AwsLocation_Ops.handler status contract", () => {
23
- test("an unset PLACE_INDEX_NAME is a service failure, not a verdict", async () => {
24
- clearIndex()
25
- let resp = await Geocoder_AwsLocation_Ops.handler({
26
- queryStringParameters: Dict.fromArray([("q", "10 Downing Street")]),
27
- })
28
- // The arm that matters most: `200 []` here would tell a translator this
29
- // address does not exist, and it would record that permanently — for every
30
- // address handed to it while the deployment stayed misconfigured.
31
- expect(resp.statusCode)->toBe(502)
32
- expect(resp.body)->toBe("[]")
33
- })
34
-
35
- test("an empty query is an answer — nothing was asked", async () => {
36
- setIndex("some-index")
37
- let resp = await Geocoder_AwsLocation_Ops.handler({
38
- queryStringParameters: Dict.fromArray([("q", "")]),
39
- })
40
- // 200, unlike the case above: "no results for nothing" is true and final,
41
- // and a search box sends exactly this on every cleared input.
42
- expect(resp.statusCode)->toBe(200)
43
- expect(resp.body)->toBe("[]")
44
- clearIndex()
45
- })
46
-
47
- test("a missing q param is treated as an empty one", async () => {
48
- setIndex("some-index")
49
- let resp = await Geocoder_AwsLocation_Ops.handler({})
50
- expect(resp.statusCode)->toBe(200)
51
- clearIndex()
52
- })
53
- })
54
-
55
- describe("Geocoder_AwsLocation_Ops.readQueryParam", () => {
56
- testSync("prefers the parsed params", () => {
57
- expect(
58
- Geocoder_AwsLocation_Ops.readQueryParam({
59
- queryStringParameters: Dict.fromArray([("q", "Berlin")]),
60
- }),
61
- )->toEqual(Some("Berlin"))
62
- })
63
-
64
- testSync("falls back to the raw query string, percent-decoded", () => {
65
- // Payload format 2.0 populates both fields, but a caller that builds its own
66
- // URL is the reason the fallback exists — and the encoding is where a plain
67
- // `split("=")` would hand back `10%20Downing%20Street`.
68
- expect(
69
- Geocoder_AwsLocation_Ops.readQueryParam({
70
- rawQueryString: "lang=en&q=10%20Downing%20Street",
71
- }),
72
- )->toEqual(Some("10 Downing Street"))
73
- })
74
-
75
- testSync("no q anywhere is None", () => {
76
- expect(Geocoder_AwsLocation_Ops.readQueryParam({rawQueryString: "lang=en"}))->toEqual(None)
77
- })
78
- })
@@ -1,71 +0,0 @@
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 */