@reventlessdev/reventless-aws 3.0.0-alpha.310 → 3.0.0-alpha.312
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 +14 -0
- package/package.json +6 -6
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res +17 -13
- package/src/adapter/Runtime/EventCollectorEntryPoint_Ops.res.mjs +4 -2
- package/src/plugin/runtime/PluginRuntime_Builder.res +6 -5
- package/src/plugin/runtime/PluginRuntime_Builder.res.mjs +3 -1
- package/tests/EventCollectorPluginDefinitionAssetTest.res +115 -0
- package/tests/EventCollectorPluginDefinitionAssetTest.res.mjs +135 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,20 @@
|
|
|
3
3
|
All notable changes to this project will be documented in this file.
|
|
4
4
|
See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
|
|
5
5
|
|
|
6
|
+
# 3.0.0-alpha.312 (2026-08-19)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **aws:** build the platform's definition asset from the shared value ([c0e432d](https://github.com/ReventlessDev/reventless-core/commit/c0e432d98d96af3ff4c305b62f658ae102c5d142))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.311 (2026-08-19)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **aws:** decode the plugin definition asset instead of casting it ([5ac8a75](https://github.com/ReventlessDev/reventless-core/commit/5ac8a758673da63479049ba17658c8f91c5d72c5))
|
|
18
|
+
|
|
19
|
+
|
|
6
20
|
# 3.0.0-alpha.310 (2026-08-18)
|
|
7
21
|
|
|
8
22
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-aws",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.312",
|
|
4
4
|
"description": "AWS adapters for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"dependencies": {
|
|
@@ -13,17 +13,17 @@
|
|
|
13
13
|
"sury": "11.0.0-rc.1",
|
|
14
14
|
"uuid": "^13.0.0",
|
|
15
15
|
"@reventlessdev/rescript-aws-sdk": "3.0.0-alpha.12",
|
|
16
|
-
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
17
16
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.32",
|
|
17
|
+
"@reventlessdev/rescript-jest": "1.0.0-alpha.10",
|
|
18
18
|
"@reventlessdev/rescript-node": "2.0.0-alpha.8",
|
|
19
19
|
"@reventlessdev/rescript-pulumi-aws": "3.0.0-alpha.1",
|
|
20
20
|
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.19",
|
|
21
21
|
"@reventlessdev/rescript-uuid": "2.0.0-alpha.0",
|
|
22
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.
|
|
22
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.241",
|
|
23
23
|
"@reventlessdev/reventless-infra": "3.0.0-alpha.146",
|
|
24
|
-
"@reventlessdev/reventless-postgres": "3.0.0-alpha.
|
|
25
|
-
"@reventlessdev/reventless-
|
|
26
|
-
"@reventlessdev/reventless-
|
|
24
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.105",
|
|
25
|
+
"@reventlessdev/reventless-spec": "3.0.0-alpha.118",
|
|
26
|
+
"@reventlessdev/reventless-interop": "3.0.0-alpha.32"
|
|
27
27
|
},
|
|
28
28
|
"devDependencies": {
|
|
29
29
|
"rescript": "12.3.0",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
// Plugin_Callback wiring, and the Lambda dispatch boundary.
|
|
13
13
|
//
|
|
14
14
|
// Runtime-pure: no `open PulumiAws` values — Pulumi appears in type positions
|
|
15
|
-
// only (erased). The
|
|
16
|
-
//
|
|
15
|
+
// only (erased). The one `%identity` cast below sits on a documented JSON
|
|
16
|
+
// contract (same pattern as AggregateEntryPoint_Ops.asConnectionConfig).
|
|
17
17
|
|
|
18
18
|
// ── Shim bindings (HandlerFactoryHelpers.mjs) ───────────────────────────────
|
|
19
19
|
// The structured-log + Effect dispatch boundary shared by every deployed entry
|
|
@@ -325,8 +325,8 @@ let projectPluginRow = (row: JSON.t): option<pluginProjection> =>
|
|
|
325
325
|
|
|
326
326
|
// A pluginDefinition viewed as a projection (the manage logic reads only the
|
|
327
327
|
// shared subset; `status` is never read for the acting plugin). Array/option
|
|
328
|
-
// fields
|
|
329
|
-
//
|
|
328
|
+
// fields stay js_nullable-normalized: a definition arriving over the wire, rather
|
|
329
|
+
// than from loadPluginDefinition's decode, still carries null for an absent field.
|
|
330
330
|
let projectionOfDefinition = (d: Reventless.Plugin.pluginDefinition): pluginProjection => {
|
|
331
331
|
id: d.id,
|
|
332
332
|
status: "",
|
|
@@ -671,20 +671,24 @@ let warnSkippedExtension = (ext: extensionConfig) =>
|
|
|
671
671
|
|
|
672
672
|
let assetPath = (fileName: string): string => NodePath.join([NodeProcess.cwd(), fileName])
|
|
673
673
|
|
|
674
|
-
// pluginDefinition.json is written
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
//
|
|
678
|
-
//
|
|
679
|
-
external asPluginDefinition: JSON.t => Reventless.Plugin.pluginDefinition = "%identity"
|
|
680
|
-
|
|
674
|
+
// pluginDefinition.json is written through the schema's encoder (Plugin_Helpers),
|
|
675
|
+
// so it holds the wire form, which is not the record's runtime shape: an @offload
|
|
676
|
+
// field is {"$offload": …} on the wire and Offloaded(…) in ReScript. Decode it
|
|
677
|
+
// back through the same schema — a cast leaves the wire form in a value typed as
|
|
678
|
+
// the record, and the next encode of it (the Connect handshake) throws.
|
|
681
679
|
let loadPluginDefinition = (): Reventless.Plugin.pluginDefinition =>
|
|
682
680
|
try {
|
|
683
|
-
assetPath("pluginDefinition.json")
|
|
681
|
+
assetPath("pluginDefinition.json")
|
|
682
|
+
->NodeFs.readFileSync
|
|
683
|
+
->Reventless.Util_Sury.fromJsonString(Reventless.Plugin.pluginDefinitionSchema)
|
|
684
684
|
} catch {
|
|
685
685
|
| exn =>
|
|
686
|
+
// Util_Sury.exnMessage, not the local one: sury raises S.Exn, which is not a
|
|
687
|
+
// JsExn, so the local reader yields "unknown error" and loses the field path —
|
|
688
|
+
// the whole diagnosis for a decode failure here.
|
|
686
689
|
JsError.throwWithMessage(
|
|
687
|
-
"Failed to load pluginDefinition.json from asset zip: " ++
|
|
690
|
+
"Failed to load pluginDefinition.json from asset zip: " ++
|
|
691
|
+
Reventless.Util_Sury.exnMessage(exn),
|
|
688
692
|
)
|
|
689
693
|
}
|
|
690
694
|
|
|
@@ -8,8 +8,10 @@ import * as Stdlib_JsExn from "@rescript/runtime/lib/es6/Stdlib_JsExn.js";
|
|
|
8
8
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
9
|
import * as Stdlib_JsError from "@rescript/runtime/lib/es6/Stdlib_JsError.js";
|
|
10
10
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
11
|
+
import * as Plugin$Reventless from "@reventlessdev/reventless-spec/src/components/Plugin.res.mjs";
|
|
11
12
|
import * as SNS_Helpers$AwsSdk from "@reventlessdev/rescript-aws-sdk/src/SNS_Helpers.res.mjs";
|
|
12
13
|
import * as Primitive_exceptions from "@rescript/runtime/lib/es6/Primitive_exceptions.js";
|
|
14
|
+
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
13
15
|
import * as HandlerFactoryHelpersMjs from "./HandlerFactoryHelpers.mjs";
|
|
14
16
|
import * as Plugin_Callback$ReventlessCore from "@reventlessdev/reventless-core/src/plugin/component/Plugin_Callback.res.mjs";
|
|
15
17
|
import * as Util_PluginMessage_Runtime$ReventlessAws from "../../plugin/runtime/Util_PluginMessage_Runtime.res.mjs";
|
|
@@ -519,10 +521,10 @@ function assetPath(fileName) {
|
|
|
519
521
|
|
|
520
522
|
function loadPluginDefinition() {
|
|
521
523
|
try {
|
|
522
|
-
return
|
|
524
|
+
return Util_Sury$Reventless.fromJsonString(Nodefs.readFileSync(assetPath("pluginDefinition.json"), "utf8"), Plugin$Reventless.pluginDefinitionSchema);
|
|
523
525
|
} catch (raw_exn) {
|
|
524
526
|
let exn = Primitive_exceptions.internalToException(raw_exn);
|
|
525
|
-
return Stdlib_JsError.throwWithMessage("Failed to load pluginDefinition.json from asset zip: " + exnMessage(exn));
|
|
527
|
+
return Stdlib_JsError.throwWithMessage("Failed to load pluginDefinition.json from asset zip: " + Util_Sury$Reventless.exnMessage(exn, undefined));
|
|
526
528
|
}
|
|
527
529
|
}
|
|
528
530
|
|
|
@@ -268,12 +268,13 @@ module Make = (
|
|
|
268
268
|
// keeps the JSON shape consistent so the entry point can parse uniformly.
|
|
269
269
|
let synthesizeAdminContext = (): ReventlessCore.Plugin_Helpers.eventCollectorContext => {
|
|
270
270
|
let config = configRef.contents
|
|
271
|
-
//
|
|
272
|
-
//
|
|
273
|
-
//
|
|
274
|
-
let platformId = ReventlessCore.Platform_Admin_Structure.pluginId
|
|
271
|
+
// Encoded from the one placeholder value, through the same schema the entry
|
|
272
|
+
// point decodes with. It was a hand-written JSON literal, which drifted: the
|
|
273
|
+
// schema gained `dcbEventLog` and `kind` and the literal did not follow.
|
|
275
274
|
let fakePluginDefinitionJson =
|
|
276
|
-
|
|
275
|
+
ReventlessCore.Platform_Admin_Structure.internalPluginDefinition
|
|
276
|
+
->Reventless.Util_Sury.toJsonString(Reventless.Plugin.pluginDefinitionSchema)
|
|
277
|
+
->Pulumi.Output.make
|
|
277
278
|
let adminEpEventTopicArn = switch config.eventTopicArn {
|
|
278
279
|
| Some(arn) => arn
|
|
279
280
|
| None => Pulumi.Output.make("NOT_AVAILABLE")
|
|
@@ -5,6 +5,8 @@ import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
|
5
5
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
6
6
|
import * as Pulumi from "@pulumi/pulumi";
|
|
7
7
|
import * as Primitive_string from "@rescript/runtime/lib/es6/Primitive_string.js";
|
|
8
|
+
import * as Plugin$Reventless from "@reventlessdev/reventless-spec/src/components/Plugin.res.mjs";
|
|
9
|
+
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
8
10
|
import * as Logger$ReventlessCore from "@reventlessdev/reventless-core/src/util/Logger.res.mjs";
|
|
9
11
|
import * as Component$ReventlessCore from "@reventlessdev/reventless-core/src/components/Component.res.mjs";
|
|
10
12
|
import * as DcbBackend$ReventlessAws from "../../adapter/DcbEventLog/DcbBackend.res.mjs";
|
|
@@ -202,7 +204,7 @@ function Make(EventCollectorChannel) {
|
|
|
202
204
|
};
|
|
203
205
|
let synthesizeAdminContext = () => {
|
|
204
206
|
let config = configRef.contents;
|
|
205
|
-
let fakePluginDefinitionJson = Pulumi.output(
|
|
207
|
+
let fakePluginDefinitionJson = Pulumi.output(Util_Sury$Reventless.toJsonString(Platform_Admin_Structure$ReventlessCore.internalPluginDefinition, Plugin$Reventless.pluginDefinitionSchema, undefined));
|
|
206
208
|
let arn = config.eventTopicArn;
|
|
207
209
|
let adminEpEventTopicArn = arn !== undefined ? arn : Pulumi.output("NOT_AVAILABLE");
|
|
208
210
|
return {
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
// Guards the write/read symmetry of the `pluginDefinition.json` asset.
|
|
2
|
+
//
|
|
3
|
+
// The deploy side writes it with the schema's encoder (Plugin_Helpers); the
|
|
4
|
+
// runtime side (EventCollectorEntryPoint_Ops.loadPluginDefinition) reads it back
|
|
5
|
+
// and republishes the value inside the Connect handshake. Those two have to be
|
|
6
|
+
// the same schema in opposite directions.
|
|
7
|
+
//
|
|
8
|
+
// They stopped being that once a field carried @offload, whose wire form is
|
|
9
|
+
// deliberately untagged: {"$offload": …} on the wire, Offloaded(…) in ReScript.
|
|
10
|
+
// The read side cast the parsed JSON instead of decoding it, so the wire form
|
|
11
|
+
// survived inside a value typed as the record and the *next* encode — publishing
|
|
12
|
+
// ConnectPlugin — threw. Registration then froze at the previous version with the
|
|
13
|
+
// deploy reporting success, so this asserts the round trip rather than the read.
|
|
14
|
+
|
|
15
|
+
open JestGlobals
|
|
16
|
+
|
|
17
|
+
let offloadedFragment: Reventless.Plugin.pluginDefinition = {
|
|
18
|
+
id: "Catalog@1.0.0-alpha.215",
|
|
19
|
+
name: "Catalog",
|
|
20
|
+
version: "1.0.0-alpha.215",
|
|
21
|
+
extensionPoints: [],
|
|
22
|
+
extensions: [],
|
|
23
|
+
eventCollector: "arn:aws:sqs:eu-west-1:1:CatalogPluginEventColl",
|
|
24
|
+
extensionProtocols: [],
|
|
25
|
+
apiSchemaFragment: Some(
|
|
26
|
+
Offloaded({
|
|
27
|
+
store: "pluginApiFragments",
|
|
28
|
+
key: "sha256/a3db053a9ca51d63982811b0c1faa42cbb83ef6011ea140841375c7b1c9e9695",
|
|
29
|
+
hash: "a3db053a9ca51d63982811b0c1faa42cbb83ef6011ea140841375c7b1c9e9695",
|
|
30
|
+
bytes: 14594,
|
|
31
|
+
}),
|
|
32
|
+
),
|
|
33
|
+
apiTarget: Some("Domain"),
|
|
34
|
+
structure: None,
|
|
35
|
+
dcbEventLog: None,
|
|
36
|
+
kind: Domain,
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
let inlineFragment: Reventless.Plugin.pluginDefinition = {
|
|
40
|
+
...offloadedFragment,
|
|
41
|
+
apiSchemaFragment: Some(Inline({encoded: "{\"types\":[]}", protocol: "1"})),
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// The asset as it lands in the code archive — the deploy side, verbatim.
|
|
45
|
+
let writeAsset = (def: Reventless.Plugin.pluginDefinition): string =>
|
|
46
|
+
def->Reventless.Util_Sury.toJsonString(Reventless.Plugin.pluginDefinitionSchema)
|
|
47
|
+
|
|
48
|
+
// The runtime side, through the real entry point: loadPluginDefinition resolves
|
|
49
|
+
// the asset against process.cwd(), so the file has to be laid down where it looks
|
|
50
|
+
// rather than the decode re-implemented here — re-implementing it is what would
|
|
51
|
+
// let a cast come back green.
|
|
52
|
+
let readAsset = (json: string): Reventless.Plugin.pluginDefinition => {
|
|
53
|
+
let dir = NodeFs.mkdtempSync(NodePath.join([NodeOs.tmpdir(), "plugindef-"]))
|
|
54
|
+
let previousCwd = NodeProcess.cwd()
|
|
55
|
+
NodeFs.writeFileSync(NodePath.join([dir, "pluginDefinition.json"]), json)
|
|
56
|
+
NodeProcess.chdir(dir)
|
|
57
|
+
let restore = () => {
|
|
58
|
+
NodeProcess.chdir(previousCwd)
|
|
59
|
+
NodeFs.rmSync(dir, {recursive: true, force: true})
|
|
60
|
+
}
|
|
61
|
+
switch EventCollectorEntryPoint_Ops.loadPluginDefinition() {
|
|
62
|
+
| def =>
|
|
63
|
+
restore()
|
|
64
|
+
def
|
|
65
|
+
| exception exn =>
|
|
66
|
+
restore()
|
|
67
|
+
throw(exn)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
describe("pluginDefinition.json write/read symmetry", () => {
|
|
72
|
+
testSync("an offloaded field reaches the runtime as Offloaded, not as its wire form", () => {
|
|
73
|
+
let def = offloadedFragment->writeAsset->readAsset
|
|
74
|
+
switch def.apiSchemaFragment {
|
|
75
|
+
| Some(Offloaded({store, bytes})) =>
|
|
76
|
+
expect(store)->toBe("pluginApiFragments")
|
|
77
|
+
expect(bytes)->toBe(14594)
|
|
78
|
+
| Some(Inline(_)) => fail("offloaded fragment decoded as Inline")
|
|
79
|
+
| None => fail("offloaded fragment decoded as None")
|
|
80
|
+
}
|
|
81
|
+
})
|
|
82
|
+
|
|
83
|
+
testSync("a definition read back from the asset can be published to the Connect handshake", () => {
|
|
84
|
+
// The encode the old cast broke. Both arms, because only Offloaded diverges
|
|
85
|
+
// between wire and runtime shape and an Inline-only test would stay green.
|
|
86
|
+
[offloadedFragment, inlineFragment]->Array.forEach(def => {
|
|
87
|
+
let published =
|
|
88
|
+
ReventlessInfra.PluginExtensionPointSpec.ConnectPlugin(def->writeAsset->readAsset)
|
|
89
|
+
->Reventless.Util_Sury.toJson(ReventlessInfra.PluginExtensionPointSpec.commandSchema)
|
|
90
|
+
expect(published->JSON.Decode.object->Option.isSome)->toBe(true)
|
|
91
|
+
})
|
|
92
|
+
})
|
|
93
|
+
|
|
94
|
+
testSync("the asset round-trips byte-identically, so no stored message shifts", () => {
|
|
95
|
+
let once = offloadedFragment->writeAsset
|
|
96
|
+
expect(once->readAsset->writeAsset)->toBe(once)
|
|
97
|
+
})
|
|
98
|
+
|
|
99
|
+
testSync("an absent optional reaches the runtime as None, not as null", () => {
|
|
100
|
+
let def = offloadedFragment->writeAsset->readAsset
|
|
101
|
+
expect(def.structure->Option.isNone)->toBe(true)
|
|
102
|
+
expect(def.dcbEventLog->Option.isNone)->toBe(true)
|
|
103
|
+
})
|
|
104
|
+
|
|
105
|
+
// The platform's own EventCollector ships a placeholder rather than a real
|
|
106
|
+
// definition — the admin IS the Plugin extension point — but it is read back on
|
|
107
|
+
// this same path, so it has to satisfy the same schema. Its asset used to be a
|
|
108
|
+
// hand-written JSON literal in PluginRuntime_Builder and fell two fields behind
|
|
109
|
+
// (dcbEventLog, kind) with nothing to notice.
|
|
110
|
+
testSync("the platform's own placeholder asset survives the same round trip", () => {
|
|
111
|
+
let def = ReventlessCore.Platform_Admin_Structure.internalPluginDefinition->writeAsset->readAsset
|
|
112
|
+
expect(def.id)->toBe(ReventlessCore.Platform_Admin_Structure.pluginId ++ "@INTERNAL")
|
|
113
|
+
expect(def.kind)->toBe(Reventless.Plugin.Domain)
|
|
114
|
+
})
|
|
115
|
+
})
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
|
+
|
|
3
|
+
import * as Nodefs from "node:fs";
|
|
4
|
+
import * as Nodeos from "node:os";
|
|
5
|
+
import * as Nodepath from "node:path";
|
|
6
|
+
import * as JestGlobals from "@reventlessdev/rescript-jest/src/JestGlobals.res.mjs";
|
|
7
|
+
import * as Stdlib_JSON from "@rescript/runtime/lib/es6/Stdlib_JSON.js";
|
|
8
|
+
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
9
|
+
import * as Plugin$Reventless from "@reventlessdev/reventless-spec/src/components/Plugin.res.mjs";
|
|
10
|
+
import * as Util_Sury$Reventless from "@reventlessdev/reventless-spec/src/util/Util_Sury.res.mjs";
|
|
11
|
+
import * as Platform_Admin_Structure$ReventlessCore from "@reventlessdev/reventless-core/src/admin/Platform_Admin_Structure.res.mjs";
|
|
12
|
+
import * as PluginExtensionPointSpec$ReventlessInfra from "@reventlessdev/reventless-infra/src/types/PluginExtensionPointSpec.res.mjs";
|
|
13
|
+
import * as EventCollectorEntryPoint_Ops$ReventlessAws from "../src/adapter/Runtime/EventCollectorEntryPoint_Ops.res.mjs";
|
|
14
|
+
|
|
15
|
+
let offloadedFragment = {
|
|
16
|
+
id: "Catalog@1.0.0-alpha.215",
|
|
17
|
+
name: "Catalog",
|
|
18
|
+
version: "1.0.0-alpha.215",
|
|
19
|
+
extensionPoints: [],
|
|
20
|
+
extensions: [],
|
|
21
|
+
eventCollector: "arn:aws:sqs:eu-west-1:1:CatalogPluginEventColl",
|
|
22
|
+
extensionProtocols: [],
|
|
23
|
+
apiSchemaFragment: {
|
|
24
|
+
TAG: "Offloaded",
|
|
25
|
+
_0: {
|
|
26
|
+
store: "pluginApiFragments",
|
|
27
|
+
key: "sha256/a3db053a9ca51d63982811b0c1faa42cbb83ef6011ea140841375c7b1c9e9695",
|
|
28
|
+
hash: "a3db053a9ca51d63982811b0c1faa42cbb83ef6011ea140841375c7b1c9e9695",
|
|
29
|
+
bytes: 14594
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
apiTarget: "Domain",
|
|
33
|
+
structure: undefined,
|
|
34
|
+
dcbEventLog: undefined,
|
|
35
|
+
kind: "Domain"
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
let inlineFragment = {
|
|
39
|
+
id: offloadedFragment.id,
|
|
40
|
+
name: offloadedFragment.name,
|
|
41
|
+
version: offloadedFragment.version,
|
|
42
|
+
extensionPoints: offloadedFragment.extensionPoints,
|
|
43
|
+
extensions: offloadedFragment.extensions,
|
|
44
|
+
eventCollector: offloadedFragment.eventCollector,
|
|
45
|
+
extensionProtocols: offloadedFragment.extensionProtocols,
|
|
46
|
+
apiSchemaFragment: {
|
|
47
|
+
TAG: "Inline",
|
|
48
|
+
_0: {
|
|
49
|
+
encoded: "{\"types\":[]}",
|
|
50
|
+
protocol: "1"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
apiTarget: offloadedFragment.apiTarget,
|
|
54
|
+
structure: offloadedFragment.structure,
|
|
55
|
+
dcbEventLog: offloadedFragment.dcbEventLog,
|
|
56
|
+
kind: offloadedFragment.kind
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
function writeAsset(def) {
|
|
60
|
+
return Util_Sury$Reventless.toJsonString(def, Plugin$Reventless.pluginDefinitionSchema, undefined);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
function readAsset(json) {
|
|
64
|
+
let dir = Nodefs.mkdtempSync(Nodepath.join(Nodeos.tmpdir(), "plugindef-"));
|
|
65
|
+
let previousCwd = process.cwd();
|
|
66
|
+
Nodefs.writeFileSync(Nodepath.join(dir, "pluginDefinition.json"), json, "utf8");
|
|
67
|
+
process.chdir(dir);
|
|
68
|
+
let restore = () => {
|
|
69
|
+
process.chdir(previousCwd);
|
|
70
|
+
Nodefs.rmSync(dir, {
|
|
71
|
+
recursive: true,
|
|
72
|
+
force: true
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
let def;
|
|
76
|
+
try {
|
|
77
|
+
def = EventCollectorEntryPoint_Ops$ReventlessAws.loadPluginDefinition();
|
|
78
|
+
} catch (exn) {
|
|
79
|
+
restore();
|
|
80
|
+
throw exn;
|
|
81
|
+
}
|
|
82
|
+
restore();
|
|
83
|
+
return def;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
globalThis.describe("pluginDefinition.json write/read symmetry", () => {
|
|
87
|
+
globalThis.test("an offloaded field reaches the runtime as Offloaded, not as its wire form", () => {
|
|
88
|
+
let def = readAsset(Util_Sury$Reventless.toJsonString(offloadedFragment, Plugin$Reventless.pluginDefinitionSchema, undefined));
|
|
89
|
+
let match = def.apiSchemaFragment;
|
|
90
|
+
if (match === undefined) {
|
|
91
|
+
return JestGlobals.fail("offloaded fragment decoded as None");
|
|
92
|
+
}
|
|
93
|
+
if (match.TAG === "Inline") {
|
|
94
|
+
return JestGlobals.fail("offloaded fragment decoded as Inline");
|
|
95
|
+
}
|
|
96
|
+
let match$1 = match._0;
|
|
97
|
+
globalThis.expect(match$1.store).toBe("pluginApiFragments");
|
|
98
|
+
globalThis.expect(match$1.bytes).toBe(14594);
|
|
99
|
+
});
|
|
100
|
+
globalThis.test("a definition read back from the asset can be published to the Connect handshake", () => {
|
|
101
|
+
[
|
|
102
|
+
offloadedFragment,
|
|
103
|
+
inlineFragment
|
|
104
|
+
].forEach(def => {
|
|
105
|
+
let published = Util_Sury$Reventless.toJson({
|
|
106
|
+
TAG: "ConnectPlugin",
|
|
107
|
+
_0: readAsset(Util_Sury$Reventless.toJsonString(def, Plugin$Reventless.pluginDefinitionSchema, undefined))
|
|
108
|
+
}, PluginExtensionPointSpec$ReventlessInfra.commandSchema);
|
|
109
|
+
globalThis.expect(Stdlib_Option.isSome(Stdlib_JSON.Decode.object(published))).toBe(true);
|
|
110
|
+
});
|
|
111
|
+
});
|
|
112
|
+
globalThis.test("the asset round-trips byte-identically, so no stored message shifts", () => {
|
|
113
|
+
let once = Util_Sury$Reventless.toJsonString(offloadedFragment, Plugin$Reventless.pluginDefinitionSchema, undefined);
|
|
114
|
+
let def = readAsset(once);
|
|
115
|
+
globalThis.expect(Util_Sury$Reventless.toJsonString(def, Plugin$Reventless.pluginDefinitionSchema, undefined)).toBe(once);
|
|
116
|
+
});
|
|
117
|
+
globalThis.test("an absent optional reaches the runtime as None, not as null", () => {
|
|
118
|
+
let def = readAsset(Util_Sury$Reventless.toJsonString(offloadedFragment, Plugin$Reventless.pluginDefinitionSchema, undefined));
|
|
119
|
+
globalThis.expect(Stdlib_Option.isNone(def.structure)).toBe(true);
|
|
120
|
+
globalThis.expect(Stdlib_Option.isNone(def.dcbEventLog)).toBe(true);
|
|
121
|
+
});
|
|
122
|
+
globalThis.test("the platform's own placeholder asset survives the same round trip", () => {
|
|
123
|
+
let def = readAsset(Util_Sury$Reventless.toJsonString(Platform_Admin_Structure$ReventlessCore.internalPluginDefinition, Plugin$Reventless.pluginDefinitionSchema, undefined));
|
|
124
|
+
globalThis.expect(def.id).toBe(Platform_Admin_Structure$ReventlessCore.pluginId + "@INTERNAL");
|
|
125
|
+
globalThis.expect(def.kind).toBe("Domain");
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
export {
|
|
130
|
+
offloadedFragment,
|
|
131
|
+
inlineFragment,
|
|
132
|
+
writeAsset,
|
|
133
|
+
readAsset,
|
|
134
|
+
}
|
|
135
|
+
/* Not a pure module */
|