@reventlessdev/reventless-spec 3.0.0-alpha.63 → 3.0.0-alpha.65

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 CHANGED
@@ -3,6 +3,22 @@
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.65 (2026-07-05)
7
+
8
+ ### Features
9
+
10
+ * @[@reventless](https://github.com/reventless).systemCallable slice opt-in for deploy-time system callers ([c5ed537](https://github.com/ReventlessDev/reventless-core/commit/c5ed537309f8e4b7d4a4d4af1ed1ec83d060aea3))
11
+ * **reventless-aws:** Postgres change-feed relay auto-wiring (B2.3d) ([62b430f](https://github.com/ReventlessDev/reventless-core/commit/62b430f1e6d8ec1f172de0cca324f7f26aaf5fcb))
12
+
13
+
14
+ # 3.0.0-alpha.64 (2026-07-03)
15
+
16
+ **Note:** Version bump only for package @reventlessdev/reventless-spec
17
+
18
+
19
+
20
+
21
+
6
22
  # 3.0.0-alpha.63 (2026-07-02)
7
23
 
8
24
  ### Bug Fixes
package/package.json CHANGED
@@ -1,18 +1,28 @@
1
1
  {
2
2
  "name": "@reventlessdev/reventless-spec",
3
- "version": "3.0.0-alpha.63",
3
+ "version": "3.0.0-alpha.65",
4
4
  "description": "Specifications for Reventless",
5
5
  "license": "Apache-2.0",
6
6
  "bin": {
7
7
  "generate-plugin": "./run-generator.mjs"
8
8
  },
9
+ "jest": {
10
+ "testMatch": [
11
+ "<rootDir>/tests/**/*Test.res.mjs"
12
+ ],
13
+ "moduleFileExtensions": [
14
+ "js",
15
+ "mjs"
16
+ ]
17
+ },
9
18
  "dependencies": {
10
19
  "jsonschema2graphql": "1.1.1",
11
20
  "sury": "11.0.0-alpha.4",
12
21
  "sury-ppx": "11.0.0-alpha.2"
13
22
  },
14
23
  "devDependencies": {
15
- "rescript": "^12.3.0"
24
+ "rescript": "^12.3.0",
25
+ "@reventlessdev/rescript-jest": "1.0.0-alpha.5"
16
26
  },
17
27
  "peerDependencies": {
18
28
  "rescript": "^12.3.0"
@@ -28,6 +38,8 @@
28
38
  "scripts": {
29
39
  "build": "rescript build",
30
40
  "start": "rescript start",
31
- "clean": "rescript clean"
41
+ "clean": "rescript clean",
42
+ "test": "NODE_OPTIONS='--experimental-vm-modules' jest",
43
+ "dev": "NODE_OPTIONS='--experimental-vm-modules' jest --watchAll"
32
44
  }
33
45
  }
package/rescript.json CHANGED
@@ -15,10 +15,15 @@
15
15
  {
16
16
  "dir": "src",
17
17
  "subdirs": true
18
+ },
19
+ {
20
+ "dir": "tests",
21
+ "subdirs": true
18
22
  }
19
23
  ],
20
24
  "dependencies": [
21
- "sury"
25
+ "sury",
26
+ "@reventlessdev/rescript-jest"
22
27
  ],
23
28
  "compiler-flags": [],
24
29
  "suffix": ".res.mjs"
@@ -0,0 +1,99 @@
1
+ // Single source of truth for the Reventless component-kind vocabulary: the kinds
2
+ // themselves, every accepted folder spelling (singular / plural / short form),
3
+ // the canonical folder name, and the body-file suffixes. The plugin generator
4
+ // (`generator/Discovery`) and the external tooling that classifies files by
5
+ // folder (`reventless-gwt`'s `ComponentMeta`) both derive from this, so the two
6
+ // can't drift — previously the generator accepted plural/short folder names that
7
+ // the gwt discovery silently didn't recognise.
8
+
9
+ type t =
10
+ | StateChangeSlice
11
+ | StateViewSlice
12
+ | StateViewSliceStream
13
+ | AutomationSlice
14
+ | InboundTranslationSlice
15
+ | OutboundTranslationSlice
16
+ | Aggregate
17
+ | ReadModel
18
+ | ReadModelStream
19
+ | Task
20
+ | ExtensionPoint
21
+ | Extension
22
+
23
+ let all = [
24
+ StateChangeSlice,
25
+ StateViewSlice,
26
+ StateViewSliceStream,
27
+ AutomationSlice,
28
+ InboundTranslationSlice,
29
+ OutboundTranslationSlice,
30
+ Aggregate,
31
+ ReadModel,
32
+ ReadModelStream,
33
+ Task,
34
+ ExtensionPoint,
35
+ Extension,
36
+ ]
37
+
38
+ // The canonical (singular) folder name for a kind — the spelling the naming
39
+ // conventions and the graph `kind` field use.
40
+ let folderName = (t: t): string =>
41
+ switch t {
42
+ | StateChangeSlice => "StateChangeSlice"
43
+ | StateViewSlice => "StateViewSlice"
44
+ | StateViewSliceStream => "StateViewSliceStream"
45
+ | AutomationSlice => "AutomationSlice"
46
+ | InboundTranslationSlice => "InboundTranslationSlice"
47
+ | OutboundTranslationSlice => "OutboundTranslationSlice"
48
+ | Aggregate => "Aggregate"
49
+ | ReadModel => "ReadModel"
50
+ | ReadModelStream => "ReadModelStream"
51
+ | Task => "Task"
52
+ | ExtensionPoint => "ExtensionPoint"
53
+ | Extension => "Extension"
54
+ }
55
+
56
+ // Every folder spelling that denotes a kind → the kind. Tolerates the singular,
57
+ // plural, and (for slices) short forms the generator has always accepted.
58
+ let folderToKind = (folder: string): option<t> =>
59
+ switch folder {
60
+ | "StateChange" | "StateChanges" | "StateChangeSlice" | "StateChangeSlices" =>
61
+ Some(StateChangeSlice)
62
+ | "StateView" | "StateViews" | "StateViewSlice" | "StateViewSlices" => Some(StateViewSlice)
63
+ | "StateViewSliceStream" | "StateViewSliceStreams" => Some(StateViewSliceStream)
64
+ | "Automation" | "Automations" | "AutomationSlice" | "AutomationSlices" => Some(AutomationSlice)
65
+ | "InboundTranslation"
66
+ | "InboundTranslations"
67
+ | "InboundTranslationSlice"
68
+ | "InboundTranslationSlices" =>
69
+ Some(InboundTranslationSlice)
70
+ | "OutboundTranslation"
71
+ | "OutboundTranslations"
72
+ | "OutboundTranslationSlice"
73
+ | "OutboundTranslationSlices" =>
74
+ Some(OutboundTranslationSlice)
75
+ | "Aggregate" | "Aggregates" => Some(Aggregate)
76
+ | "ReadModel" | "ReadModels" => Some(ReadModel)
77
+ | "ReadModelStream" | "ReadModelStreams" => Some(ReadModelStream)
78
+ | "Task" | "Tasks" => Some(Task)
79
+ | "ExtensionPoint" | "ExtensionPoints" => Some(ExtensionPoint)
80
+ | "Extension" | "Extensions" => Some(Extension)
81
+ | _ => None
82
+ }
83
+
84
+ let isKindFolder = (folder: string): bool => folderToKind(folder)->Option.isSome
85
+
86
+ // Body-file suffixes stripped to recover a component's spec stem (longest first,
87
+ // so `_ExtensionPointMapping` is removed before `_ExtensionPoint`). Spec and body
88
+ // files in one folder collapse to the same component name.
89
+ let bodySuffixes = [
90
+ "_ExtensionPointMapping",
91
+ "_ExtensionPoint",
92
+ "_Extension",
93
+ "_Projections",
94
+ "_Projection",
95
+ "_Mappings",
96
+ "_Behavior",
97
+ "_Automation",
98
+ "_Translation",
99
+ ]
@@ -0,0 +1,125 @@
1
+ // Generated by ReScript, PLEASE EDIT WITH CARE
2
+
3
+ import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
4
+
5
+ let all = [
6
+ "StateChangeSlice",
7
+ "StateViewSlice",
8
+ "StateViewSliceStream",
9
+ "AutomationSlice",
10
+ "InboundTranslationSlice",
11
+ "OutboundTranslationSlice",
12
+ "Aggregate",
13
+ "ReadModel",
14
+ "ReadModelStream",
15
+ "Task",
16
+ "ExtensionPoint",
17
+ "Extension"
18
+ ];
19
+
20
+ function folderName(t) {
21
+ switch (t) {
22
+ case "StateChangeSlice" :
23
+ return "StateChangeSlice";
24
+ case "StateViewSlice" :
25
+ return "StateViewSlice";
26
+ case "StateViewSliceStream" :
27
+ return "StateViewSliceStream";
28
+ case "AutomationSlice" :
29
+ return "AutomationSlice";
30
+ case "InboundTranslationSlice" :
31
+ return "InboundTranslationSlice";
32
+ case "OutboundTranslationSlice" :
33
+ return "OutboundTranslationSlice";
34
+ case "Aggregate" :
35
+ return "Aggregate";
36
+ case "ReadModel" :
37
+ return "ReadModel";
38
+ case "ReadModelStream" :
39
+ return "ReadModelStream";
40
+ case "Task" :
41
+ return "Task";
42
+ case "ExtensionPoint" :
43
+ return "ExtensionPoint";
44
+ case "Extension" :
45
+ return "Extension";
46
+ }
47
+ }
48
+
49
+ function folderToKind(folder) {
50
+ switch (folder) {
51
+ case "Aggregate" :
52
+ case "Aggregates" :
53
+ return "Aggregate";
54
+ case "Automation" :
55
+ case "AutomationSlice" :
56
+ case "AutomationSlices" :
57
+ case "Automations" :
58
+ return "AutomationSlice";
59
+ case "ExtensionPoint" :
60
+ case "ExtensionPoints" :
61
+ return "ExtensionPoint";
62
+ case "Extension" :
63
+ case "Extensions" :
64
+ return "Extension";
65
+ case "InboundTranslation" :
66
+ case "InboundTranslationSlice" :
67
+ case "InboundTranslationSlices" :
68
+ case "InboundTranslations" :
69
+ return "InboundTranslationSlice";
70
+ case "OutboundTranslation" :
71
+ case "OutboundTranslationSlice" :
72
+ case "OutboundTranslationSlices" :
73
+ case "OutboundTranslations" :
74
+ return "OutboundTranslationSlice";
75
+ case "ReadModelStream" :
76
+ case "ReadModelStreams" :
77
+ return "ReadModelStream";
78
+ case "ReadModel" :
79
+ case "ReadModels" :
80
+ return "ReadModel";
81
+ case "StateChange" :
82
+ case "StateChangeSlice" :
83
+ case "StateChangeSlices" :
84
+ case "StateChanges" :
85
+ return "StateChangeSlice";
86
+ case "StateViewSliceStream" :
87
+ case "StateViewSliceStreams" :
88
+ return "StateViewSliceStream";
89
+ case "StateView" :
90
+ case "StateViewSlice" :
91
+ case "StateViewSlices" :
92
+ case "StateViews" :
93
+ return "StateViewSlice";
94
+ case "Task" :
95
+ case "Tasks" :
96
+ return "Task";
97
+ default:
98
+ return;
99
+ }
100
+ }
101
+
102
+ function isKindFolder(folder) {
103
+ return Stdlib_Option.isSome(folderToKind(folder));
104
+ }
105
+
106
+ let bodySuffixes = [
107
+ "_ExtensionPointMapping",
108
+ "_ExtensionPoint",
109
+ "_Extension",
110
+ "_Projections",
111
+ "_Projection",
112
+ "_Mappings",
113
+ "_Behavior",
114
+ "_Automation",
115
+ "_Translation"
116
+ ];
117
+
118
+ export {
119
+ all,
120
+ folderName,
121
+ folderToKind,
122
+ isKindFolder,
123
+ bodySuffixes,
124
+ }
125
+ /* No side effect */
@@ -18,16 +18,7 @@ let buildVariantLookup = (schema: S.t<unknown>): dict<variantKind> => {
18
18
  anyOf->Array.forEach(variantSchema =>
19
19
  switch variantSchema {
20
20
  | Object({items, properties}) =>
21
- let tagName =
22
- items
23
- ->Array.find(item => item.location == "TAG")
24
- ->Option.flatMap(item =>
25
- switch item.schema {
26
- | String({const}) => Some(const)
27
- | _ => None
28
- }
29
- )
30
- switch tagName {
21
+ switch DcbTag.variantTagName(items) {
31
22
  | Some(name) =>
32
23
  let kind = if properties->Dict.keysToArray->Array.length == 0 {
33
24
  PayloadLess
@@ -45,16 +36,7 @@ let buildVariantLookup = (schema: S.t<unknown>): dict<variantKind> => {
45
36
  )
46
37
  | Object({items}) =>
47
38
  // Single-variant schema with fields
48
- let tagName =
49
- items
50
- ->Array.find(item => item.location == "TAG")
51
- ->Option.flatMap(item =>
52
- switch item.schema {
53
- | String({const}) => Some(const)
54
- | _ => None
55
- }
56
- )
57
- switch tagName {
39
+ switch DcbTag.variantTagName(items) {
58
40
  | Some(name) => lookup->Dict.set(name, WithFields)
59
41
  | None => ()
60
42
  }
@@ -1,8 +1,8 @@
1
1
  // Generated by ReScript, PLEASE EDIT WITH CARE
2
2
 
3
3
  import * as S from "sury/src/S.res.mjs";
4
- import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
5
4
  import * as Primitive_option from "@rescript/runtime/lib/es6/Primitive_option.js";
5
+ import * as DcbTag$Reventless from "./DcbTag.res.mjs";
6
6
 
7
7
  function buildVariantLookup(schema) {
8
8
  let lookup = {};
@@ -14,18 +14,9 @@ function buildVariantLookup(schema) {
14
14
  }
15
15
  break;
16
16
  case "object" :
17
- let tagName = Stdlib_Option.flatMap(schema.items.find(item => item.location === "TAG"), item => {
18
- let match = item.schema;
19
- if (match.type !== "string") {
20
- return;
21
- }
22
- let $$const = match.const;
23
- if ($$const !== undefined) {
24
- return $$const;
25
- }
26
- });
27
- if (tagName !== undefined) {
28
- lookup[tagName] = "WithFields";
17
+ let name$1 = DcbTag$Reventless.variantTagName(schema.items);
18
+ if (name$1 !== undefined) {
19
+ lookup[name$1] = "WithFields";
29
20
  }
30
21
  break;
31
22
  case "union" :
@@ -40,21 +31,12 @@ function buildVariantLookup(schema) {
40
31
  return;
41
32
  }
42
33
  case "object" :
43
- let tagName = Stdlib_Option.flatMap(variantSchema.items.find(item => item.location === "TAG"), item => {
44
- let match = item.schema;
45
- if (match.type !== "string") {
46
- return;
47
- }
48
- let $$const = match.const;
49
- if ($$const !== undefined) {
50
- return $$const;
51
- }
52
- });
53
- if (tagName === undefined) {
34
+ let name$1 = DcbTag$Reventless.variantTagName(variantSchema.items);
35
+ if (name$1 === undefined) {
54
36
  return;
55
37
  }
56
38
  let kind = Object.keys(variantSchema.properties).length === 0 ? "PayloadLess" : "WithFields";
57
- lookup[tagName] = kind;
39
+ lookup[name$1] = kind;
58
40
  return;
59
41
  default:
60
42
  return;
@@ -23,6 +23,7 @@ type tag = {key: string, value: string}
23
23
  Identifies which tag field is used as the storage partition key.
24
24
  The partition key determines how events are distributed across DynamoDB partitions.
25
25
  */
26
+ @schema
26
27
  type partitionTag = {key: string}
27
28
 
28
29
  /**
@@ -238,12 +239,14 @@ let isCompositePartitionMember = (fieldSchema: S.t<unknown>): bool =>
238
239
  Composite partition key specification — the ordered field names and inter-field separators.
239
240
  `seps[i]` is placed between `keys[i]` and `keys[i+1]`; length is always `keys.length - 1`.
240
241
  */
242
+ @schema
241
243
  type compositePartitionSpec = {
242
244
  keys: array<string>,
243
245
  seps: array<string>,
244
246
  }
245
247
 
246
248
  /** Union of simple and composite partition tag strategies. */
249
+ @schema
247
250
  type derivedPartitionTag =
248
251
  | Simple(partitionTag)
249
252
  | Composite(compositePartitionSpec)
@@ -331,6 +334,22 @@ let extractTagsFromProperties = (properties: dict<S.t<unknown>>, jsonDict: dict<
331
334
  }
332
335
  )
333
336
 
337
+ // Extract the discriminating TAG constructor name from a variant Object schema's
338
+ // `items`. sury compiles a record-payload variant `Foo({...})` to an Object whose
339
+ // `items` carry one entry at location "TAG" holding a `String` const = "Foo".
340
+ // Returns None for a non-tagged object (no TAG item, or a non-const schema).
341
+ // Single source for the ~dozen previously-inlined identical extractions across
342
+ // this file, DcbDecode and DcbValidation.
343
+ let variantTagName = (items: array<S.item>): option<string> =>
344
+ items
345
+ ->Array.find(item => item.location == "TAG")
346
+ ->Option.flatMap(item =>
347
+ switch item.schema {
348
+ | String({const}) => Some(const)
349
+ | _ => None
350
+ }
351
+ )
352
+
334
353
  /**
335
354
  Extracts DCB tags from an event JSON value using the event's sury schema.
336
355
 
@@ -354,15 +373,7 @@ let extractTagsFromJson = (schema: S.t<unknown>, json: JSON.t): array<tag> =>
354
373
  } else {
355
374
  switch variantSchema {
356
375
  | Object({items, properties}) =>
357
- let variantTag = items
358
- ->Array.find(item => item.location == "TAG")
359
- ->Option.flatMap(item =>
360
- switch item.schema {
361
- | String({const}) => Some(const)
362
- | _ => None
363
- }
364
- )
365
- if variantTag == jsonTag {
376
+ if variantTagName(items) == jsonTag {
366
377
  extractTagsFromProperties(properties, jsonDict)
367
378
  } else {
368
379
  []
@@ -417,15 +428,7 @@ let extractVariantNames = (schema: S.t<'a>): array<string> => {
417
428
  | Union({anyOf}) =>
418
429
  anyOf->Array.filterMap(variantSchema =>
419
430
  switch variantSchema {
420
- | Object({items}) =>
421
- items
422
- ->Array.find(item => item.location == "TAG")
423
- ->Option.flatMap(item =>
424
- switch item.schema {
425
- | String({const}) => Some(const)
426
- | _ => None
427
- }
428
- )
431
+ | Object({items}) => variantTagName(items)
429
432
  // Payload-less variants (sury-compiled `S.literal("Name")` strings) are
430
433
  // intentionally excluded here: DCB event-type lookups can't WHERE-clause
431
434
  // on bare-string events, so Plugin_Structure.consumedEventTypes and
@@ -437,16 +440,7 @@ let extractVariantNames = (schema: S.t<'a>): array<string> => {
437
440
  | _ => None
438
441
  }
439
442
  )
440
- | Object({items}) =>
441
- items
442
- ->Array.find(item => item.location == "TAG")
443
- ->Option.flatMap(item =>
444
- switch item.schema {
445
- | String({const}) => Some([const])
446
- | _ => None
447
- }
448
- )
449
- ->Option.getOr([])
443
+ | Object({items}) => variantTagName(items)->Option.mapOr([], t => [t])
450
444
  | _ => []
451
445
  }
452
446
  }
@@ -466,29 +460,12 @@ let extractAllVariantNames = (schema: S.t<'a>): array<string> => {
466
460
  | Union({anyOf}) =>
467
461
  anyOf->Array.filterMap(variantSchema =>
468
462
  switch variantSchema {
469
- | Object({items}) =>
470
- items
471
- ->Array.find(item => item.location == "TAG")
472
- ->Option.flatMap(item =>
473
- switch item.schema {
474
- | String({const}) => Some(const)
475
- | _ => None
476
- }
477
- )
463
+ | Object({items}) => variantTagName(items)
478
464
  | String({const}) => Some(const)
479
465
  | _ => None
480
466
  }
481
467
  )
482
- | Object({items}) =>
483
- items
484
- ->Array.find(item => item.location == "TAG")
485
- ->Option.flatMap(item =>
486
- switch item.schema {
487
- | String({const}) => Some([const])
488
- | _ => None
489
- }
490
- )
491
- ->Option.getOr([])
468
+ | Object({items}) => variantTagName(items)->Option.mapOr([], t => [t])
492
469
  | String({const: ?Some(name)}) => [name]
493
470
  | _ => []
494
471
  }
@@ -514,29 +491,11 @@ let isVariantPayloadBearing = (schema: S.t<'a>, name: string): bool => {
514
491
  | Union({anyOf}) =>
515
492
  anyOf->Array.some(variantSchema =>
516
493
  switch variantSchema {
517
- | Object({items}) =>
518
- items
519
- ->Array.find(item => item.location == "TAG")
520
- ->Option.flatMap(item =>
521
- switch item.schema {
522
- | String({const}) => Some(const == name)
523
- | _ => None
524
- }
525
- )
526
- ->Option.getOr(false)
494
+ | Object({items}) => variantTagName(items)->Option.mapOr(false, t => t == name)
527
495
  | _ => false
528
496
  }
529
497
  )
530
- | Object({items}) =>
531
- items
532
- ->Array.find(item => item.location == "TAG")
533
- ->Option.flatMap(item =>
534
- switch item.schema {
535
- | String({const}) => Some(const == name)
536
- | _ => None
537
- }
538
- )
539
- ->Option.getOr(false)
498
+ | Object({items}) => variantTagName(items)->Option.mapOr(false, t => t == name)
540
499
  | _ => false
541
500
  }
542
501
  }
@@ -602,15 +561,7 @@ let extractTagsFromJsonExpanded = (schema: S.t<unknown>, json: JSON.t): array<ta
602
561
  } else {
603
562
  switch variantSchema {
604
563
  | Object({items, properties}) =>
605
- let variantTag = items
606
- ->Array.find(item => item.location == "TAG")
607
- ->Option.flatMap(item =>
608
- switch item.schema {
609
- | String({const}) => Some(const)
610
- | _ => None
611
- }
612
- )
613
- if variantTag == jsonTag {
564
+ if variantTagName(items) == jsonTag {
614
565
  extractTagsFromPropertiesExpanded(properties, jsonDict)
615
566
  } else {
616
567
  []
@@ -703,15 +654,9 @@ let extractTagKeysByEventType = (schema: S.t<'a>): dict<array<string>> => {
703
654
  let addVariant = (variantSchema: S.t<unknown>) =>
704
655
  switch variantSchema {
705
656
  | Object({items, properties}) =>
706
- items
707
- ->Array.find(item => item.location == "TAG")
708
- ->Option.flatMap(item =>
709
- switch item.schema {
710
- | String({const}) => Some(const)
711
- | _ => None
712
- }
657
+ variantTagName(items)->Option.forEach(eventType =>
658
+ result->Dict.set(eventType, tagKeysOfProperties(properties))
713
659
  )
714
- ->Option.forEach(eventType => result->Dict.set(eventType, tagKeysOfProperties(properties)))
715
660
  | _ => ()
716
661
  }
717
662
  switch schema->toUnknownSchema {
@@ -957,15 +902,10 @@ let eventShapesOfSchema = (schema: S.t<'a>): array<DcbScopeInference.eventShape>
957
902
  let ofVariant = (variantSchema: S.t<unknown>): option<DcbScopeInference.eventShape> =>
958
903
  switch variantSchema {
959
904
  | Object({items, properties}) =>
960
- items
961
- ->Array.find(item => item.location == "TAG")
962
- ->Option.flatMap(item =>
963
- switch item.schema {
964
- | String({const}) => Some(const)
965
- | _ => None
966
- }
967
- )
968
- ->Option.map(eventType => {DcbScopeInference.eventType, idFields: idFieldsOfProperties(properties)})
905
+ variantTagName(items)->Option.map(eventType => {
906
+ DcbScopeInference.eventType,
907
+ idFields: idFieldsOfProperties(properties),
908
+ })
969
909
  | String({const}) => Some({DcbScopeInference.eventType: const, idFields: []})
970
910
  | _ => None
971
911
  }
@@ -1091,17 +1031,7 @@ let findMultiTagVariantNames = (schema: S.t<unknown>): array<string> => {
1091
1031
  ->Array.filter(((_, fieldSchema)) => isTagged(fieldSchema))
1092
1032
  ->Array.length
1093
1033
  if tagCount > 1 {
1094
- Some(
1095
- items
1096
- ->Array.find(item => item.location == "TAG")
1097
- ->Option.flatMap(item =>
1098
- switch item.schema {
1099
- | String({const}) => Some(const)
1100
- | _ => None
1101
- }
1102
- )
1103
- ->Option.getOr("(unknown)"),
1104
- )
1034
+ Some(variantTagName(items)->Option.getOr("(unknown)"))
1105
1035
  } else {
1106
1036
  None
1107
1037
  }