@reventlessdev/reventless-spec 3.0.0-alpha.128 → 3.0.0-alpha.130
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 +56 -0
- package/package.json +2 -2
- package/schema/platform-api.graphql +1 -0
- package/src/AnsiStyle.res +31 -7
- package/src/AnsiStyle.res.mjs +16 -2
- package/src/components/DcbTag.res +229 -32
- package/src/components/DcbTag.res.mjs +232 -41
- package/src/components/Plugin.res +106 -89
- package/src/components/Plugin.res.mjs +47 -82
- package/src/components/Reference.res +48 -0
- package/src/components/Reference.res.mjs +28 -0
- package/src/generator/Codegen.res +14 -1
- package/src/generator/Codegen.res.mjs +9 -5
- package/src/generator/GraftTrait.res +5 -4
- package/src/generator/GraftTrait.res.mjs +4 -4
- package/src/generator/PluginGenerator.res +4 -1
- package/src/generator/PluginGenerator.res.mjs +2 -1
- package/src/types/Message.res +14 -12
- package/src/types/Message.res.mjs +2 -1
- package/src/types/Transition.res +30 -3
- package/src/types/Transition.res.mjs +13 -4
|
@@ -49,26 +49,18 @@ let apiTargetSchema = Sury.union([
|
|
|
49
49
|
|
|
50
50
|
let apiSchemaFragmentOffloadSchema = Offload$Reventless.optionSchema(undefined, "pluginApiFragments", undefined, apiSchemaFragmentSchema);
|
|
51
51
|
|
|
52
|
-
let dcbEventLogOptionSchema = Sury.$nullAsOption(dcbEventLogDefinitionSchema);
|
|
53
|
-
|
|
54
|
-
let stringOptionSchema = Sury.$nullAsOption(Sury.string);
|
|
55
|
-
|
|
56
|
-
let stringArrayOptionSchema = Sury.$nullAsOption(Sury.array(Sury.string));
|
|
57
|
-
|
|
58
|
-
let boolOptionSchema = Sury.$nullAsOption(Sury.bool);
|
|
59
|
-
|
|
60
52
|
let panelManifestEntrySchema = Sury.$schema(s => ({
|
|
61
53
|
fragmentId: s.m(Sury.string),
|
|
62
54
|
title: s.m(Sury.string),
|
|
63
55
|
description: s.m(Sury.string),
|
|
64
56
|
positions: s.m(Sury.array(Sury.string)),
|
|
65
|
-
requiredAccess: s.m(
|
|
57
|
+
requiredAccess: s.m(Sury.$option(Sury.string))
|
|
66
58
|
}));
|
|
67
59
|
|
|
68
60
|
let menuEntrySchema = Sury.$schema(s => ({
|
|
69
61
|
label: s.m(Sury.string),
|
|
70
|
-
icon: s.m(
|
|
71
|
-
group: s.m(
|
|
62
|
+
icon: s.m(Sury.$option(Sury.string)),
|
|
63
|
+
group: s.m(Sury.$option(Sury.string)),
|
|
72
64
|
sortOrder: s.m(Sury.int)
|
|
73
65
|
}));
|
|
74
66
|
|
|
@@ -76,7 +68,7 @@ let pageManifestEntrySchema = Sury.$schema(s => ({
|
|
|
76
68
|
fragmentId: s.m(Sury.string),
|
|
77
69
|
title: s.m(Sury.string),
|
|
78
70
|
menuEntry: s.m(menuEntrySchema),
|
|
79
|
-
requiredAccess: s.m(
|
|
71
|
+
requiredAccess: s.m(Sury.$option(Sury.string))
|
|
80
72
|
}));
|
|
81
73
|
|
|
82
74
|
let uiFragmentManifestSchema = Sury.$schema(s => ({
|
|
@@ -85,7 +77,7 @@ let uiFragmentManifestSchema = Sury.$schema(s => ({
|
|
|
85
77
|
pages: s.m(Sury.array(pageManifestEntrySchema))
|
|
86
78
|
}));
|
|
87
79
|
|
|
88
|
-
let uiFragmentManifestOptionSchema = Sury.$
|
|
80
|
+
let uiFragmentManifestOptionSchema = Sury.$option(uiFragmentManifestSchema);
|
|
89
81
|
|
|
90
82
|
let commandLevelSchema = Sury.union([
|
|
91
83
|
Sury.literal("Collection"),
|
|
@@ -95,21 +87,22 @@ let commandLevelSchema = Sury.union([
|
|
|
95
87
|
let fieldReferenceSchema = Sury.$schema(s => ({
|
|
96
88
|
fieldName: s.m(Sury.string),
|
|
97
89
|
entity: s.m(Sury.string),
|
|
98
|
-
plugin: s.m(
|
|
90
|
+
plugin: s.m(Sury.$option(Sury.string))
|
|
99
91
|
}));
|
|
100
92
|
|
|
101
93
|
let commandDefSchema = Sury.$schema(s => ({
|
|
102
94
|
name: s.m(Sury.string),
|
|
103
95
|
schema: s.m(Sury.string),
|
|
104
96
|
level: s.m(commandLevelSchema),
|
|
105
|
-
aggregateIdField: s.m(
|
|
97
|
+
aggregateIdField: s.m(Sury.$option(Sury.string)),
|
|
106
98
|
mutationField: s.m(Sury.string),
|
|
107
99
|
references: s.m(Sury.array(fieldReferenceSchema)),
|
|
108
|
-
allowedStates: s.m(
|
|
109
|
-
targetState: s.m(
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
100
|
+
allowedStates: s.m(Sury.$option(Sury.array(Sury.string))),
|
|
101
|
+
targetState: s.m(Sury.$option(Sury.string)),
|
|
102
|
+
allowedStatesSource: s.m(Sury.$option(Sury.string)),
|
|
103
|
+
apiExposed: s.m(Sury.$option(Sury.bool)),
|
|
104
|
+
requiredAccess: s.m(Sury.$option(Sury.array(Sury.string))),
|
|
105
|
+
ownerField: s.m(Sury.$option(Sury.string))
|
|
113
106
|
}));
|
|
114
107
|
|
|
115
108
|
let queryableDefSchema = Sury.$schema(s => ({
|
|
@@ -120,18 +113,18 @@ let queryableDefSchema = Sury.$schema(s => ({
|
|
|
120
113
|
linkedWriteSide: s.m(Sury.array(Sury.string)),
|
|
121
114
|
labelField: s.m(Sury.string),
|
|
122
115
|
searchableFields: s.m(Sury.array(Sury.string)),
|
|
123
|
-
labelFieldSource: s.m(
|
|
124
|
-
lifecycleField: s.m(
|
|
125
|
-
ownerField: s.m(
|
|
126
|
-
retiredField: s.m(
|
|
127
|
-
retiredValues: s.m(
|
|
128
|
-
namedWhenRetired: s.m(
|
|
129
|
-
visibility: s.m(
|
|
130
|
-
chapter: s.m(
|
|
131
|
-
singleQueryField: s.m(
|
|
132
|
-
idField: s.m(
|
|
133
|
-
idFieldSource: s.m(
|
|
134
|
-
requiredAccess: s.m(
|
|
116
|
+
labelFieldSource: s.m(Sury.$option(Sury.string)),
|
|
117
|
+
lifecycleField: s.m(Sury.$option(Sury.string)),
|
|
118
|
+
ownerField: s.m(Sury.$option(Sury.string)),
|
|
119
|
+
retiredField: s.m(Sury.$option(Sury.string)),
|
|
120
|
+
retiredValues: s.m(Sury.$option(Sury.array(Sury.string))),
|
|
121
|
+
namedWhenRetired: s.m(Sury.$option(Sury.bool)),
|
|
122
|
+
visibility: s.m(Sury.$option(Sury.string)),
|
|
123
|
+
chapter: s.m(Sury.$option(Sury.string)),
|
|
124
|
+
singleQueryField: s.m(Sury.$option(Sury.string)),
|
|
125
|
+
idField: s.m(Sury.$option(Sury.string)),
|
|
126
|
+
idFieldSource: s.m(Sury.$option(Sury.string)),
|
|
127
|
+
requiredAccess: s.m(Sury.$option(Sury.array(Sury.string)))
|
|
135
128
|
}));
|
|
136
129
|
|
|
137
130
|
let eventDefSchema = Sury.$schema(s => ({
|
|
@@ -152,10 +145,10 @@ let writableDefSchema = Sury.$schema(s => ({
|
|
|
152
145
|
producedEventTypes: s.m(Sury.array(Sury.string)),
|
|
153
146
|
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
154
147
|
linkedViews: s.m(Sury.array(Sury.string)),
|
|
155
|
-
consistencyRead: s.m(
|
|
148
|
+
consistencyRead: s.m(Sury.$option(Sury.string)),
|
|
156
149
|
events: s.m(Sury.array(eventDefSchema)),
|
|
157
150
|
errors: s.m(Sury.array(errorDefSchema)),
|
|
158
|
-
chapter: s.m(
|
|
151
|
+
chapter: s.m(Sury.$option(Sury.string))
|
|
159
152
|
}));
|
|
160
153
|
|
|
161
154
|
let automationSliceDefSchema = Sury.$schema(s => ({
|
|
@@ -163,25 +156,25 @@ let automationSliceDefSchema = Sury.$schema(s => ({
|
|
|
163
156
|
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
164
157
|
producedCommandTypes: s.m(Sury.array(Sury.string)),
|
|
165
158
|
targetName: s.m(Sury.string),
|
|
166
|
-
chapter: s.m(
|
|
159
|
+
chapter: s.m(Sury.$option(Sury.string))
|
|
167
160
|
}));
|
|
168
161
|
|
|
169
162
|
let outboundTranslationSliceDefSchema = Sury.$schema(s => ({
|
|
170
163
|
name: s.m(Sury.string),
|
|
171
164
|
consumedEventTypes: s.m(Sury.array(Sury.string)),
|
|
172
165
|
inboundCommandTypes: s.m(Sury.array(Sury.string)),
|
|
173
|
-
targetName: s.m(
|
|
174
|
-
externalSystem: s.m(
|
|
175
|
-
chapter: s.m(
|
|
176
|
-
consumedSources: s.m(
|
|
166
|
+
targetName: s.m(Sury.$option(Sury.string)),
|
|
167
|
+
externalSystem: s.m(Sury.$option(Sury.string)),
|
|
168
|
+
chapter: s.m(Sury.$option(Sury.string)),
|
|
169
|
+
consumedSources: s.m(Sury.$option(Sury.array(Sury.string)))
|
|
177
170
|
}));
|
|
178
171
|
|
|
179
172
|
let inboundTranslationSliceDefSchema = Sury.$schema(s => ({
|
|
180
173
|
name: s.m(Sury.string),
|
|
181
174
|
commandTypes: s.m(Sury.array(Sury.string)),
|
|
182
175
|
targetName: s.m(Sury.string),
|
|
183
|
-
externalSystem: s.m(
|
|
184
|
-
chapter: s.m(
|
|
176
|
+
externalSystem: s.m(Sury.$option(Sury.string)),
|
|
177
|
+
chapter: s.m(Sury.$option(Sury.string))
|
|
185
178
|
}));
|
|
186
179
|
|
|
187
180
|
let publishedEventDefSchema = Sury.$schema(s => ({
|
|
@@ -189,65 +182,51 @@ let publishedEventDefSchema = Sury.$schema(s => ({
|
|
|
189
182
|
fromEventTypes: s.m(Sury.array(Sury.string))
|
|
190
183
|
}));
|
|
191
184
|
|
|
192
|
-
let publishedEventDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(publishedEventDefSchema));
|
|
193
|
-
|
|
194
185
|
let acceptedCommandDefSchema = Sury.$schema(s => ({
|
|
195
186
|
name: s.m(Sury.string),
|
|
196
187
|
toCommandTypes: s.m(Sury.array(Sury.string))
|
|
197
188
|
}));
|
|
198
189
|
|
|
199
|
-
let acceptedCommandDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(acceptedCommandDefSchema));
|
|
200
|
-
|
|
201
190
|
let handledEventDefSchema = Sury.$schema(s => ({
|
|
202
191
|
name: s.m(Sury.string),
|
|
203
192
|
toCommandTypes: s.m(Sury.array(Sury.string))
|
|
204
193
|
}));
|
|
205
194
|
|
|
206
|
-
let handledEventDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(handledEventDefSchema));
|
|
207
|
-
|
|
208
195
|
let issuedCommandDefSchema = Sury.$schema(s => ({
|
|
209
196
|
name: s.m(Sury.string),
|
|
210
197
|
fromEventTypes: s.m(Sury.array(Sury.string))
|
|
211
198
|
}));
|
|
212
199
|
|
|
213
|
-
let issuedCommandDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(issuedCommandDefSchema));
|
|
214
|
-
|
|
215
200
|
let extensionDefSchema = Sury.$schema(s => ({
|
|
216
201
|
name: s.m(Sury.string),
|
|
217
202
|
delegateNames: s.m(Sury.array(Sury.string)),
|
|
218
203
|
eventTypes: s.m(Sury.array(Sury.string)),
|
|
219
204
|
commandTypes: s.m(Sury.array(Sury.string)),
|
|
220
|
-
handledEvents: s.m(
|
|
221
|
-
issuedCommands: s.m(
|
|
205
|
+
handledEvents: s.m(Sury.$option(Sury.array(handledEventDefSchema))),
|
|
206
|
+
issuedCommands: s.m(Sury.$option(Sury.array(issuedCommandDefSchema)))
|
|
222
207
|
}));
|
|
223
208
|
|
|
224
209
|
let extensionPointDefSchema = Sury.$schema(s => ({
|
|
225
210
|
name: s.m(Sury.string),
|
|
226
211
|
delegateNames: s.m(Sury.array(Sury.string)),
|
|
227
212
|
sourceEventTypes: s.m(Sury.array(Sury.string)),
|
|
228
|
-
commandTypes: s.m(
|
|
229
|
-
publishedEvents: s.m(
|
|
230
|
-
acceptedCommands: s.m(
|
|
213
|
+
commandTypes: s.m(Sury.$option(Sury.array(Sury.string))),
|
|
214
|
+
publishedEvents: s.m(Sury.$option(Sury.array(publishedEventDefSchema))),
|
|
215
|
+
acceptedCommands: s.m(Sury.$option(Sury.array(acceptedCommandDefSchema)))
|
|
231
216
|
}));
|
|
232
217
|
|
|
233
|
-
let extensionPointDefArrayOptionSchema = Sury.$nullAsOption(Sury.array(extensionPointDefSchema));
|
|
234
|
-
|
|
235
218
|
let requiredStoreDeclarationSchema = Sury.$schema(s => ({
|
|
236
219
|
store: s.m(Sury.string),
|
|
237
220
|
component: s.m(Sury.string),
|
|
238
221
|
field: s.m(Sury.string),
|
|
239
|
-
annotation: s.m(
|
|
222
|
+
annotation: s.m(Sury.$option(Sury.string))
|
|
240
223
|
}));
|
|
241
224
|
|
|
242
|
-
let requiredStoreDeclarationArrayOptionSchema = Sury.$nullAsOption(Sury.array(requiredStoreDeclarationSchema));
|
|
243
|
-
|
|
244
225
|
let requiredCapabilityDeclarationSchema = Sury.$schema(s => ({
|
|
245
226
|
capability: s.m(Sury.string),
|
|
246
227
|
component: s.m(Sury.string)
|
|
247
228
|
}));
|
|
248
229
|
|
|
249
|
-
let requiredCapabilityDeclarationArrayOptionSchema = Sury.$nullAsOption(Sury.array(requiredCapabilityDeclarationSchema));
|
|
250
|
-
|
|
251
230
|
let traitDeclarationSchema = Sury.$schema(s => ({
|
|
252
231
|
trait: s.m(Sury.string),
|
|
253
232
|
version: s.m(Sury.string),
|
|
@@ -255,8 +234,6 @@ let traitDeclarationSchema = Sury.$schema(s => ({
|
|
|
255
234
|
component: s.m(Sury.string)
|
|
256
235
|
}));
|
|
257
236
|
|
|
258
|
-
let traitDeclarationArrayOptionSchema = Sury.$nullAsOption(Sury.array(traitDeclarationSchema));
|
|
259
|
-
|
|
260
237
|
let pluginStructureSchema = Sury.$schema(s => ({
|
|
261
238
|
readModels: s.m(Sury.array(queryableDefSchema)),
|
|
262
239
|
stateViewSlices: s.m(Sury.array(queryableDefSchema)),
|
|
@@ -266,11 +243,11 @@ let pluginStructureSchema = Sury.$schema(s => ({
|
|
|
266
243
|
outboundTranslationSlices: s.m(Sury.array(outboundTranslationSliceDefSchema)),
|
|
267
244
|
inboundTranslationSlices: s.m(Sury.array(inboundTranslationSliceDefSchema)),
|
|
268
245
|
extensions: s.m(Sury.array(extensionDefSchema)),
|
|
269
|
-
extensionPoints: s.m(
|
|
270
|
-
requiredStores: s.m(
|
|
271
|
-
requiredStoreDeclarations: s.m(
|
|
272
|
-
requiredCapabilities: s.m(
|
|
273
|
-
traitDeclarations: s.m(
|
|
246
|
+
extensionPoints: s.m(Sury.$option(Sury.array(extensionPointDefSchema))),
|
|
247
|
+
requiredStores: s.m(Sury.$option(Sury.array(Sury.string))),
|
|
248
|
+
requiredStoreDeclarations: s.m(Sury.$option(Sury.array(requiredStoreDeclarationSchema))),
|
|
249
|
+
requiredCapabilities: s.m(Sury.$option(Sury.array(requiredCapabilityDeclarationSchema))),
|
|
250
|
+
traitDeclarations: s.m(Sury.$option(Sury.array(traitDeclarationSchema)))
|
|
274
251
|
}));
|
|
275
252
|
|
|
276
253
|
let pluginStructureOffloadSchema = Offload$Reventless.optionSchema(undefined, "pluginStructures", undefined, pluginStructureSchema);
|
|
@@ -284,9 +261,9 @@ let pluginDefinitionSchema = Sury.$schema(s => ({
|
|
|
284
261
|
eventCollector: s.m(Sury.string),
|
|
285
262
|
extensionProtocols: s.m(Sury.array(extensionProtocolSchema)),
|
|
286
263
|
apiSchemaFragment: s.m(apiSchemaFragmentOffloadSchema),
|
|
287
|
-
apiTarget: s.m(
|
|
264
|
+
apiTarget: s.m(Sury.$option(Sury.string)),
|
|
288
265
|
structure: s.m(pluginStructureOffloadSchema),
|
|
289
|
-
dcbEventLog: s.m(
|
|
266
|
+
dcbEventLog: s.m(Sury.$option(dcbEventLogDefinitionSchema)),
|
|
290
267
|
kind: s.m(pluginKindSchema)
|
|
291
268
|
}));
|
|
292
269
|
|
|
@@ -301,10 +278,6 @@ export {
|
|
|
301
278
|
apiSchemaFragmentSchema,
|
|
302
279
|
apiTargetSchema,
|
|
303
280
|
apiSchemaFragmentOffloadSchema,
|
|
304
|
-
dcbEventLogOptionSchema,
|
|
305
|
-
stringOptionSchema,
|
|
306
|
-
stringArrayOptionSchema,
|
|
307
|
-
boolOptionSchema,
|
|
308
281
|
panelManifestEntrySchema,
|
|
309
282
|
menuEntrySchema,
|
|
310
283
|
pageManifestEntrySchema,
|
|
@@ -321,22 +294,14 @@ export {
|
|
|
321
294
|
outboundTranslationSliceDefSchema,
|
|
322
295
|
inboundTranslationSliceDefSchema,
|
|
323
296
|
publishedEventDefSchema,
|
|
324
|
-
publishedEventDefArrayOptionSchema,
|
|
325
297
|
acceptedCommandDefSchema,
|
|
326
|
-
acceptedCommandDefArrayOptionSchema,
|
|
327
298
|
handledEventDefSchema,
|
|
328
|
-
handledEventDefArrayOptionSchema,
|
|
329
299
|
issuedCommandDefSchema,
|
|
330
|
-
issuedCommandDefArrayOptionSchema,
|
|
331
300
|
extensionDefSchema,
|
|
332
301
|
extensionPointDefSchema,
|
|
333
|
-
extensionPointDefArrayOptionSchema,
|
|
334
302
|
requiredStoreDeclarationSchema,
|
|
335
|
-
requiredStoreDeclarationArrayOptionSchema,
|
|
336
303
|
requiredCapabilityDeclarationSchema,
|
|
337
|
-
requiredCapabilityDeclarationArrayOptionSchema,
|
|
338
304
|
traitDeclarationSchema,
|
|
339
|
-
traitDeclarationArrayOptionSchema,
|
|
340
305
|
pluginStructureSchema,
|
|
341
306
|
pluginStructureOffloadSchema,
|
|
342
307
|
pluginDefinitionSchema,
|
|
@@ -62,6 +62,11 @@ Only wrappers around the field's own value are followed — the optional union a
|
|
|
62
62
|
the array element, to any depth. Object properties are not: a reference declared
|
|
63
63
|
on a nested record's field belongs to that field, and attributing it to the
|
|
64
64
|
enclosing one would name the wrong field.
|
|
65
|
+
|
|
66
|
+
That is still the right answer to the question this asks. A caller collecting
|
|
67
|
+
*every* reference a command or event declares — including the ones on the fields
|
|
68
|
+
of records it holds — wants [`collectFieldTargets`], which names each one by its
|
|
69
|
+
own path.
|
|
65
70
|
*/
|
|
66
71
|
let rec getFieldTarget = (schema: S.t<unknown>): option<target> =>
|
|
67
72
|
switch getTarget(schema) {
|
|
@@ -75,6 +80,49 @@ let rec getFieldTarget = (schema: S.t<unknown>): option<target> =>
|
|
|
75
80
|
}
|
|
76
81
|
}
|
|
77
82
|
|
|
83
|
+
/**
|
|
84
|
+
Every reference a field declares, each paired with the path that names it.
|
|
85
|
+
|
|
86
|
+
A reference on the field's own value keeps the bare field name (`customerId`), so
|
|
87
|
+
nothing that reads today's paths has to learn the new form to go on working. One
|
|
88
|
+
declared on a field of a record the field holds is named by its path:
|
|
89
|
+
`lineItems[].productId` — `[]` for "each element of", `.` for "property of", and
|
|
90
|
+
no index, because a marker lives on the element *schema* and so applies to every
|
|
91
|
+
element or to none.
|
|
92
|
+
|
|
93
|
+
⚠️ A path is a **widened** contract, not a compatible one, for a consumer that
|
|
94
|
+
uses the name as a dictionary key into a value's properties: such a consumer
|
|
95
|
+
simply misses a nested reference and falls back to whatever it does for an
|
|
96
|
+
unreferenced field. That degradation is the correct one, but it is a degradation.
|
|
97
|
+
|
|
98
|
+
Only one record deep, matching [`DcbTag.nestedRecordProperties`], which is the
|
|
99
|
+
walk shared with the tag extraction so a marker is found in the same places by
|
|
100
|
+
both.
|
|
101
|
+
*/
|
|
102
|
+
let collectFieldTargets = (
|
|
103
|
+
fieldName: string,
|
|
104
|
+
schema: S.t<unknown>,
|
|
105
|
+
): array<(string, target)> =>
|
|
106
|
+
switch getFieldTarget(schema) {
|
|
107
|
+
| Some(target) => [(fieldName, target)]
|
|
108
|
+
| None =>
|
|
109
|
+
switch DcbTag.nestedRecordProperties(schema) {
|
|
110
|
+
| None => []
|
|
111
|
+
| Some((properties, isList)) =>
|
|
112
|
+
let prefix = isList ? fieldName ++ "[]" : fieldName
|
|
113
|
+
properties
|
|
114
|
+
->Dict.toArray
|
|
115
|
+
->Array.filterMap(((propName, propSchema)) =>
|
|
116
|
+
propName === "TAG"
|
|
117
|
+
? None
|
|
118
|
+
: getFieldTarget(propSchema)->Option.map(target => (
|
|
119
|
+
`${prefix}.${propName}`,
|
|
120
|
+
target,
|
|
121
|
+
))
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
78
126
|
/**
|
|
79
127
|
Like `to_` but does not imply DCB tag semantics.
|
|
80
128
|
Use with `@ref("Entity") @noDcbTag` when the field references another entity
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
// Generated by ReScript, PLEASE EDIT WITH CARE
|
|
2
2
|
|
|
3
3
|
import * as Sury from "sury";
|
|
4
|
+
import * as Stdlib_Array from "@rescript/runtime/lib/es6/Stdlib_Array.js";
|
|
4
5
|
import * as Stdlib_Option from "@rescript/runtime/lib/es6/Stdlib_Option.js";
|
|
5
6
|
import * as DcbTag$Reventless from "./DcbTag.res.mjs";
|
|
6
7
|
import * as Semantic$Reventless from "../semantic/Semantic.res.mjs";
|
|
@@ -53,6 +54,32 @@ function getFieldTarget(_schema) {
|
|
|
53
54
|
};
|
|
54
55
|
}
|
|
55
56
|
|
|
57
|
+
function collectFieldTargets(fieldName, schema) {
|
|
58
|
+
let target = getFieldTarget(schema);
|
|
59
|
+
if (target !== undefined) {
|
|
60
|
+
return [[
|
|
61
|
+
fieldName,
|
|
62
|
+
target
|
|
63
|
+
]];
|
|
64
|
+
}
|
|
65
|
+
let match = DcbTag$Reventless.nestedRecordProperties(schema);
|
|
66
|
+
if (match === undefined) {
|
|
67
|
+
return [];
|
|
68
|
+
}
|
|
69
|
+
let prefix = match[1] ? fieldName + "[]" : fieldName;
|
|
70
|
+
return Stdlib_Array.filterMap(Object.entries(match[0]), param => {
|
|
71
|
+
let propName = param[0];
|
|
72
|
+
if (propName === "TAG") {
|
|
73
|
+
return;
|
|
74
|
+
} else {
|
|
75
|
+
return Stdlib_Option.map(getFieldTarget(param[1]), target => [
|
|
76
|
+
prefix + `.` + propName,
|
|
77
|
+
target
|
|
78
|
+
]);
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
56
83
|
function toWithoutDcbTag(plugin, entity) {
|
|
57
84
|
return Semantic$Reventless.mark(Sury.string, Semantic$Reventless.Id.reference, {
|
|
58
85
|
TAG: "ReferenceTo",
|
|
@@ -67,6 +94,7 @@ export {
|
|
|
67
94
|
to_,
|
|
68
95
|
getTarget,
|
|
69
96
|
getFieldTarget,
|
|
97
|
+
collectFieldTargets,
|
|
70
98
|
toWithoutDcbTag,
|
|
71
99
|
}
|
|
72
100
|
/* sury Not a pure module */
|
|
@@ -350,6 +350,7 @@ let renderPluginStructureCall = (
|
|
|
350
350
|
~extensions: array<string>,
|
|
351
351
|
~extensionPoints: array<Pairing.extensionPointDef>,
|
|
352
352
|
~componentChapters: array<(string, string)>,
|
|
353
|
+
~hasLifecycleModel: bool,
|
|
353
354
|
): option<array<string>> => {
|
|
354
355
|
// The structure call carries the EP *mapping* files (one per Delegate
|
|
355
356
|
// connection), not the wrapped ExtensionPoint module — Plugin_Structure reads
|
|
@@ -428,6 +429,15 @@ let renderPluginStructureCall = (
|
|
|
428
429
|
)
|
|
429
430
|
ls->Array.push(" ~componentChapters=Dict.fromArray([" ++ entries->Array.join(", ") ++ "]),")
|
|
430
431
|
}
|
|
432
|
+
// What the plugin's own scenarios say about each command's lifecycle edge.
|
|
433
|
+
// Written by `check:lifecycle:update`, not here: the sidecars it harvests are
|
|
434
|
+
// produced by the build this generator runs *before*, so a generator-written
|
|
435
|
+
// model would always be one build stale and a cold clone would have none at
|
|
436
|
+
// all. Referenced only when the file is on disk, so a plugin that has never
|
|
437
|
+
// been harvested keeps a byte-identical generated Plugin.res.
|
|
438
|
+
if hasLifecycleModel {
|
|
439
|
+
ls->Array.push(" ~lifecycleModel=LifecycleModel.model,")
|
|
440
|
+
}
|
|
431
441
|
ls->Array.push(" )")
|
|
432
442
|
Some(ls)
|
|
433
443
|
}
|
|
@@ -595,6 +605,7 @@ let renderComposition = (
|
|
|
595
605
|
~config: Config.config,
|
|
596
606
|
~resolved: Pairing.resolved,
|
|
597
607
|
~componentChapters: array<(string, string)>,
|
|
608
|
+
~hasLifecycleModel: bool,
|
|
598
609
|
): string => {
|
|
599
610
|
let lines: array<string> = []
|
|
600
611
|
|
|
@@ -740,6 +751,7 @@ let renderComposition = (
|
|
|
740
751
|
~extensions=resolved.extensions,
|
|
741
752
|
~extensionPoints=resolved.extensionPoints,
|
|
742
753
|
~componentChapters,
|
|
754
|
+
~hasLifecycleModel,
|
|
743
755
|
)
|
|
744
756
|
let hasPluginStructure = pluginStructureLines->Option.isSome
|
|
745
757
|
switch pluginStructureLines {
|
|
@@ -833,6 +845,7 @@ let render = (
|
|
|
833
845
|
~config: Config.config,
|
|
834
846
|
~resolved: Pairing.resolved,
|
|
835
847
|
~discovered: array<Discovery.discoveredFile>,
|
|
848
|
+
~hasLifecycleModel: bool=false,
|
|
836
849
|
): string => {
|
|
837
850
|
validateUniqueSpecStems(~discovered)
|
|
838
851
|
validateSliceTargets(~resolved)
|
|
@@ -858,6 +871,6 @@ let render = (
|
|
|
858
871
|
)
|
|
859
872
|
switch config.variant {
|
|
860
873
|
| Aws({compositionNamespace}) => renderAwsWrapper(~compositionNamespace)
|
|
861
|
-
| Composition => renderComposition(~config, ~resolved, ~componentChapters)
|
|
874
|
+
| Composition => renderComposition(~config, ~resolved, ~componentChapters, ~hasLifecycleModel)
|
|
862
875
|
}
|
|
863
876
|
}
|
|
@@ -239,7 +239,7 @@ function renderTaskMakeParam(tasks) {
|
|
|
239
239
|
return " ~tasks=[" + entries.join(", ") + "],";
|
|
240
240
|
}
|
|
241
241
|
|
|
242
|
-
function renderPluginStructureCall(name, aggregates, readModels, stateViewSlices, stateViewSlicesStream, stateChangeSlices, automationSlices, outboundTranslationSlices, inboundTranslationSlices, extensions, extensionPoints, componentChapters) {
|
|
242
|
+
function renderPluginStructureCall(name, aggregates, readModels, stateViewSlices, stateViewSlicesStream, stateChangeSlices, automationSlices, outboundTranslationSlices, inboundTranslationSlices, extensions, extensionPoints, componentChapters, hasLifecycleModel) {
|
|
243
243
|
let epMappingStems = extensionPoints.flatMap(param => param.mappings);
|
|
244
244
|
let hasComponents = aggregates.length !== 0 || readModels.length !== 0 || stateViewSlices.length !== 0 || stateViewSlicesStream.length !== 0 || stateChangeSlices.length !== 0 || automationSlices.length !== 0 || outboundTranslationSlices.length !== 0 || inboundTranslationSlices.length !== 0 || extensions.length !== 0 || epMappingStems.length !== 0;
|
|
245
245
|
if (!hasComponents) {
|
|
@@ -295,6 +295,9 @@ function renderPluginStructureCall(name, aggregates, readModels, stateViewSlices
|
|
|
295
295
|
let entries$8 = componentChapters.map(param => "(\"" + param[0] + "\", \"" + param[1] + "\")");
|
|
296
296
|
ls.push(" ~componentChapters=Dict.fromArray([" + entries$8.join(", ") + "]),");
|
|
297
297
|
}
|
|
298
|
+
if (hasLifecycleModel) {
|
|
299
|
+
ls.push(" ~lifecycleModel=LifecycleModel.model,");
|
|
300
|
+
}
|
|
298
301
|
ls.push(" )");
|
|
299
302
|
return ls;
|
|
300
303
|
}
|
|
@@ -394,7 +397,7 @@ function renderAwsWrapper(compositionNamespace) {
|
|
|
394
397
|
].join("\n");
|
|
395
398
|
}
|
|
396
399
|
|
|
397
|
-
function renderComposition(config, resolved, componentChapters) {
|
|
400
|
+
function renderComposition(config, resolved, componentChapters, hasLifecycleModel) {
|
|
398
401
|
let lines = [];
|
|
399
402
|
lines.push("// AUTO-GENERATED — do not edit. Run `npm run generate` to update.");
|
|
400
403
|
lines.push("");
|
|
@@ -459,7 +462,7 @@ function renderComposition(config, resolved, componentChapters) {
|
|
|
459
462
|
lines.push(" // Extensions");
|
|
460
463
|
push(renderExtensions(resolved.extensions));
|
|
461
464
|
}
|
|
462
|
-
let pluginStructureLines = renderPluginStructureCall(config.name, resolved.aggregates, resolved.readModels, resolved.stateViewSlices, resolved.stateViewSlicesStream, resolved.stateChangeSlices, resolved.automationSlices, resolved.outboundTranslationSlices, resolved.inboundTranslationSlices, resolved.extensions, resolved.extensionPoints, componentChapters);
|
|
465
|
+
let pluginStructureLines = renderPluginStructureCall(config.name, resolved.aggregates, resolved.readModels, resolved.stateViewSlices, resolved.stateViewSlicesStream, resolved.stateChangeSlices, resolved.automationSlices, resolved.outboundTranslationSlices, resolved.inboundTranslationSlices, resolved.extensions, resolved.extensionPoints, componentChapters, hasLifecycleModel);
|
|
463
466
|
let hasPluginStructure = Stdlib_Option.isSome(pluginStructureLines);
|
|
464
467
|
if (pluginStructureLines !== undefined) {
|
|
465
468
|
pluginStructureLines.forEach(l => {
|
|
@@ -517,7 +520,8 @@ function renderComposition(config, resolved, componentChapters) {
|
|
|
517
520
|
return lines.join("\n");
|
|
518
521
|
}
|
|
519
522
|
|
|
520
|
-
function render(config, resolved, discovered) {
|
|
523
|
+
function render(config, resolved, discovered, hasLifecycleModelOpt) {
|
|
524
|
+
let hasLifecycleModel = hasLifecycleModelOpt !== undefined ? hasLifecycleModelOpt : false;
|
|
521
525
|
validateUniqueSpecStems(discovered);
|
|
522
526
|
validateSliceTargets(resolved);
|
|
523
527
|
let componentStems = [
|
|
@@ -533,7 +537,7 @@ function render(config, resolved, discovered) {
|
|
|
533
537
|
let componentChapters = Discovery$Reventless.chaptersByStem(discovered).filter(param => componentStems.includes(param[0]));
|
|
534
538
|
let match = config.variant;
|
|
535
539
|
if (typeof match !== "object") {
|
|
536
|
-
return renderComposition(config, resolved, componentChapters);
|
|
540
|
+
return renderComposition(config, resolved, componentChapters, hasLifecycleModel);
|
|
537
541
|
} else {
|
|
538
542
|
return renderAwsWrapper(match.compositionNamespace);
|
|
539
543
|
}
|
|
@@ -55,7 +55,7 @@ let parseFlags = (args: array<string>): dict<JSON.t> => {
|
|
|
55
55
|
switch args->Array.get(i) {
|
|
56
56
|
| None => ()
|
|
57
57
|
| Some(arg) if arg->String.startsWith("--") =>
|
|
58
|
-
let key = arg->String.
|
|
58
|
+
let key = arg->String.slice(~start=2, ~end=arg->String.length)
|
|
59
59
|
switch args->Array.get(i + 1) {
|
|
60
60
|
| Some(value) if !(value->String.startsWith("--")) =>
|
|
61
61
|
out->Dict.set(key, JSON.Encode.string(value))
|
|
@@ -107,14 +107,14 @@ let arrayFieldNames = (schema: S.t<unknown>): array<string> =>
|
|
|
107
107
|
// ── Entry point ──────────────────────────────────────────────────────────────
|
|
108
108
|
|
|
109
109
|
let main = async () => {
|
|
110
|
-
let argv = NodeProcess.argv->Array.
|
|
110
|
+
let argv = NodeProcess.argv->Array.slice(~start=2, ~end=NodeProcess.argv->Array.length)
|
|
111
111
|
switch argv->Array.get(0) {
|
|
112
112
|
| None | Some("") | Some("--help") | Some("-h") => {
|
|
113
113
|
Console.log(usage)
|
|
114
114
|
NodeProcess.exit(argv->Array.length == 0 ? 1 : 0)
|
|
115
115
|
}
|
|
116
116
|
| Some(traitPackage) => {
|
|
117
|
-
let flags = parseFlags(argv->Array.
|
|
117
|
+
let flags = parseFlags(argv->Array.slice(~start=1, ~end=argv->Array.length))
|
|
118
118
|
let stringFlag = key => flags->Dict.get(key)->Option.flatMap(JSON.Decode.string)
|
|
119
119
|
let into = stringFlag("into")
|
|
120
120
|
let tests = stringFlag("tests")
|
|
@@ -136,7 +136,8 @@ let main = async () => {
|
|
|
136
136
|
->String.replace("trait-", "")
|
|
137
137
|
->String.split("-")
|
|
138
138
|
->Array.map(part =>
|
|
139
|
-
part->String.charAt(0)->String.toUpperCase ++
|
|
139
|
+
part->String.charAt(0)->String.toUpperCase ++
|
|
140
|
+
part->String.slice(~start=1, ~end=part->String.length)
|
|
140
141
|
)
|
|
141
142
|
->Array.join("") ++ "_Scaffold"
|
|
142
143
|
let specifier = `${traitPackage}/src/${scaffoldModule}.res.mjs`
|
|
@@ -36,7 +36,7 @@ function parseFlags(args) {
|
|
|
36
36
|
return;
|
|
37
37
|
}
|
|
38
38
|
if (arg.startsWith("--")) {
|
|
39
|
-
let key = arg.slice(2);
|
|
39
|
+
let key = arg.slice(2, arg.length);
|
|
40
40
|
let value = args[i + 1 | 0];
|
|
41
41
|
if (value !== undefined && !value.startsWith("--")) {
|
|
42
42
|
out[key] = value;
|
|
@@ -83,7 +83,7 @@ function arrayFieldNames(schema) {
|
|
|
83
83
|
}
|
|
84
84
|
|
|
85
85
|
async function main() {
|
|
86
|
-
let argv = process.argv.slice(2);
|
|
86
|
+
let argv = process.argv.slice(2, process.argv.length);
|
|
87
87
|
let traitPackage = argv[0];
|
|
88
88
|
if (traitPackage !== undefined) {
|
|
89
89
|
switch (traitPackage) {
|
|
@@ -92,7 +92,7 @@ async function main() {
|
|
|
92
92
|
case "-h" :
|
|
93
93
|
break;
|
|
94
94
|
default:
|
|
95
|
-
let flags = parseFlags(argv.slice(1));
|
|
95
|
+
let flags = parseFlags(argv.slice(1, argv.length));
|
|
96
96
|
let stringFlag = key => Stdlib_Option.flatMap(flags[key], Stdlib_JSON.Decode.string);
|
|
97
97
|
let into = stringFlag("into");
|
|
98
98
|
let tests = stringFlag("tests");
|
|
@@ -103,7 +103,7 @@ async function main() {
|
|
|
103
103
|
if (tests === undefined) {
|
|
104
104
|
return fail("--into and --tests are both required.\n\n" + usage);
|
|
105
105
|
}
|
|
106
|
-
let scaffoldModule = Stdlib_Option.getOr(Stdlib_Array.last(traitPackage.split("/")), "").replace("trait-", "").split("-").map(part => part.charAt(0).toUpperCase() + part.slice(1)).join("") + "_Scaffold";
|
|
106
|
+
let scaffoldModule = Stdlib_Option.getOr(Stdlib_Array.last(traitPackage.split("/")), "").replace("trait-", "").split("-").map(part => part.charAt(0).toUpperCase() + part.slice(1, part.length)).join("") + "_Scaffold";
|
|
107
107
|
let specifier = traitPackage + `/src/` + scaffoldModule + `.res.mjs`;
|
|
108
108
|
let modulePath;
|
|
109
109
|
try {
|
|
@@ -34,7 +34,10 @@ let () = {
|
|
|
34
34
|
let config = {...Config.read(~srcDir), variant}
|
|
35
35
|
let discovered = Discovery.scan(~srcDir, ~exclude=config.exclude)
|
|
36
36
|
let resolved = Pairing.resolve(discovered, ~srcDir)
|
|
37
|
-
|
|
37
|
+
// Sits at the src root rather than in a kind folder, so `Discovery` never
|
|
38
|
+
// sees it and it is not a component. Its presence is the whole question.
|
|
39
|
+
let hasLifecycleModel = NodePath.join([srcDir, "LifecycleModel.res"])->NodeFs.existsSync
|
|
40
|
+
let source = Codegen.render(~config, ~resolved, ~discovered, ~hasLifecycleModel)
|
|
38
41
|
|
|
39
42
|
let outputDir = switch variant {
|
|
40
43
|
| Config.Composition => srcDir
|
|
@@ -56,7 +56,8 @@ if (srcDirArg === "") {
|
|
|
56
56
|
};
|
|
57
57
|
let discovered = Discovery$Reventless.scan(srcDir, config_exclude);
|
|
58
58
|
let resolved = Pairing$Reventless.resolve(discovered, srcDir);
|
|
59
|
-
let
|
|
59
|
+
let hasLifecycleModel = Nodefs.existsSync(Nodepath.join(srcDir, "LifecycleModel.res"));
|
|
60
|
+
let source = Codegen$Reventless.render(config, resolved, discovered, hasLifecycleModel);
|
|
60
61
|
let outputDir;
|
|
61
62
|
outputDir = typeof variant !== "object" ? srcDir : Nodepath.join(process.cwd(), "src");
|
|
62
63
|
let pluginPath = Nodepath.join(outputDir, "Plugin.res");
|