@reventlessdev/reventless-local 3.0.0-alpha.168 → 3.0.0-alpha.170
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 +7 -7
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res +1 -1
- package/src/adapter/CommandGenerator/InboundTranslationResolvers_GraphQL.res.mjs +2 -2
- package/tests/adapter/GraphQL_SchemaInspectorTest.res +46 -1
- package/tests/adapter/GraphQL_SchemaInspectorTest.res.mjs +33 -1
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.170 (2026-07-27)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **aws:** keep InboundTranslationSlice runtime path out of the Pulumi graph ([9166cff](https://github.com/ReventlessDev/reventless-core/commit/9166cff85939012d12e44835e2eb79a88fd1b66a))
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
# 3.0.0-alpha.169 (2026-07-26)
|
|
14
|
+
|
|
15
|
+
### Bug Fixes
|
|
16
|
+
|
|
17
|
+
* **api:** preserve nullability for optional enum fields in generated GraphQL ([3110a4a](https://github.com/ReventlessDev/reventless-core/commit/3110a4af032440ba2639519f61f221960ac78fba))
|
|
18
|
+
|
|
19
|
+
|
|
6
20
|
# 3.0.0-alpha.168 (2026-07-26)
|
|
7
21
|
|
|
8
22
|
### Bug Fixes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-local",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.170",
|
|
4
4
|
"description": "Local platform for Reventless (in-memory or SQLite backend, for development and testing without AWS)",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"jest": {
|
|
@@ -32,15 +32,15 @@
|
|
|
32
32
|
"sury": "11.0.0-alpha.4",
|
|
33
33
|
"ws": "^8.18.0",
|
|
34
34
|
"@reventlessdev/rescript-effect": "0.1.0-alpha.31",
|
|
35
|
+
"@reventlessdev/rescript-graphql-yoga": "1.0.0-alpha.25",
|
|
35
36
|
"@reventlessdev/rescript-jest": "1.0.0-alpha.9",
|
|
36
|
-
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.17",
|
|
37
37
|
"@reventlessdev/rescript-mcp-sdk": "1.0.0-alpha.20",
|
|
38
|
-
"@reventlessdev/rescript-
|
|
39
|
-
"@reventlessdev/reventless-core": "3.0.0-alpha.
|
|
40
|
-
"@reventlessdev/reventless-graphql-server": "1.0.0-alpha.
|
|
41
|
-
"@reventlessdev/reventless-gwt": "1.0.0-alpha.128",
|
|
42
|
-
"@reventlessdev/reventless-postgres": "3.0.0-alpha.45",
|
|
38
|
+
"@reventlessdev/rescript-pulumi-pulumi": "2.3.0-alpha.17",
|
|
39
|
+
"@reventlessdev/reventless-core": "3.0.0-alpha.183",
|
|
40
|
+
"@reventlessdev/reventless-graphql-server": "1.0.0-alpha.30",
|
|
43
41
|
"@reventlessdev/reventless-infra": "3.0.0-alpha.105",
|
|
42
|
+
"@reventlessdev/reventless-gwt": "1.0.0-alpha.130",
|
|
43
|
+
"@reventlessdev/reventless-postgres": "3.0.0-alpha.47",
|
|
44
44
|
"@reventlessdev/reventless-spec": "3.0.0-alpha.81"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -57,7 +57,7 @@ let register = (~fieldName: string, ~externalInputSchema: S.t<unknown>, ~server:
|
|
|
57
57
|
let inputJson: JSON.t = args->Obj.magic
|
|
58
58
|
let receive = receiveRegistry->Dict.getUnsafe(fieldName)
|
|
59
59
|
let result = await receive(inputJson)
|
|
60
|
-
result->
|
|
60
|
+
result->InboundTranslationSlice_Callback.receiveResultToOutcome->CommandTopic.commandOutcomeToJson
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
let resolvers = Dict.make()
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as CommandTopic$ReventlessCore from "@reventlessdev/reventless-core/src/components/CommandTopic/CommandTopic.res.mjs";
|
|
4
|
-
import * as InboundTranslationSlice$ReventlessCore from "@reventlessdev/reventless-core/src/components/InboundTranslationSlice/InboundTranslationSlice.res.mjs";
|
|
5
4
|
import * as GraphQL_FragmentGenerator$ReventlessCore from "@reventlessdev/reventless-core/src/components/Api/GraphQL_FragmentGenerator.res.mjs";
|
|
5
|
+
import * as InboundTranslationSlice_Callback$ReventlessCore from "@reventlessdev/reventless-core/src/components/InboundTranslationSlice/InboundTranslationSlice_Callback.res.mjs";
|
|
6
6
|
import * as CommandGeneratorResolvers_GraphQL$ReventlessLocal from "./CommandGeneratorResolvers_GraphQL.res.mjs";
|
|
7
7
|
|
|
8
8
|
let receiveRegistry = {};
|
|
@@ -27,7 +27,7 @@ function register(fieldName, externalInputSchema, server) {
|
|
|
27
27
|
let resolver = async (_root, args, _ctx) => {
|
|
28
28
|
let receive = receiveRegistry[fieldName];
|
|
29
29
|
let result = await receive(args);
|
|
30
|
-
return CommandTopic$ReventlessCore.commandOutcomeToJson(
|
|
30
|
+
return CommandTopic$ReventlessCore.commandOutcomeToJson(InboundTranslationSlice_Callback$ReventlessCore.receiveResultToOutcome(result));
|
|
31
31
|
};
|
|
32
32
|
let resolvers = {};
|
|
33
33
|
resolvers[fieldName] = resolver;
|
|
@@ -27,6 +27,21 @@ type svState = {
|
|
|
27
27
|
price: float,
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
+
// Multi-variant enum used both as a required and as an optional state field, to pin
|
|
31
|
+
// the nullability the sury→GraphQL deriver must preserve for the optional case.
|
|
32
|
+
@schema
|
|
33
|
+
type sourceKind =
|
|
34
|
+
| @as("tagged") Tagged
|
|
35
|
+
| @as("ancestry") Ancestry
|
|
36
|
+
| @as("substrate") Substrate
|
|
37
|
+
|
|
38
|
+
@schema
|
|
39
|
+
type enumState = {
|
|
40
|
+
productId: @s.matches(Reventless.DcbTag.string) string,
|
|
41
|
+
requiredSource: sourceKind,
|
|
42
|
+
optionalSource?: sourceKind,
|
|
43
|
+
}
|
|
44
|
+
|
|
30
45
|
@schema
|
|
31
46
|
type addCommand = {
|
|
32
47
|
productId: @s.matches(Reventless.DcbTag.string) string,
|
|
@@ -907,8 +922,38 @@ describe("Plugin admin fragment — kind enum + kindEq filter", () => {
|
|
|
907
922
|
// kind is a real enum on the Plugin type (auto-derived from the payload-less variant)
|
|
908
923
|
expect(sdl->String.includes("enum Platform_PluginKind"))->toBe(true)
|
|
909
924
|
expect(sdl->String.includes("PlatformInfrastructure"))->toBe(true)
|
|
910
|
-
|
|
925
|
+
// `kind` is `option<pluginKind>` — nullable on purpose so a kind-less legacy row
|
|
926
|
+
// can't collapse the whole Platform_Plugins query. It must render without a `!`.
|
|
927
|
+
expect(sdl->String.includes("kind: Platform_PluginKind"))->toBe(true)
|
|
928
|
+
expect(sdl->String.includes("kind: Platform_PluginKind!"))->toBe(false)
|
|
911
929
|
// @scan folds a server-side equality filter for the panel split
|
|
912
930
|
expect(sdl->String.includes("kindEq: String"))->toBe(true)
|
|
913
931
|
})
|
|
914
932
|
})
|
|
933
|
+
|
|
934
|
+
describe("optional enum fields preserve GraphQL nullability", () => {
|
|
935
|
+
testPromise(
|
|
936
|
+
"required variant field → SomeEnum!; optional variant field → nullable SomeEnum",
|
|
937
|
+
async () => {
|
|
938
|
+
let fragment = ReventlessCore.GraphQL_FragmentGenerator.generate(
|
|
939
|
+
~mutationEntries=[],
|
|
940
|
+
~queryEntries=[
|
|
941
|
+
{
|
|
942
|
+
singleFieldName: "SV_Sourced",
|
|
943
|
+
listFieldName: "SV_Sourceds",
|
|
944
|
+
returnTypeName: "EnumState",
|
|
945
|
+
stateSchema: enumStateSchema->S.castToUnknown,
|
|
946
|
+
authorization: None,
|
|
947
|
+
includeIdParam: false,
|
|
948
|
+
},
|
|
949
|
+
],
|
|
950
|
+
)
|
|
951
|
+
let sdl = ReventlessCore.GraphQL_SchemaInspector.inspectFragment(fragment).sdlPreview
|
|
952
|
+
// A required variant field stays non-null.
|
|
953
|
+
expect(sdl->String.includes("requiredSource: EnumStateRequiredSource!"))->toBe(true)
|
|
954
|
+
// An optional variant field is nullable: the enum is present but never with a `!`.
|
|
955
|
+
expect(sdl->String.includes("optionalSource: EnumStateOptionalSource"))->toBe(true)
|
|
956
|
+
expect(sdl->String.includes("optionalSource: EnumStateOptionalSource!"))->toBe(false)
|
|
957
|
+
},
|
|
958
|
+
)
|
|
959
|
+
})
|
|
@@ -29,6 +29,18 @@ let svStateSchema = S.schema(s => ({
|
|
|
29
29
|
price: s.m(S.float)
|
|
30
30
|
}));
|
|
31
31
|
|
|
32
|
+
let sourceKindSchema = S.union([
|
|
33
|
+
S.literal("tagged"),
|
|
34
|
+
S.literal("ancestry"),
|
|
35
|
+
S.literal("substrate")
|
|
36
|
+
]);
|
|
37
|
+
|
|
38
|
+
let enumStateSchema = S.schema(s => ({
|
|
39
|
+
productId: s.m(DcbTag$Reventless.string),
|
|
40
|
+
requiredSource: s.m(sourceKindSchema),
|
|
41
|
+
optionalSource: s.m(S.option(sourceKindSchema))
|
|
42
|
+
}));
|
|
43
|
+
|
|
32
44
|
let addCommandSchema = S.schema(s => ({
|
|
33
45
|
productId: s.m(DcbTag$Reventless.string),
|
|
34
46
|
name: s.m(S.string)
|
|
@@ -641,11 +653,29 @@ globalThis.describe("Plugin admin fragment — kind enum + kindEq filter", () =>
|
|
|
641
653
|
let sdl = GraphQL_SchemaInspector$ReventlessCore.inspectFragment(fragment).sdlPreview;
|
|
642
654
|
globalThis.expect(sdl.includes("enum Platform_PluginKind")).toBe(true);
|
|
643
655
|
globalThis.expect(sdl.includes("PlatformInfrastructure")).toBe(true);
|
|
644
|
-
globalThis.expect(sdl.includes("kind: Platform_PluginKind
|
|
656
|
+
globalThis.expect(sdl.includes("kind: Platform_PluginKind")).toBe(true);
|
|
657
|
+
globalThis.expect(sdl.includes("kind: Platform_PluginKind!")).toBe(false);
|
|
645
658
|
globalThis.expect(sdl.includes("kindEq: String")).toBe(true);
|
|
646
659
|
});
|
|
647
660
|
});
|
|
648
661
|
|
|
662
|
+
globalThis.describe("optional enum fields preserve GraphQL nullability", () => {
|
|
663
|
+
globalThis.test("required variant field → SomeEnum!; optional variant field → nullable SomeEnum", async () => {
|
|
664
|
+
let fragment = GraphQL_FragmentGenerator$ReventlessCore.generate([], [{
|
|
665
|
+
singleFieldName: "SV_Sourced",
|
|
666
|
+
listFieldName: "SV_Sourceds",
|
|
667
|
+
returnTypeName: "EnumState",
|
|
668
|
+
stateSchema: enumStateSchema,
|
|
669
|
+
authorization: undefined,
|
|
670
|
+
includeIdParam: false
|
|
671
|
+
}]);
|
|
672
|
+
let sdl = GraphQL_SchemaInspector$ReventlessCore.inspectFragment(fragment).sdlPreview;
|
|
673
|
+
globalThis.expect(sdl.includes("requiredSource: EnumStateRequiredSource!")).toBe(true);
|
|
674
|
+
globalThis.expect(sdl.includes("optionalSource: EnumStateOptionalSource")).toBe(true);
|
|
675
|
+
globalThis.expect(sdl.includes("optionalSource: EnumStateOptionalSource!")).toBe(false);
|
|
676
|
+
});
|
|
677
|
+
});
|
|
678
|
+
|
|
649
679
|
let stringSchema = S.string;
|
|
650
680
|
|
|
651
681
|
let taggedSchema = DcbTag$Reventless.string;
|
|
@@ -661,6 +691,8 @@ export {
|
|
|
661
691
|
boolSchema,
|
|
662
692
|
testStateSchema,
|
|
663
693
|
svStateSchema,
|
|
694
|
+
sourceKindSchema,
|
|
695
|
+
enumStateSchema,
|
|
664
696
|
addCommandSchema,
|
|
665
697
|
unionCommandSchema,
|
|
666
698
|
dcbSingleCommandSchema,
|