@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
|
@@ -105,13 +105,12 @@ type apiTarget = Domain | Platform
|
|
|
105
105
|
// Sury's nullableAsOption creates T | undefined | null which fails jsonableValidation
|
|
106
106
|
// inside union variant payloads. js_nullable creates T | null (no undefined) which is
|
|
107
107
|
// JSON-safe and passes jsonableValidation in all contexts.
|
|
108
|
-
@module("sury/src/Sury.res.mjs") external _jsNullable: (S.t<'a>, unit) => S.t<option<'a>> = "js_nullable"
|
|
109
108
|
let apiSchemaFragmentOffloadSchema = Offload.optionSchema(~store="pluginApiFragments", apiSchemaFragmentSchema)
|
|
110
|
-
let dcbEventLogOptionSchema =
|
|
109
|
+
let dcbEventLogOptionSchema = dcbEventLogDefinitionSchema->S.nullAsOption
|
|
111
110
|
// js_nullable creates T | null which passes sury's jsonableValidation inside union variant payloads.
|
|
112
|
-
let stringOptionSchema =
|
|
113
|
-
let stringArrayOptionSchema =
|
|
114
|
-
let boolOptionSchema =
|
|
111
|
+
let stringOptionSchema = S.string->S.nullAsOption
|
|
112
|
+
let stringArrayOptionSchema = S.array(S.string)->S.nullAsOption
|
|
113
|
+
let boolOptionSchema = S.bool->S.nullAsOption
|
|
115
114
|
|
|
116
115
|
// ── UI fragment manifest types ────────────────────────────────────────────────
|
|
117
116
|
|
|
@@ -147,7 +146,7 @@ type uiFragmentManifest = {
|
|
|
147
146
|
pages: array<pageManifestEntry>,
|
|
148
147
|
}
|
|
149
148
|
|
|
150
|
-
let uiFragmentManifestOptionSchema =
|
|
149
|
+
let uiFragmentManifestOptionSchema = uiFragmentManifestSchema->S.nullAsOption
|
|
151
150
|
|
|
152
151
|
// ── Plugin structure types (component metadata for Auto UI and event graph) ──
|
|
153
152
|
|
|
@@ -325,6 +324,26 @@ type queryableDef = {
|
|
|
325
324
|
*/
|
|
326
325
|
retiredValues: @s.matches(stringArrayOptionSchema) option<array<string>>,
|
|
327
326
|
/**
|
|
327
|
+
Whether this view publishes a **reference door**: the by-ids read that names a
|
|
328
|
+
retired row for any caller holding a pointer to it, projected to the row's id,
|
|
329
|
+
its `labelField` and the value of `retiredField`. Declared with
|
|
330
|
+
`@namedWhenRetired` on the state record.
|
|
331
|
+
|
|
332
|
+
Published so a client knows the door exists without probing for it — a query
|
|
333
|
+
against a field the schema does not have is a validation error, not an empty
|
|
334
|
+
answer, so "ask and see" is not a usable fallback here.
|
|
335
|
+
|
|
336
|
+
Nullable rather than a bare required bool, which is the rule this schema's own
|
|
337
|
+
tripwire enforces: a definition stored before the field existed would otherwise
|
|
338
|
+
decode with an invented value and a runtime warning. Absent and `false` mean the
|
|
339
|
+
same thing to every reader — the archive stays shut — but only one of them is
|
|
340
|
+
something the platform actually said.
|
|
341
|
+
|
|
342
|
+
It is never `true` without `retiredField`: the PPX refuses the annotation on a
|
|
343
|
+
record with no retirement.
|
|
344
|
+
*/
|
|
345
|
+
namedWhenRetired: @s.matches(boolOptionSchema) option<bool>,
|
|
346
|
+
/**
|
|
328
347
|
Component visibility hint (`@@reventless.visibility`). `Some("Internal")` marks a
|
|
329
348
|
ReadModel / StateViewSlice that the deployed AutoUI hides from its menu, drill-down
|
|
330
349
|
pages, web event graph and cross-plugin edges. `None` (absent) means Public. Internal
|
|
@@ -546,7 +565,7 @@ type extensionPointDef = {
|
|
|
546
565
|
|
|
547
566
|
// js_nullable creates `array | null` (not `| undefined`), which passes sury's
|
|
548
567
|
// jsonableValidation inside the pluginStructure union variant payload.
|
|
549
|
-
let extensionPointDefArrayOptionSchema =
|
|
568
|
+
let extensionPointDefArrayOptionSchema = S.array(extensionPointDefSchema)->S.nullAsOption
|
|
550
569
|
|
|
551
570
|
/**
|
|
552
571
|
One field's store requirement, with its provenance.
|
|
@@ -584,10 +603,8 @@ type requiredStoreDeclaration = {
|
|
|
584
603
|
annotation: @s.matches(stringOptionSchema) option<string>,
|
|
585
604
|
}
|
|
586
605
|
|
|
587
|
-
let requiredStoreDeclarationArrayOptionSchema =
|
|
588
|
-
S.array(requiredStoreDeclarationSchema)
|
|
589
|
-
(),
|
|
590
|
-
)
|
|
606
|
+
let requiredStoreDeclarationArrayOptionSchema =
|
|
607
|
+
S.array(requiredStoreDeclarationSchema)->S.nullAsOption
|
|
591
608
|
|
|
592
609
|
/**
|
|
593
610
|
Adding a field here? It has to be a shape a stale event can be healed into.
|
|
@@ -1,107 +1,110 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as Sury from "sury";
|
|
4
4
|
import * as Offload$Reventless from "../semantic/Offload.res.mjs";
|
|
5
|
-
import * as SuryResMjs from "sury/src/Sury.res.mjs";
|
|
6
5
|
|
|
7
|
-
let
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
let nameSchema = Sury.string;
|
|
7
|
+
|
|
8
|
+
let versionSchema = Sury.string;
|
|
9
|
+
|
|
10
|
+
let pluginKindSchema = Sury.union([
|
|
11
|
+
Sury.literal("Domain"),
|
|
12
|
+
Sury.literal("PlatformInfrastructure"),
|
|
13
|
+
Sury.literal("Commercial"),
|
|
14
|
+
Sury.literal("Marketplace")
|
|
12
15
|
]);
|
|
13
16
|
|
|
14
|
-
let extensionPointDefinitionSchema =
|
|
15
|
-
name: s.m(
|
|
16
|
-
commandTopic: s.m(
|
|
17
|
-
eventTopic: s.m(
|
|
17
|
+
let extensionPointDefinitionSchema = Sury.$schema(s => ({
|
|
18
|
+
name: s.m(Sury.string),
|
|
19
|
+
commandTopic: s.m(Sury.string),
|
|
20
|
+
eventTopic: s.m(Sury.string)
|
|
18
21
|
}));
|
|
19
22
|
|
|
20
|
-
let extensionDefinitionSchema =
|
|
21
|
-
name: s.m(
|
|
22
|
-
extensionPointName: s.m(
|
|
23
|
-
dcbSources: s.m(
|
|
23
|
+
let extensionDefinitionSchema = Sury.$schema(s => ({
|
|
24
|
+
name: s.m(Sury.string),
|
|
25
|
+
extensionPointName: s.m(Sury.string),
|
|
26
|
+
dcbSources: s.m(Sury.array(Sury.string))
|
|
24
27
|
}));
|
|
25
28
|
|
|
26
|
-
let dcbEventLogDefinitionSchema =
|
|
27
|
-
name: s.m(
|
|
28
|
-
eventTopicArn: s.m(
|
|
29
|
+
let dcbEventLogDefinitionSchema = Sury.$schema(s => ({
|
|
30
|
+
name: s.m(Sury.string),
|
|
31
|
+
eventTopicArn: s.m(Sury.string)
|
|
29
32
|
}));
|
|
30
33
|
|
|
31
|
-
let extensionProtocolSchema =
|
|
32
|
-
extensionPointName: s.m(
|
|
33
|
-
commandVersion: s.m(
|
|
34
|
-
eventVersion: s.m(
|
|
34
|
+
let extensionProtocolSchema = Sury.$schema(s => ({
|
|
35
|
+
extensionPointName: s.m(Sury.string),
|
|
36
|
+
commandVersion: s.m(Sury.string),
|
|
37
|
+
eventVersion: s.m(Sury.string)
|
|
35
38
|
}));
|
|
36
39
|
|
|
37
|
-
let apiSchemaFragmentSchema =
|
|
38
|
-
encoded: s.m(
|
|
39
|
-
protocol: s.m(
|
|
40
|
+
let apiSchemaFragmentSchema = Sury.$schema(s => ({
|
|
41
|
+
encoded: s.m(Sury.string),
|
|
42
|
+
protocol: s.m(Sury.string)
|
|
40
43
|
}));
|
|
41
44
|
|
|
42
|
-
let apiTargetSchema =
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
let apiTargetSchema = Sury.union([
|
|
46
|
+
Sury.literal("Domain"),
|
|
47
|
+
Sury.literal("Platform")
|
|
45
48
|
]);
|
|
46
49
|
|
|
47
50
|
let apiSchemaFragmentOffloadSchema = Offload$Reventless.optionSchema(undefined, "pluginApiFragments", undefined, apiSchemaFragmentSchema);
|
|
48
51
|
|
|
49
|
-
let dcbEventLogOptionSchema =
|
|
52
|
+
let dcbEventLogOptionSchema = Sury.$nullAsOption(dcbEventLogDefinitionSchema);
|
|
50
53
|
|
|
51
|
-
let stringOptionSchema =
|
|
54
|
+
let stringOptionSchema = Sury.$nullAsOption(Sury.string);
|
|
52
55
|
|
|
53
|
-
let stringArrayOptionSchema =
|
|
56
|
+
let stringArrayOptionSchema = Sury.$nullAsOption(Sury.array(Sury.string));
|
|
54
57
|
|
|
55
|
-
let boolOptionSchema =
|
|
58
|
+
let boolOptionSchema = Sury.$nullAsOption(Sury.bool);
|
|
56
59
|
|
|
57
|
-
let panelManifestEntrySchema =
|
|
58
|
-
fragmentId: s.m(
|
|
59
|
-
title: s.m(
|
|
60
|
-
description: s.m(
|
|
61
|
-
positions: s.m(
|
|
60
|
+
let panelManifestEntrySchema = Sury.$schema(s => ({
|
|
61
|
+
fragmentId: s.m(Sury.string),
|
|
62
|
+
title: s.m(Sury.string),
|
|
63
|
+
description: s.m(Sury.string),
|
|
64
|
+
positions: s.m(Sury.array(Sury.string)),
|
|
62
65
|
requiredAccess: s.m(stringOptionSchema)
|
|
63
66
|
}));
|
|
64
67
|
|
|
65
|
-
let menuEntrySchema =
|
|
66
|
-
label: s.m(
|
|
68
|
+
let menuEntrySchema = Sury.$schema(s => ({
|
|
69
|
+
label: s.m(Sury.string),
|
|
67
70
|
icon: s.m(stringOptionSchema),
|
|
68
71
|
group: s.m(stringOptionSchema),
|
|
69
|
-
sortOrder: s.m(
|
|
72
|
+
sortOrder: s.m(Sury.int)
|
|
70
73
|
}));
|
|
71
74
|
|
|
72
|
-
let pageManifestEntrySchema =
|
|
73
|
-
fragmentId: s.m(
|
|
74
|
-
title: s.m(
|
|
75
|
+
let pageManifestEntrySchema = Sury.$schema(s => ({
|
|
76
|
+
fragmentId: s.m(Sury.string),
|
|
77
|
+
title: s.m(Sury.string),
|
|
75
78
|
menuEntry: s.m(menuEntrySchema),
|
|
76
79
|
requiredAccess: s.m(stringOptionSchema)
|
|
77
80
|
}));
|
|
78
81
|
|
|
79
|
-
let uiFragmentManifestSchema =
|
|
80
|
-
remoteEntryUrl: s.m(
|
|
81
|
-
panels: s.m(
|
|
82
|
-
pages: s.m(
|
|
82
|
+
let uiFragmentManifestSchema = Sury.$schema(s => ({
|
|
83
|
+
remoteEntryUrl: s.m(Sury.string),
|
|
84
|
+
panels: s.m(Sury.array(panelManifestEntrySchema)),
|
|
85
|
+
pages: s.m(Sury.array(pageManifestEntrySchema))
|
|
83
86
|
}));
|
|
84
87
|
|
|
85
|
-
let uiFragmentManifestOptionSchema =
|
|
88
|
+
let uiFragmentManifestOptionSchema = Sury.$nullAsOption(uiFragmentManifestSchema);
|
|
86
89
|
|
|
87
|
-
let commandLevelSchema =
|
|
88
|
-
|
|
89
|
-
|
|
90
|
+
let commandLevelSchema = Sury.union([
|
|
91
|
+
Sury.literal("Collection"),
|
|
92
|
+
Sury.literal("Instance")
|
|
90
93
|
]);
|
|
91
94
|
|
|
92
|
-
let fieldReferenceSchema =
|
|
93
|
-
fieldName: s.m(
|
|
94
|
-
entity: s.m(
|
|
95
|
+
let fieldReferenceSchema = Sury.$schema(s => ({
|
|
96
|
+
fieldName: s.m(Sury.string),
|
|
97
|
+
entity: s.m(Sury.string),
|
|
95
98
|
plugin: s.m(stringOptionSchema)
|
|
96
99
|
}));
|
|
97
100
|
|
|
98
|
-
let commandDefSchema =
|
|
99
|
-
name: s.m(
|
|
100
|
-
schema: s.m(
|
|
101
|
+
let commandDefSchema = Sury.$schema(s => ({
|
|
102
|
+
name: s.m(Sury.string),
|
|
103
|
+
schema: s.m(Sury.string),
|
|
101
104
|
level: s.m(commandLevelSchema),
|
|
102
105
|
aggregateIdField: s.m(stringOptionSchema),
|
|
103
|
-
mutationField: s.m(
|
|
104
|
-
references: s.m(
|
|
106
|
+
mutationField: s.m(Sury.string),
|
|
107
|
+
references: s.m(Sury.array(fieldReferenceSchema)),
|
|
105
108
|
allowedStates: s.m(stringArrayOptionSchema),
|
|
106
109
|
targetState: s.m(stringOptionSchema),
|
|
107
110
|
apiExposed: s.m(boolOptionSchema),
|
|
@@ -109,19 +112,20 @@ let commandDefSchema = S.schema(s => ({
|
|
|
109
112
|
ownerField: s.m(stringOptionSchema)
|
|
110
113
|
}));
|
|
111
114
|
|
|
112
|
-
let queryableDefSchema =
|
|
113
|
-
name: s.m(
|
|
114
|
-
queryField: s.m(
|
|
115
|
-
schema: s.m(
|
|
116
|
-
consumedEventTypes: s.m(
|
|
117
|
-
linkedWriteSide: s.m(
|
|
118
|
-
labelField: s.m(
|
|
119
|
-
searchableFields: s.m(
|
|
115
|
+
let queryableDefSchema = Sury.$schema(s => ({
|
|
116
|
+
name: s.m(Sury.string),
|
|
117
|
+
queryField: s.m(Sury.string),
|
|
118
|
+
schema: s.m(Sury.string),
|
|
119
|
+
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
120
|
+
linkedWriteSide: s.m(Sury.array(Sury.string)),
|
|
121
|
+
labelField: s.m(Sury.string),
|
|
122
|
+
searchableFields: s.m(Sury.array(Sury.string)),
|
|
120
123
|
labelFieldSource: s.m(stringOptionSchema),
|
|
121
124
|
lifecycleField: s.m(stringOptionSchema),
|
|
122
125
|
ownerField: s.m(stringOptionSchema),
|
|
123
126
|
retiredField: s.m(stringOptionSchema),
|
|
124
127
|
retiredValues: s.m(stringArrayOptionSchema),
|
|
128
|
+
namedWhenRetired: s.m(boolOptionSchema),
|
|
125
129
|
visibility: s.m(stringOptionSchema),
|
|
126
130
|
chapter: s.m(stringOptionSchema),
|
|
127
131
|
singleQueryField: s.m(stringOptionSchema),
|
|
@@ -130,89 +134,89 @@ let queryableDefSchema = S.schema(s => ({
|
|
|
130
134
|
requiredAccess: s.m(stringArrayOptionSchema)
|
|
131
135
|
}));
|
|
132
136
|
|
|
133
|
-
let eventDefSchema =
|
|
134
|
-
name: s.m(
|
|
135
|
-
schema: s.m(
|
|
136
|
-
references: s.m(
|
|
137
|
+
let eventDefSchema = Sury.$schema(s => ({
|
|
138
|
+
name: s.m(Sury.string),
|
|
139
|
+
schema: s.m(Sury.string),
|
|
140
|
+
references: s.m(Sury.array(fieldReferenceSchema))
|
|
137
141
|
}));
|
|
138
142
|
|
|
139
|
-
let errorDefSchema =
|
|
140
|
-
name: s.m(
|
|
141
|
-
schema: s.m(
|
|
142
|
-
references: s.m(
|
|
143
|
+
let errorDefSchema = Sury.$schema(s => ({
|
|
144
|
+
name: s.m(Sury.string),
|
|
145
|
+
schema: s.m(Sury.string),
|
|
146
|
+
references: s.m(Sury.array(fieldReferenceSchema))
|
|
143
147
|
}));
|
|
144
148
|
|
|
145
|
-
let writableDefSchema =
|
|
146
|
-
name: s.m(
|
|
147
|
-
commands: s.m(
|
|
148
|
-
producedEventTypes: s.m(
|
|
149
|
-
consumedEventTypes: s.m(
|
|
150
|
-
linkedViews: s.m(
|
|
149
|
+
let writableDefSchema = Sury.$schema(s => ({
|
|
150
|
+
name: s.m(Sury.string),
|
|
151
|
+
commands: s.m(Sury.array(commandDefSchema)),
|
|
152
|
+
producedEventTypes: s.m(Sury.array(Sury.string)),
|
|
153
|
+
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
154
|
+
linkedViews: s.m(Sury.array(Sury.string)),
|
|
151
155
|
consistencyRead: s.m(stringOptionSchema),
|
|
152
|
-
events: s.m(
|
|
153
|
-
errors: s.m(
|
|
156
|
+
events: s.m(Sury.array(eventDefSchema)),
|
|
157
|
+
errors: s.m(Sury.array(errorDefSchema)),
|
|
154
158
|
chapter: s.m(stringOptionSchema)
|
|
155
159
|
}));
|
|
156
160
|
|
|
157
|
-
let automationSliceDefSchema =
|
|
158
|
-
name: s.m(
|
|
159
|
-
consumedEventTypes: s.m(
|
|
160
|
-
producedCommandTypes: s.m(
|
|
161
|
-
targetName: s.m(
|
|
161
|
+
let automationSliceDefSchema = Sury.$schema(s => ({
|
|
162
|
+
name: s.m(Sury.string),
|
|
163
|
+
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
164
|
+
producedCommandTypes: s.m(Sury.array(Sury.string)),
|
|
165
|
+
targetName: s.m(Sury.string),
|
|
162
166
|
chapter: s.m(stringOptionSchema)
|
|
163
167
|
}));
|
|
164
168
|
|
|
165
|
-
let outboundTranslationSliceDefSchema =
|
|
166
|
-
name: s.m(
|
|
167
|
-
consumedEventTypes: s.m(
|
|
168
|
-
inboundCommandTypes: s.m(
|
|
169
|
+
let outboundTranslationSliceDefSchema = Sury.$schema(s => ({
|
|
170
|
+
name: s.m(Sury.string),
|
|
171
|
+
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
172
|
+
inboundCommandTypes: s.m(Sury.array(Sury.string)),
|
|
169
173
|
targetName: s.m(stringOptionSchema),
|
|
170
174
|
externalSystem: s.m(stringOptionSchema),
|
|
171
175
|
chapter: s.m(stringOptionSchema)
|
|
172
176
|
}));
|
|
173
177
|
|
|
174
|
-
let inboundTranslationSliceDefSchema =
|
|
175
|
-
name: s.m(
|
|
176
|
-
commandTypes: s.m(
|
|
177
|
-
targetName: s.m(
|
|
178
|
+
let inboundTranslationSliceDefSchema = Sury.$schema(s => ({
|
|
179
|
+
name: s.m(Sury.string),
|
|
180
|
+
commandTypes: s.m(Sury.array(Sury.string)),
|
|
181
|
+
targetName: s.m(Sury.string),
|
|
178
182
|
externalSystem: s.m(stringOptionSchema),
|
|
179
183
|
chapter: s.m(stringOptionSchema)
|
|
180
184
|
}));
|
|
181
185
|
|
|
182
|
-
let extensionDefSchema =
|
|
183
|
-
name: s.m(
|
|
184
|
-
delegateNames: s.m(
|
|
185
|
-
eventTypes: s.m(
|
|
186
|
-
commandTypes: s.m(
|
|
186
|
+
let extensionDefSchema = Sury.$schema(s => ({
|
|
187
|
+
name: s.m(Sury.string),
|
|
188
|
+
delegateNames: s.m(Sury.array(Sury.string)),
|
|
189
|
+
eventTypes: s.m(Sury.array(Sury.string)),
|
|
190
|
+
commandTypes: s.m(Sury.array(Sury.string))
|
|
187
191
|
}));
|
|
188
192
|
|
|
189
|
-
let extensionPointDefSchema =
|
|
190
|
-
name: s.m(
|
|
191
|
-
delegateNames: s.m(
|
|
192
|
-
sourceEventTypes: s.m(
|
|
193
|
+
let extensionPointDefSchema = Sury.$schema(s => ({
|
|
194
|
+
name: s.m(Sury.string),
|
|
195
|
+
delegateNames: s.m(Sury.array(Sury.string)),
|
|
196
|
+
sourceEventTypes: s.m(Sury.array(Sury.string)),
|
|
193
197
|
commandTypes: s.m(stringArrayOptionSchema)
|
|
194
198
|
}));
|
|
195
199
|
|
|
196
|
-
let extensionPointDefArrayOptionSchema =
|
|
200
|
+
let extensionPointDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(extensionPointDefSchema));
|
|
197
201
|
|
|
198
|
-
let requiredStoreDeclarationSchema =
|
|
199
|
-
store: s.m(
|
|
200
|
-
component: s.m(
|
|
201
|
-
field: s.m(
|
|
202
|
+
let requiredStoreDeclarationSchema = Sury.$schema(s => ({
|
|
203
|
+
store: s.m(Sury.string),
|
|
204
|
+
component: s.m(Sury.string),
|
|
205
|
+
field: s.m(Sury.string),
|
|
202
206
|
annotation: s.m(stringOptionSchema)
|
|
203
207
|
}));
|
|
204
208
|
|
|
205
|
-
let requiredStoreDeclarationArrayOptionSchema =
|
|
206
|
-
|
|
207
|
-
let pluginStructureSchema =
|
|
208
|
-
readModels: s.m(
|
|
209
|
-
stateViewSlices: s.m(
|
|
210
|
-
stateChangeSlices: s.m(
|
|
211
|
-
aggregates: s.m(
|
|
212
|
-
automationSlices: s.m(
|
|
213
|
-
outboundTranslationSlices: s.m(
|
|
214
|
-
inboundTranslationSlices: s.m(
|
|
215
|
-
extensions: s.m(
|
|
209
|
+
let requiredStoreDeclarationArrayOptionSchema = Sury.$nullAsOption(Sury.array(requiredStoreDeclarationSchema));
|
|
210
|
+
|
|
211
|
+
let pluginStructureSchema = Sury.$schema(s => ({
|
|
212
|
+
readModels: s.m(Sury.array(queryableDefSchema)),
|
|
213
|
+
stateViewSlices: s.m(Sury.array(queryableDefSchema)),
|
|
214
|
+
stateChangeSlices: s.m(Sury.array(writableDefSchema)),
|
|
215
|
+
aggregates: s.m(Sury.array(writableDefSchema)),
|
|
216
|
+
automationSlices: s.m(Sury.array(automationSliceDefSchema)),
|
|
217
|
+
outboundTranslationSlices: s.m(Sury.array(outboundTranslationSliceDefSchema)),
|
|
218
|
+
inboundTranslationSlices: s.m(Sury.array(inboundTranslationSliceDefSchema)),
|
|
219
|
+
extensions: s.m(Sury.array(extensionDefSchema)),
|
|
216
220
|
extensionPoints: s.m(extensionPointDefArrayOptionSchema),
|
|
217
221
|
requiredStores: s.m(stringArrayOptionSchema),
|
|
218
222
|
requiredStoreDeclarations: s.m(requiredStoreDeclarationArrayOptionSchema)
|
|
@@ -220,14 +224,14 @@ let pluginStructureSchema = S.schema(s => ({
|
|
|
220
224
|
|
|
221
225
|
let pluginStructureOffloadSchema = Offload$Reventless.optionSchema(undefined, "pluginStructures", undefined, pluginStructureSchema);
|
|
222
226
|
|
|
223
|
-
let pluginDefinitionSchema =
|
|
224
|
-
id: s.m(
|
|
225
|
-
name: s.m(
|
|
226
|
-
version: s.m(
|
|
227
|
-
extensionPoints: s.m(
|
|
228
|
-
extensions: s.m(
|
|
229
|
-
eventCollector: s.m(
|
|
230
|
-
extensionProtocols: s.m(
|
|
227
|
+
let pluginDefinitionSchema = Sury.$schema(s => ({
|
|
228
|
+
id: s.m(Sury.string),
|
|
229
|
+
name: s.m(nameSchema),
|
|
230
|
+
version: s.m(versionSchema),
|
|
231
|
+
extensionPoints: s.m(Sury.array(extensionPointDefinitionSchema)),
|
|
232
|
+
extensions: s.m(Sury.array(extensionDefinitionSchema)),
|
|
233
|
+
eventCollector: s.m(Sury.string),
|
|
234
|
+
extensionProtocols: s.m(Sury.array(extensionProtocolSchema)),
|
|
231
235
|
apiSchemaFragment: s.m(apiSchemaFragmentOffloadSchema),
|
|
232
236
|
apiTarget: s.m(stringOptionSchema),
|
|
233
237
|
structure: s.m(pluginStructureOffloadSchema),
|
|
@@ -235,10 +239,6 @@ let pluginDefinitionSchema = S.schema(s => ({
|
|
|
235
239
|
kind: s.m(pluginKindSchema)
|
|
236
240
|
}));
|
|
237
241
|
|
|
238
|
-
let nameSchema = S.string;
|
|
239
|
-
|
|
240
|
-
let versionSchema = S.string;
|
|
241
|
-
|
|
242
242
|
export {
|
|
243
243
|
nameSchema,
|
|
244
244
|
versionSchema,
|
|
@@ -278,4 +278,4 @@ export {
|
|
|
278
278
|
pluginStructureOffloadSchema,
|
|
279
279
|
pluginDefinitionSchema,
|
|
280
280
|
}
|
|
281
|
-
/*
|
|
281
|
+
/* nameSchema Not a pure module */
|
|
@@ -1,12 +1,12 @@
|
|
|
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_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
5
|
import * as DcbTag$Reventless from "./DcbTag.res.mjs";
|
|
6
6
|
import * as Semantic$Reventless from "../semantic/Semantic.res.mjs";
|
|
7
7
|
|
|
8
8
|
function to_(plugin, key, entity) {
|
|
9
|
-
let base = Semantic$Reventless.mark(
|
|
9
|
+
let base = Semantic$Reventless.mark(Sury.$Metadata_set(Sury.string, DcbTag$Reventless.dcbTagId, true), Semantic$Reventless.Id.reference, {
|
|
10
10
|
TAG: "ReferenceTo",
|
|
11
11
|
_0: {
|
|
12
12
|
entity: entity,
|
|
@@ -14,7 +14,7 @@ function to_(plugin, key, entity) {
|
|
|
14
14
|
}
|
|
15
15
|
});
|
|
16
16
|
if (key !== undefined) {
|
|
17
|
-
return
|
|
17
|
+
return Sury.$Metadata_set(base, DcbTag$Reventless.dcbTagKeyOverrideId, key);
|
|
18
18
|
} else {
|
|
19
19
|
return base;
|
|
20
20
|
}
|
|
@@ -54,7 +54,7 @@ function getFieldTarget(_schema) {
|
|
|
54
54
|
}
|
|
55
55
|
|
|
56
56
|
function toWithoutDcbTag(plugin, entity) {
|
|
57
|
-
return Semantic$Reventless.mark(
|
|
57
|
+
return Semantic$Reventless.mark(Sury.string, Semantic$Reventless.Id.reference, {
|
|
58
58
|
TAG: "ReferenceTo",
|
|
59
59
|
_0: {
|
|
60
60
|
entity: entity,
|
|
@@ -69,4 +69,4 @@ export {
|
|
|
69
69
|
getFieldTarget,
|
|
70
70
|
toWithoutDcbTag,
|
|
71
71
|
}
|
|
72
|
-
/*
|
|
72
|
+
/* sury Not a pure module */
|
|
@@ -15,6 +15,8 @@ Each list contains the source field names; `indexes` carries `(fieldName,
|
|
|
15
15
|
indexName)` pairs where `indexName` is `""` for unnamed `@index` annotations.
|
|
16
16
|
`hidden` lists fields the UI should suppress from summary/list views;
|
|
17
17
|
`summary` lists fields the UI should always include in summary/list views.
|
|
18
|
+
`internal` lists fields that are not on the GraphQL surface at all — see the
|
|
19
|
+
field's own note below; it is a different kind of claim from `hidden`.
|
|
18
20
|
`drillTargets` carries `(fieldName, sliceName)` pairs naming the slice/view
|
|
19
21
|
the UI should navigate to instead of expanding the field inline;
|
|
20
22
|
`drillTargetKeys` carries `(fieldName, keyPath)` pairs for fields whose
|
|
@@ -81,6 +83,27 @@ type retiredSpec = {
|
|
|
81
83
|
most visibly — would stop firing on a value that looks merely empty.
|
|
82
84
|
*/
|
|
83
85
|
values: option<array<string>>,
|
|
86
|
+
/**
|
|
87
|
+
Whether a reference to a retired row of this record still resolves — the
|
|
88
|
+
`@namedWhenRetired` opt-in on the `@schema type state` declaration.
|
|
89
|
+
|
|
90
|
+
Retirement withholds a row from every door at once, which is the right answer
|
|
91
|
+
to "what may this caller browse" and an unasked answer to "what is the row this
|
|
92
|
+
caller is already holding a reference to called". An order names a product it
|
|
93
|
+
bought; archiving the product should not unname it on the order.
|
|
94
|
+
|
|
95
|
+
`true` opens exactly one door: a retired row answers a by-ids reference read
|
|
96
|
+
with its id, its label field and the value of `field` — and nothing else, for
|
|
97
|
+
any caller. It does not widen the list, the single-entity read, the index reads
|
|
98
|
+
or the live frame, and it does not touch the owner rule: a retired row that is
|
|
99
|
+
owner-scoped still resolves for its owner alone.
|
|
100
|
+
|
|
101
|
+
Inside `retiredSpec` rather than beside it, because it is a rule about withheld
|
|
102
|
+
rows and there are none without a retirement — the PPX errors on the annotation
|
|
103
|
+
when the record declares no `@retired`, so the nesting states a guarantee rather
|
|
104
|
+
than a convention.
|
|
105
|
+
*/
|
|
106
|
+
namedWhenRetired: bool,
|
|
84
107
|
}
|
|
85
108
|
|
|
86
109
|
type stateAnnotationSpec = {
|
|
@@ -91,6 +114,27 @@ type stateAnnotationSpec = {
|
|
|
91
114
|
indexes: array<(string, string)>,
|
|
92
115
|
hidden: array<string>,
|
|
93
116
|
summary: array<string>,
|
|
117
|
+
/**
|
|
118
|
+
Fields annotated `@internal` — present in the record and in storage, absent
|
|
119
|
+
from the generated SDL type and from the published state schema.
|
|
120
|
+
|
|
121
|
+
A different claim from `hidden`, and the distinction is the point. `hidden`
|
|
122
|
+
says "do not show this": the field is on the API and any client may ask for
|
|
123
|
+
it. `internal` says "this is not on the API", so nothing can ask and nothing
|
|
124
|
+
needs to be told not to show it. That is why the two are separate lists rather
|
|
125
|
+
than one flag with a mode — a consumer reading `hidden` is deciding what to
|
|
126
|
+
render, and a consumer reading this is deciding what exists.
|
|
127
|
+
|
|
128
|
+
**Not a security boundary** — the same caveat `visibility` carries. It shapes
|
|
129
|
+
the generated surface; `@owner` and `@retired` remain the enforcement markers.
|
|
130
|
+
The PPX rejects `@internal` beside either of them, and beside every other
|
|
131
|
+
marker that keys a door, because a door cannot be keyed on a field the SDL
|
|
132
|
+
does not have.
|
|
133
|
+
|
|
134
|
+
Optional so a state schema annotated by a PPX that predates the marker still
|
|
135
|
+
reads: absent and empty mean the same thing to every consumer.
|
|
136
|
+
*/
|
|
137
|
+
internal?: array<string>,
|
|
94
138
|
drillTargets: array<(string, string)>,
|
|
95
139
|
drillTargetKeys: array<(string, string)>,
|
|
96
140
|
collapsed: array<string>,
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
|
-
import * as
|
|
3
|
+
import * as Sury from "sury";
|
|
4
4
|
|
|
5
|
-
let stateAnnotationsId =
|
|
5
|
+
let stateAnnotationsId = Sury.$Metadata_Id_make("reventless", "stateAnnotations");
|
|
6
6
|
|
|
7
7
|
function getSpec(schema) {
|
|
8
|
-
return
|
|
8
|
+
return Sury.$Metadata_get(schema, stateAnnotationsId);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
export {
|
|
@@ -73,17 +73,16 @@ let splitKey = (key: string): option<(string, string)> =>
|
|
|
73
73
|
key->String.slice(~start=i + 1),
|
|
74
74
|
))
|
|
75
75
|
|
|
76
|
-
// The provenance comment
|
|
77
|
-
//
|
|
76
|
+
// The provenance comment names the store as the field spells it — taken from
|
|
77
|
+
// the manifest, which recorded it at the one place the owning plugin was
|
|
78
78
|
// unambiguous. Inferring it here is what this replaced: the manifest carries a
|
|
79
79
|
// deploy-manifest entry name and the key carries the registered name, and no
|
|
80
80
|
// rule relates the two (`platform-inspector` against `PlatformInspector` is an
|
|
81
|
-
// ordinary pairing), so any comparison here eventually
|
|
81
|
+
// ordinary pairing), so any comparison here eventually names a string that is
|
|
82
82
|
// in no source file.
|
|
83
83
|
//
|
|
84
|
-
// A site with no recorded
|
|
85
|
-
// field, which is the comment's job; it just makes no claim
|
|
86
|
-
// text it cannot see.
|
|
84
|
+
// A site with no recorded store predates the recording. It still names the
|
|
85
|
+
// field, which is the comment's job; it just makes no claim it cannot support.
|
|
87
86
|
let renderEntry = (entry: unionEntry): result<array<string>, string> =>
|
|
88
87
|
switch splitKey(entry.key) {
|
|
89
88
|
| None =>
|
|
@@ -94,8 +93,13 @@ let renderEntry = (entry: unionEntry): result<array<string>, string> =>
|
|
|
94
93
|
let comments =
|
|
95
94
|
entry.declaredBy->Array.map(site => {
|
|
96
95
|
let site_ = ` // ${site.pluginName}: ${site.component}.${site.field}`
|
|
96
|
+
// `→ store` rather than `@storageRef("store")`: a field may name its
|
|
97
|
+
// store by annotation *or* by being named, and the manifest carries
|
|
98
|
+
// the store either way without saying which. Naming the annotation
|
|
99
|
+
// would send a reader looking for source text a derived field has not
|
|
100
|
+
// got.
|
|
97
101
|
switch site.annotation {
|
|
98
|
-
| Some(annotation) => `${site_}
|
|
102
|
+
| Some(annotation) => `${site_} → ${annotation}`
|
|
99
103
|
| None => site_
|
|
100
104
|
}
|
|
101
105
|
})
|
|
@@ -115,13 +119,12 @@ aggregate is keyed by the registered name — so a second plugin registering an
|
|
|
115
119
|
existing name is not rejected but read as a **new version of the first**, and
|
|
116
120
|
silently supersedes it in the registry.
|
|
117
121
|
|
|
118
|
-
Ownership is read from the
|
|
119
|
-
separates a duplicate from legitimate sharing: an **unqualified**
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
trip this.
|
|
122
|
+
Ownership is read from the store as the field states it, which is the one signal
|
|
123
|
+
that separates a duplicate from legitimate sharing: an **unqualified**
|
|
124
|
+
`productImages` means "a store of my own plugin", so the deployable that stated
|
|
125
|
+
it is the plugin the key names. A **qualified** `Catalog.productImages` points at
|
|
126
|
+
someone else's store and says nothing about who owns it — that is the sanctioned
|
|
127
|
+
cross-plugin form and must not trip this.
|
|
125
128
|
|
|
126
129
|
Partial by construction: it can only see plugins that declare a store, because
|
|
127
130
|
capability manifests are the only per-plugin input the generator reads. A
|
|
@@ -59,7 +59,7 @@ function renderEntry(entry) {
|
|
|
59
59
|
let site_ = ` // ` + site.pluginName + `: ` + site.component + `.` + site.field;
|
|
60
60
|
let annotation = site.annotation;
|
|
61
61
|
if (annotation !== undefined) {
|
|
62
|
-
return site_ + `
|
|
62
|
+
return site_ + ` → ` + annotation;
|
|
63
63
|
} else {
|
|
64
64
|
return site_;
|
|
65
65
|
}
|
|
@@ -95,7 +95,7 @@ let () = {
|
|
|
95
95
|
)
|
|
96
96
|
let manifest = try NodeFs.readFileSync(path)
|
|
97
97
|
->JSON.parseOrThrow
|
|
98
|
-
->S.parseOrThrow(CapabilityManifest.schema) catch {
|
|
98
|
+
->S.parseOrThrow(~to=CapabilityManifest.schema) catch {
|
|
99
99
|
| _ => {
|
|
100
100
|
fail(`could not parse ${path} as a capability manifest`)
|
|
101
101
|
({capabilities: []}: CapabilityManifest.t)
|