@reventlessdev/reventless-spec 3.0.0-alpha.116 → 3.0.0-alpha.118
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 +29 -0
- package/package.json +4 -4
- package/schema/platform-api.graphql +11 -2
- package/src/components/CapabilityManifest.res +1 -1
- package/src/components/CapabilityManifest.res.mjs +13 -12
- package/src/components/DcbDecode.res +8 -8
- package/src/components/DcbDecode.res.mjs +9 -8
- package/src/components/DcbTag.res +43 -42
- package/src/components/DcbTag.res.mjs +90 -87
- package/src/components/DcbValidation.res +6 -6
- package/src/components/DcbValidation.res.mjs +6 -6
- package/src/components/DisplayName.res.mjs +3 -3
- package/src/components/Owner.res +1 -1
- package/src/components/Owner.res.mjs +7 -7
- package/src/components/Plugin.res +28 -11
- package/src/components/Plugin.res.mjs +134 -134
- package/src/components/Reference.res.mjs +5 -5
- package/src/components/StateAnnotations.res +44 -0
- package/src/components/StateAnnotations.res.mjs +3 -3
- package/src/generator/PlatformCodegen.res +17 -14
- package/src/generator/PlatformCodegen.res.mjs +1 -1
- package/src/generator/PlatformGenerator.res +1 -1
- package/src/semantic/Bytes.res.mjs +2 -2
- package/src/semantic/Color.res.mjs +2 -2
- package/src/semantic/Currency.res.mjs +167 -167
- package/src/semantic/DateRange.res.mjs +2 -2
- package/src/semantic/Duration.res.mjs +2 -2
- package/src/semantic/Email.res +2 -2
- package/src/semantic/Email.res.mjs +3 -2
- package/src/semantic/FileRef.res +28 -0
- package/src/semantic/FileRef.res.mjs +17 -0
- package/src/semantic/GeoPoint.res +14 -10
- package/src/semantic/GeoPoint.res.mjs +10 -17
- package/src/semantic/ImageRef.res +51 -0
- package/src/semantic/ImageRef.res.mjs +17 -0
- package/src/semantic/Media_Ref.res +33 -0
- package/src/semantic/Media_Ref.res.mjs +37 -0
- package/src/semantic/Money.res +7 -5
- package/src/semantic/Money.res.mjs +6 -9
- package/src/semantic/Offload.res +29 -43
- package/src/semantic/Offload.res.mjs +18 -49
- package/src/semantic/Percent.res.mjs +2 -2
- package/src/semantic/Phone.res.mjs +2 -2
- package/src/semantic/Semantic.res +24 -6
- package/src/semantic/Semantic.res.mjs +13 -12
- package/src/semantic/StorageRef.res +33 -19
- package/src/semantic/StorageRef.res.mjs +14 -14
- package/src/semantic/UploadableFile.res +30 -0
- package/src/semantic/UploadableFile.res.mjs +23 -0
- package/src/semantic/UploadableImage.res +56 -0
- package/src/semantic/UploadableImage.res.mjs +23 -0
- package/src/semantic/Url.res +8 -2
- package/src/semantic/Url.res.mjs +3 -2
- package/src/types/Authorization.res.mjs +7 -7
- package/src/types/DateTime.res.mjs +2 -2
- package/src/types/Id.res.mjs +6 -4
- package/src/types/Identity.res +0 -1
- package/src/types/Identity.res.mjs +12 -14
- package/src/types/Message.res +29 -10
- package/src/types/Message.res.mjs +56 -37
- package/src/types/ReadConsistency.res.mjs +5 -5
- package/src/types/Schedule.res.mjs +37 -37
- package/src/types/StoredEvent.res +2 -2
- package/src/types/StoredEvent.res.mjs +11 -10
- package/src/types/Visibility.res.mjs +4 -4
- package/src/util/Util_Sury.res +32 -0
- package/src/util/Util_Sury.res.mjs +39 -0
package/CHANGELOG.md
CHANGED
|
@@ -3,6 +3,35 @@
|
|
|
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.118 (2026-08-18)
|
|
7
|
+
|
|
8
|
+
### Bug Fixes
|
|
9
|
+
|
|
10
|
+
* **core:** report the real reason a decode failed ([233c835](https://github.com/ReventlessDev/reventless-core/commit/233c835be47cb83fbd247ab0d8a7073cad622fee)), closes [DZakh/sury#392](https://github.com/DZakh/sury/issues/392)
|
|
11
|
+
* feat(sury)!: migrate to sury 11.0.0-rc.1 ([2cf8969](https://github.com/ReventlessDev/reventless-core/commit/2cf8969a222ce1b775563668a4126cb20611966c))
|
|
12
|
+
### Features
|
|
13
|
+
|
|
14
|
+
* **spec,ppx:** uploadable types that derive their store from the field name ([722b404](https://github.com/ReventlessDev/reventless-core/commit/722b4044a2e8dfb6a34231d6bfb529526de38b20))
|
|
15
|
+
* **spec:** ImageRef and FileRef, for media the platform does not own ([a63425c](https://github.com/ReventlessDev/reventless-core/commit/a63425cba5fd381da6deaabccc94501739e3ad59))
|
|
16
|
+
|
|
17
|
+
### BREAKING CHANGES
|
|
18
|
+
|
|
19
|
+
* sury is a direct dependency of the published packages and
|
|
20
|
+
its schema and serialization surface changed; consumers must migrate to
|
|
21
|
+
sury 11.
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
# 3.0.0-alpha.117 (2026-08-18)
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* **api:** declare the reference door in the SDL every backend is built from ([5c1857e](https://github.com/ReventlessDev/reventless-core/commit/5c1857ea90ff40305a1c44a9e57043528e6a93aa))
|
|
30
|
+
### Features
|
|
31
|
+
|
|
32
|
+
* **core:** let a reference name a retired row, and let an elevated caller open one ([9e2623a](https://github.com/ReventlessDev/reventless-core/commit/9e2623a4b22487561607fcc0ca19d51726069ee4))
|
|
33
|
+
|
|
34
|
+
|
|
6
35
|
# 3.0.0-alpha.116 (2026-08-16)
|
|
7
36
|
|
|
8
37
|
### Features
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reventlessdev/reventless-spec",
|
|
3
|
-
"version": "3.0.0-alpha.
|
|
3
|
+
"version": "3.0.0-alpha.118",
|
|
4
4
|
"description": "Specifications for Reventless",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"bin": {
|
|
@@ -18,10 +18,10 @@
|
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
20
|
"jsonschema2graphql": "1.1.1",
|
|
21
|
-
"sury": "11.0.0-
|
|
22
|
-
"sury-ppx": "11.0.0-
|
|
21
|
+
"sury": "11.0.0-rc.1",
|
|
22
|
+
"sury-ppx": "11.0.0-rc.1",
|
|
23
23
|
"yaml": "^2.8.3",
|
|
24
|
-
"@reventlessdev/rescript-node": "2.0.0-alpha.
|
|
24
|
+
"@reventlessdev/rescript-node": "2.0.0-alpha.8"
|
|
25
25
|
},
|
|
26
26
|
"devDependencies": {
|
|
27
27
|
"rescript": "12.3.0",
|
|
@@ -178,6 +178,13 @@ enum Platform_PluginKind {
|
|
|
178
178
|
PlatformInfrastructure
|
|
179
179
|
}
|
|
180
180
|
|
|
181
|
+
type Platform_PluginRef {
|
|
182
|
+
id: ID!
|
|
183
|
+
label: String!
|
|
184
|
+
retired: Boolean!
|
|
185
|
+
retiredState: String
|
|
186
|
+
}
|
|
187
|
+
|
|
181
188
|
enum Platform_PluginStatus {
|
|
182
189
|
Connected
|
|
183
190
|
Disconnected
|
|
@@ -215,6 +222,7 @@ type Platform_ReadSideDef {
|
|
|
215
222
|
lifecycleField: String
|
|
216
223
|
linkedWriteSide: [String!]!
|
|
217
224
|
name: String!
|
|
225
|
+
namedWhenRetired: Boolean!
|
|
218
226
|
ownerField: String
|
|
219
227
|
queryField: String!
|
|
220
228
|
requiredAccess: [String!]
|
|
@@ -290,10 +298,11 @@ type PluginStatusChangeEvent {
|
|
|
290
298
|
|
|
291
299
|
type Query {
|
|
292
300
|
Platform_ComponentDefinitions: [Platform_ComponentDefinitionEntry!]!
|
|
293
|
-
Platform_Plugin(id: ID
|
|
301
|
+
Platform_Plugin(id: ID!, includeRetired: Boolean): Platform_Plugin
|
|
294
302
|
Platform_PluginStructures: [Platform_PluginStructureEntry!]!
|
|
295
303
|
Platform_Plugins(after: String, before: String, filter: Platform_PluginFilter, first: Int, includeRetired: Boolean, last: Int): Platform_PluginConnection!
|
|
296
|
-
Platform_PluginsByIds(ids: [String!]
|
|
304
|
+
Platform_PluginsByIds(ids: [String!]!, includeRetired: Boolean): [Platform_Plugin!]!
|
|
305
|
+
Platform_PluginsRefs(ids: [ID!]!): [Platform_PluginRef!]!
|
|
297
306
|
Platform_UIFragments: [Platform_UIFragmentEntry!]!
|
|
298
307
|
}
|
|
299
308
|
|
|
@@ -67,7 +67,7 @@ let fromStructure = (structure: Plugin.pluginStructure): t => {
|
|
|
67
67
|
no source change must produce a byte-identical file, so the committed
|
|
68
68
|
manifest never churns. */
|
|
69
69
|
let render = (manifest: t): string =>
|
|
70
|
-
JSON.stringify(manifest->
|
|
70
|
+
JSON.stringify(manifest->Util_Sury.toJson(schema), ~space=2) ++ "\n"
|
|
71
71
|
|
|
72
72
|
/** One call for the emit CLI: structure in, `capabilities.json` content out. */
|
|
73
73
|
let renderForStructure = (structure: Plugin.pluginStructure): string =>
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as Sury from "sury";
|
|
4
4
|
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
|
+
import * as Util_Sury$Reventless from "../util/Util_Sury.res.mjs";
|
|
6
7
|
|
|
7
|
-
let kindSchema =
|
|
8
|
+
let kindSchema = Sury.literal("ObjectStore");
|
|
8
9
|
|
|
9
|
-
let provenanceSchema =
|
|
10
|
-
component: s.m(
|
|
11
|
-
field: s.m(
|
|
12
|
-
annotation: s.m(
|
|
10
|
+
let provenanceSchema = Sury.$schema(s => ({
|
|
11
|
+
component: s.m(Sury.string),
|
|
12
|
+
field: s.m(Sury.string),
|
|
13
|
+
annotation: s.m(Sury.$option(Sury.string))
|
|
13
14
|
}));
|
|
14
15
|
|
|
15
|
-
let entrySchema =
|
|
16
|
+
let entrySchema = Sury.$schema(s => ({
|
|
16
17
|
kind: s.m(kindSchema),
|
|
17
|
-
key: s.m(
|
|
18
|
-
declaredBy: s.m(
|
|
18
|
+
key: s.m(Sury.string),
|
|
19
|
+
declaredBy: s.m(Sury.array(provenanceSchema))
|
|
19
20
|
}));
|
|
20
21
|
|
|
21
|
-
let schema =
|
|
22
|
-
capabilities: s.m(
|
|
22
|
+
let schema = Sury.$schema(s => ({
|
|
23
|
+
capabilities: s.m(Sury.array(entrySchema))
|
|
23
24
|
}));
|
|
24
25
|
|
|
25
26
|
function fromStructure(structure) {
|
|
@@ -42,7 +43,7 @@ function fromStructure(structure) {
|
|
|
42
43
|
}
|
|
43
44
|
|
|
44
45
|
function render(manifest) {
|
|
45
|
-
return JSON.stringify(
|
|
46
|
+
return JSON.stringify(Util_Sury$Reventless.toJson(manifest, schema), undefined, 2) + "\n";
|
|
46
47
|
}
|
|
47
48
|
|
|
48
49
|
function renderForStructure(structure) {
|
|
@@ -14,11 +14,11 @@ type variantKind =
|
|
|
14
14
|
let buildVariantLookup = (schema: S.t<unknown>): dict<variantKind> => {
|
|
15
15
|
let lookup = Dict.make()
|
|
16
16
|
switch schema {
|
|
17
|
-
|
|
|
17
|
+
| AnyOf({anyOf}) =>
|
|
18
18
|
anyOf->Array.forEach(variantSchema =>
|
|
19
19
|
switch variantSchema {
|
|
20
|
-
| Object({
|
|
21
|
-
switch DcbTag.variantTagName(
|
|
20
|
+
| Object({properties}) =>
|
|
21
|
+
switch DcbTag.variantTagName(properties) {
|
|
22
22
|
| Some(name) =>
|
|
23
23
|
let kind = if properties->Dict.keysToArray->Array.length == 0 {
|
|
24
24
|
PayloadLess
|
|
@@ -34,9 +34,9 @@ let buildVariantLookup = (schema: S.t<unknown>): dict<variantKind> => {
|
|
|
34
34
|
| _ => ()
|
|
35
35
|
}
|
|
36
36
|
)
|
|
37
|
-
| Object({
|
|
37
|
+
| Object({properties}) =>
|
|
38
38
|
// Single-variant schema with fields
|
|
39
|
-
switch DcbTag.variantTagName(
|
|
39
|
+
switch DcbTag.variantTagName(properties) {
|
|
40
40
|
| Some(name) => lookup->Dict.set(name, WithFields)
|
|
41
41
|
| None => ()
|
|
42
42
|
}
|
|
@@ -64,12 +64,12 @@ let buildPayloadLessConstructors = (schema: S.t<'event>, lookup: dict<variantKin
|
|
|
64
64
|
// For payload-less variants, we need to figure out what ReScript value
|
|
65
65
|
// corresponds to each TAG name. sury's schema for a union with payload-less
|
|
66
66
|
// variants encodes them as bare strings. So `| ItemCreated` serializes to
|
|
67
|
-
// JSON string "ItemCreated". We can use
|
|
67
|
+
// JSON string "ItemCreated". We can use Util_Sury.fromJson with the string.
|
|
68
68
|
lookup->Dict.toArray->Array.forEach(((tagName, kind)) =>
|
|
69
69
|
switch kind {
|
|
70
70
|
| PayloadLess =>
|
|
71
71
|
try {
|
|
72
|
-
let value = JSON.String(tagName)->
|
|
72
|
+
let value = JSON.String(tagName)->Util_Sury.fromJson(schema)
|
|
73
73
|
constructors->Dict.set(tagName, value)
|
|
74
74
|
} catch {
|
|
75
75
|
| _ => ()
|
|
@@ -100,7 +100,7 @@ let makeDecoder = (schema: S.t<'event>): makeDecoderResult<'event> => {
|
|
|
100
100
|
let jsonDict = data->Dict.copy
|
|
101
101
|
jsonDict->Dict.set("TAG", JSON.String(eventType))
|
|
102
102
|
try {
|
|
103
|
-
Some(JSON.Object(jsonDict)->
|
|
103
|
+
Some(JSON.Object(jsonDict)->Util_Sury.fromJson(schema))
|
|
104
104
|
} catch {
|
|
105
105
|
| _ =>
|
|
106
106
|
// A parse failure here means a stored event no longer matches the
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as S from "sury/src/S.res.mjs";
|
|
4
3
|
import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
|
|
5
4
|
import * as DcbTag$Reventless from "./DcbTag.res.mjs";
|
|
5
|
+
import * as Util_Sury$Reventless from "../util/Util_Sury.res.mjs";
|
|
6
6
|
|
|
7
7
|
function buildVariantLookup(schema) {
|
|
8
8
|
let lookup = {};
|
|
@@ -14,12 +14,12 @@ function buildVariantLookup(schema) {
|
|
|
14
14
|
}
|
|
15
15
|
break;
|
|
16
16
|
case "object" :
|
|
17
|
-
let name$1 = DcbTag$Reventless.variantTagName(schema.
|
|
17
|
+
let name$1 = DcbTag$Reventless.variantTagName(schema.properties);
|
|
18
18
|
if (name$1 !== undefined) {
|
|
19
19
|
lookup[name$1] = "WithFields";
|
|
20
20
|
}
|
|
21
21
|
break;
|
|
22
|
-
case "
|
|
22
|
+
case "anyOf" :
|
|
23
23
|
schema.anyOf.forEach(variantSchema => {
|
|
24
24
|
switch (variantSchema.type) {
|
|
25
25
|
case "string" :
|
|
@@ -31,11 +31,12 @@ function buildVariantLookup(schema) {
|
|
|
31
31
|
return;
|
|
32
32
|
}
|
|
33
33
|
case "object" :
|
|
34
|
-
let
|
|
34
|
+
let properties = variantSchema.properties;
|
|
35
|
+
let name$1 = DcbTag$Reventless.variantTagName(properties);
|
|
35
36
|
if (name$1 === undefined) {
|
|
36
37
|
return;
|
|
37
38
|
}
|
|
38
|
-
let kind = Object.keys(
|
|
39
|
+
let kind = Object.keys(properties).length === 0 ? "PayloadLess" : "WithFields";
|
|
39
40
|
lookup[name$1] = kind;
|
|
40
41
|
return;
|
|
41
42
|
default:
|
|
@@ -55,7 +56,7 @@ function buildPayloadLessConstructors(schema, lookup) {
|
|
|
55
56
|
return;
|
|
56
57
|
}
|
|
57
58
|
try {
|
|
58
|
-
let value =
|
|
59
|
+
let value = Util_Sury$Reventless.fromJson(tagName, schema);
|
|
59
60
|
constructors[tagName] = value;
|
|
60
61
|
return;
|
|
61
62
|
} catch (exn) {
|
|
@@ -80,7 +81,7 @@ function makeDecoder(schema) {
|
|
|
80
81
|
let jsonDict = Object.assign({}, data);
|
|
81
82
|
jsonDict["TAG"] = eventType;
|
|
82
83
|
try {
|
|
83
|
-
return Primitive_option.some(
|
|
84
|
+
return Primitive_option.some(Util_Sury$Reventless.fromJson(jsonDict, schema));
|
|
84
85
|
} catch (exn) {
|
|
85
86
|
console.warn("DcbDecode: dropped event `" + eventType + "` — payload does not match the current schema (drift?)");
|
|
86
87
|
return;
|
|
@@ -97,4 +98,4 @@ export {
|
|
|
97
98
|
buildPayloadLessConstructors,
|
|
98
99
|
makeDecoder,
|
|
99
100
|
}
|
|
100
|
-
/*
|
|
101
|
+
/* DcbTag-Reventless Not a pure module */
|
|
@@ -339,17 +339,18 @@ let extractTagsFromProperties = (properties: dict<S.t<unknown>>, jsonDict: dict<
|
|
|
339
339
|
)
|
|
340
340
|
|
|
341
341
|
// Extract the discriminating TAG constructor name from a variant Object schema's
|
|
342
|
-
// `
|
|
343
|
-
// `
|
|
344
|
-
// Returns None for a non-tagged object (no TAG
|
|
342
|
+
// `properties`. sury (11) compiles a record-payload variant `Foo({...})` to an
|
|
343
|
+
// Object whose `properties` include a `"TAG"` key holding a `String` const = "Foo".
|
|
344
|
+
// Returns None for a non-tagged object (no TAG property, or a non-const schema).
|
|
345
345
|
// Single source for the ~dozen previously-inlined identical extractions across
|
|
346
|
-
// this file, DcbDecode and DcbValidation.
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
->
|
|
351
|
-
|
|
352
|
-
|
|
346
|
+
// this file, DcbDecode and DcbValidation. (sury 11 replaced the alpha.4
|
|
347
|
+
// `items`/`location` introspection with `properties` — see docs/plans/sury-11-migration.md.)
|
|
348
|
+
let variantTagName = (properties: dict<S.t<unknown>>): option<string> =>
|
|
349
|
+
properties
|
|
350
|
+
->Dict.get("TAG")
|
|
351
|
+
->Option.flatMap(schema =>
|
|
352
|
+
switch schema {
|
|
353
|
+
| String({const: ?Some(name)}) => Some(name)
|
|
353
354
|
| _ => None
|
|
354
355
|
}
|
|
355
356
|
)
|
|
@@ -362,7 +363,7 @@ only the fields of the matching variant branch are inspected.
|
|
|
362
363
|
*/
|
|
363
364
|
let extractTagsFromJson = (schema: S.t<unknown>, json: JSON.t): array<tag> =>
|
|
364
365
|
switch schema {
|
|
365
|
-
|
|
|
366
|
+
| AnyOf({anyOf}) =>
|
|
366
367
|
switch json->JSON.Decode.object {
|
|
367
368
|
| Some(jsonDict) =>
|
|
368
369
|
let jsonTag = jsonDict->Dict.get("TAG")->Option.flatMap(j =>
|
|
@@ -376,8 +377,8 @@ let extractTagsFromJson = (schema: S.t<unknown>, json: JSON.t): array<tag> =>
|
|
|
376
377
|
acc
|
|
377
378
|
} else {
|
|
378
379
|
switch variantSchema {
|
|
379
|
-
| Object({
|
|
380
|
-
if variantTagName(
|
|
380
|
+
| Object({properties}) =>
|
|
381
|
+
if variantTagName(properties) == jsonTag {
|
|
381
382
|
extractTagsFromProperties(properties, jsonDict)
|
|
382
383
|
} else {
|
|
383
384
|
[]
|
|
@@ -415,7 +416,7 @@ let tags = DcbTag.extractTags(
|
|
|
415
416
|
```
|
|
416
417
|
*/
|
|
417
418
|
let extractTags = (schema: S.t<'a>, value: 'a): array<tag> =>
|
|
418
|
-
extractTagsFromJson(schema->toUnknownSchema, value->
|
|
419
|
+
extractTagsFromJson(schema->toUnknownSchema, value->Util_Sury.toJson(schema))
|
|
419
420
|
|
|
420
421
|
// --- Extract variant constructor names from a tagged union schema ---
|
|
421
422
|
// For a variant type like `type event = ItemCreated({...}) | ItemRenamed({...})`,
|
|
@@ -431,10 +432,10 @@ Used by the DCB runtime to build `queryItem.eventTypes` arrays automatically.
|
|
|
431
432
|
*/
|
|
432
433
|
let extractVariantNames = (schema: S.t<'a>): array<string> => {
|
|
433
434
|
switch schema->toUnknownSchema {
|
|
434
|
-
|
|
|
435
|
+
| AnyOf({anyOf}) =>
|
|
435
436
|
anyOf->Array.filterMap(variantSchema =>
|
|
436
437
|
switch variantSchema {
|
|
437
|
-
| Object({
|
|
438
|
+
| Object({properties}) => variantTagName(properties)
|
|
438
439
|
// Payload-less variants (sury-compiled `S.literal("Name")` strings) are
|
|
439
440
|
// intentionally excluded here: DCB event-type lookups can't WHERE-clause
|
|
440
441
|
// on bare-string events, so Plugin_Structure.consumedEventTypes and
|
|
@@ -446,7 +447,7 @@ let extractVariantNames = (schema: S.t<'a>): array<string> => {
|
|
|
446
447
|
| _ => None
|
|
447
448
|
}
|
|
448
449
|
)
|
|
449
|
-
| Object({
|
|
450
|
+
| Object({properties}) => variantTagName(properties)->Option.mapOr([], t => [t])
|
|
450
451
|
| _ => []
|
|
451
452
|
}
|
|
452
453
|
}
|
|
@@ -463,15 +464,15 @@ WHERE-clause filtering.
|
|
|
463
464
|
*/
|
|
464
465
|
let extractAllVariantNames = (schema: S.t<'a>): array<string> => {
|
|
465
466
|
switch schema->toUnknownSchema {
|
|
466
|
-
|
|
|
467
|
+
| AnyOf({anyOf}) =>
|
|
467
468
|
anyOf->Array.filterMap(variantSchema =>
|
|
468
469
|
switch variantSchema {
|
|
469
|
-
| Object({
|
|
470
|
+
| Object({properties}) => variantTagName(properties)
|
|
470
471
|
| String({const}) => Some(const)
|
|
471
472
|
| _ => None
|
|
472
473
|
}
|
|
473
474
|
)
|
|
474
|
-
| Object({
|
|
475
|
+
| Object({properties}) => variantTagName(properties)->Option.mapOr([], t => [t])
|
|
475
476
|
| String({const: ?Some(name)}) => [name]
|
|
476
477
|
| _ => []
|
|
477
478
|
}
|
|
@@ -494,14 +495,14 @@ let isVariantPayloadBearing = (schema: S.t<'a>, name: string): bool => {
|
|
|
494
495
|
false
|
|
495
496
|
} else {
|
|
496
497
|
switch schema->toUnknownSchema {
|
|
497
|
-
|
|
|
498
|
+
| AnyOf({anyOf}) =>
|
|
498
499
|
anyOf->Array.some(variantSchema =>
|
|
499
500
|
switch variantSchema {
|
|
500
|
-
| Object({
|
|
501
|
+
| Object({properties}) => variantTagName(properties)->Option.mapOr(false, t => t == name)
|
|
501
502
|
| _ => false
|
|
502
503
|
}
|
|
503
504
|
)
|
|
504
|
-
| Object({
|
|
505
|
+
| Object({properties}) => variantTagName(properties)->Option.mapOr(false, t => t == name)
|
|
505
506
|
| _ => false
|
|
506
507
|
}
|
|
507
508
|
}
|
|
@@ -552,7 +553,7 @@ instead of a single tag with the stringified array.
|
|
|
552
553
|
*/
|
|
553
554
|
let extractTagsFromJsonExpanded = (schema: S.t<unknown>, json: JSON.t): array<tag> =>
|
|
554
555
|
switch schema {
|
|
555
|
-
|
|
|
556
|
+
| AnyOf({anyOf}) =>
|
|
556
557
|
switch json->JSON.Decode.object {
|
|
557
558
|
| Some(jsonDict) =>
|
|
558
559
|
let jsonTag = jsonDict->Dict.get("TAG")->Option.flatMap(j =>
|
|
@@ -566,8 +567,8 @@ let extractTagsFromJsonExpanded = (schema: S.t<unknown>, json: JSON.t): array<ta
|
|
|
566
567
|
acc
|
|
567
568
|
} else {
|
|
568
569
|
switch variantSchema {
|
|
569
|
-
| Object({
|
|
570
|
-
if variantTagName(
|
|
570
|
+
| Object({properties}) =>
|
|
571
|
+
if variantTagName(properties) == jsonTag {
|
|
571
572
|
extractTagsFromPropertiesExpanded(properties, jsonDict)
|
|
572
573
|
} else {
|
|
573
574
|
[]
|
|
@@ -599,7 +600,7 @@ let tags = DcbTag.extractTagsExpanded(
|
|
|
599
600
|
```
|
|
600
601
|
*/
|
|
601
602
|
let extractTagsExpanded = (schema: S.t<'a>, value: 'a): array<tag> =>
|
|
602
|
-
extractTagsFromJsonExpanded(schema->toUnknownSchema, value->
|
|
603
|
+
extractTagsFromJsonExpanded(schema->toUnknownSchema, value->Util_Sury.toJson(schema))
|
|
603
604
|
|
|
604
605
|
// --- Automatic query construction from command schema ---
|
|
605
606
|
|
|
@@ -610,7 +611,7 @@ Used to automatically determine whether to build single-clause or multi-clause q
|
|
|
610
611
|
*/
|
|
611
612
|
let hasTaggedArrayFields = (schema: S.t<'a>): bool =>
|
|
612
613
|
switch schema->toUnknownSchema {
|
|
613
|
-
|
|
|
614
|
+
| AnyOf({anyOf}) =>
|
|
614
615
|
anyOf->Array.some(variantSchema =>
|
|
615
616
|
switch variantSchema {
|
|
616
617
|
| Object({properties}) =>
|
|
@@ -657,14 +658,14 @@ let extractTagKeysByEventType = (schema: S.t<'a>): dict<array<string>> => {
|
|
|
657
658
|
let result = Dict.make()
|
|
658
659
|
let addVariant = (variantSchema: S.t<unknown>) =>
|
|
659
660
|
switch variantSchema {
|
|
660
|
-
| Object({
|
|
661
|
-
variantTagName(
|
|
661
|
+
| Object({properties}) =>
|
|
662
|
+
variantTagName(properties)->Option.forEach(eventType =>
|
|
662
663
|
result->Dict.set(eventType, tagKeysOfProperties(properties))
|
|
663
664
|
)
|
|
664
665
|
| _ => ()
|
|
665
666
|
}
|
|
666
667
|
switch schema->toUnknownSchema {
|
|
667
|
-
|
|
|
668
|
+
| AnyOf({anyOf}) => anyOf->Array.forEach(addVariant)
|
|
668
669
|
| Object(_) as obj => addVariant(obj)
|
|
669
670
|
| _ => ()
|
|
670
671
|
}
|
|
@@ -789,7 +790,7 @@ For `CatalogEventLog.event` returns `["categoryId", "productId"]`.
|
|
|
789
790
|
*/
|
|
790
791
|
let extractTaggedFields = (schema: S.t<'event>): array<string> => {
|
|
791
792
|
switch schema->toUnknownSchema {
|
|
792
|
-
|
|
|
793
|
+
| AnyOf({anyOf}) =>
|
|
793
794
|
// For union types, collect tagged fields from all variants
|
|
794
795
|
let allFields = anyOf->Array.flatMap(variantSchema =>
|
|
795
796
|
switch variantSchema {
|
|
@@ -860,7 +861,7 @@ returns `["studentId"]`.
|
|
|
860
861
|
*/
|
|
861
862
|
let extractCrossPartitionTagKeys = (schema: S.t<'event>): array<string> => {
|
|
862
863
|
let keys = switch schema->toUnknownSchema {
|
|
863
|
-
|
|
|
864
|
+
| AnyOf({anyOf}) =>
|
|
864
865
|
anyOf->Array.flatMap(variantSchema =>
|
|
865
866
|
switch variantSchema {
|
|
866
867
|
| Object({properties}) => crossPartitionKeysOfProperties(properties)
|
|
@@ -905,8 +906,8 @@ return a single shape.
|
|
|
905
906
|
let eventShapesOfSchema = (schema: S.t<'a>): array<DcbScopeInference.eventShape> => {
|
|
906
907
|
let ofVariant = (variantSchema: S.t<unknown>): option<DcbScopeInference.eventShape> =>
|
|
907
908
|
switch variantSchema {
|
|
908
|
-
| Object({
|
|
909
|
-
variantTagName(
|
|
909
|
+
| Object({properties}) =>
|
|
910
|
+
variantTagName(properties)->Option.map(eventType => {
|
|
910
911
|
DcbScopeInference.eventType,
|
|
911
912
|
idFields: idFieldsOfProperties(properties),
|
|
912
913
|
})
|
|
@@ -914,7 +915,7 @@ let eventShapesOfSchema = (schema: S.t<'a>): array<DcbScopeInference.eventShape>
|
|
|
914
915
|
| _ => None
|
|
915
916
|
}
|
|
916
917
|
switch schema->toUnknownSchema {
|
|
917
|
-
|
|
|
918
|
+
| AnyOf({anyOf}) => anyOf->Array.filterMap(ofVariant)
|
|
918
919
|
| Object(_) as obj => ofVariant(obj)->Option.mapOr([], s => [s])
|
|
919
920
|
| _ => []
|
|
920
921
|
}
|
|
@@ -927,7 +928,7 @@ Extracts field names annotated with `@s.matches(DcbTag.partition)` from an event
|
|
|
927
928
|
*/
|
|
928
929
|
let extractPartitionTagFields = (schema: S.t<'event>): array<string> => {
|
|
929
930
|
switch schema->toUnknownSchema {
|
|
930
|
-
|
|
|
931
|
+
| AnyOf({anyOf}) =>
|
|
931
932
|
let allFields = anyOf->Array.flatMap(variantSchema =>
|
|
932
933
|
switch variantSchema {
|
|
933
934
|
| Object({properties}) =>
|
|
@@ -1063,7 +1064,7 @@ If so, a partition tag annotation is needed to disambiguate.
|
|
|
1063
1064
|
*/
|
|
1064
1065
|
let hasMultiTagVariant = (schema: S.t<unknown>): bool =>
|
|
1065
1066
|
switch schema {
|
|
1066
|
-
|
|
|
1067
|
+
| AnyOf({anyOf}) =>
|
|
1067
1068
|
anyOf->Array.some(variantSchema =>
|
|
1068
1069
|
switch variantSchema {
|
|
1069
1070
|
| Object({properties}) => {
|
|
@@ -1096,14 +1097,14 @@ let findMultiTagVariantNames = (schema: S.t<unknown>): array<string> => {
|
|
|
1096
1097
|
// Extract the variant name from a single object-variant schema via its TAG item.
|
|
1097
1098
|
let variantName = (variantSchema: S.t<unknown>): option<string> =>
|
|
1098
1099
|
switch variantSchema {
|
|
1099
|
-
| Object({
|
|
1100
|
+
| Object({properties}) => {
|
|
1100
1101
|
let tagCount =
|
|
1101
1102
|
properties
|
|
1102
1103
|
->Dict.toArray
|
|
1103
1104
|
->Array.filter(((_, fieldSchema)) => isTagged(fieldSchema))
|
|
1104
1105
|
->Array.length
|
|
1105
1106
|
if tagCount > 1 {
|
|
1106
|
-
Some(variantTagName(
|
|
1107
|
+
Some(variantTagName(properties)->Option.getOr("(unknown)"))
|
|
1107
1108
|
} else {
|
|
1108
1109
|
None
|
|
1109
1110
|
}
|
|
@@ -1112,7 +1113,7 @@ let findMultiTagVariantNames = (schema: S.t<unknown>): array<string> => {
|
|
|
1112
1113
|
}
|
|
1113
1114
|
|
|
1114
1115
|
switch schema {
|
|
1115
|
-
|
|
|
1116
|
+
| AnyOf({anyOf}) => anyOf->Array.filterMap(variantName)
|
|
1116
1117
|
| _ =>
|
|
1117
1118
|
// Single-variant event type — schema is the object directly
|
|
1118
1119
|
switch variantName(schema) {
|
|
@@ -1159,7 +1160,7 @@ let extractCompositePartitionFields = (schema: S.t<'event>): array<compositePart
|
|
|
1159
1160
|
}
|
|
1160
1161
|
})
|
|
1161
1162
|
switch schema->toUnknownSchema {
|
|
1162
|
-
|
|
|
1163
|
+
| AnyOf({anyOf}) =>
|
|
1163
1164
|
anyOf->Array.flatMap(variantSchema =>
|
|
1164
1165
|
switch variantSchema {
|
|
1165
1166
|
| Object({properties}) => collect(properties)
|