domaintrail 0.1.0 → 0.2.0
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/README.md +9 -5
- package/dist/dt.js +713 -277
- package/dist/web/{chunk-kxmrt1q2.js → chunk-13zkn5c3.js} +99 -99
- package/dist/web/chunk-s7gt31ry.css +1 -0
- package/dist/web/index.html +1 -1
- package/package.json +1 -1
- package/dist/web/chunk-qa46tqx1.css +0 -1
package/dist/dt.js
CHANGED
|
@@ -49,6 +49,9 @@ function isEventDecl(item) {
|
|
|
49
49
|
function isExistsExpr(item) {
|
|
50
50
|
return reflection.isInstance(item, ExistsExpr.$type);
|
|
51
51
|
}
|
|
52
|
+
function isFieldSet(item) {
|
|
53
|
+
return reflection.isInstance(item, FieldSet.$type);
|
|
54
|
+
}
|
|
52
55
|
function isIdType(item) {
|
|
53
56
|
return reflection.isInstance(item, IdType.$type);
|
|
54
57
|
}
|
|
@@ -103,10 +106,11 @@ function isUnionDecl(item) {
|
|
|
103
106
|
function isValueObject(item) {
|
|
104
107
|
return reflection.isInstance(item, ValueObject.$type);
|
|
105
108
|
}
|
|
106
|
-
var Aggregate, AggregateMember, BinaryExpr, BoolLiteral, Command, Context, ContextElement, CountExpr, DataMember, DecimalLiteral, Entity, EnumDecl, EnumValue, ErrorDecl, EventDecl, ExistsExpr, Expression, Field, IdType, IntLiteral, Invariant, LambdaParam, LengthExpr, MatchesExpr, MemberAccess, Model, Multiplicity, NameRef, NotExpr, OwnsField, Parameter, PrimitiveDecl, QuantifierExpr, RangeExpr, ReferenceField, State, StringLiteral, TermEntry, Terms, TypeDecl, TypeRef, UnionDecl, ValueObject, Variant, DomainAstReflection, reflection;
|
|
109
|
+
var Aggregate, AggregateMember, BinaryExpr, BoolLiteral, Command, Context, ContextElement, CountExpr, DataMember, DecimalLiteral, Entity, EnumDecl, EnumValue, ErrorDecl, EventDecl, ExistsExpr, Expression, Field, FieldSet, IdType, IntLiteral, Invariant, LambdaParam, LengthExpr, MatchesExpr, MemberAccess, Model, Multiplicity, NameRef, NotExpr, OwnsField, Parameter, PrimitiveDecl, QuantifierExpr, RangeExpr, ReferenceField, State, StringLiteral, TermEntry, Terms, TypeDecl, TypeRef, UnionDecl, ValueObject, Variant, DomainAstReflection, reflection;
|
|
107
110
|
var init_ast = __esm(() => {
|
|
108
111
|
Aggregate = {
|
|
109
112
|
$type: "Aggregate",
|
|
113
|
+
fieldSets: "fieldSets",
|
|
110
114
|
label: "label",
|
|
111
115
|
members: "members",
|
|
112
116
|
name: "name"
|
|
@@ -160,6 +164,7 @@ var init_ast = __esm(() => {
|
|
|
160
164
|
};
|
|
161
165
|
Entity = {
|
|
162
166
|
$type: "Entity",
|
|
167
|
+
fieldSets: "fieldSets",
|
|
163
168
|
label: "label",
|
|
164
169
|
members: "members",
|
|
165
170
|
name: "name"
|
|
@@ -177,12 +182,14 @@ var init_ast = __esm(() => {
|
|
|
177
182
|
};
|
|
178
183
|
ErrorDecl = {
|
|
179
184
|
$type: "ErrorDecl",
|
|
185
|
+
fieldSets: "fieldSets",
|
|
180
186
|
label: "label",
|
|
181
187
|
members: "members",
|
|
182
188
|
name: "name"
|
|
183
189
|
};
|
|
184
190
|
EventDecl = {
|
|
185
191
|
$type: "EventDecl",
|
|
192
|
+
fieldSets: "fieldSets",
|
|
186
193
|
label: "label",
|
|
187
194
|
members: "members",
|
|
188
195
|
name: "name",
|
|
@@ -202,6 +209,13 @@ var init_ast = __esm(() => {
|
|
|
202
209
|
name: "name",
|
|
203
210
|
type: "type"
|
|
204
211
|
};
|
|
212
|
+
FieldSet = {
|
|
213
|
+
$type: "FieldSet",
|
|
214
|
+
fieldSets: "fieldSets",
|
|
215
|
+
label: "label",
|
|
216
|
+
members: "members",
|
|
217
|
+
name: "name"
|
|
218
|
+
};
|
|
205
219
|
IdType = {
|
|
206
220
|
$type: "IdType",
|
|
207
221
|
base: "base",
|
|
@@ -338,6 +352,7 @@ var init_ast = __esm(() => {
|
|
|
338
352
|
};
|
|
339
353
|
ValueObject = {
|
|
340
354
|
$type: "ValueObject",
|
|
355
|
+
fieldSets: "fieldSets",
|
|
341
356
|
label: "label",
|
|
342
357
|
members: "members",
|
|
343
358
|
name: "name"
|
|
@@ -353,6 +368,12 @@ var init_ast = __esm(() => {
|
|
|
353
368
|
Aggregate: {
|
|
354
369
|
name: Aggregate.$type,
|
|
355
370
|
properties: {
|
|
371
|
+
fieldSets: {
|
|
372
|
+
name: Aggregate.fieldSets,
|
|
373
|
+
defaultValue: [],
|
|
374
|
+
referenceType: FieldSet.$type,
|
|
375
|
+
optional: true
|
|
376
|
+
},
|
|
356
377
|
label: {
|
|
357
378
|
name: Aggregate.label,
|
|
358
379
|
optional: true
|
|
@@ -508,6 +529,12 @@ var init_ast = __esm(() => {
|
|
|
508
529
|
Entity: {
|
|
509
530
|
name: Entity.$type,
|
|
510
531
|
properties: {
|
|
532
|
+
fieldSets: {
|
|
533
|
+
name: Entity.fieldSets,
|
|
534
|
+
defaultValue: [],
|
|
535
|
+
referenceType: FieldSet.$type,
|
|
536
|
+
optional: true
|
|
537
|
+
},
|
|
511
538
|
label: {
|
|
512
539
|
name: Entity.label,
|
|
513
540
|
optional: true
|
|
@@ -557,6 +584,12 @@ var init_ast = __esm(() => {
|
|
|
557
584
|
ErrorDecl: {
|
|
558
585
|
name: ErrorDecl.$type,
|
|
559
586
|
properties: {
|
|
587
|
+
fieldSets: {
|
|
588
|
+
name: ErrorDecl.fieldSets,
|
|
589
|
+
defaultValue: [],
|
|
590
|
+
referenceType: FieldSet.$type,
|
|
591
|
+
optional: true
|
|
592
|
+
},
|
|
560
593
|
label: {
|
|
561
594
|
name: ErrorDecl.label,
|
|
562
595
|
optional: true
|
|
@@ -575,6 +608,12 @@ var init_ast = __esm(() => {
|
|
|
575
608
|
EventDecl: {
|
|
576
609
|
name: EventDecl.$type,
|
|
577
610
|
properties: {
|
|
611
|
+
fieldSets: {
|
|
612
|
+
name: EventDecl.fieldSets,
|
|
613
|
+
defaultValue: [],
|
|
614
|
+
referenceType: FieldSet.$type,
|
|
615
|
+
optional: true
|
|
616
|
+
},
|
|
578
617
|
label: {
|
|
579
618
|
name: EventDecl.label,
|
|
580
619
|
optional: true
|
|
@@ -629,6 +668,30 @@ var init_ast = __esm(() => {
|
|
|
629
668
|
},
|
|
630
669
|
superTypes: [DataMember.$type]
|
|
631
670
|
},
|
|
671
|
+
FieldSet: {
|
|
672
|
+
name: FieldSet.$type,
|
|
673
|
+
properties: {
|
|
674
|
+
fieldSets: {
|
|
675
|
+
name: FieldSet.fieldSets,
|
|
676
|
+
defaultValue: [],
|
|
677
|
+
referenceType: FieldSet.$type,
|
|
678
|
+
optional: true
|
|
679
|
+
},
|
|
680
|
+
label: {
|
|
681
|
+
name: FieldSet.label,
|
|
682
|
+
optional: true
|
|
683
|
+
},
|
|
684
|
+
members: {
|
|
685
|
+
name: FieldSet.members,
|
|
686
|
+
defaultValue: [],
|
|
687
|
+
optional: true
|
|
688
|
+
},
|
|
689
|
+
name: {
|
|
690
|
+
name: FieldSet.name
|
|
691
|
+
}
|
|
692
|
+
},
|
|
693
|
+
superTypes: [ContextElement.$type]
|
|
694
|
+
},
|
|
632
695
|
IdType: {
|
|
633
696
|
name: IdType.$type,
|
|
634
697
|
properties: {
|
|
@@ -1001,6 +1064,12 @@ var init_ast = __esm(() => {
|
|
|
1001
1064
|
ValueObject: {
|
|
1002
1065
|
name: ValueObject.$type,
|
|
1003
1066
|
properties: {
|
|
1067
|
+
fieldSets: {
|
|
1068
|
+
name: ValueObject.fieldSets,
|
|
1069
|
+
defaultValue: [],
|
|
1070
|
+
referenceType: FieldSet.$type,
|
|
1071
|
+
optional: true
|
|
1072
|
+
},
|
|
1004
1073
|
label: {
|
|
1005
1074
|
name: ValueObject.label,
|
|
1006
1075
|
optional: true
|
|
@@ -1093,7 +1162,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1093
1162
|
"terminal": {
|
|
1094
1163
|
"$type": "RuleCall",
|
|
1095
1164
|
"rule": {
|
|
1096
|
-
"$ref": "#/rules@
|
|
1165
|
+
"$ref": "#/rules@46"
|
|
1097
1166
|
},
|
|
1098
1167
|
"arguments": []
|
|
1099
1168
|
}
|
|
@@ -1105,7 +1174,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1105
1174
|
"terminal": {
|
|
1106
1175
|
"$type": "RuleCall",
|
|
1107
1176
|
"rule": {
|
|
1108
|
-
"$ref": "#/rules@
|
|
1177
|
+
"$ref": "#/rules@45"
|
|
1109
1178
|
},
|
|
1110
1179
|
"arguments": []
|
|
1111
1180
|
},
|
|
@@ -1205,7 +1274,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1205
1274
|
"terminal": {
|
|
1206
1275
|
"$type": "RuleCall",
|
|
1207
1276
|
"rule": {
|
|
1208
|
-
"$ref": "#/rules@
|
|
1277
|
+
"$ref": "#/rules@40"
|
|
1209
1278
|
},
|
|
1210
1279
|
"arguments": []
|
|
1211
1280
|
}
|
|
@@ -1221,7 +1290,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1221
1290
|
"terminal": {
|
|
1222
1291
|
"$type": "RuleCall",
|
|
1223
1292
|
"rule": {
|
|
1224
|
-
"$ref": "#/rules@
|
|
1293
|
+
"$ref": "#/rules@45"
|
|
1225
1294
|
},
|
|
1226
1295
|
"arguments": []
|
|
1227
1296
|
}
|
|
@@ -1269,35 +1338,42 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1269
1338
|
{
|
|
1270
1339
|
"$type": "RuleCall",
|
|
1271
1340
|
"rule": {
|
|
1272
|
-
"$ref": "#/rules@
|
|
1341
|
+
"$ref": "#/rules@13"
|
|
1273
1342
|
},
|
|
1274
1343
|
"arguments": []
|
|
1275
1344
|
},
|
|
1276
1345
|
{
|
|
1277
1346
|
"$type": "RuleCall",
|
|
1278
1347
|
"rule": {
|
|
1279
|
-
"$ref": "#/rules@
|
|
1348
|
+
"$ref": "#/rules@15"
|
|
1349
|
+
},
|
|
1350
|
+
"arguments": []
|
|
1351
|
+
},
|
|
1352
|
+
{
|
|
1353
|
+
"$type": "RuleCall",
|
|
1354
|
+
"rule": {
|
|
1355
|
+
"$ref": "#/rules@16"
|
|
1280
1356
|
},
|
|
1281
1357
|
"arguments": []
|
|
1282
1358
|
},
|
|
1283
1359
|
{
|
|
1284
1360
|
"$type": "RuleCall",
|
|
1285
1361
|
"rule": {
|
|
1286
|
-
"$ref": "#/rules@
|
|
1362
|
+
"$ref": "#/rules@25"
|
|
1287
1363
|
},
|
|
1288
1364
|
"arguments": []
|
|
1289
1365
|
},
|
|
1290
1366
|
{
|
|
1291
1367
|
"$type": "RuleCall",
|
|
1292
1368
|
"rule": {
|
|
1293
|
-
"$ref": "#/rules@
|
|
1369
|
+
"$ref": "#/rules@26"
|
|
1294
1370
|
},
|
|
1295
1371
|
"arguments": []
|
|
1296
1372
|
},
|
|
1297
1373
|
{
|
|
1298
1374
|
"$type": "RuleCall",
|
|
1299
1375
|
"rule": {
|
|
1300
|
-
"$ref": "#/rules@
|
|
1376
|
+
"$ref": "#/rules@11"
|
|
1301
1377
|
},
|
|
1302
1378
|
"arguments": []
|
|
1303
1379
|
}
|
|
@@ -1324,7 +1400,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1324
1400
|
"terminal": {
|
|
1325
1401
|
"$type": "RuleCall",
|
|
1326
1402
|
"rule": {
|
|
1327
|
-
"$ref": "#/rules@
|
|
1403
|
+
"$ref": "#/rules@46"
|
|
1328
1404
|
},
|
|
1329
1405
|
"arguments": []
|
|
1330
1406
|
}
|
|
@@ -1336,7 +1412,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1336
1412
|
"terminal": {
|
|
1337
1413
|
"$type": "RuleCall",
|
|
1338
1414
|
"rule": {
|
|
1339
|
-
"$ref": "#/rules@
|
|
1415
|
+
"$ref": "#/rules@45"
|
|
1340
1416
|
},
|
|
1341
1417
|
"arguments": []
|
|
1342
1418
|
},
|
|
@@ -1353,7 +1429,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1353
1429
|
"terminal": {
|
|
1354
1430
|
"$type": "RuleCall",
|
|
1355
1431
|
"rule": {
|
|
1356
|
-
"$ref": "#/rules@
|
|
1432
|
+
"$ref": "#/rules@28"
|
|
1357
1433
|
},
|
|
1358
1434
|
"arguments": []
|
|
1359
1435
|
}
|
|
@@ -1389,7 +1465,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1389
1465
|
"terminal": {
|
|
1390
1466
|
"$type": "RuleCall",
|
|
1391
1467
|
"rule": {
|
|
1392
|
-
"$ref": "#/rules@
|
|
1468
|
+
"$ref": "#/rules@46"
|
|
1393
1469
|
},
|
|
1394
1470
|
"arguments": []
|
|
1395
1471
|
}
|
|
@@ -1401,7 +1477,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1401
1477
|
"terminal": {
|
|
1402
1478
|
"$type": "RuleCall",
|
|
1403
1479
|
"rule": {
|
|
1404
|
-
"$ref": "#/rules@
|
|
1480
|
+
"$ref": "#/rules@45"
|
|
1405
1481
|
},
|
|
1406
1482
|
"arguments": []
|
|
1407
1483
|
},
|
|
@@ -1418,7 +1494,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1418
1494
|
"terminal": {
|
|
1419
1495
|
"$type": "RuleCall",
|
|
1420
1496
|
"rule": {
|
|
1421
|
-
"$ref": "#/rules@
|
|
1497
|
+
"$ref": "#/rules@28"
|
|
1422
1498
|
},
|
|
1423
1499
|
"arguments": []
|
|
1424
1500
|
}
|
|
@@ -1458,7 +1534,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1458
1534
|
"terminal": {
|
|
1459
1535
|
"$type": "RuleCall",
|
|
1460
1536
|
"rule": {
|
|
1461
|
-
"$ref": "#/rules@
|
|
1537
|
+
"$ref": "#/rules@30"
|
|
1462
1538
|
},
|
|
1463
1539
|
"arguments": []
|
|
1464
1540
|
},
|
|
@@ -1471,7 +1547,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1471
1547
|
"terminal": {
|
|
1472
1548
|
"$type": "RuleCall",
|
|
1473
1549
|
"rule": {
|
|
1474
|
-
"$ref": "#/rules@
|
|
1550
|
+
"$ref": "#/rules@31"
|
|
1475
1551
|
},
|
|
1476
1552
|
"arguments": []
|
|
1477
1553
|
}
|
|
@@ -1504,7 +1580,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1504
1580
|
"terminal": {
|
|
1505
1581
|
"$type": "RuleCall",
|
|
1506
1582
|
"rule": {
|
|
1507
|
-
"$ref": "#/rules@
|
|
1583
|
+
"$ref": "#/rules@46"
|
|
1508
1584
|
},
|
|
1509
1585
|
"arguments": []
|
|
1510
1586
|
}
|
|
@@ -1516,7 +1592,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1516
1592
|
"terminal": {
|
|
1517
1593
|
"$type": "RuleCall",
|
|
1518
1594
|
"rule": {
|
|
1519
|
-
"$ref": "#/rules@
|
|
1595
|
+
"$ref": "#/rules@45"
|
|
1520
1596
|
},
|
|
1521
1597
|
"arguments": []
|
|
1522
1598
|
},
|
|
@@ -1590,7 +1666,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1590
1666
|
"terminal": {
|
|
1591
1667
|
"$type": "RuleCall",
|
|
1592
1668
|
"rule": {
|
|
1593
|
-
"$ref": "#/rules@
|
|
1669
|
+
"$ref": "#/rules@46"
|
|
1594
1670
|
},
|
|
1595
1671
|
"arguments": []
|
|
1596
1672
|
}
|
|
@@ -1602,7 +1678,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1602
1678
|
"terminal": {
|
|
1603
1679
|
"$type": "RuleCall",
|
|
1604
1680
|
"rule": {
|
|
1605
|
-
"$ref": "#/rules@
|
|
1681
|
+
"$ref": "#/rules@45"
|
|
1606
1682
|
},
|
|
1607
1683
|
"arguments": []
|
|
1608
1684
|
},
|
|
@@ -1631,7 +1707,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1631
1707
|
"terminal": {
|
|
1632
1708
|
"$type": "RuleCall",
|
|
1633
1709
|
"rule": {
|
|
1634
|
-
"$ref": "#/rules@
|
|
1710
|
+
"$ref": "#/rules@46"
|
|
1635
1711
|
},
|
|
1636
1712
|
"arguments": []
|
|
1637
1713
|
}
|
|
@@ -1643,12 +1719,20 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1643
1719
|
"terminal": {
|
|
1644
1720
|
"$type": "RuleCall",
|
|
1645
1721
|
"rule": {
|
|
1646
|
-
"$ref": "#/rules@
|
|
1722
|
+
"$ref": "#/rules@45"
|
|
1647
1723
|
},
|
|
1648
1724
|
"arguments": []
|
|
1649
1725
|
},
|
|
1650
1726
|
"cardinality": "?"
|
|
1651
1727
|
},
|
|
1728
|
+
{
|
|
1729
|
+
"$type": "RuleCall",
|
|
1730
|
+
"rule": {
|
|
1731
|
+
"$ref": "#/rules@12"
|
|
1732
|
+
},
|
|
1733
|
+
"arguments": [],
|
|
1734
|
+
"cardinality": "?"
|
|
1735
|
+
},
|
|
1652
1736
|
{
|
|
1653
1737
|
"$type": "Group",
|
|
1654
1738
|
"elements": [
|
|
@@ -1663,7 +1747,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1663
1747
|
"terminal": {
|
|
1664
1748
|
"$type": "RuleCall",
|
|
1665
1749
|
"rule": {
|
|
1666
|
-
"$ref": "#/rules@
|
|
1750
|
+
"$ref": "#/rules@18"
|
|
1667
1751
|
},
|
|
1668
1752
|
"arguments": []
|
|
1669
1753
|
},
|
|
@@ -1682,6 +1766,142 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1682
1766
|
"fragment": false,
|
|
1683
1767
|
"parameters": []
|
|
1684
1768
|
},
|
|
1769
|
+
{
|
|
1770
|
+
"$type": "ParserRule",
|
|
1771
|
+
"name": "FieldSet",
|
|
1772
|
+
"definition": {
|
|
1773
|
+
"$type": "Group",
|
|
1774
|
+
"elements": [
|
|
1775
|
+
{
|
|
1776
|
+
"$type": "Keyword",
|
|
1777
|
+
"value": "fields"
|
|
1778
|
+
},
|
|
1779
|
+
{
|
|
1780
|
+
"$type": "Assignment",
|
|
1781
|
+
"feature": "name",
|
|
1782
|
+
"operator": "=",
|
|
1783
|
+
"terminal": {
|
|
1784
|
+
"$type": "RuleCall",
|
|
1785
|
+
"rule": {
|
|
1786
|
+
"$ref": "#/rules@46"
|
|
1787
|
+
},
|
|
1788
|
+
"arguments": []
|
|
1789
|
+
}
|
|
1790
|
+
},
|
|
1791
|
+
{
|
|
1792
|
+
"$type": "Assignment",
|
|
1793
|
+
"feature": "label",
|
|
1794
|
+
"operator": "=",
|
|
1795
|
+
"terminal": {
|
|
1796
|
+
"$type": "RuleCall",
|
|
1797
|
+
"rule": {
|
|
1798
|
+
"$ref": "#/rules@45"
|
|
1799
|
+
},
|
|
1800
|
+
"arguments": []
|
|
1801
|
+
},
|
|
1802
|
+
"cardinality": "?"
|
|
1803
|
+
},
|
|
1804
|
+
{
|
|
1805
|
+
"$type": "RuleCall",
|
|
1806
|
+
"rule": {
|
|
1807
|
+
"$ref": "#/rules@12"
|
|
1808
|
+
},
|
|
1809
|
+
"arguments": [],
|
|
1810
|
+
"cardinality": "?"
|
|
1811
|
+
},
|
|
1812
|
+
{
|
|
1813
|
+
"$type": "Keyword",
|
|
1814
|
+
"value": "{"
|
|
1815
|
+
},
|
|
1816
|
+
{
|
|
1817
|
+
"$type": "Assignment",
|
|
1818
|
+
"feature": "members",
|
|
1819
|
+
"operator": "+=",
|
|
1820
|
+
"terminal": {
|
|
1821
|
+
"$type": "RuleCall",
|
|
1822
|
+
"rule": {
|
|
1823
|
+
"$ref": "#/rules@18"
|
|
1824
|
+
},
|
|
1825
|
+
"arguments": []
|
|
1826
|
+
},
|
|
1827
|
+
"cardinality": "*"
|
|
1828
|
+
},
|
|
1829
|
+
{
|
|
1830
|
+
"$type": "Keyword",
|
|
1831
|
+
"value": "}"
|
|
1832
|
+
}
|
|
1833
|
+
]
|
|
1834
|
+
},
|
|
1835
|
+
"entry": false,
|
|
1836
|
+
"fragment": false,
|
|
1837
|
+
"parameters": []
|
|
1838
|
+
},
|
|
1839
|
+
{
|
|
1840
|
+
"$type": "ParserRule",
|
|
1841
|
+
"fragment": true,
|
|
1842
|
+
"name": "WithFieldSets",
|
|
1843
|
+
"definition": {
|
|
1844
|
+
"$type": "Group",
|
|
1845
|
+
"elements": [
|
|
1846
|
+
{
|
|
1847
|
+
"$type": "Keyword",
|
|
1848
|
+
"value": "with"
|
|
1849
|
+
},
|
|
1850
|
+
{
|
|
1851
|
+
"$type": "Assignment",
|
|
1852
|
+
"feature": "fieldSets",
|
|
1853
|
+
"operator": "+=",
|
|
1854
|
+
"terminal": {
|
|
1855
|
+
"$type": "CrossReference",
|
|
1856
|
+
"type": {
|
|
1857
|
+
"$ref": "#/rules@11"
|
|
1858
|
+
},
|
|
1859
|
+
"terminal": {
|
|
1860
|
+
"$type": "RuleCall",
|
|
1861
|
+
"rule": {
|
|
1862
|
+
"$ref": "#/rules@41"
|
|
1863
|
+
},
|
|
1864
|
+
"arguments": []
|
|
1865
|
+
},
|
|
1866
|
+
"deprecatedSyntax": false,
|
|
1867
|
+
"isMulti": false
|
|
1868
|
+
}
|
|
1869
|
+
},
|
|
1870
|
+
{
|
|
1871
|
+
"$type": "Group",
|
|
1872
|
+
"elements": [
|
|
1873
|
+
{
|
|
1874
|
+
"$type": "Keyword",
|
|
1875
|
+
"value": ","
|
|
1876
|
+
},
|
|
1877
|
+
{
|
|
1878
|
+
"$type": "Assignment",
|
|
1879
|
+
"feature": "fieldSets",
|
|
1880
|
+
"operator": "+=",
|
|
1881
|
+
"terminal": {
|
|
1882
|
+
"$type": "CrossReference",
|
|
1883
|
+
"type": {
|
|
1884
|
+
"$ref": "#/rules@11"
|
|
1885
|
+
},
|
|
1886
|
+
"terminal": {
|
|
1887
|
+
"$type": "RuleCall",
|
|
1888
|
+
"rule": {
|
|
1889
|
+
"$ref": "#/rules@41"
|
|
1890
|
+
},
|
|
1891
|
+
"arguments": []
|
|
1892
|
+
},
|
|
1893
|
+
"deprecatedSyntax": false,
|
|
1894
|
+
"isMulti": false
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
],
|
|
1898
|
+
"cardinality": "*"
|
|
1899
|
+
}
|
|
1900
|
+
]
|
|
1901
|
+
},
|
|
1902
|
+
"entry": false,
|
|
1903
|
+
"parameters": []
|
|
1904
|
+
},
|
|
1685
1905
|
{
|
|
1686
1906
|
"$type": "ParserRule",
|
|
1687
1907
|
"name": "UnionDecl",
|
|
@@ -1699,7 +1919,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1699
1919
|
"terminal": {
|
|
1700
1920
|
"$type": "RuleCall",
|
|
1701
1921
|
"rule": {
|
|
1702
|
-
"$ref": "#/rules@
|
|
1922
|
+
"$ref": "#/rules@46"
|
|
1703
1923
|
},
|
|
1704
1924
|
"arguments": []
|
|
1705
1925
|
}
|
|
@@ -1711,7 +1931,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1711
1931
|
"terminal": {
|
|
1712
1932
|
"$type": "RuleCall",
|
|
1713
1933
|
"rule": {
|
|
1714
|
-
"$ref": "#/rules@
|
|
1934
|
+
"$ref": "#/rules@45"
|
|
1715
1935
|
},
|
|
1716
1936
|
"arguments": []
|
|
1717
1937
|
},
|
|
@@ -1731,7 +1951,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1731
1951
|
"terminal": {
|
|
1732
1952
|
"$type": "RuleCall",
|
|
1733
1953
|
"rule": {
|
|
1734
|
-
"$ref": "#/rules@
|
|
1954
|
+
"$ref": "#/rules@40"
|
|
1735
1955
|
},
|
|
1736
1956
|
"arguments": []
|
|
1737
1957
|
}
|
|
@@ -1755,7 +1975,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1755
1975
|
"terminal": {
|
|
1756
1976
|
"$type": "RuleCall",
|
|
1757
1977
|
"rule": {
|
|
1758
|
-
"$ref": "#/rules@
|
|
1978
|
+
"$ref": "#/rules@41"
|
|
1759
1979
|
},
|
|
1760
1980
|
"arguments": []
|
|
1761
1981
|
},
|
|
@@ -1780,7 +2000,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1780
2000
|
"terminal": {
|
|
1781
2001
|
"$type": "RuleCall",
|
|
1782
2002
|
"rule": {
|
|
1783
|
-
"$ref": "#/rules@
|
|
2003
|
+
"$ref": "#/rules@14"
|
|
1784
2004
|
},
|
|
1785
2005
|
"arguments": []
|
|
1786
2006
|
},
|
|
@@ -1809,7 +2029,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1809
2029
|
"terminal": {
|
|
1810
2030
|
"$type": "RuleCall",
|
|
1811
2031
|
"rule": {
|
|
1812
|
-
"$ref": "#/rules@
|
|
2032
|
+
"$ref": "#/rules@46"
|
|
1813
2033
|
},
|
|
1814
2034
|
"arguments": []
|
|
1815
2035
|
}
|
|
@@ -1821,7 +2041,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1821
2041
|
"terminal": {
|
|
1822
2042
|
"$type": "RuleCall",
|
|
1823
2043
|
"rule": {
|
|
1824
|
-
"$ref": "#/rules@
|
|
2044
|
+
"$ref": "#/rules@45"
|
|
1825
2045
|
},
|
|
1826
2046
|
"arguments": []
|
|
1827
2047
|
},
|
|
@@ -1841,7 +2061,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1841
2061
|
"terminal": {
|
|
1842
2062
|
"$type": "RuleCall",
|
|
1843
2063
|
"rule": {
|
|
1844
|
-
"$ref": "#/rules@
|
|
2064
|
+
"$ref": "#/rules@18"
|
|
1845
2065
|
},
|
|
1846
2066
|
"arguments": []
|
|
1847
2067
|
},
|
|
@@ -1877,7 +2097,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1877
2097
|
"terminal": {
|
|
1878
2098
|
"$type": "RuleCall",
|
|
1879
2099
|
"rule": {
|
|
1880
|
-
"$ref": "#/rules@
|
|
2100
|
+
"$ref": "#/rules@46"
|
|
1881
2101
|
},
|
|
1882
2102
|
"arguments": []
|
|
1883
2103
|
}
|
|
@@ -1889,12 +2109,20 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1889
2109
|
"terminal": {
|
|
1890
2110
|
"$type": "RuleCall",
|
|
1891
2111
|
"rule": {
|
|
1892
|
-
"$ref": "#/rules@
|
|
2112
|
+
"$ref": "#/rules@45"
|
|
1893
2113
|
},
|
|
1894
2114
|
"arguments": []
|
|
1895
2115
|
},
|
|
1896
2116
|
"cardinality": "?"
|
|
1897
2117
|
},
|
|
2118
|
+
{
|
|
2119
|
+
"$type": "RuleCall",
|
|
2120
|
+
"rule": {
|
|
2121
|
+
"$ref": "#/rules@12"
|
|
2122
|
+
},
|
|
2123
|
+
"arguments": [],
|
|
2124
|
+
"cardinality": "?"
|
|
2125
|
+
},
|
|
1898
2126
|
{
|
|
1899
2127
|
"$type": "Keyword",
|
|
1900
2128
|
"value": "{"
|
|
@@ -1906,7 +2134,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1906
2134
|
"terminal": {
|
|
1907
2135
|
"$type": "RuleCall",
|
|
1908
2136
|
"rule": {
|
|
1909
|
-
"$ref": "#/rules@
|
|
2137
|
+
"$ref": "#/rules@18"
|
|
1910
2138
|
},
|
|
1911
2139
|
"arguments": []
|
|
1912
2140
|
},
|
|
@@ -1939,7 +2167,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1939
2167
|
"terminal": {
|
|
1940
2168
|
"$type": "RuleCall",
|
|
1941
2169
|
"rule": {
|
|
1942
|
-
"$ref": "#/rules@
|
|
2170
|
+
"$ref": "#/rules@46"
|
|
1943
2171
|
},
|
|
1944
2172
|
"arguments": []
|
|
1945
2173
|
}
|
|
@@ -1951,12 +2179,20 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1951
2179
|
"terminal": {
|
|
1952
2180
|
"$type": "RuleCall",
|
|
1953
2181
|
"rule": {
|
|
1954
|
-
"$ref": "#/rules@
|
|
2182
|
+
"$ref": "#/rules@45"
|
|
1955
2183
|
},
|
|
1956
2184
|
"arguments": []
|
|
1957
2185
|
},
|
|
1958
2186
|
"cardinality": "?"
|
|
1959
2187
|
},
|
|
2188
|
+
{
|
|
2189
|
+
"$type": "RuleCall",
|
|
2190
|
+
"rule": {
|
|
2191
|
+
"$ref": "#/rules@12"
|
|
2192
|
+
},
|
|
2193
|
+
"arguments": [],
|
|
2194
|
+
"cardinality": "?"
|
|
2195
|
+
},
|
|
1960
2196
|
{
|
|
1961
2197
|
"$type": "Keyword",
|
|
1962
2198
|
"value": "{"
|
|
@@ -1968,7 +2204,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1968
2204
|
"terminal": {
|
|
1969
2205
|
"$type": "RuleCall",
|
|
1970
2206
|
"rule": {
|
|
1971
|
-
"$ref": "#/rules@
|
|
2207
|
+
"$ref": "#/rules@17"
|
|
1972
2208
|
},
|
|
1973
2209
|
"arguments": []
|
|
1974
2210
|
},
|
|
@@ -1993,21 +2229,21 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
1993
2229
|
{
|
|
1994
2230
|
"$type": "RuleCall",
|
|
1995
2231
|
"rule": {
|
|
1996
|
-
"$ref": "#/rules@
|
|
2232
|
+
"$ref": "#/rules@18"
|
|
1997
2233
|
},
|
|
1998
2234
|
"arguments": []
|
|
1999
2235
|
},
|
|
2000
2236
|
{
|
|
2001
2237
|
"$type": "RuleCall",
|
|
2002
2238
|
"rule": {
|
|
2003
|
-
"$ref": "#/rules@
|
|
2239
|
+
"$ref": "#/rules@19"
|
|
2004
2240
|
},
|
|
2005
2241
|
"arguments": []
|
|
2006
2242
|
},
|
|
2007
2243
|
{
|
|
2008
2244
|
"$type": "RuleCall",
|
|
2009
2245
|
"rule": {
|
|
2010
|
-
"$ref": "#/rules@
|
|
2246
|
+
"$ref": "#/rules@23"
|
|
2011
2247
|
},
|
|
2012
2248
|
"arguments": []
|
|
2013
2249
|
}
|
|
@@ -2026,28 +2262,28 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2026
2262
|
{
|
|
2027
2263
|
"$type": "RuleCall",
|
|
2028
2264
|
"rule": {
|
|
2029
|
-
"$ref": "#/rules@
|
|
2265
|
+
"$ref": "#/rules@20"
|
|
2030
2266
|
},
|
|
2031
2267
|
"arguments": []
|
|
2032
2268
|
},
|
|
2033
2269
|
{
|
|
2034
2270
|
"$type": "RuleCall",
|
|
2035
2271
|
"rule": {
|
|
2036
|
-
"$ref": "#/rules@
|
|
2272
|
+
"$ref": "#/rules@21"
|
|
2037
2273
|
},
|
|
2038
2274
|
"arguments": []
|
|
2039
2275
|
},
|
|
2040
2276
|
{
|
|
2041
2277
|
"$type": "RuleCall",
|
|
2042
2278
|
"rule": {
|
|
2043
|
-
"$ref": "#/rules@
|
|
2279
|
+
"$ref": "#/rules@22"
|
|
2044
2280
|
},
|
|
2045
2281
|
"arguments": []
|
|
2046
2282
|
},
|
|
2047
2283
|
{
|
|
2048
2284
|
"$type": "RuleCall",
|
|
2049
2285
|
"rule": {
|
|
2050
|
-
"$ref": "#/rules@
|
|
2286
|
+
"$ref": "#/rules@30"
|
|
2051
2287
|
},
|
|
2052
2288
|
"arguments": []
|
|
2053
2289
|
}
|
|
@@ -2074,7 +2310,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2074
2310
|
"terminal": {
|
|
2075
2311
|
"$type": "RuleCall",
|
|
2076
2312
|
"rule": {
|
|
2077
|
-
"$ref": "#/rules@
|
|
2313
|
+
"$ref": "#/rules@46"
|
|
2078
2314
|
},
|
|
2079
2315
|
"arguments": []
|
|
2080
2316
|
}
|
|
@@ -2086,7 +2322,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2086
2322
|
"terminal": {
|
|
2087
2323
|
"$type": "RuleCall",
|
|
2088
2324
|
"rule": {
|
|
2089
|
-
"$ref": "#/rules@
|
|
2325
|
+
"$ref": "#/rules@45"
|
|
2090
2326
|
},
|
|
2091
2327
|
"arguments": []
|
|
2092
2328
|
},
|
|
@@ -2106,7 +2342,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2106
2342
|
"terminal": {
|
|
2107
2343
|
"$type": "RuleCall",
|
|
2108
2344
|
"rule": {
|
|
2109
|
-
"$ref": "#/rules@
|
|
2345
|
+
"$ref": "#/rules@18"
|
|
2110
2346
|
},
|
|
2111
2347
|
"arguments": []
|
|
2112
2348
|
},
|
|
@@ -2138,7 +2374,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2138
2374
|
"terminal": {
|
|
2139
2375
|
"$type": "RuleCall",
|
|
2140
2376
|
"rule": {
|
|
2141
|
-
"$ref": "#/rules@
|
|
2377
|
+
"$ref": "#/rules@40"
|
|
2142
2378
|
},
|
|
2143
2379
|
"arguments": []
|
|
2144
2380
|
}
|
|
@@ -2154,7 +2390,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2154
2390
|
"terminal": {
|
|
2155
2391
|
"$type": "RuleCall",
|
|
2156
2392
|
"rule": {
|
|
2157
|
-
"$ref": "#/rules@
|
|
2393
|
+
"$ref": "#/rules@27"
|
|
2158
2394
|
},
|
|
2159
2395
|
"arguments": []
|
|
2160
2396
|
}
|
|
@@ -2166,7 +2402,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2166
2402
|
"terminal": {
|
|
2167
2403
|
"$type": "RuleCall",
|
|
2168
2404
|
"rule": {
|
|
2169
|
-
"$ref": "#/rules@
|
|
2405
|
+
"$ref": "#/rules@29"
|
|
2170
2406
|
},
|
|
2171
2407
|
"arguments": []
|
|
2172
2408
|
},
|
|
@@ -2179,7 +2415,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2179
2415
|
"terminal": {
|
|
2180
2416
|
"$type": "RuleCall",
|
|
2181
2417
|
"rule": {
|
|
2182
|
-
"$ref": "#/rules@
|
|
2418
|
+
"$ref": "#/rules@45"
|
|
2183
2419
|
},
|
|
2184
2420
|
"arguments": []
|
|
2185
2421
|
},
|
|
@@ -2208,7 +2444,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2208
2444
|
"terminal": {
|
|
2209
2445
|
"$type": "RuleCall",
|
|
2210
2446
|
"rule": {
|
|
2211
|
-
"$ref": "#/rules@
|
|
2447
|
+
"$ref": "#/rules@40"
|
|
2212
2448
|
},
|
|
2213
2449
|
"arguments": []
|
|
2214
2450
|
}
|
|
@@ -2224,7 +2460,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2224
2460
|
"terminal": {
|
|
2225
2461
|
"$type": "RuleCall",
|
|
2226
2462
|
"rule": {
|
|
2227
|
-
"$ref": "#/rules@
|
|
2463
|
+
"$ref": "#/rules@27"
|
|
2228
2464
|
},
|
|
2229
2465
|
"arguments": []
|
|
2230
2466
|
}
|
|
@@ -2236,7 +2472,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2236
2472
|
"terminal": {
|
|
2237
2473
|
"$type": "RuleCall",
|
|
2238
2474
|
"rule": {
|
|
2239
|
-
"$ref": "#/rules@
|
|
2475
|
+
"$ref": "#/rules@29"
|
|
2240
2476
|
},
|
|
2241
2477
|
"arguments": []
|
|
2242
2478
|
},
|
|
@@ -2249,7 +2485,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2249
2485
|
"terminal": {
|
|
2250
2486
|
"$type": "RuleCall",
|
|
2251
2487
|
"rule": {
|
|
2252
|
-
"$ref": "#/rules@
|
|
2488
|
+
"$ref": "#/rules@45"
|
|
2253
2489
|
},
|
|
2254
2490
|
"arguments": []
|
|
2255
2491
|
},
|
|
@@ -2278,7 +2514,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2278
2514
|
"terminal": {
|
|
2279
2515
|
"$type": "RuleCall",
|
|
2280
2516
|
"rule": {
|
|
2281
|
-
"$ref": "#/rules@
|
|
2517
|
+
"$ref": "#/rules@40"
|
|
2282
2518
|
},
|
|
2283
2519
|
"arguments": []
|
|
2284
2520
|
}
|
|
@@ -2294,7 +2530,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2294
2530
|
"terminal": {
|
|
2295
2531
|
"$type": "RuleCall",
|
|
2296
2532
|
"rule": {
|
|
2297
|
-
"$ref": "#/rules@
|
|
2533
|
+
"$ref": "#/rules@27"
|
|
2298
2534
|
},
|
|
2299
2535
|
"arguments": []
|
|
2300
2536
|
}
|
|
@@ -2306,7 +2542,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2306
2542
|
"terminal": {
|
|
2307
2543
|
"$type": "RuleCall",
|
|
2308
2544
|
"rule": {
|
|
2309
|
-
"$ref": "#/rules@
|
|
2545
|
+
"$ref": "#/rules@29"
|
|
2310
2546
|
},
|
|
2311
2547
|
"arguments": []
|
|
2312
2548
|
},
|
|
@@ -2323,12 +2559,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2323
2559
|
"terminal": {
|
|
2324
2560
|
"$type": "CrossReference",
|
|
2325
2561
|
"type": {
|
|
2326
|
-
"$ref": "#/rules@
|
|
2562
|
+
"$ref": "#/rules@16"
|
|
2327
2563
|
},
|
|
2328
2564
|
"terminal": {
|
|
2329
2565
|
"$type": "RuleCall",
|
|
2330
2566
|
"rule": {
|
|
2331
|
-
"$ref": "#/rules@
|
|
2567
|
+
"$ref": "#/rules@41"
|
|
2332
2568
|
},
|
|
2333
2569
|
"arguments": []
|
|
2334
2570
|
},
|
|
@@ -2343,7 +2579,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2343
2579
|
"terminal": {
|
|
2344
2580
|
"$type": "RuleCall",
|
|
2345
2581
|
"rule": {
|
|
2346
|
-
"$ref": "#/rules@
|
|
2582
|
+
"$ref": "#/rules@45"
|
|
2347
2583
|
},
|
|
2348
2584
|
"arguments": []
|
|
2349
2585
|
},
|
|
@@ -2382,7 +2618,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2382
2618
|
"terminal": {
|
|
2383
2619
|
"$type": "RuleCall",
|
|
2384
2620
|
"rule": {
|
|
2385
|
-
"$ref": "#/rules@
|
|
2621
|
+
"$ref": "#/rules@40"
|
|
2386
2622
|
},
|
|
2387
2623
|
"arguments": []
|
|
2388
2624
|
}
|
|
@@ -2401,7 +2637,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2401
2637
|
"terminal": {
|
|
2402
2638
|
"$type": "RuleCall",
|
|
2403
2639
|
"rule": {
|
|
2404
|
-
"$ref": "#/rules@
|
|
2640
|
+
"$ref": "#/rules@24"
|
|
2405
2641
|
},
|
|
2406
2642
|
"arguments": []
|
|
2407
2643
|
}
|
|
@@ -2420,7 +2656,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2420
2656
|
"terminal": {
|
|
2421
2657
|
"$type": "RuleCall",
|
|
2422
2658
|
"rule": {
|
|
2423
|
-
"$ref": "#/rules@
|
|
2659
|
+
"$ref": "#/rules@24"
|
|
2424
2660
|
},
|
|
2425
2661
|
"arguments": []
|
|
2426
2662
|
}
|
|
@@ -2442,7 +2678,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2442
2678
|
"terminal": {
|
|
2443
2679
|
"$type": "RuleCall",
|
|
2444
2680
|
"rule": {
|
|
2445
|
-
"$ref": "#/rules@
|
|
2681
|
+
"$ref": "#/rules@45"
|
|
2446
2682
|
},
|
|
2447
2683
|
"arguments": []
|
|
2448
2684
|
},
|
|
@@ -2462,12 +2698,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2462
2698
|
"terminal": {
|
|
2463
2699
|
"$type": "CrossReference",
|
|
2464
2700
|
"type": {
|
|
2465
|
-
"$ref": "#/rules@
|
|
2701
|
+
"$ref": "#/rules@19"
|
|
2466
2702
|
},
|
|
2467
2703
|
"terminal": {
|
|
2468
2704
|
"$type": "RuleCall",
|
|
2469
2705
|
"rule": {
|
|
2470
|
-
"$ref": "#/rules@
|
|
2706
|
+
"$ref": "#/rules@46"
|
|
2471
2707
|
},
|
|
2472
2708
|
"arguments": []
|
|
2473
2709
|
},
|
|
@@ -2489,12 +2725,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2489
2725
|
"terminal": {
|
|
2490
2726
|
"$type": "CrossReference",
|
|
2491
2727
|
"type": {
|
|
2492
|
-
"$ref": "#/rules@
|
|
2728
|
+
"$ref": "#/rules@19"
|
|
2493
2729
|
},
|
|
2494
2730
|
"terminal": {
|
|
2495
2731
|
"$type": "RuleCall",
|
|
2496
2732
|
"rule": {
|
|
2497
|
-
"$ref": "#/rules@
|
|
2733
|
+
"$ref": "#/rules@46"
|
|
2498
2734
|
},
|
|
2499
2735
|
"arguments": []
|
|
2500
2736
|
},
|
|
@@ -2522,12 +2758,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2522
2758
|
"terminal": {
|
|
2523
2759
|
"$type": "CrossReference",
|
|
2524
2760
|
"type": {
|
|
2525
|
-
"$ref": "#/rules@
|
|
2761
|
+
"$ref": "#/rules@19"
|
|
2526
2762
|
},
|
|
2527
2763
|
"terminal": {
|
|
2528
2764
|
"$type": "RuleCall",
|
|
2529
2765
|
"rule": {
|
|
2530
|
-
"$ref": "#/rules@
|
|
2766
|
+
"$ref": "#/rules@46"
|
|
2531
2767
|
},
|
|
2532
2768
|
"arguments": []
|
|
2533
2769
|
},
|
|
@@ -2549,12 +2785,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2549
2785
|
"terminal": {
|
|
2550
2786
|
"$type": "CrossReference",
|
|
2551
2787
|
"type": {
|
|
2552
|
-
"$ref": "#/rules@
|
|
2788
|
+
"$ref": "#/rules@19"
|
|
2553
2789
|
},
|
|
2554
2790
|
"terminal": {
|
|
2555
2791
|
"$type": "RuleCall",
|
|
2556
2792
|
"rule": {
|
|
2557
|
-
"$ref": "#/rules@
|
|
2793
|
+
"$ref": "#/rules@46"
|
|
2558
2794
|
},
|
|
2559
2795
|
"arguments": []
|
|
2560
2796
|
},
|
|
@@ -2582,12 +2818,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2582
2818
|
"terminal": {
|
|
2583
2819
|
"$type": "CrossReference",
|
|
2584
2820
|
"type": {
|
|
2585
|
-
"$ref": "#/rules@
|
|
2821
|
+
"$ref": "#/rules@25"
|
|
2586
2822
|
},
|
|
2587
2823
|
"terminal": {
|
|
2588
2824
|
"$type": "RuleCall",
|
|
2589
2825
|
"rule": {
|
|
2590
|
-
"$ref": "#/rules@
|
|
2826
|
+
"$ref": "#/rules@41"
|
|
2591
2827
|
},
|
|
2592
2828
|
"arguments": []
|
|
2593
2829
|
},
|
|
@@ -2609,12 +2845,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2609
2845
|
"terminal": {
|
|
2610
2846
|
"$type": "CrossReference",
|
|
2611
2847
|
"type": {
|
|
2612
|
-
"$ref": "#/rules@
|
|
2848
|
+
"$ref": "#/rules@25"
|
|
2613
2849
|
},
|
|
2614
2850
|
"terminal": {
|
|
2615
2851
|
"$type": "RuleCall",
|
|
2616
2852
|
"rule": {
|
|
2617
|
-
"$ref": "#/rules@
|
|
2853
|
+
"$ref": "#/rules@41"
|
|
2618
2854
|
},
|
|
2619
2855
|
"arguments": []
|
|
2620
2856
|
},
|
|
@@ -2642,12 +2878,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2642
2878
|
"terminal": {
|
|
2643
2879
|
"$type": "CrossReference",
|
|
2644
2880
|
"type": {
|
|
2645
|
-
"$ref": "#/rules@
|
|
2881
|
+
"$ref": "#/rules@26"
|
|
2646
2882
|
},
|
|
2647
2883
|
"terminal": {
|
|
2648
2884
|
"$type": "RuleCall",
|
|
2649
2885
|
"rule": {
|
|
2650
|
-
"$ref": "#/rules@
|
|
2886
|
+
"$ref": "#/rules@41"
|
|
2651
2887
|
},
|
|
2652
2888
|
"arguments": []
|
|
2653
2889
|
},
|
|
@@ -2669,12 +2905,12 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2669
2905
|
"terminal": {
|
|
2670
2906
|
"$type": "CrossReference",
|
|
2671
2907
|
"type": {
|
|
2672
|
-
"$ref": "#/rules@
|
|
2908
|
+
"$ref": "#/rules@26"
|
|
2673
2909
|
},
|
|
2674
2910
|
"terminal": {
|
|
2675
2911
|
"$type": "RuleCall",
|
|
2676
2912
|
"rule": {
|
|
2677
|
-
"$ref": "#/rules@
|
|
2913
|
+
"$ref": "#/rules@41"
|
|
2678
2914
|
},
|
|
2679
2915
|
"arguments": []
|
|
2680
2916
|
},
|
|
@@ -2707,7 +2943,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2707
2943
|
"terminal": {
|
|
2708
2944
|
"$type": "RuleCall",
|
|
2709
2945
|
"rule": {
|
|
2710
|
-
"$ref": "#/rules@
|
|
2946
|
+
"$ref": "#/rules@40"
|
|
2711
2947
|
},
|
|
2712
2948
|
"arguments": []
|
|
2713
2949
|
}
|
|
@@ -2723,7 +2959,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2723
2959
|
"terminal": {
|
|
2724
2960
|
"$type": "RuleCall",
|
|
2725
2961
|
"rule": {
|
|
2726
|
-
"$ref": "#/rules@
|
|
2962
|
+
"$ref": "#/rules@27"
|
|
2727
2963
|
},
|
|
2728
2964
|
"arguments": []
|
|
2729
2965
|
}
|
|
@@ -2735,7 +2971,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2735
2971
|
"terminal": {
|
|
2736
2972
|
"$type": "RuleCall",
|
|
2737
2973
|
"rule": {
|
|
2738
|
-
"$ref": "#/rules@
|
|
2974
|
+
"$ref": "#/rules@29"
|
|
2739
2975
|
},
|
|
2740
2976
|
"arguments": []
|
|
2741
2977
|
},
|
|
@@ -2748,7 +2984,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2748
2984
|
"terminal": {
|
|
2749
2985
|
"$type": "RuleCall",
|
|
2750
2986
|
"rule": {
|
|
2751
|
-
"$ref": "#/rules@
|
|
2987
|
+
"$ref": "#/rules@45"
|
|
2752
2988
|
},
|
|
2753
2989
|
"arguments": []
|
|
2754
2990
|
},
|
|
@@ -2787,7 +3023,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2787
3023
|
"terminal": {
|
|
2788
3024
|
"$type": "RuleCall",
|
|
2789
3025
|
"rule": {
|
|
2790
|
-
"$ref": "#/rules@
|
|
3026
|
+
"$ref": "#/rules@46"
|
|
2791
3027
|
},
|
|
2792
3028
|
"arguments": []
|
|
2793
3029
|
}
|
|
@@ -2799,12 +3035,20 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2799
3035
|
"terminal": {
|
|
2800
3036
|
"$type": "RuleCall",
|
|
2801
3037
|
"rule": {
|
|
2802
|
-
"$ref": "#/rules@
|
|
3038
|
+
"$ref": "#/rules@45"
|
|
2803
3039
|
},
|
|
2804
3040
|
"arguments": []
|
|
2805
3041
|
},
|
|
2806
3042
|
"cardinality": "?"
|
|
2807
3043
|
},
|
|
3044
|
+
{
|
|
3045
|
+
"$type": "RuleCall",
|
|
3046
|
+
"rule": {
|
|
3047
|
+
"$ref": "#/rules@12"
|
|
3048
|
+
},
|
|
3049
|
+
"arguments": [],
|
|
3050
|
+
"cardinality": "?"
|
|
3051
|
+
},
|
|
2808
3052
|
{
|
|
2809
3053
|
"$type": "Group",
|
|
2810
3054
|
"elements": [
|
|
@@ -2819,7 +3063,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2819
3063
|
"terminal": {
|
|
2820
3064
|
"$type": "RuleCall",
|
|
2821
3065
|
"rule": {
|
|
2822
|
-
"$ref": "#/rules@
|
|
3066
|
+
"$ref": "#/rules@20"
|
|
2823
3067
|
},
|
|
2824
3068
|
"arguments": []
|
|
2825
3069
|
},
|
|
@@ -2855,7 +3099,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2855
3099
|
"terminal": {
|
|
2856
3100
|
"$type": "RuleCall",
|
|
2857
3101
|
"rule": {
|
|
2858
|
-
"$ref": "#/rules@
|
|
3102
|
+
"$ref": "#/rules@46"
|
|
2859
3103
|
},
|
|
2860
3104
|
"arguments": []
|
|
2861
3105
|
}
|
|
@@ -2867,12 +3111,20 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2867
3111
|
"terminal": {
|
|
2868
3112
|
"$type": "RuleCall",
|
|
2869
3113
|
"rule": {
|
|
2870
|
-
"$ref": "#/rules@
|
|
3114
|
+
"$ref": "#/rules@45"
|
|
2871
3115
|
},
|
|
2872
3116
|
"arguments": []
|
|
2873
3117
|
},
|
|
2874
3118
|
"cardinality": "?"
|
|
2875
3119
|
},
|
|
3120
|
+
{
|
|
3121
|
+
"$type": "RuleCall",
|
|
3122
|
+
"rule": {
|
|
3123
|
+
"$ref": "#/rules@12"
|
|
3124
|
+
},
|
|
3125
|
+
"arguments": [],
|
|
3126
|
+
"cardinality": "?"
|
|
3127
|
+
},
|
|
2876
3128
|
{
|
|
2877
3129
|
"$type": "Group",
|
|
2878
3130
|
"elements": [
|
|
@@ -2887,7 +3139,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2887
3139
|
"terminal": {
|
|
2888
3140
|
"$type": "RuleCall",
|
|
2889
3141
|
"rule": {
|
|
2890
|
-
"$ref": "#/rules@
|
|
3142
|
+
"$ref": "#/rules@20"
|
|
2891
3143
|
},
|
|
2892
3144
|
"arguments": []
|
|
2893
3145
|
},
|
|
@@ -2919,7 +3171,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2919
3171
|
"terminal": {
|
|
2920
3172
|
"$type": "RuleCall",
|
|
2921
3173
|
"rule": {
|
|
2922
|
-
"$ref": "#/rules@
|
|
3174
|
+
"$ref": "#/rules@28"
|
|
2923
3175
|
},
|
|
2924
3176
|
"arguments": []
|
|
2925
3177
|
}
|
|
@@ -2936,7 +3188,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
2936
3188
|
"terminal": {
|
|
2937
3189
|
"$type": "RuleCall",
|
|
2938
3190
|
"rule": {
|
|
2939
|
-
"$ref": "#/rules@
|
|
3191
|
+
"$ref": "#/rules@41"
|
|
2940
3192
|
},
|
|
2941
3193
|
"arguments": []
|
|
2942
3194
|
},
|
|
@@ -3016,7 +3268,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3016
3268
|
"terminal": {
|
|
3017
3269
|
"$type": "RuleCall",
|
|
3018
3270
|
"rule": {
|
|
3019
|
-
"$ref": "#/rules@
|
|
3271
|
+
"$ref": "#/rules@44"
|
|
3020
3272
|
},
|
|
3021
3273
|
"arguments": []
|
|
3022
3274
|
}
|
|
@@ -3035,7 +3287,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3035
3287
|
"terminal": {
|
|
3036
3288
|
"$type": "RuleCall",
|
|
3037
3289
|
"rule": {
|
|
3038
|
-
"$ref": "#/rules@
|
|
3290
|
+
"$ref": "#/rules@44"
|
|
3039
3291
|
},
|
|
3040
3292
|
"arguments": []
|
|
3041
3293
|
}
|
|
@@ -3080,7 +3332,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3080
3332
|
"terminal": {
|
|
3081
3333
|
"$type": "RuleCall",
|
|
3082
3334
|
"rule": {
|
|
3083
|
-
"$ref": "#/rules@
|
|
3335
|
+
"$ref": "#/rules@46"
|
|
3084
3336
|
},
|
|
3085
3337
|
"arguments": []
|
|
3086
3338
|
}
|
|
@@ -3092,7 +3344,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3092
3344
|
"terminal": {
|
|
3093
3345
|
"$type": "RuleCall",
|
|
3094
3346
|
"rule": {
|
|
3095
|
-
"$ref": "#/rules@
|
|
3347
|
+
"$ref": "#/rules@45"
|
|
3096
3348
|
},
|
|
3097
3349
|
"arguments": []
|
|
3098
3350
|
},
|
|
@@ -3109,7 +3361,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3109
3361
|
"terminal": {
|
|
3110
3362
|
"$type": "RuleCall",
|
|
3111
3363
|
"rule": {
|
|
3112
|
-
"$ref": "#/rules@
|
|
3364
|
+
"$ref": "#/rules@31"
|
|
3113
3365
|
},
|
|
3114
3366
|
"arguments": []
|
|
3115
3367
|
}
|
|
@@ -3130,7 +3382,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3130
3382
|
"definition": {
|
|
3131
3383
|
"$type": "RuleCall",
|
|
3132
3384
|
"rule": {
|
|
3133
|
-
"$ref": "#/rules@
|
|
3385
|
+
"$ref": "#/rules@32"
|
|
3134
3386
|
},
|
|
3135
3387
|
"arguments": []
|
|
3136
3388
|
},
|
|
@@ -3151,7 +3403,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3151
3403
|
{
|
|
3152
3404
|
"$type": "RuleCall",
|
|
3153
3405
|
"rule": {
|
|
3154
|
-
"$ref": "#/rules@
|
|
3406
|
+
"$ref": "#/rules@33"
|
|
3155
3407
|
},
|
|
3156
3408
|
"arguments": []
|
|
3157
3409
|
},
|
|
@@ -3183,7 +3435,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3183
3435
|
"terminal": {
|
|
3184
3436
|
"$type": "RuleCall",
|
|
3185
3437
|
"rule": {
|
|
3186
|
-
"$ref": "#/rules@
|
|
3438
|
+
"$ref": "#/rules@33"
|
|
3187
3439
|
},
|
|
3188
3440
|
"arguments": []
|
|
3189
3441
|
}
|
|
@@ -3210,7 +3462,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3210
3462
|
{
|
|
3211
3463
|
"$type": "RuleCall",
|
|
3212
3464
|
"rule": {
|
|
3213
|
-
"$ref": "#/rules@
|
|
3465
|
+
"$ref": "#/rules@34"
|
|
3214
3466
|
},
|
|
3215
3467
|
"arguments": []
|
|
3216
3468
|
},
|
|
@@ -3242,7 +3494,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3242
3494
|
"terminal": {
|
|
3243
3495
|
"$type": "RuleCall",
|
|
3244
3496
|
"rule": {
|
|
3245
|
-
"$ref": "#/rules@
|
|
3497
|
+
"$ref": "#/rules@34"
|
|
3246
3498
|
},
|
|
3247
3499
|
"arguments": []
|
|
3248
3500
|
}
|
|
@@ -3269,7 +3521,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3269
3521
|
{
|
|
3270
3522
|
"$type": "RuleCall",
|
|
3271
3523
|
"rule": {
|
|
3272
|
-
"$ref": "#/rules@
|
|
3524
|
+
"$ref": "#/rules@35"
|
|
3273
3525
|
},
|
|
3274
3526
|
"arguments": []
|
|
3275
3527
|
},
|
|
@@ -3301,7 +3553,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3301
3553
|
"terminal": {
|
|
3302
3554
|
"$type": "RuleCall",
|
|
3303
3555
|
"rule": {
|
|
3304
|
-
"$ref": "#/rules@
|
|
3556
|
+
"$ref": "#/rules@35"
|
|
3305
3557
|
},
|
|
3306
3558
|
"arguments": []
|
|
3307
3559
|
}
|
|
@@ -3328,7 +3580,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3328
3580
|
{
|
|
3329
3581
|
"$type": "RuleCall",
|
|
3330
3582
|
"rule": {
|
|
3331
|
-
"$ref": "#/rules@
|
|
3583
|
+
"$ref": "#/rules@36"
|
|
3332
3584
|
},
|
|
3333
3585
|
"arguments": []
|
|
3334
3586
|
},
|
|
@@ -3388,7 +3640,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3388
3640
|
"terminal": {
|
|
3389
3641
|
"$type": "RuleCall",
|
|
3390
3642
|
"rule": {
|
|
3391
|
-
"$ref": "#/rules@
|
|
3643
|
+
"$ref": "#/rules@36"
|
|
3392
3644
|
},
|
|
3393
3645
|
"arguments": []
|
|
3394
3646
|
}
|
|
@@ -3418,7 +3670,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3418
3670
|
"terminal": {
|
|
3419
3671
|
"$type": "RuleCall",
|
|
3420
3672
|
"rule": {
|
|
3421
|
-
"$ref": "#/rules@
|
|
3673
|
+
"$ref": "#/rules@36"
|
|
3422
3674
|
},
|
|
3423
3675
|
"arguments": []
|
|
3424
3676
|
}
|
|
@@ -3434,7 +3686,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3434
3686
|
"terminal": {
|
|
3435
3687
|
"$type": "RuleCall",
|
|
3436
3688
|
"rule": {
|
|
3437
|
-
"$ref": "#/rules@
|
|
3689
|
+
"$ref": "#/rules@36"
|
|
3438
3690
|
},
|
|
3439
3691
|
"arguments": []
|
|
3440
3692
|
}
|
|
@@ -3481,7 +3733,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3481
3733
|
"terminal": {
|
|
3482
3734
|
"$type": "RuleCall",
|
|
3483
3735
|
"rule": {
|
|
3484
|
-
"$ref": "#/rules@
|
|
3736
|
+
"$ref": "#/rules@36"
|
|
3485
3737
|
},
|
|
3486
3738
|
"arguments": []
|
|
3487
3739
|
}
|
|
@@ -3491,7 +3743,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3491
3743
|
{
|
|
3492
3744
|
"$type": "RuleCall",
|
|
3493
3745
|
"rule": {
|
|
3494
|
-
"$ref": "#/rules@
|
|
3746
|
+
"$ref": "#/rules@37"
|
|
3495
3747
|
},
|
|
3496
3748
|
"arguments": []
|
|
3497
3749
|
}
|
|
@@ -3514,7 +3766,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3514
3766
|
{
|
|
3515
3767
|
"$type": "RuleCall",
|
|
3516
3768
|
"rule": {
|
|
3517
|
-
"$ref": "#/rules@
|
|
3769
|
+
"$ref": "#/rules@38"
|
|
3518
3770
|
},
|
|
3519
3771
|
"arguments": []
|
|
3520
3772
|
},
|
|
@@ -3541,7 +3793,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3541
3793
|
"terminal": {
|
|
3542
3794
|
"$type": "RuleCall",
|
|
3543
3795
|
"rule": {
|
|
3544
|
-
"$ref": "#/rules@
|
|
3796
|
+
"$ref": "#/rules@40"
|
|
3545
3797
|
},
|
|
3546
3798
|
"arguments": []
|
|
3547
3799
|
}
|
|
@@ -3575,7 +3827,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3575
3827
|
{
|
|
3576
3828
|
"$type": "RuleCall",
|
|
3577
3829
|
"rule": {
|
|
3578
|
-
"$ref": "#/rules@
|
|
3830
|
+
"$ref": "#/rules@31"
|
|
3579
3831
|
},
|
|
3580
3832
|
"arguments": []
|
|
3581
3833
|
},
|
|
@@ -3610,7 +3862,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3610
3862
|
"terminal": {
|
|
3611
3863
|
"$type": "RuleCall",
|
|
3612
3864
|
"rule": {
|
|
3613
|
-
"$ref": "#/rules@
|
|
3865
|
+
"$ref": "#/rules@31"
|
|
3614
3866
|
},
|
|
3615
3867
|
"arguments": []
|
|
3616
3868
|
}
|
|
@@ -3646,7 +3898,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3646
3898
|
"terminal": {
|
|
3647
3899
|
"$type": "RuleCall",
|
|
3648
3900
|
"rule": {
|
|
3649
|
-
"$ref": "#/rules@
|
|
3901
|
+
"$ref": "#/rules@31"
|
|
3650
3902
|
},
|
|
3651
3903
|
"arguments": []
|
|
3652
3904
|
}
|
|
@@ -3682,7 +3934,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3682
3934
|
"terminal": {
|
|
3683
3935
|
"$type": "RuleCall",
|
|
3684
3936
|
"rule": {
|
|
3685
|
-
"$ref": "#/rules@
|
|
3937
|
+
"$ref": "#/rules@31"
|
|
3686
3938
|
},
|
|
3687
3939
|
"arguments": []
|
|
3688
3940
|
}
|
|
@@ -3718,7 +3970,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3718
3970
|
"terminal": {
|
|
3719
3971
|
"$type": "RuleCall",
|
|
3720
3972
|
"rule": {
|
|
3721
|
-
"$ref": "#/rules@
|
|
3973
|
+
"$ref": "#/rules@31"
|
|
3722
3974
|
},
|
|
3723
3975
|
"arguments": []
|
|
3724
3976
|
}
|
|
@@ -3734,7 +3986,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3734
3986
|
"terminal": {
|
|
3735
3987
|
"$type": "RuleCall",
|
|
3736
3988
|
"rule": {
|
|
3737
|
-
"$ref": "#/rules@
|
|
3989
|
+
"$ref": "#/rules@45"
|
|
3738
3990
|
},
|
|
3739
3991
|
"arguments": []
|
|
3740
3992
|
}
|
|
@@ -3784,7 +4036,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3784
4036
|
"terminal": {
|
|
3785
4037
|
"$type": "RuleCall",
|
|
3786
4038
|
"rule": {
|
|
3787
|
-
"$ref": "#/rules@
|
|
4039
|
+
"$ref": "#/rules@31"
|
|
3788
4040
|
},
|
|
3789
4041
|
"arguments": []
|
|
3790
4042
|
}
|
|
@@ -3800,7 +4052,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3800
4052
|
"terminal": {
|
|
3801
4053
|
"$type": "RuleCall",
|
|
3802
4054
|
"rule": {
|
|
3803
|
-
"$ref": "#/rules@
|
|
4055
|
+
"$ref": "#/rules@39"
|
|
3804
4056
|
},
|
|
3805
4057
|
"arguments": []
|
|
3806
4058
|
}
|
|
@@ -3816,7 +4068,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3816
4068
|
"terminal": {
|
|
3817
4069
|
"$type": "RuleCall",
|
|
3818
4070
|
"rule": {
|
|
3819
|
-
"$ref": "#/rules@
|
|
4071
|
+
"$ref": "#/rules@31"
|
|
3820
4072
|
},
|
|
3821
4073
|
"arguments": []
|
|
3822
4074
|
}
|
|
@@ -3884,7 +4136,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3884
4136
|
"terminal": {
|
|
3885
4137
|
"$type": "RuleCall",
|
|
3886
4138
|
"rule": {
|
|
3887
|
-
"$ref": "#/rules@
|
|
4139
|
+
"$ref": "#/rules@43"
|
|
3888
4140
|
},
|
|
3889
4141
|
"arguments": []
|
|
3890
4142
|
}
|
|
@@ -3918,7 +4170,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3918
4170
|
"terminal": {
|
|
3919
4171
|
"$type": "RuleCall",
|
|
3920
4172
|
"rule": {
|
|
3921
|
-
"$ref": "#/rules@
|
|
4173
|
+
"$ref": "#/rules@44"
|
|
3922
4174
|
},
|
|
3923
4175
|
"arguments": []
|
|
3924
4176
|
}
|
|
@@ -3942,7 +4194,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3942
4194
|
"terminal": {
|
|
3943
4195
|
"$type": "RuleCall",
|
|
3944
4196
|
"rule": {
|
|
3945
|
-
"$ref": "#/rules@
|
|
4197
|
+
"$ref": "#/rules@45"
|
|
3946
4198
|
},
|
|
3947
4199
|
"arguments": []
|
|
3948
4200
|
}
|
|
@@ -3966,7 +4218,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3966
4218
|
"terminal": {
|
|
3967
4219
|
"$type": "RuleCall",
|
|
3968
4220
|
"rule": {
|
|
3969
|
-
"$ref": "#/rules@
|
|
4221
|
+
"$ref": "#/rules@40"
|
|
3970
4222
|
},
|
|
3971
4223
|
"arguments": []
|
|
3972
4224
|
}
|
|
@@ -3989,7 +4241,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
3989
4241
|
"terminal": {
|
|
3990
4242
|
"$type": "RuleCall",
|
|
3991
4243
|
"rule": {
|
|
3992
|
-
"$ref": "#/rules@
|
|
4244
|
+
"$ref": "#/rules@40"
|
|
3993
4245
|
},
|
|
3994
4246
|
"arguments": []
|
|
3995
4247
|
}
|
|
@@ -4008,7 +4260,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
4008
4260
|
{
|
|
4009
4261
|
"$type": "RuleCall",
|
|
4010
4262
|
"rule": {
|
|
4011
|
-
"$ref": "#/rules@
|
|
4263
|
+
"$ref": "#/rules@46"
|
|
4012
4264
|
},
|
|
4013
4265
|
"arguments": []
|
|
4014
4266
|
},
|
|
@@ -4027,6 +4279,14 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
4027
4279
|
{
|
|
4028
4280
|
"$type": "Keyword",
|
|
4029
4281
|
"value": "persistent"
|
|
4282
|
+
},
|
|
4283
|
+
{
|
|
4284
|
+
"$type": "Keyword",
|
|
4285
|
+
"value": "fields"
|
|
4286
|
+
},
|
|
4287
|
+
{
|
|
4288
|
+
"$type": "Keyword",
|
|
4289
|
+
"value": "with"
|
|
4030
4290
|
}
|
|
4031
4291
|
]
|
|
4032
4292
|
},
|
|
@@ -4044,7 +4304,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
4044
4304
|
{
|
|
4045
4305
|
"$type": "RuleCall",
|
|
4046
4306
|
"rule": {
|
|
4047
|
-
"$ref": "#/rules@
|
|
4307
|
+
"$ref": "#/rules@46"
|
|
4048
4308
|
},
|
|
4049
4309
|
"arguments": []
|
|
4050
4310
|
},
|
|
@@ -4058,7 +4318,7 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
4058
4318
|
{
|
|
4059
4319
|
"$type": "RuleCall",
|
|
4060
4320
|
"rule": {
|
|
4061
|
-
"$ref": "#/rules@
|
|
4321
|
+
"$ref": "#/rules@46"
|
|
4062
4322
|
},
|
|
4063
4323
|
"arguments": []
|
|
4064
4324
|
}
|
|
@@ -4191,19 +4451,19 @@ var loadedDomainGrammar, DomainGrammar = () => loadedDomainGrammar ?? (loadedDom
|
|
|
4191
4451
|
{
|
|
4192
4452
|
"$type": "SimpleType",
|
|
4193
4453
|
"typeRef": {
|
|
4194
|
-
"$ref": "#/rules@
|
|
4454
|
+
"$ref": "#/rules@13"
|
|
4195
4455
|
}
|
|
4196
4456
|
},
|
|
4197
4457
|
{
|
|
4198
4458
|
"$type": "SimpleType",
|
|
4199
4459
|
"typeRef": {
|
|
4200
|
-
"$ref": "#/rules@
|
|
4460
|
+
"$ref": "#/rules@15"
|
|
4201
4461
|
}
|
|
4202
4462
|
},
|
|
4203
4463
|
{
|
|
4204
4464
|
"$type": "SimpleType",
|
|
4205
4465
|
"typeRef": {
|
|
4206
|
-
"$ref": "#/rules@
|
|
4466
|
+
"$ref": "#/rules@16"
|
|
4207
4467
|
}
|
|
4208
4468
|
}
|
|
4209
4469
|
]
|
|
@@ -4555,6 +4815,17 @@ class ModelIndex {
|
|
|
4555
4815
|
get errors() {
|
|
4556
4816
|
return this.elements.filter(isErrorDecl);
|
|
4557
4817
|
}
|
|
4818
|
+
get fieldSets() {
|
|
4819
|
+
return this.elements.filter(isFieldSet);
|
|
4820
|
+
}
|
|
4821
|
+
}
|
|
4822
|
+
function fieldSetsOf(el) {
|
|
4823
|
+
return [...new Set(el.fieldSets.map((r) => r.ref).filter((f) => !!f))];
|
|
4824
|
+
}
|
|
4825
|
+
function includedFields(el) {
|
|
4826
|
+
if (isFieldSet(el))
|
|
4827
|
+
return [];
|
|
4828
|
+
return fieldSetsOf(el).flatMap((fieldSet) => fieldsOf(fieldSet.members).map((field) => ({ field, fieldSet })));
|
|
4558
4829
|
}
|
|
4559
4830
|
function primitiveInvariants(p) {
|
|
4560
4831
|
if (p.constraint)
|
|
@@ -4613,6 +4884,11 @@ function buildModel(index, fileOf) {
|
|
|
4613
4884
|
line: (node.$cstNode?.range.start.line ?? 0) + 1,
|
|
4614
4885
|
endLine: (node.$cstNode?.range.end.line ?? 0) + 1
|
|
4615
4886
|
});
|
|
4887
|
+
const included = (el) => includedFields(el).map(({ field: f, fieldSet }) => ({ ...field(f), fieldSet: elementId(fieldSet.$container.name, fieldSet.name) }));
|
|
4888
|
+
const withFieldSets = (el) => {
|
|
4889
|
+
const sets = fieldSetsOf(el);
|
|
4890
|
+
return sets.length && !isFieldSet(el) ? { fieldSets: sets.map((s) => elementId(s.$container.name, s.name)) } : {};
|
|
4891
|
+
};
|
|
4616
4892
|
for (const el of index.elements) {
|
|
4617
4893
|
const id = elementId(el.$container.name, el.name);
|
|
4618
4894
|
if (elements[id])
|
|
@@ -4656,14 +4932,16 @@ function buildModel(index, fileOf) {
|
|
|
4656
4932
|
};
|
|
4657
4933
|
});
|
|
4658
4934
|
} else if (isAggregate(el)) {
|
|
4659
|
-
base
|
|
4935
|
+
Object.assign(base, withFieldSets(el));
|
|
4936
|
+
base.fields = [...included(el), ...commonFields(el).map(field)];
|
|
4660
4937
|
base.invariants = invariantsOf(el.members).map(invariant);
|
|
4661
4938
|
base.states = statesOf(el).map((s) => state(id, s, loc, field));
|
|
4662
4939
|
base.commands = commandsOf(el).map((c) => command(id, c, loc, field));
|
|
4663
4940
|
} else {
|
|
4941
|
+
Object.assign(base, withFieldSets(el));
|
|
4664
4942
|
if (isEventDecl(el) && el.persistent)
|
|
4665
4943
|
base.persistent = true;
|
|
4666
|
-
base.fields = fieldsOf(el.members).map(field);
|
|
4944
|
+
base.fields = [...included(el), ...fieldsOf(el.members).map(field)];
|
|
4667
4945
|
base.invariants = invariantsOf(el.members).map(invariant);
|
|
4668
4946
|
}
|
|
4669
4947
|
elements[id] = base;
|
|
@@ -4704,6 +4982,8 @@ function kindOf(el) {
|
|
|
4704
4982
|
return "event";
|
|
4705
4983
|
if (isErrorDecl(el))
|
|
4706
4984
|
return "error";
|
|
4985
|
+
if (isFieldSet(el))
|
|
4986
|
+
return "fieldSet";
|
|
4707
4987
|
throw new Error(`unknown element ${el.$type}`);
|
|
4708
4988
|
}
|
|
4709
4989
|
function typeExpr(ref) {
|
|
@@ -4817,6 +5097,227 @@ var init_commands = __esm(() => {
|
|
|
4817
5097
|
init_model_index();
|
|
4818
5098
|
});
|
|
4819
5099
|
|
|
5100
|
+
// src/generator/naming.ts
|
|
5101
|
+
function generatedNames(index, ctx) {
|
|
5102
|
+
const out = [];
|
|
5103
|
+
const seen = new Set;
|
|
5104
|
+
for (const el of index.elementsOf(ctx)) {
|
|
5105
|
+
if (seen.has(el.name))
|
|
5106
|
+
continue;
|
|
5107
|
+
seen.add(el.name);
|
|
5108
|
+
if (!isAggregate(el)) {
|
|
5109
|
+
out.push({ name: el.name, origin: `${KIND_LABELS[el.$type]} '${el.name}'`, node: el });
|
|
5110
|
+
if (isIdType(el) || isPrimitiveDecl(el)) {
|
|
5111
|
+
out.push({ name: makeTypeName(el), origin: `the constructor of '${el.name}'`, node: el });
|
|
5112
|
+
if (primitiveInvariants(el).length)
|
|
5113
|
+
out.push({ name: invalidTypeName(el), origin: `the error of '${el.name}'`, node: el });
|
|
5114
|
+
}
|
|
5115
|
+
continue;
|
|
5116
|
+
}
|
|
5117
|
+
const states = firstByName(statesOf(el));
|
|
5118
|
+
out.push({ name: el.name, origin: `aggregate '${el.name}'`, node: el });
|
|
5119
|
+
if (states.length > 0) {
|
|
5120
|
+
out.push({ name: commonTypeName(el), origin: `common fields of '${el.name}'`, node: el });
|
|
5121
|
+
for (const s of states) {
|
|
5122
|
+
out.push({ name: stateTypeName(el, s), origin: `state '${el.name}.${s.name}'`, node: s });
|
|
5123
|
+
}
|
|
5124
|
+
}
|
|
5125
|
+
const commands = firstByName(commandsOf(el));
|
|
5126
|
+
if (commands.length > 0) {
|
|
5127
|
+
out.push({ name: commandsInterfaceName(el), origin: `commands of '${el.name}'`, node: el });
|
|
5128
|
+
}
|
|
5129
|
+
for (const c of commands) {
|
|
5130
|
+
out.push({ name: commandTypeName(el, c), origin: `command '${el.name}.${c.name}'`, node: c });
|
|
5131
|
+
}
|
|
5132
|
+
if (commands.some((c) => c.emits.length > 0)) {
|
|
5133
|
+
out.push({ name: aggregateEventTypeName(el), origin: `the union of the events of '${el.name}'`, node: el });
|
|
5134
|
+
}
|
|
5135
|
+
}
|
|
5136
|
+
const persistent = index.elementsOf(ctx).find((el) => isEventDecl(el) && el.persistent);
|
|
5137
|
+
if (persistent)
|
|
5138
|
+
out.push({ name: PERSISTENT_EVENT_TYPE, origin: "the union of persistent events", node: persistent });
|
|
5139
|
+
const event = index.elementsOf(ctx).find(isEventDecl);
|
|
5140
|
+
if (event)
|
|
5141
|
+
out.push({ name: DOMAIN_EVENT_TYPE, origin: "the union of the events", node: event });
|
|
5142
|
+
const aggregate = index.elementsOf(ctx).find(isAggregate);
|
|
5143
|
+
if (aggregate)
|
|
5144
|
+
out.push({ name: AGGREGATE_TYPE, origin: "the union of the aggregates", node: aggregate });
|
|
5145
|
+
return out;
|
|
5146
|
+
}
|
|
5147
|
+
function firstByName(items) {
|
|
5148
|
+
const seen = new Set;
|
|
5149
|
+
return items.filter((i) => !seen.has(i.name) && seen.add(i.name));
|
|
5150
|
+
}
|
|
5151
|
+
var RUNTIME_NAMES, EVENT_TAG = "type", STATE_TAG = "state", pascal = (s) => s.charAt(0).toUpperCase() + s.slice(1), camel = (s) => s.charAt(0).toLowerCase() + s.slice(1), commonTypeName = (agg) => `${agg.name}Common`, stateTypeName = (agg, state) => `${typeof state === "string" ? state : state.name}${agg.name}`, commandTypeName = (agg, cmd) => `${pascal(cmd.name)}${agg.name}`, commandsInterfaceName = (agg) => `${agg.name}Commands`, aggregateParamName = (agg) => camel(agg.name), makeTypeName = (p) => `Make${p.name}`, invalidTypeName = (p) => `Invalid${p.name}`, PERSISTENT_EVENT_TYPE = "PersistentEvent", DOMAIN_EVENT_TYPE = "DomainEvent", AGGREGATE_TYPE = "Aggregate", aggregateEventTypeName = (agg) => `${agg.name}Event`, KIND_LABELS, TS_RESERVED;
|
|
5152
|
+
var init_naming = __esm(() => {
|
|
5153
|
+
init_ast();
|
|
5154
|
+
init_model_index();
|
|
5155
|
+
RUNTIME_NAMES = ["Result", "Ok", "Err", "Decimal", "Timestamp", "ok", "err"];
|
|
5156
|
+
KIND_LABELS = {
|
|
5157
|
+
IdType: "id",
|
|
5158
|
+
PrimitiveDecl: "primitive",
|
|
5159
|
+
EnumDecl: "enum",
|
|
5160
|
+
ValueObject: "value object",
|
|
5161
|
+
UnionDecl: "union",
|
|
5162
|
+
Entity: "entity",
|
|
5163
|
+
EventDecl: "event",
|
|
5164
|
+
ErrorDecl: "error",
|
|
5165
|
+
FieldSet: "field set"
|
|
5166
|
+
};
|
|
5167
|
+
TS_RESERVED = new Set([
|
|
5168
|
+
"break",
|
|
5169
|
+
"case",
|
|
5170
|
+
"catch",
|
|
5171
|
+
"class",
|
|
5172
|
+
"const",
|
|
5173
|
+
"continue",
|
|
5174
|
+
"debugger",
|
|
5175
|
+
"default",
|
|
5176
|
+
"delete",
|
|
5177
|
+
"do",
|
|
5178
|
+
"else",
|
|
5179
|
+
"enum",
|
|
5180
|
+
"export",
|
|
5181
|
+
"extends",
|
|
5182
|
+
"false",
|
|
5183
|
+
"finally",
|
|
5184
|
+
"for",
|
|
5185
|
+
"function",
|
|
5186
|
+
"if",
|
|
5187
|
+
"import",
|
|
5188
|
+
"in",
|
|
5189
|
+
"instanceof",
|
|
5190
|
+
"new",
|
|
5191
|
+
"null",
|
|
5192
|
+
"return",
|
|
5193
|
+
"super",
|
|
5194
|
+
"switch",
|
|
5195
|
+
"this",
|
|
5196
|
+
"throw",
|
|
5197
|
+
"true",
|
|
5198
|
+
"try",
|
|
5199
|
+
"typeof",
|
|
5200
|
+
"var",
|
|
5201
|
+
"void",
|
|
5202
|
+
"while",
|
|
5203
|
+
"with",
|
|
5204
|
+
"yield",
|
|
5205
|
+
"let",
|
|
5206
|
+
"static",
|
|
5207
|
+
"implements",
|
|
5208
|
+
"interface",
|
|
5209
|
+
"package",
|
|
5210
|
+
"private",
|
|
5211
|
+
"protected",
|
|
5212
|
+
"public",
|
|
5213
|
+
"await",
|
|
5214
|
+
"any",
|
|
5215
|
+
"boolean",
|
|
5216
|
+
"number",
|
|
5217
|
+
"string",
|
|
5218
|
+
"symbol",
|
|
5219
|
+
"never",
|
|
5220
|
+
"unknown",
|
|
5221
|
+
"object",
|
|
5222
|
+
"undefined",
|
|
5223
|
+
"bigint"
|
|
5224
|
+
]);
|
|
5225
|
+
});
|
|
5226
|
+
|
|
5227
|
+
// src/core/checker/events.ts
|
|
5228
|
+
function checkEventIds(index, sink) {
|
|
5229
|
+
for (const agg of index.aggregates) {
|
|
5230
|
+
const idType = identityField(agg)?.type?.decl?.ref;
|
|
5231
|
+
if (!idType || !isIdType(idType))
|
|
5232
|
+
continue;
|
|
5233
|
+
const checked = new Set;
|
|
5234
|
+
for (const cmd of commandsOf(agg)) {
|
|
5235
|
+
cmd.emits.forEach((r, i) => {
|
|
5236
|
+
const ev = r.ref;
|
|
5237
|
+
if (!ev || checked.has(ev))
|
|
5238
|
+
return;
|
|
5239
|
+
checked.add(ev);
|
|
5240
|
+
const fields = [...includedFields(ev).map((x) => x.field), ...ev.members];
|
|
5241
|
+
if (fields.some((f) => f.type?.decl?.ref === idType))
|
|
5242
|
+
return;
|
|
5243
|
+
const typeName = idType.$container.name === ev.$container.name ? idType.name : `${idType.$container.name}.${idType.name}`;
|
|
5244
|
+
sink.warning("M017", `Event '${ev.name}' emitted by '${agg.name}.${cmd.name}' has no field of type '${idType.name}' to tell which '${agg.name}' it is about (e.g. '${camel(agg.name)}Id: ${typeName}').`, cmd, "emits", i);
|
|
5245
|
+
});
|
|
5246
|
+
}
|
|
5247
|
+
}
|
|
5248
|
+
}
|
|
5249
|
+
var init_events = __esm(() => {
|
|
5250
|
+
init_ast();
|
|
5251
|
+
init_naming();
|
|
5252
|
+
init_model_index();
|
|
5253
|
+
});
|
|
5254
|
+
|
|
5255
|
+
// src/core/checker/field-sets.ts
|
|
5256
|
+
function checkFieldSets(index, sink) {
|
|
5257
|
+
for (const fs of index.fieldSets) {
|
|
5258
|
+
for (const m of fs.members) {
|
|
5259
|
+
if (isInvariant(m)) {
|
|
5260
|
+
sink.error("M016", `Field set '${fs.name}' cannot hold invariants; write invariant '${m.name}' in the elements that use it.`, m, "name");
|
|
5261
|
+
} else if (isOwnsField(m) || isReferenceField(m)) {
|
|
5262
|
+
const keyword = isOwnsField(m) ? "owns" : "references";
|
|
5263
|
+
sink.error("M016", `A field set holds plain fields only; '${m.name}' is declared with '${keyword}'.`, m, "name");
|
|
5264
|
+
} else if (m.name === "id") {
|
|
5265
|
+
sink.error("M016", `Field set '${fs.name}' cannot declare 'id'; the identity is declared by each aggregate and entity itself.`, m, "name");
|
|
5266
|
+
}
|
|
5267
|
+
}
|
|
5268
|
+
}
|
|
5269
|
+
for (const el of index.elements) {
|
|
5270
|
+
if (!("fieldSets" in el) || el.fieldSets.length === 0)
|
|
5271
|
+
continue;
|
|
5272
|
+
if (isFieldSet(el) || isValueObject(el) || isErrorDecl(el)) {
|
|
5273
|
+
const what = isFieldSet(el) ? `field set '${el.name}' cannot include other field sets` : `${isValueObject(el) ? "value object" : "error"} '${el.name}' cannot take field sets`;
|
|
5274
|
+
sink.error("M016", `'with' is only for aggregates, entities and events; ${what}.`, el, "fieldSets");
|
|
5275
|
+
continue;
|
|
5276
|
+
}
|
|
5277
|
+
if (isAggregate(el) || isEntity(el) || isEventDecl(el))
|
|
5278
|
+
checkUses(el, sink);
|
|
5279
|
+
}
|
|
5280
|
+
}
|
|
5281
|
+
function checkUses(el, sink) {
|
|
5282
|
+
const seen = new Set;
|
|
5283
|
+
el.fieldSets.forEach((r, i) => {
|
|
5284
|
+
if (!r.ref)
|
|
5285
|
+
return;
|
|
5286
|
+
if (seen.has(r.ref))
|
|
5287
|
+
sink.warning("M016", `Field set '${r.$refText}' is listed more than once.`, el, "fieldSets", i);
|
|
5288
|
+
seen.add(r.ref);
|
|
5289
|
+
});
|
|
5290
|
+
const from = new Map;
|
|
5291
|
+
for (const { field, fieldSet } of includedFields(el)) {
|
|
5292
|
+
const first = from.get(field.name);
|
|
5293
|
+
if (first === undefined) {
|
|
5294
|
+
from.set(field.name, fieldSet.name);
|
|
5295
|
+
} else if (first !== fieldSet.name) {
|
|
5296
|
+
const at = el.fieldSets.findIndex((r) => r.ref === fieldSet);
|
|
5297
|
+
sink.error("M016", `Field '${field.name}' of field set '${fieldSet.name}' is also declared in field set '${first}', both used by '${el.name}'.`, el, "fieldSets", at);
|
|
5298
|
+
}
|
|
5299
|
+
}
|
|
5300
|
+
const own = isAggregate(el) ? commonFields(el) : fieldsOf(el.members);
|
|
5301
|
+
for (const f of own) {
|
|
5302
|
+
const fs = from.get(f.name);
|
|
5303
|
+
if (fs)
|
|
5304
|
+
sink.error("M016", `Field '${f.name}' of '${el.name}' is already taken from field set '${fs}'.`, f, "name");
|
|
5305
|
+
}
|
|
5306
|
+
if (isAggregate(el)) {
|
|
5307
|
+
for (const s of statesOf(el)) {
|
|
5308
|
+
for (const f of fieldsOf(s.members)) {
|
|
5309
|
+
const fs = from.get(f.name);
|
|
5310
|
+
if (fs)
|
|
5311
|
+
sink.error("M016", `Field '${f.name}' of state '${s.name}' shadows the field of field set '${fs}' in '${el.name}'.`, f, "name");
|
|
5312
|
+
}
|
|
5313
|
+
}
|
|
5314
|
+
}
|
|
5315
|
+
}
|
|
5316
|
+
var init_field_sets = __esm(() => {
|
|
5317
|
+
init_ast();
|
|
5318
|
+
init_model_index();
|
|
5319
|
+
});
|
|
5320
|
+
|
|
4820
5321
|
// src/core/checker/expressions.ts
|
|
4821
5322
|
import { GrammarUtils } from "langium";
|
|
4822
5323
|
function checkInvariants(index, sink) {
|
|
@@ -4826,7 +5327,7 @@ function checkInvariants(index, sink) {
|
|
|
4826
5327
|
checkAggregate(el, ctx, index, sink);
|
|
4827
5328
|
} else if (isEntity(el) || isValueObject(el)) {
|
|
4828
5329
|
const members = el.members;
|
|
4829
|
-
const fields = new Map(fieldsOf(members).map((f) => [f.name, f]));
|
|
5330
|
+
const fields = new Map([...includedFields(el).map((x) => x.field), ...fieldsOf(members)].map((f) => [f.name, f]));
|
|
4830
5331
|
for (const inv of invariantsOf(members)) {
|
|
4831
5332
|
checkInvariant(inv, { ctx, fields, stateOnly: new Map, lambdas: [], present: new Set }, index, sink);
|
|
4832
5333
|
}
|
|
@@ -4863,7 +5364,7 @@ function checkPrimitive(p, ctx, index, sink) {
|
|
|
4863
5364
|
}
|
|
4864
5365
|
}
|
|
4865
5366
|
function checkAggregate(agg, ctx, index, sink) {
|
|
4866
|
-
const common = new Map(commonFields(agg).map((f) => [f.name, f]));
|
|
5367
|
+
const common = new Map([...includedFields(agg).map((x) => x.field), ...commonFields(agg)].map((f) => [f.name, f]));
|
|
4867
5368
|
const states = statesOf(agg);
|
|
4868
5369
|
const stateOnly = (except) => {
|
|
4869
5370
|
const m = new Map;
|
|
@@ -5085,7 +5586,7 @@ class ExprChecker {
|
|
|
5085
5586
|
return ERROR;
|
|
5086
5587
|
}
|
|
5087
5588
|
case "struct": {
|
|
5088
|
-
const f = fieldsOf(recv.decl.members).find((x) => x.name === m);
|
|
5589
|
+
const f = [...includedFields(recv.decl).map((x) => x.field), ...fieldsOf(recv.decl.members)].find((x) => x.name === m);
|
|
5089
5590
|
if (f)
|
|
5090
5591
|
return narrow(memberType(f), pathOf(e) ?? "", scope);
|
|
5091
5592
|
this.sink.error("M001", `'${recv.decl.name}' has no field '${m}'.`, e, "member");
|
|
@@ -5214,11 +5715,12 @@ function checkLabels(index, sink) {
|
|
|
5214
5715
|
sameLabel(invariantsOf(v.members).map((i) => ({ node: i, name: i.name, label: i.label })), `the invariants of '${el.name}.${v.name}'`, sink);
|
|
5215
5716
|
}
|
|
5216
5717
|
} else if (isAggregate(el)) {
|
|
5718
|
+
const included = includedFields(el).map((x) => x.field);
|
|
5217
5719
|
const common = commonFields(el);
|
|
5218
5720
|
const states = statesOf(el);
|
|
5219
|
-
fieldScope(common, `'${el.name}'
|
|
5721
|
+
fieldScope(common, `'${el.name}'`, included);
|
|
5220
5722
|
for (const s of states)
|
|
5221
|
-
fieldScope(fieldsOf(s.members), `state '${el.name}.${s.name}'`, common);
|
|
5723
|
+
fieldScope(fieldsOf(s.members), `state '${el.name}.${s.name}'`, [...included, ...common]);
|
|
5222
5724
|
sameLabel(states.map((s) => ({ node: s, name: s.name, label: s.label })), `the states of '${el.name}'`, sink);
|
|
5223
5725
|
sameLabel(commandsOf(el).map((c) => ({ node: c, name: c.name, label: c.label })), `the commands of '${el.name}'`, sink);
|
|
5224
5726
|
const invariants = [...invariantsOf(el.members), ...states.flatMap((s) => invariantsOf(s.members))];
|
|
@@ -5226,7 +5728,7 @@ function checkLabels(index, sink) {
|
|
|
5226
5728
|
for (const c of commandsOf(el))
|
|
5227
5729
|
fieldScope(c.params, `command '${el.name}.${c.name}'`);
|
|
5228
5730
|
} else if ("members" in el) {
|
|
5229
|
-
fieldScope(fieldsOf(el.members), `'${el.name}'
|
|
5731
|
+
fieldScope(fieldsOf(el.members), `'${el.name}'`, includedFields(el).map((x) => x.field));
|
|
5230
5732
|
if (isEntity(el) || isValueObject(el)) {
|
|
5231
5733
|
sameLabel(invariantsOf(el.members).map((i) => ({ node: i, name: i.name, label: i.label })), `the invariants of '${el.name}'`, sink);
|
|
5232
5734
|
}
|
|
@@ -5355,7 +5857,7 @@ function checkShared(index, sink) {
|
|
|
5355
5857
|
const ctx = el.$container.name;
|
|
5356
5858
|
if (!shared.has(ctx))
|
|
5357
5859
|
continue;
|
|
5358
|
-
if (!isPrimitiveDecl(el) && !isEnumDecl(el) && !isValueObject(el) && !isUnionDecl(el)) {
|
|
5860
|
+
if (!isPrimitiveDecl(el) && !isEnumDecl(el) && !isValueObject(el) && !isUnionDecl(el) && !isFieldSet(el)) {
|
|
5359
5861
|
sink.error("M014", `Shared context '${ctx}' can only contain ${ALLOWED}; found ${kind(el)} '${el.name}'.`, el, "name");
|
|
5360
5862
|
}
|
|
5361
5863
|
for (const ref of AstUtils4.streamAllContents(el).filter(isTypeRef)) {
|
|
@@ -5384,7 +5886,7 @@ function kind(el) {
|
|
|
5384
5886
|
const names = { Aggregate: "aggregate", Entity: "entity", IdType: "ID", EventDecl: "event", ErrorDecl: "error" };
|
|
5385
5887
|
return names[el.$type] ?? el.$type;
|
|
5386
5888
|
}
|
|
5387
|
-
var ALLOWED = "domain primitives, enums, value objects, unions and terms";
|
|
5889
|
+
var ALLOWED = "domain primitives, enums, value objects, unions, field sets and terms";
|
|
5388
5890
|
var init_shared = __esm(() => {
|
|
5389
5891
|
init_ast();
|
|
5390
5892
|
});
|
|
@@ -5403,6 +5905,11 @@ function checkStructure(index, sink) {
|
|
|
5403
5905
|
for (const f of allFields2(el))
|
|
5404
5906
|
checkFieldKind(el, f, sink);
|
|
5405
5907
|
}
|
|
5908
|
+
for (const fs of index.fieldSets) {
|
|
5909
|
+
for (const f of fieldsOf(fs.members))
|
|
5910
|
+
if (f.$type === "Field")
|
|
5911
|
+
checkFieldKind(fs, f, sink);
|
|
5912
|
+
}
|
|
5406
5913
|
checkPayloads(index, sink);
|
|
5407
5914
|
checkIdentity(index, sink);
|
|
5408
5915
|
checkOwningAggregates(index, sink);
|
|
@@ -5561,123 +6068,6 @@ var init_structure = __esm(() => {
|
|
|
5561
6068
|
init_model_index();
|
|
5562
6069
|
});
|
|
5563
6070
|
|
|
5564
|
-
// src/generator/naming.ts
|
|
5565
|
-
function generatedNames(index, ctx) {
|
|
5566
|
-
const out = [];
|
|
5567
|
-
const seen = new Set;
|
|
5568
|
-
for (const el of index.elementsOf(ctx)) {
|
|
5569
|
-
if (seen.has(el.name))
|
|
5570
|
-
continue;
|
|
5571
|
-
seen.add(el.name);
|
|
5572
|
-
if (!isAggregate(el)) {
|
|
5573
|
-
out.push({ name: el.name, origin: `${KIND_LABELS[el.$type]} '${el.name}'`, node: el });
|
|
5574
|
-
if (isIdType(el) || isPrimitiveDecl(el)) {
|
|
5575
|
-
out.push({ name: makeTypeName(el), origin: `the constructor of '${el.name}'`, node: el });
|
|
5576
|
-
if (primitiveInvariants(el).length)
|
|
5577
|
-
out.push({ name: invalidTypeName(el), origin: `the error of '${el.name}'`, node: el });
|
|
5578
|
-
}
|
|
5579
|
-
continue;
|
|
5580
|
-
}
|
|
5581
|
-
const states = firstByName(statesOf(el));
|
|
5582
|
-
out.push({ name: el.name, origin: `aggregate '${el.name}'`, node: el });
|
|
5583
|
-
if (states.length > 0) {
|
|
5584
|
-
out.push({ name: commonTypeName(el), origin: `common fields of '${el.name}'`, node: el });
|
|
5585
|
-
for (const s of states) {
|
|
5586
|
-
out.push({ name: stateTypeName(el, s), origin: `state '${el.name}.${s.name}'`, node: s });
|
|
5587
|
-
}
|
|
5588
|
-
}
|
|
5589
|
-
const commands = firstByName(commandsOf(el));
|
|
5590
|
-
if (commands.length > 0) {
|
|
5591
|
-
out.push({ name: commandsInterfaceName(el), origin: `commands of '${el.name}'`, node: el });
|
|
5592
|
-
}
|
|
5593
|
-
for (const c of commands) {
|
|
5594
|
-
out.push({ name: commandTypeName(el, c), origin: `command '${el.name}.${c.name}'`, node: c });
|
|
5595
|
-
}
|
|
5596
|
-
}
|
|
5597
|
-
const persistent = index.elementsOf(ctx).find((el) => isEventDecl(el) && el.persistent);
|
|
5598
|
-
if (persistent)
|
|
5599
|
-
out.push({ name: PERSISTENT_EVENT_TYPE, origin: "the union of persistent events", node: persistent });
|
|
5600
|
-
return out;
|
|
5601
|
-
}
|
|
5602
|
-
function firstByName(items) {
|
|
5603
|
-
const seen = new Set;
|
|
5604
|
-
return items.filter((i) => !seen.has(i.name) && seen.add(i.name));
|
|
5605
|
-
}
|
|
5606
|
-
var RUNTIME_NAMES, EVENT_TAG = "type", STATE_TAG = "state", pascal = (s) => s.charAt(0).toUpperCase() + s.slice(1), camel = (s) => s.charAt(0).toLowerCase() + s.slice(1), commonTypeName = (agg) => `${agg.name}Common`, stateTypeName = (agg, state) => `${typeof state === "string" ? state : state.name}${agg.name}`, commandTypeName = (agg, cmd) => `${pascal(cmd.name)}${agg.name}`, commandsInterfaceName = (agg) => `${agg.name}Commands`, aggregateParamName = (agg) => camel(agg.name), makeTypeName = (p) => `Make${p.name}`, invalidTypeName = (p) => `Invalid${p.name}`, PERSISTENT_EVENT_TYPE = "PersistentEvent", KIND_LABELS, TS_RESERVED;
|
|
5607
|
-
var init_naming = __esm(() => {
|
|
5608
|
-
init_ast();
|
|
5609
|
-
init_model_index();
|
|
5610
|
-
RUNTIME_NAMES = ["Result", "Ok", "Err", "Decimal", "Timestamp", "ok", "err"];
|
|
5611
|
-
KIND_LABELS = {
|
|
5612
|
-
IdType: "id",
|
|
5613
|
-
PrimitiveDecl: "primitive",
|
|
5614
|
-
EnumDecl: "enum",
|
|
5615
|
-
ValueObject: "value object",
|
|
5616
|
-
UnionDecl: "union",
|
|
5617
|
-
Entity: "entity",
|
|
5618
|
-
EventDecl: "event",
|
|
5619
|
-
ErrorDecl: "error"
|
|
5620
|
-
};
|
|
5621
|
-
TS_RESERVED = new Set([
|
|
5622
|
-
"break",
|
|
5623
|
-
"case",
|
|
5624
|
-
"catch",
|
|
5625
|
-
"class",
|
|
5626
|
-
"const",
|
|
5627
|
-
"continue",
|
|
5628
|
-
"debugger",
|
|
5629
|
-
"default",
|
|
5630
|
-
"delete",
|
|
5631
|
-
"do",
|
|
5632
|
-
"else",
|
|
5633
|
-
"enum",
|
|
5634
|
-
"export",
|
|
5635
|
-
"extends",
|
|
5636
|
-
"false",
|
|
5637
|
-
"finally",
|
|
5638
|
-
"for",
|
|
5639
|
-
"function",
|
|
5640
|
-
"if",
|
|
5641
|
-
"import",
|
|
5642
|
-
"in",
|
|
5643
|
-
"instanceof",
|
|
5644
|
-
"new",
|
|
5645
|
-
"null",
|
|
5646
|
-
"return",
|
|
5647
|
-
"super",
|
|
5648
|
-
"switch",
|
|
5649
|
-
"this",
|
|
5650
|
-
"throw",
|
|
5651
|
-
"true",
|
|
5652
|
-
"try",
|
|
5653
|
-
"typeof",
|
|
5654
|
-
"var",
|
|
5655
|
-
"void",
|
|
5656
|
-
"while",
|
|
5657
|
-
"with",
|
|
5658
|
-
"yield",
|
|
5659
|
-
"let",
|
|
5660
|
-
"static",
|
|
5661
|
-
"implements",
|
|
5662
|
-
"interface",
|
|
5663
|
-
"package",
|
|
5664
|
-
"private",
|
|
5665
|
-
"protected",
|
|
5666
|
-
"public",
|
|
5667
|
-
"await",
|
|
5668
|
-
"any",
|
|
5669
|
-
"boolean",
|
|
5670
|
-
"number",
|
|
5671
|
-
"string",
|
|
5672
|
-
"symbol",
|
|
5673
|
-
"never",
|
|
5674
|
-
"unknown",
|
|
5675
|
-
"object",
|
|
5676
|
-
"undefined",
|
|
5677
|
-
"bigint"
|
|
5678
|
-
]);
|
|
5679
|
-
});
|
|
5680
|
-
|
|
5681
6071
|
// src/core/checker/tsnames.ts
|
|
5682
6072
|
function checkTsNames(index, sink) {
|
|
5683
6073
|
const contexts = index.contextNames;
|
|
@@ -5702,11 +6092,18 @@ function checkTsNames(index, sink) {
|
|
|
5702
6092
|
}
|
|
5703
6093
|
}
|
|
5704
6094
|
for (const el of [...index.events, ...index.errors]) {
|
|
6095
|
+
const kind = el.$type === "EventDecl" ? "event" : "error";
|
|
5705
6096
|
for (const f of el.members) {
|
|
5706
6097
|
if (f.name === EVENT_TAG) {
|
|
5707
|
-
sink.error("M011", `Field '${EVENT_TAG}' is reserved for the discriminant of generated ${
|
|
6098
|
+
sink.error("M011", `Field '${EVENT_TAG}' is reserved for the discriminant of generated ${kind} types.`, f, "name");
|
|
5708
6099
|
}
|
|
5709
6100
|
}
|
|
6101
|
+
for (const { field, fieldSet } of includedFields(el)) {
|
|
6102
|
+
if (field.name !== EVENT_TAG)
|
|
6103
|
+
continue;
|
|
6104
|
+
const at = el.fieldSets.findIndex((r) => r.ref === fieldSet);
|
|
6105
|
+
sink.error("M011", `Field '${EVENT_TAG}' of field set '${fieldSet.name}' is reserved for the discriminant of generated ${kind} types.`, el, "fieldSets", at);
|
|
6106
|
+
}
|
|
5710
6107
|
}
|
|
5711
6108
|
for (const agg of index.elements.filter(isAggregate)) {
|
|
5712
6109
|
const self = aggregateParamName(agg);
|
|
@@ -5857,7 +6254,9 @@ async function analyze(sources) {
|
|
|
5857
6254
|
checkShared(index, sink);
|
|
5858
6255
|
checkStructure(index, sink);
|
|
5859
6256
|
checkUnions(index, sink);
|
|
6257
|
+
checkFieldSets(index, sink);
|
|
5860
6258
|
checkCommands(index, sink);
|
|
6259
|
+
checkEventIds(index, sink);
|
|
5861
6260
|
checkInvariants(index, sink);
|
|
5862
6261
|
checkTsNames(index, sink);
|
|
5863
6262
|
checkLabels(index, sink);
|
|
@@ -5910,6 +6309,8 @@ var init_analyze = __esm(() => {
|
|
|
5910
6309
|
init_build();
|
|
5911
6310
|
init_ids();
|
|
5912
6311
|
init_commands();
|
|
6312
|
+
init_events();
|
|
6313
|
+
init_field_sets();
|
|
5913
6314
|
init_expressions();
|
|
5914
6315
|
init_labels2();
|
|
5915
6316
|
init_names();
|
|
@@ -5923,13 +6324,15 @@ var init_analyze = __esm(() => {
|
|
|
5923
6324
|
from: "M006",
|
|
5924
6325
|
to: "M006",
|
|
5925
6326
|
emits: "M007",
|
|
5926
|
-
errors: "M007"
|
|
6327
|
+
errors: "M007",
|
|
6328
|
+
fieldSets: "M016"
|
|
5927
6329
|
};
|
|
5928
6330
|
LINK_KINDS = {
|
|
5929
6331
|
from: "state",
|
|
5930
6332
|
to: "state",
|
|
5931
6333
|
emits: "event",
|
|
5932
6334
|
errors: "error",
|
|
6335
|
+
fieldSets: "field set",
|
|
5933
6336
|
target: "aggregate",
|
|
5934
6337
|
decl: "type"
|
|
5935
6338
|
};
|
|
@@ -6134,7 +6537,7 @@ var init_files = __esm(() => {
|
|
|
6134
6537
|
});
|
|
6135
6538
|
|
|
6136
6539
|
// src/model/model.ts
|
|
6137
|
-
var elementsIn = (model, ctx) => Object.values(model.elements).filter((e) => e.context === ctx), elementList = (model) => Object.values(model.elements), allFieldsOf = (el) => [
|
|
6540
|
+
var elementsIn = (model, ctx) => Object.values(model.elements).filter((e) => e.context === ctx), elementList = (model) => Object.values(model.elements), ownFields = (el) => el.fields.filter((f) => !f.fieldSet), allFieldsOf = (el) => [
|
|
6138
6541
|
...el.fields,
|
|
6139
6542
|
...(el.states ?? []).flatMap((s) => s.fields),
|
|
6140
6543
|
...(el.variants ?? []).flatMap((v) => v.fields)
|
|
@@ -6308,8 +6711,10 @@ function contextDependencies(model) {
|
|
|
6308
6711
|
else if (f.type.kind === "ref")
|
|
6309
6712
|
add(f.type.ref, path);
|
|
6310
6713
|
};
|
|
6311
|
-
for (const f of el
|
|
6714
|
+
for (const f of ownFields(el))
|
|
6312
6715
|
field(f, f.name);
|
|
6716
|
+
for (const fs of el.fieldSets ?? [])
|
|
6717
|
+
add(fs, "with");
|
|
6313
6718
|
for (const s of el.states ?? [])
|
|
6314
6719
|
for (const f of s.fields)
|
|
6315
6720
|
field(f, `${s.name}.${f.name}`);
|
|
@@ -6382,13 +6787,14 @@ function fieldLine(f, ctx, model, indent = "") {
|
|
|
6382
6787
|
label: `${marker}${f.label ?? f.name}`,
|
|
6383
6788
|
both: `${marker}${f.label ? `${f.label} ` : ""}${f.name}`
|
|
6384
6789
|
}),
|
|
6385
|
-
value: anyLang({ name: byName + f.multiplicity, label: byLabel + f.multiplicity, both: byName + f.multiplicity })
|
|
6790
|
+
value: anyLang({ name: byName + f.multiplicity, label: byLabel + f.multiplicity, both: byName + f.multiplicity }),
|
|
6791
|
+
...f.fieldSet && { origin: named(typeText({ kind: "ref", ref: f.fieldSet, text: "" }, ctx, model.sharedContexts), lookupLabel(model, f.fieldSet), (l) => l) }
|
|
6386
6792
|
};
|
|
6387
6793
|
}
|
|
6388
6794
|
function bodyUnits(lines) {
|
|
6389
6795
|
return Math.max(0, ...TEXT_VARIANTS.map(([g, m]) => {
|
|
6390
6796
|
const key = Math.max(0, ...lines.filter((l) => l.value).map((l) => textUnits(l.key[g][m])));
|
|
6391
|
-
const value = Math.max(0, ...lines.map((l) => l.value ? textUnits(l.value[g][m]) : 0));
|
|
6797
|
+
const value = Math.max(0, ...lines.map((l) => l.value ? textUnits(l.value[g][m]) + (l.origin ? COLUMN_GAP + textUnits(l.origin[g][m]) : 0) : 0));
|
|
6392
6798
|
const keyOnly = Math.max(0, ...lines.filter((l) => !l.value).map((l) => textUnits(l.key[g][m])));
|
|
6393
6799
|
return Math.max(value ? key + COLUMN_GAP + value : 0, keyOnly);
|
|
6394
6800
|
}));
|
|
@@ -6784,7 +7190,8 @@ var init_build2 = __esm(() => {
|
|
|
6784
7190
|
primitive: stereotype("ドメインプリミティブ", "primitive"),
|
|
6785
7191
|
id: stereotype("ID", "id"),
|
|
6786
7192
|
event: stereotype("ドメインイベント", "event"),
|
|
6787
|
-
error: stereotype("エラー", "error")
|
|
7193
|
+
error: stereotype("エラー", "error"),
|
|
7194
|
+
fieldSet: stereotype("項目セット", "field set")
|
|
6788
7195
|
};
|
|
6789
7196
|
});
|
|
6790
7197
|
|
|
@@ -7398,7 +7805,11 @@ class ContextEmitter {
|
|
|
7398
7805
|
case "valueObject":
|
|
7399
7806
|
case "entity":
|
|
7400
7807
|
this.jsdoc([...describedLines(el), ...invariantLines(el.invariants)]);
|
|
7401
|
-
this.iface(el.name,
|
|
7808
|
+
this.iface(el.name, this.fieldSets(el), [], ownFields(el));
|
|
7809
|
+
break;
|
|
7810
|
+
case "fieldSet":
|
|
7811
|
+
this.jsdoc([...describedLines(el), `Fields taken on with \`with ${el.name}\`.`]);
|
|
7812
|
+
this.iface(el.name, [], [], el.fields);
|
|
7402
7813
|
break;
|
|
7403
7814
|
case "union":
|
|
7404
7815
|
this.union(el);
|
|
@@ -7406,7 +7817,7 @@ class ContextEmitter {
|
|
|
7406
7817
|
case "event":
|
|
7407
7818
|
case "error":
|
|
7408
7819
|
this.jsdoc([...describedLines(el), ...el.persistent ? [PERSISTENT_LINE] : []]);
|
|
7409
|
-
this.iface(el.name,
|
|
7820
|
+
this.iface(el.name, this.fieldSets(el), [`readonly ${EVENT_TAG}: '${el.name}';`], ownFields(el));
|
|
7410
7821
|
break;
|
|
7411
7822
|
case "aggregate":
|
|
7412
7823
|
this.aggregate(el);
|
|
@@ -7415,6 +7826,7 @@ class ContextEmitter {
|
|
|
7415
7826
|
this.out.push("");
|
|
7416
7827
|
}
|
|
7417
7828
|
this.persistentEvents();
|
|
7829
|
+
this.unions();
|
|
7418
7830
|
const body = this.out.join(`
|
|
7419
7831
|
`);
|
|
7420
7832
|
const runtime = ["Decimal", "Result", "Timestamp"].filter((n) => new RegExp(`\\b${n}\\b`).test(body));
|
|
@@ -7433,6 +7845,24 @@ class ContextEmitter {
|
|
|
7433
7845
|
this.line(`export type ${PERSISTENT_EVENT_TYPE} = ${events.map((e) => e.name).join(" | ")};`);
|
|
7434
7846
|
this.out.push("");
|
|
7435
7847
|
}
|
|
7848
|
+
unions() {
|
|
7849
|
+
const els = elementsIn(this.model, this.ctx);
|
|
7850
|
+
const events = els.filter((el) => el.kind === "event");
|
|
7851
|
+
if (events.length) {
|
|
7852
|
+
this.jsdoc([`Events of ${this.ctx}.`]);
|
|
7853
|
+
this.line(`export type ${DOMAIN_EVENT_TYPE} = ${events.map((e) => e.name).join(" | ")};`);
|
|
7854
|
+
this.out.push("");
|
|
7855
|
+
}
|
|
7856
|
+
const aggregates = els.filter((el) => el.kind === "aggregate");
|
|
7857
|
+
if (aggregates.length) {
|
|
7858
|
+
this.jsdoc([`Aggregates of ${this.ctx}.`]);
|
|
7859
|
+
this.line(`export type ${AGGREGATE_TYPE} = ${aggregates.map((e) => e.name).join(" | ")};`);
|
|
7860
|
+
this.out.push("");
|
|
7861
|
+
}
|
|
7862
|
+
}
|
|
7863
|
+
fieldSets(el) {
|
|
7864
|
+
return (el.fieldSets ?? []).map((f) => this.ref(f));
|
|
7865
|
+
}
|
|
7436
7866
|
primitive(p) {
|
|
7437
7867
|
const base = PRIMITIVES[p.base ?? "String"];
|
|
7438
7868
|
const summary = p.kind === "id" && !p.label ? [`Identifier of ${p.name}.`] : [];
|
|
@@ -7487,14 +7917,14 @@ class ContextEmitter {
|
|
|
7487
7917
|
const states = agg.states ?? [];
|
|
7488
7918
|
if (states.length === 0) {
|
|
7489
7919
|
this.jsdoc([...describedLines(agg), ...invariantLines(agg.invariants)]);
|
|
7490
|
-
this.iface(agg.name,
|
|
7920
|
+
this.iface(agg.name, this.fieldSets(agg), [], ownFields(agg));
|
|
7491
7921
|
} else {
|
|
7492
7922
|
this.jsdoc([`Fields shared by every state of ${agg.label ? `${agg.label} (${agg.name})` : agg.name}.`, ...invariantLines(agg.invariants)]);
|
|
7493
|
-
this.iface(commonTypeName(agg),
|
|
7923
|
+
this.iface(commonTypeName(agg), this.fieldSets(agg), [], ownFields(agg));
|
|
7494
7924
|
for (const s of states) {
|
|
7495
7925
|
this.out.push("");
|
|
7496
7926
|
this.jsdoc([...describedLines(s), ...invariantLines(s.invariants)]);
|
|
7497
|
-
this.iface(stateTypeName(agg, s), commonTypeName(agg), [`readonly ${STATE_TAG}: '${s.name}';`], s.fields);
|
|
7927
|
+
this.iface(stateTypeName(agg, s), [commonTypeName(agg)], [`readonly ${STATE_TAG}: '${s.name}';`], s.fields);
|
|
7498
7928
|
}
|
|
7499
7929
|
this.out.push("");
|
|
7500
7930
|
this.jsdoc(describedLines(agg));
|
|
@@ -7516,6 +7946,12 @@ class ContextEmitter {
|
|
|
7516
7946
|
}
|
|
7517
7947
|
this.line("}");
|
|
7518
7948
|
}
|
|
7949
|
+
const events = [...new Set(commands.flatMap((c) => c.emits))];
|
|
7950
|
+
if (events.length > 0) {
|
|
7951
|
+
this.out.push("");
|
|
7952
|
+
this.jsdoc([`Events that the commands of ${agg.name} may emit.`]);
|
|
7953
|
+
this.line(`export type ${aggregateEventTypeName(agg)} = ${events.map((e) => this.ref(e)).join(" | ")};`);
|
|
7954
|
+
}
|
|
7519
7955
|
}
|
|
7520
7956
|
command(agg, c) {
|
|
7521
7957
|
const stateful = (agg.states ?? []).length > 0;
|
|
@@ -7540,9 +7976,9 @@ class ContextEmitter {
|
|
|
7540
7976
|
this.line(` ${p},`);
|
|
7541
7977
|
this.line(`) => Result<readonly [${output}, ${eventArray}], ${errors}>;`);
|
|
7542
7978
|
}
|
|
7543
|
-
iface(name,
|
|
7979
|
+
iface(name, bases, extra, fields) {
|
|
7544
7980
|
const lines = [...extra, ...fields.flatMap((f) => this.property(f))];
|
|
7545
|
-
const ext =
|
|
7981
|
+
const ext = bases.length ? ` extends ${bases.join(", ")}` : "";
|
|
7546
7982
|
if (lines.length === 0) {
|
|
7547
7983
|
this.line(`export interface ${name}${ext} {}`);
|
|
7548
7984
|
return;
|
|
@@ -7599,7 +8035,7 @@ class ContextEmitter {
|
|
|
7599
8035
|
}
|
|
7600
8036
|
|
|
7601
8037
|
// docs/guide.md
|
|
7602
|
-
var guide_default = "# DomainTrail guide\n\n`dt` checks domain models written in the DomainTrail DSL (`.dt` files) and generates TypeScript types and command\ncontracts from them. The DSL describes domain **structure and contracts** only — never business logic, which is written\nby hand against the generated types.\n\nThis guide is what `dt guide` prints. It is written for people and AI agents using `dt` without other documentation.\n\n## Workflow\n\n1. Write or edit `.dt` files (see [DSL](#dsl) and [File layout](#file-layout-recommended)).\n2. Run `dt check` and fix every reported problem until it exits 0.\n3. Run `dt generate ts` to write the TypeScript (it runs `check` first and writes nothing on errors).\n4. Implement the generated contracts in your own code, and type-check that code with your own TypeScript setup\n (e.g. `tsc --noEmit`). `dt` does not run the TypeScript compiler.\n\n`dt view` starts the Live View, a browser page where people watch the model update as files are saved. It is a server\nthat keeps running and never exits by itself (stop it with Ctrl+C), so do not wait for it to finish: run it in the\nbackground, or use `dt check` for a result.\n\n`dt --help` and `dt <command> --help` list the options with examples.\n\n```bash\ndt check # every *.dt file below the current directory\ndt -r domain check # below domain/ (or as configured by a domaintrail.jsonc found there or above)\ndt generate ts # into <root>/generated/domain\ndt generate ts --out src/domain/generated\ndt view --port 8080 # http://127.0.0.1:8080, until Ctrl+C\n```\n\n## Output and exit codes\n\n`check` (and `generate ts`, which checks first) prints one line per problem, sorted by file and position, then a\nsummary:\n\n```text\nsales/order.dt:2:11 - warning L002: Term 'note' (\"備考\") is not used by any field or parameter in context 'Sales'.\nsales/order.dt:8:32 - error M009: count() requires a collection, but got 'Money'.\n1 file(s) checked: 1 error(s), 1 warning(s).\n```\n\nPaths are relative to the root, lines and columns 1-based. Errors go to stderr, warnings to stdout. Fix errors first;\nwarnings do not fail the check. Other failures (missing root, invalid config, port in use, …) are one line on stderr.\n\n| Exit code | Meaning |\n|---|---|\n| 0 | success (`check`: no errors; warnings are allowed) |\n| 1 | the model has errors, no `.dt` file was found, generation was refused, or the root / a file could not be read |\n| 2 | invalid configuration (`domaintrail.jsonc` / `--config`, including a context name in `generate.ts.contexts` that the model does not have) or an unknown `generate` target |\n\nCommands that use the model look for a config file first; `--root` (`-r`, default `.`) is where that search starts.\n\n## Configuration\n\n`domaintrail.jsonc` (comments and trailing commas allowed) or `domaintrail.json` is looked up in `--root` and its\nparents, like `tsconfig.json`; `--config <file>` (`-c`) picks one explicitly. All paths in it are relative to the config\nfile, and its directory becomes the root. Without a config file, the defaults apply with `--root` as the root.\nEvery key is optional.\n\n```jsonc\n{\n \"$schema\": \"./node_modules/domaintrail/schema/domaintrail.schema.json\",\n // globs of DSL files; \"!\" excludes (node_modules, .git, .domaintrail are never scanned)\n \"sources\": [\"domain/**/*.dt\", \"!domain/drafts/**\"], // default: [\"**/*.dt\"]\n \"generate\": {\n \"ts\": {\n \"out\": \"src/domain/generated\", // default: \"generated/domain\"\n // contexts written elsewhere than \"out\" (optional)\n \"contexts\": { \"Common\": { \"out\": \"packages/shared/src/generated\" } }\n }\n },\n \"view\": { \"port\": 4321, \"host\": \"127.0.0.1\" } // defaults shown\n}\n```\n\nCLI options win over the file: `generate ts --out`, `view --port`, `view --host`. `--out` replaces `generate.ts.out`\nonly; contexts listed in `generate.ts.contexts` keep their own directories. Sources and output directories, `--out`\nincluded, must stay inside the config file's directory (the root without a config file): an absolute path or one with\n`..` is a config error, and an output directory reached through a symlink stops generation. A name in `generate.ts.contexts` that is not a context of the model is a config\nerror, reported by `generate ts` once the model has been checked.\n\n## File layout (recommended)\n\nFile names and directories carry no meaning: every matching `.dt` file belongs to the workspace, and a context may be\nsplit across any files. The recommended layout is one directory per context and one file per aggregate:\n\n```text\ncommon/context.dt shared context Common \"共通\" { ... } // a shared context has no aggregates\nsales/context.dt /// 説明 context Sales \"販売\" { terms { ... } }\nsales/order.dt context Sales { id OrderId ... aggregate Order { ... } entity OrderItem ... event OrderPlaced ... }\nsales/customer.dt context Sales { id CustomerId ... aggregate Customer { ... } }\nbilling/context.dt /// 説明 context Billing \"請求\" { terms { ... } }\nbilling/invoice.dt context Billing { id InvoiceId ... aggregate Invoice { ... } }\n```\n\n- `<context>/<aggregate>.dt` holds the aggregate and what only it uses: its ID, entities, events, errors, enums,\n primitives and values.\n- `<context>/context.dt` holds the context's name (表示名), description and `terms`, and the elements used by several\n of its aggregates or by none. The other files open the context without a name: `context Sales { ... }`.\n- An aggregate's ID stays in the aggregate's file even when other aggregates reference it.\n- Directory and file names are kebab-case: `PurchaseOrder` → `purchase-order.dt`, `OrderFulfillment` →\n `order-fulfillment/`.\n\nThis is a convention, not a rule: `check` neither requires nor warns about any layout.\n\n## DSL\n\nThe examples below are the files of one valid workspace (the file name is in the first comment).\n\n### Contexts and aggregates\n\n```dt\n// sales/order.dt\ncontext Sales { // a bounded context; may be split across files\n id OrderId: UUID // ID type with a base primitive type\n id OrderItemId: UUID\n enum CancelReason { Requested Other } // commas between values are optional\n value Address { city: String street: String }\n\n aggregate Order {\n id: OrderId // identity field of its own ID type (required)\n owns items: OrderItem[0..*] // owned entity / value inside the aggregate\n references customer: CustomerId -> Customer // another aggregate, by ID\n owns shipTo: Address? // ? = optional\n note: String?\n\n invariant quantitiesPositive { // applies to every state; sees the common fields\n all(items, item => item.quantity > 0)\n }\n\n create command place(customer: CustomerId) to Draft emits OrderPlaced // factory: no `from`\n\n state Draft\n state Confirmed {\n confirmedAt: Timestamp // exists only in this state\n invariant hasItems { count(items) > 0 and count(items) <= 100 } // sees common + Confirmed fields\n }\n state Cancelled {\n reason: CancelReason\n invariant otherNeedsNote { reason == CancelReason.Other implies exists(note) }\n }\n\n command confirm(at: Timestamp)\n from Draft\n to Confirmed // several: `to A | B`\n emits OrderConfirmed // events that MAY be emitted (0..n)\n errors EmptyOrder // errors that MAY be returned\n\n command cancel(reason: CancelReason) from Draft | Confirmed to Cancelled emits OrderCancelled\n }\n\n entity OrderItem { id: OrderItemId quantity: Quantity owns unitPrice: Money }\n\n persistent event OrderPlaced { orderId: OrderId } // storing it is part of its contract\n persistent event OrderConfirmed { orderId: OrderId confirmedAt: Timestamp }\n event OrderCancelled { orderId: OrderId reason: CancelReason } // not persisted (default)\n error EmptyOrder // payload optional: error E { field: Type }\n}\n```\n\n```dt\n// sales/customer.dt\ncontext Sales {\n id CustomerId: UUID\n\n aggregate Customer { // no states: commands have no `from` / `to`\n id: CustomerId\n email: EmailAddress // from the shared context Common\n active: Bool\n owns addresses: Address[0..*]\n\n invariant activeHasAddress { active == true implies count(addresses) > 0 }\n invariant servedArea { active == false or any(addresses, a => a.city == \"Tokyo\" or not (a.city == \"Osaka\")) }\n\n command changeEmail(email: EmailAddress) errors EmailTaken\n }\n\n error EmailTaken { email: EmailAddress }\n}\n```\n\n- Context elements: `id`, `primitive`, `enum`, `value`, `union`, `entity`, `aggregate`, `event`, `error`.\n- Fields: `name: Type`, `owns name: Type` (entities and values held by the aggregate),\n `references name: IdType -> Aggregate` (other aggregates, by ID only). Entities are owned by exactly one aggregate.\n- Primitive types: `String`, `Int`, `Decimal`, `Bool`, `Timestamp`, `UUID`.\n- Multiplicity after the type: `?`, `[0..1]`, `[0..*]`, `[1..*]`, `[n..m]`.\n- Aggregate members: fields, `invariant`, `state` (with its own fields and invariants), `command`.\n An aggregate with states needs `to` on every command and `from` on every non-`create` one; without states, neither.\n- `create command` makes a new aggregate; other commands take the aggregate in one of their `from` states.\n- `value`, `state`, `event` and `error` bodies are optional (`state Draft`, `error EmptyOrder`).\n- Other contexts' elements are referenced with qualified names: `Sales.OrderId`, `-> Sales.Order`.\n- Comments: `// …` and `/* … */`; `///` is a description (see [Names](#names-labels-and-descriptions)).\n\n### Domain primitives\n\nA single value with domain meaning and constraints, wrapping a primitive type. Values combining several fields are\nvalue objects.\n\n```dt\n// sales/primitives.dt\ncontext Sales {\n primitive Quantity \"数量\": Int { value in 1..999 } // one anonymous constraint\n primitive Sku: String { // or named invariants\n invariant format \"形式\" { matches(value, \"^[A-Z]{3}-\\d{4}$\") }\n invariant maxLength { length(value) <= 8 }\n }\n id InvoiceNo: String { matches(value, \"^INV-\\d{8}$\") } // an ID is a domain primitive used as identity\n}\n```\n\n- The base is always a primitive type; a domain primitive cannot refine another one or an enum.\n- Inside the constraint only `value` (of the base type) is visible; `length(value)`, `matches(value, \"regex\")` and\n ranges `value in 1..999` (negative literals allowed) are available there.\n- Regular expressions are written as in JavaScript: backslashes are not string escapes (`\"\\d\"` means `\\d`).\n- Elsewhere a domain primitive compares with literals and with the same domain primitive, not with another domain\n primitive or a plain field of its base type (M009).\n- Only IDs can be identity fields and reference types. Domain primitives cannot be owned.\n\n### Unions\n\nA value whose shape depends on a kind fixed when it is made (a tagged union). Use a union for a classification that\nnever changes, and aggregate states for a lifecycle that commands move through.\n\n```dt\n// sales/payment.dt\ncontext Sales {\n union Payer \"支払者\" { // discriminator `kind` by default\n CUSTOMER \"顧客\" { customerId: CustomerId }\n COMPANY \"法人\" { name: String billingEmail: EmailAddress? }\n }\n enum PaymentMethod { CARD TRANSFER }\n union PaymentDetails by method: PaymentMethod { // `by name`, optionally bound to an enum\n CARD { last4: String } // exactly the enum's values (M015)\n TRANSFER { bankCode: String }\n }\n}\n```\n\n- A union is a value type: usable like a value object (fields, `owns`, parameters, payloads, shared contexts).\n Variants hold value fields and invariants (seeing their own fields); entities and aggregates are not allowed.\n- In invariants, `payer.kind` compares with `Payer.COMPANY` (or the bound enum's values); variant fields are not\n accessible from outside the union.\n\n### Shared contexts\n\n```dt\n// common/context.dt\nshared context Common \"共通\" { // shared kernel: usable by simple name from every context\n terms { currency: \"通貨\" }\n enum Currency { JPY USD }\n value Money { amount: Decimal currency: Currency }\n primitive EmailAddress: String { matches(value, \"^[^@\\s]+@[^@\\s]+$\") }\n}\n```\n\n- `Money` and `Common.Money` both work in other contexts. A context's own element with the same name wins (M014 warning).\n- A shared context holds only domain primitives, enums, value objects, unions and terms, and depends only on shared\n contexts. Its `terms` apply to fields of every context that has no term of its own for the name.\n\n### Names (labels and descriptions)\n\n```dt\n// billing/context.dt\n/// 注文への請求と支払いを扱う。\ncontext Billing \"請求\" {\n terms { // field / parameter names, defined once per context\n /// 請求書が支払われた日時。\n paidAt: \"支払日時\"\n }\n}\n```\n\n```dt\n// billing/invoice.dt\ncontext Billing { // other files open the context without a name\n id InvoiceId \"請求書ID\": UUID\n\n /// 注文1件に対する請求。\n aggregate Invoice \"請求書\" { // declarations: a string after the name\n id: InvoiceId\n references order: Sales.OrderId -> Sales.Order \"請求対象\" // an inline label on a field\n owns amount: Money \"請求金額\"\n state Open \"未払い\"\n state Paid \"支払済み\" { paidAt: Timestamp } // → 支払日時 (from terms)\n invariant positive \"金額が正\" { amount.amount > 0 }\n create command issue(order: Sales.OrderId, amount: Money) \"請求書を発行する\" to Open\n command pay(at: Timestamp \"支払日時\") \"支払う\" from Open to Paid emits InvoicePaid\n }\n enum InvoiceKind \"請求区分\" { Regular \"通常\" Refund \"返金\" }\n event InvoicePaid \"支払完了\" { invoiceId: InvoiceId paidAt: Timestamp }\n}\n```\n\n- Declarations (context, id, primitive, enum and its values, value, union and its variants, entity, aggregate, state,\n command, invariant, event, error) take an optional string label after the name.\n- A field or parameter is named by, in order: its inline string → the context's `terms` → the name of its type\n (for `references`, the target aggregate) → the English name.\n- `///` lines directly above a declaration or term are its description.\n- Labels appear in the Live View and as JSDoc in the generated TypeScript; identifiers and generated type names stay\n English.\n\n### Invariant expressions\n\n- Literals: `true`, `false`, `42`, `-1`, `3.14`, `\"text\"`; enum values `CancelReason.Other`.\n- Field paths: `note`, `item.quantity`, `amount.amount`.\n- Operators, loosest first: `implies`, `or`, `and`, `== != < <= > >=`, `x in 1..9`, `not`.\n- Functions: `exists(x)` (an optional is present; narrows `x` on the right of `and` / `implies`), `count(c)`,\n `all(c, x => …)`, `any(c, x => …)`, and in domain primitives `length(value)`, `matches(value, \"regex\")`.\n- An invariant must be a Bool expression. Only its type is checked, not whether it holds.\n\n## Rules\n\n| Code | Check |\n|---|---|\n| SYNTAX | lexer / parser errors |\n| M001 | types, aggregates and names in invariants resolve |\n| M002 | names are unique in their scope (also across files of one context) |\n| M003 | an entity is owned by exactly one aggregate (warning when owned by none) |\n| M004 | no ownership across aggregate boundaries (entities need `owns`, aggregates need `references`, …) |\n| M005 | a reference's ID type matches the identity of the target aggregate |\n| M006 | command input/output states exist and fit the aggregate (factory / stateful / stateless) |\n| M007 | `emits` / `errors` refer to existing events / errors |\n| M008 | an invariant is a Bool expression |\n| M009 | operators and operands have compatible types |\n| M010 | state-specific fields are used only in their own state's invariants |\n| M011 | generated TypeScript names do not collide |\n| M012 | the ownership graph has no cycles |\n| M013 | aggregates and entities have an `id` field of their own ID type |\n| M014 | shared contexts: only value types, no dependency on other contexts, consistent `shared`, unambiguous names (shadowing is a warning) |\n| M015 | unions: at least one variant, variants match the bound enum exactly, no variant field named like the discriminator |\n| L001 | (warning) an inline field label disagrees with the term, or context fragments disagree on the context name |\n| L002 | (warning) a term is not used by any field or parameter |\n| L003 | (warning) different things in one scope share a Japanese name |\n\n## Generated TypeScript\n\nPer context a module (`Sales.ts`, …) with ID brands, enums, value objects, entities, unions, a discriminated union per\nstateful aggregate (`DraftOrder | ConfirmedOrder | …`), event / error types with a `type` tag, a function type per\ncommand and an `<Aggregate>Commands` interface to implement, plus `index.ts` and `_runtime.ts`. A domain primitive\ngets a branded type and a constructor contract `Make<Name>` to implement by hand.\n\n```ts\nexport type ConfirmOrder = (\n order: DraftOrder,\n at: Timestamp,\n) => Result<readonly [ConfirmedOrder, readonly OrderConfirmed[]], EmptyOrder>;\n```\n\n### Generated code and your code\n\nThe generated files are the **contract**, your code is the **implementation**:\n\n- Generated: types only — the shapes of the model, the command signatures (`ConfirmOrder`, `OrderCommands`) and the\n constructor signatures of domain primitives (`MakeQuantity`). Invariants appear as JSDoc (`@invariant`); nothing in\n the generated code checks them.\n- Yours: everything that runs — command implementations, `Make<Name>` constructors, invariant checks — in your own\n files, which import the generated modules (never the other way round) and are type-checked against them.\n\n```ts\n// src/primitives.ts — your code\nimport { err, ok, type Sales } from '../generated/domain/index.js';\n\nexport const makeQuantity: Sales.MakeQuantity = (value) =>\n Number.isInteger(value) && value >= 1 && value <= 999 ? ok(value as Sales.Quantity) : err({ type: 'InvalidQuantity', value, invariant: 'valid' });\n```\n\nDo not edit generated files: change the `.dt` sources and generate again. Adding properties or methods to generated\ntypes (declaration merging, editing the output) is not supported; write functions that take the generated types.\n\n### Output directories\n\nBy default every context goes to `generate.ts.out`. Contexts listed in `generate.ts.contexts` go to their own\ndirectory instead, e.g. a shared context into a package used by several applications. Each directory written to gets\nits own `_runtime.ts` and an `index.ts` re-exporting only the contexts in it; a module imports other contexts by\nrelative path (`import type * as Common from '../../packages/shared/src/generated/Common.js'`). The runtimes are\nidentical, so values typed with one are accepted where the other is expected.\n\nEach run replaces the files generated before (recognized by their header). The files written are recorded in\n`.domaintrail/generated.json` under the root, and generated files of earlier runs that are no longer written (an output\ndirectory moved, a context removed) are deleted, along with a directory left empty. Only recorded paths inside the root\nand not reached through a symlink are deleted; other entries in that file are ignored. Other files are never deleted —\nneither hand-written files nor generated files you edited — and generation stops instead of overwriting one.\n";
|
|
8038
|
+
var guide_default = "# DomainTrail guide\n\n`dt` checks domain models written in the DomainTrail DSL (`.dt` files) and generates TypeScript types and command\ncontracts from them. The DSL describes domain **structure and contracts** only — never business logic, which is written\nby hand against the generated types.\n\nThis guide is what `dt guide` prints. It is written for people and AI agents using `dt` without other documentation.\n\n## Workflow\n\n1. Write or edit `.dt` files (see [DSL](#dsl) and [File layout](#file-layout-recommended)).\n2. Run `dt check` and fix every reported problem until it exits 0.\n3. Run `dt generate ts` to write the TypeScript (it runs `check` first and writes nothing on errors).\n4. Implement the generated contracts in your own code, and type-check that code with your own TypeScript setup\n (e.g. `tsc --noEmit`). `dt` does not run the TypeScript compiler.\n\n`dt view` starts the Live View, a browser page where people watch the model update as files are saved. It is a server\nthat keeps running and never exits by itself (stop it with Ctrl+C), so do not wait for it to finish: run it in the\nbackground, or use `dt check` for a result.\n\n`dt --help` and `dt <command> --help` list the options with examples.\n\n```bash\ndt check # every *.dt file below the current directory\ndt -r domain check # below domain/ (or as configured by a domaintrail.jsonc found there or above)\ndt generate ts # into <root>/generated/domain\ndt generate ts --out src/domain/generated\ndt view --port 8080 # http://127.0.0.1:8080, until Ctrl+C\n```\n\n## Output and exit codes\n\n`check` (and `generate ts`, which checks first) prints one line per problem, sorted by file and position, then a\nsummary:\n\n```text\nsales/order.dt:2:11 - warning L002: Term 'note' (\"備考\") is not used by any field or parameter in context 'Sales'.\nsales/order.dt:8:32 - error M009: count() requires a collection, but got 'Money'.\n1 file(s) checked: 1 error(s), 1 warning(s).\n```\n\nPaths are relative to the root, lines and columns 1-based. Errors go to stderr, warnings to stdout. Fix errors first;\nwarnings do not fail the check. Other failures (missing root, invalid config, port in use, …) are one line on stderr.\n\n| Exit code | Meaning |\n|---|---|\n| 0 | success (`check`: no errors; warnings are allowed) |\n| 1 | the model has errors, no `.dt` file was found, generation was refused, or the root / a file could not be read |\n| 2 | invalid configuration (`domaintrail.jsonc` / `--config`, including a context name in `generate.ts.contexts` that the model does not have) or an unknown `generate` target |\n\nCommands that use the model look for a config file first; `--root` (`-r`, default `.`) is where that search starts.\n\n## Configuration\n\n`domaintrail.jsonc` (comments and trailing commas allowed) or `domaintrail.json` is looked up in `--root` and its\nparents, like `tsconfig.json`; `--config <file>` (`-c`) picks one explicitly. All paths in it are relative to the config\nfile, and its directory becomes the root. Without a config file, the defaults apply with `--root` as the root.\nEvery key is optional.\n\n```jsonc\n{\n \"$schema\": \"./node_modules/domaintrail/schema/domaintrail.schema.json\",\n // globs of DSL files; \"!\" excludes (node_modules, .git, .domaintrail are never scanned)\n \"sources\": [\"domain/**/*.dt\", \"!domain/drafts/**\"], // default: [\"**/*.dt\"]\n \"generate\": {\n \"ts\": {\n \"out\": \"src/domain/generated\", // default: \"generated/domain\"\n // contexts written elsewhere than \"out\" (optional)\n \"contexts\": { \"Common\": { \"out\": \"packages/shared/src/generated\" } }\n }\n },\n \"view\": { \"port\": 4321, \"host\": \"127.0.0.1\" } // defaults shown\n}\n```\n\nCLI options win over the file: `generate ts --out`, `view --port`, `view --host`. `--out` replaces `generate.ts.out`\nonly; contexts listed in `generate.ts.contexts` keep their own directories. Sources and output directories, `--out`\nincluded, must stay inside the config file's directory (the root without a config file): an absolute path or one with\n`..` is a config error, and an output directory reached through a symlink stops generation. A name in `generate.ts.contexts` that is not a context of the model is a config\nerror, reported by `generate ts` once the model has been checked.\n\n## File layout (recommended)\n\nFile names and directories carry no meaning: every matching `.dt` file belongs to the workspace, and a context may be\nsplit across any files. The recommended layout is one directory per context and one file per aggregate:\n\n```text\ncommon/context.dt shared context Common \"共通\" { ... } // a shared context has no aggregates\nsales/context.dt /// 説明 context Sales \"販売\" { terms { ... } }\nsales/order.dt context Sales { id OrderId ... aggregate Order { ... } entity OrderItem ... event OrderPlaced ... }\nsales/customer.dt context Sales { id CustomerId ... aggregate Customer { ... } }\nbilling/context.dt /// 説明 context Billing \"請求\" { terms { ... } }\nbilling/invoice.dt context Billing { id InvoiceId ... aggregate Invoice { ... } }\n```\n\n- `<context>/<aggregate>.dt` holds the aggregate and what only it uses: its ID, entities, events, errors, enums,\n primitives and values.\n- `<context>/context.dt` holds the context's name (表示名), description and `terms`, and the elements used by several\n of its aggregates or by none (field sets, for example). The other files open the context without a name: `context Sales { ... }`.\n- An aggregate's ID stays in the aggregate's file even when other aggregates reference it.\n- Directory and file names are kebab-case: `PurchaseOrder` → `purchase-order.dt`, `OrderFulfillment` →\n `order-fulfillment/`.\n\nThis is a convention, not a rule: `check` neither requires nor warns about any layout.\n\n## DSL\n\nThe examples below are the files of one valid workspace (the file name is in the first comment).\n\n### Contexts and aggregates\n\n```dt\n// sales/order.dt\ncontext Sales { // a bounded context; may be split across files\n id OrderId: UUID // ID type with a base primitive type\n id OrderItemId: UUID\n enum CancelReason { Requested Other } // commas between values are optional\n value Address { city: String street: String }\n\n aggregate Order {\n id: OrderId // identity field of its own ID type (required)\n owns items: OrderItem[0..*] // owned entity / value inside the aggregate\n references customer: CustomerId -> Customer // another aggregate, by ID\n owns shipTo: Address? // ? = optional\n note: String?\n\n invariant quantitiesPositive { // applies to every state; sees the common fields\n all(items, item => item.quantity > 0)\n }\n\n create command place(customer: CustomerId) to Draft emits OrderPlaced // factory: no `from`\n\n state Draft\n state Confirmed {\n confirmedAt: Timestamp // exists only in this state\n invariant hasItems { count(items) > 0 and count(items) <= 100 } // sees common + Confirmed fields\n }\n state Cancelled {\n reason: CancelReason\n invariant otherNeedsNote { reason == CancelReason.Other implies exists(note) }\n }\n\n command confirm(at: Timestamp)\n from Draft\n to Confirmed // several: `to A | B`\n emits OrderConfirmed // events that MAY be emitted (0..n)\n errors EmptyOrder // errors that MAY be returned\n\n command cancel(reason: CancelReason) from Draft | Confirmed to Cancelled emits OrderCancelled\n }\n\n entity OrderItem { id: OrderItemId quantity: Quantity owns unitPrice: Money }\n\n persistent event OrderPlaced { orderId: OrderId } // storing it is part of its contract\n persistent event OrderConfirmed { orderId: OrderId confirmedAt: Timestamp }\n event OrderCancelled { orderId: OrderId reason: CancelReason } // not persisted (default)\n error EmptyOrder // payload optional: error E { field: Type }\n}\n```\n\n```dt\n// sales/customer.dt\ncontext Sales {\n id CustomerId: UUID\n\n aggregate Customer { // no states: commands have no `from` / `to`\n id: CustomerId\n email: EmailAddress // from the shared context Common\n active: Bool\n owns addresses: Address[0..*]\n\n invariant activeHasAddress { active == true implies count(addresses) > 0 }\n invariant servedArea { active == false or any(addresses, a => a.city == \"Tokyo\" or not (a.city == \"Osaka\")) }\n\n command changeEmail(email: EmailAddress) errors EmailTaken\n }\n\n error EmailTaken { email: EmailAddress }\n}\n```\n\n- Context elements: `id`, `primitive`, `enum`, `value`, `union`, `entity`, `aggregate`, `event`, `error`, and `fields`\n (see [Field sets](#field-sets)).\n- Fields: `name: Type`, `owns name: Type` (entities and values held by the aggregate),\n `references name: IdType -> Aggregate` (other aggregates, by ID only). Entities are owned by exactly one aggregate.\n- Primitive types: `String`, `Int`, `Decimal`, `Bool`, `Timestamp`, `UUID`.\n- Multiplicity after the type: `?`, `[0..1]`, `[0..*]`, `[1..*]`, `[n..m]`.\n- Aggregate members: fields, `invariant`, `state` (with its own fields and invariants), `command`.\n An aggregate with states needs `to` on every command and `from` on every non-`create` one; without states, neither.\n- `create command` makes a new aggregate; other commands take the aggregate in one of their `from` states.\n- `value`, `state`, `event` and `error` bodies are optional (`state Draft`, `error EmptyOrder`).\n- Other contexts' elements are referenced with qualified names: `Sales.OrderId`, `-> Sales.Order`.\n- Comments: `// …` and `/* … */`; `///` is a description (see [Names](#names-labels-and-descriptions)).\n\n### Domain primitives\n\nA single value with domain meaning and constraints, wrapping a primitive type. Values combining several fields are\nvalue objects.\n\n```dt\n// sales/primitives.dt\ncontext Sales {\n primitive Quantity \"数量\": Int { value in 1..999 } // one anonymous constraint\n primitive Sku: String { // or named invariants\n invariant format \"形式\" { matches(value, \"^[A-Z]{3}-\\d{4}$\") }\n invariant maxLength { length(value) <= 8 }\n }\n id InvoiceNo: String { matches(value, \"^INV-\\d{8}$\") } // an ID is a domain primitive used as identity\n}\n```\n\n- The base is always a primitive type; a domain primitive cannot refine another one or an enum.\n- Inside the constraint only `value` (of the base type) is visible; `length(value)`, `matches(value, \"regex\")` and\n ranges `value in 1..999` (negative literals allowed) are available there.\n- Regular expressions are written as in JavaScript: backslashes are not string escapes (`\"\\d\"` means `\\d`).\n- Elsewhere a domain primitive compares with literals and with the same domain primitive, not with another domain\n primitive or a plain field of its base type (M009).\n- Only IDs can be identity fields and reference types. Domain primitives cannot be owned.\n\n### Unions\n\nA value whose shape depends on a kind fixed when it is made (a tagged union). Use a union for a classification that\nnever changes, and aggregate states for a lifecycle that commands move through.\n\n```dt\n// sales/payment.dt\ncontext Sales {\n union Payer \"支払者\" { // discriminator `kind` by default\n CUSTOMER \"顧客\" { customerId: CustomerId }\n COMPANY \"法人\" { name: String billingEmail: EmailAddress? }\n }\n enum PaymentMethod { CARD TRANSFER }\n union PaymentDetails by method: PaymentMethod { // `by name`, optionally bound to an enum\n CARD { last4: String } // exactly the enum's values (M015)\n TRANSFER { bankCode: String }\n }\n}\n```\n\n- A union is a value type: usable like a value object (fields, `owns`, parameters, payloads, shared contexts).\n Variants hold value fields and invariants (seeing their own fields); entities and aggregates are not allowed.\n- In invariants, `payer.kind` compares with `Payer.COMPANY` (or the bound enum's values); variant fields are not\n accessible from outside the union.\n\n### Shared contexts\n\n```dt\n// common/context.dt\nshared context Common \"共通\" { // shared kernel: usable by simple name from every context\n terms { currency: \"通貨\" }\n enum Currency { JPY USD }\n value Money { amount: Decimal currency: Currency }\n primitive EmailAddress: String { matches(value, \"^[^@\\s]+@[^@\\s]+$\") }\n}\n```\n\n- `Money` and `Common.Money` both work in other contexts. A context's own element with the same name wins (M014 warning).\n- A shared context holds only domain primitives, enums, value objects, unions, field sets and terms, and depends only on\n shared contexts. Its `terms` apply to fields of every context that has no term of its own for the name.\n\n### Field sets\n\nFields that several aggregates, entities or events have for the same domain reason are written once as a field set\nand taken on with `with`.\n\n```dt\n// common/tenancy.dt\nshared context Common {\n /// 契約者(テナント)。業務データはテナントごとに分かれる。\n primitive TenantId \"テナントID\": UUID\n fields Tenanted \"テナント所属\" { // a field set: plain fields only\n tenant: TenantId \"テナント\"\n }\n}\n```\n\n```dt\n// expenses/expense.dt\ncontext Expenses \"経費\" {\n id ExpenseId \"経費申請ID\": UUID\n id StaffId \"職員ID\": UUID\n\n /// 規程により、申請の受付には実施者を記録する。\n fields Performed \"実施記録\" {\n performedBy: StaffId \"実施者\"\n }\n\n aggregate Expense \"経費申請\" with Tenanted { // tenant first, then its own fields\n id: ExpenseId\n applicant: StaffId \"申請者\"\n approver: StaffId? \"承認者\"\n invariant notSelfApproved \"申請者は承認できない\" { exists(approver) implies approver != applicant }\n\n create command submit(applicant: StaffId \"申請者\") \"申請する\" emits ExpenseSubmitted\n command approve(approver: StaffId \"承認者\", approvedAt: Timestamp \"承認日時\") \"承認する\" emits ExpenseApproved\n }\n\n event ExpenseSubmitted \"申請受付\" with Tenanted, Performed { expenseId: ExpenseId }\n event ExpenseApproved \"承認\" with Tenanted {\n expenseId: ExpenseId\n approver: StaffId \"承認者\" // a business role, named by the role\n approvedAt: Timestamp \"承認日時\" // when it happened in business terms\n }\n}\n```\n\n- `fields Name \"label\" { ... }` holds plain fields, written like any other field (type, multiplicity, label, `///`).\n No `owns`, `references`, invariants, `with` or `id` inside (M016).\n- `with A, B` after the name and label of an `aggregate`, `entity` or `event` (only those, M016). A field set is\n referenced like a type: by name in its own context and from shared contexts, as `Context.Name` otherwise.\n- The fields come first, in the order of `with`, and then count as the element's own: invariants see them, and an\n aggregate's states share them. A name may come from one place only, the element or one of its field sets (M016).\n- The identity of aggregates and entities is never a field set: every aggregate and entity declares `id` itself (M013).\n- A command's event should say which aggregate it is about: it needs a field of the aggregate's ID type, its own or\n from a field set (M017 warning). An event emitted by several aggregates needs the ID type of each (optional fields\n count).\n\n### Domain fields and technical fields\n\nWrite a field in the DSL when **domain experts talk about it, or a business rule (an invariant, a transition, a\ncommand's decision) refers to it**. A field that is neither is technical: leave it out of the DSL and of the generated\ncode, and add it in your own code around the generated types (see [Technical metadata](#technical-metadata)).\n\n- **Required by the kind of element** (the ID of an aggregate or entity): enforced by the language (M013), not a field\n set.\n- **Chosen for some elements** (a tenant, a recorded performer): a field set and `with`.\n- **Technical**: event ID, the time the system recorded something (`recordedAt`), optimistic-lock `version`,\n `createdAt` / `updatedAt`, correlation / causation IDs, the system's acting account, schema versions.\n\nTwo cases look alike but are not:\n\n- **When**: the time something happened in business terms is domain — rules refer to it (\"within 30 days of\n confirmation\"). Name it by its meaning (`confirmedAt: Timestamp \"確定日時\"`). If every event is to carry its business\n time, say so with a field set: `fields Occurred { occurredAt: Timestamp \"発生日時\" }`. The time the system recorded it\n is technical. The two differ with late entry, offline work and imports.\n- **Who**: a business role (approver, person in charge) is domain — rules refer to it (\"the applicant cannot\n approve\"). Name it by the role (`approvedBy: StaffId \"承認者\"`), usually passed from the command's parameters to the\n event. If regulations require recording the performer of every operation,\n `fields Performed { performedBy: StaffId \"実施者\" }`. The login account, service account or IP address is technical; it differs with proxy entry and batches.\n\n### Names (labels and descriptions)\n\n```dt\n// billing/context.dt\n/// 注文への請求と支払いを扱う。\ncontext Billing \"請求\" {\n terms { // field / parameter names, defined once per context\n /// 請求書が支払われた日時。\n paidAt: \"支払日時\"\n }\n}\n```\n\n```dt\n// billing/invoice.dt\ncontext Billing { // other files open the context without a name\n id InvoiceId \"請求書ID\": UUID\n\n /// 注文1件に対する請求。\n aggregate Invoice \"請求書\" { // declarations: a string after the name\n id: InvoiceId\n references order: Sales.OrderId -> Sales.Order \"請求対象\" // an inline label on a field\n owns amount: Money \"請求金額\"\n state Open \"未払い\"\n state Paid \"支払済み\" { paidAt: Timestamp } // → 支払日時 (from terms)\n invariant positive \"金額が正\" { amount.amount > 0 }\n create command issue(order: Sales.OrderId, amount: Money) \"請求書を発行する\" to Open\n command pay(at: Timestamp \"支払日時\") \"支払う\" from Open to Paid emits InvoicePaid\n }\n enum InvoiceKind \"請求区分\" { Regular \"通常\" Refund \"返金\" }\n event InvoicePaid \"支払完了\" { invoiceId: InvoiceId paidAt: Timestamp }\n}\n```\n\n- Declarations (context, id, primitive, enum and its values, value, union and its variants, entity, aggregate, state,\n command, invariant, event, error) take an optional string label after the name.\n- A field or parameter is named by, in order: its inline string → the context's `terms` → the name of its type\n (for `references`, the target aggregate) → the English name.\n- `///` lines directly above a declaration or term are its description.\n- Labels appear in the Live View and as JSDoc in the generated TypeScript; identifiers and generated type names stay\n English.\n\n### Invariant expressions\n\n- Literals: `true`, `false`, `42`, `-1`, `3.14`, `\"text\"`; enum values `CancelReason.Other`.\n- Field paths: `note`, `item.quantity`, `amount.amount`.\n- Operators, loosest first: `implies`, `or`, `and`, `== != < <= > >=`, `x in 1..9`, `not`.\n- Functions: `exists(x)` (an optional is present; narrows `x` on the right of `and` / `implies`), `count(c)`,\n `all(c, x => …)`, `any(c, x => …)`, and in domain primitives `length(value)`, `matches(value, \"regex\")`.\n- An invariant must be a Bool expression. Only its type is checked, not whether it holds.\n\n## Rules\n\n| Code | Check |\n|---|---|\n| SYNTAX | lexer / parser errors |\n| M001 | types, aggregates and names in invariants resolve |\n| M002 | names are unique in their scope (also across files of one context) |\n| M003 | an entity is owned by exactly one aggregate (warning when owned by none) |\n| M004 | no ownership across aggregate boundaries (entities need `owns`, aggregates need `references`, …) |\n| M005 | a reference's ID type matches the identity of the target aggregate |\n| M006 | command input/output states exist and fit the aggregate (factory / stateful / stateless) |\n| M007 | `emits` / `errors` refer to existing events / errors |\n| M008 | an invariant is a Bool expression |\n| M009 | operators and operands have compatible types |\n| M010 | state-specific fields are used only in their own state's invariants |\n| M011 | generated TypeScript names do not collide |\n| M012 | the ownership graph has no cycles |\n| M013 | aggregates and entities have an `id` field of their own ID type |\n| M014 | shared contexts: only value types, no dependency on other contexts, consistent `shared`, unambiguous names (shadowing is a warning) |\n| M015 | unions: at least one variant, variants match the bound enum exactly, no variant field named like the discriminator |\n| M016 | field sets: plain fields only (no `id`), `with` only on aggregates, entities and events, each field name from one place |\n| M017 | (warning) an event emitted by an aggregate's command has a field of that aggregate's ID type |\n| L001 | (warning) an inline field label disagrees with the term, or context fragments disagree on the context name |\n| L002 | (warning) a term is not used by any field or parameter |\n| L003 | (warning) different things in one scope share a Japanese name |\n\n## Generated TypeScript\n\nPer context a module (`Sales.ts`, …) with ID brands, enums, value objects, entities, unions, a discriminated union per\nstateful aggregate (`DraftOrder | ConfirmedOrder | …`), event / error types with a `type` tag, a function type per\ncommand and an `<Aggregate>Commands` interface to implement, plus `index.ts` and `_runtime.ts`. A domain primitive\ngets a branded type and a constructor contract `Make<Name>` to implement by hand. A field set is an interface that the\nelements using it extend (`interface Expense extends Common.Tenanted`; for a stateful aggregate, its `…Common`).\n\nUnions to name groups of them, each generated only when it has a member:\n\n| Type | Members |\n|---|---|\n| `DomainEvent` | every event of the context |\n| `PersistentEvent` | the events declared `persistent` |\n| `Aggregate` | every aggregate of the context |\n| `<Aggregate>Event` (`OrderEvent`) | the events the aggregate's commands may emit (also of other contexts) |\n\n```ts\nexport type ConfirmOrder = (\n order: DraftOrder,\n at: Timestamp,\n) => Result<readonly [ConfirmedOrder, readonly OrderConfirmed[]], EmptyOrder>;\n```\n\n### Generated code and your code\n\nThe generated files are the **contract**, your code is the **implementation**:\n\n- Generated: types only — the shapes of the model, the command signatures (`ConfirmOrder`, `OrderCommands`) and the\n constructor signatures of domain primitives (`MakeQuantity`). Invariants appear as JSDoc (`@invariant`); nothing in\n the generated code checks them.\n- Yours: everything that runs — command implementations, `Make<Name>` constructors, invariant checks — in your own\n files, which import the generated modules (never the other way round) and are type-checked against them.\n\n```ts\n// src/primitives.ts — your code\nimport { err, ok, type Sales } from '../generated/domain/index.js';\n\nexport const makeQuantity: Sales.MakeQuantity = (value) =>\n Number.isInteger(value) && value >= 1 && value <= 999 ? ok(value as Sales.Quantity) : err({ type: 'InvalidQuantity', value, invariant: 'valid' });\n```\n\nDo not edit generated files: change the `.dt` sources and generate again. Adding properties or methods to generated\ntypes (declaration merging, editing the output) is not supported; write functions that take the generated types.\n\n### Technical metadata\n\nTechnical fields (see [Domain fields and technical fields](#domain-fields-and-technical-fields)) are added by your code,\naround the generated types. Keep the two apart in an envelope, `{ event, meta }`, rather than an intersection\n(`E & Meta`): names cannot clash, and domain and technical fields stay separate. `dt` generates no envelope type.\n\n```ts\n// src/stored.ts — your code: metadata of stored events and aggregates\nimport type { Sales } from '../generated/domain/index.js';\n\nexport interface EventMeta {\n readonly eventId: string;\n readonly recordedAt: Date;\n readonly correlationId?: string;\n readonly causationId?: string;\n}\n\n/** What Sales records in addition. */\nexport interface SalesEventMeta extends EventMeta {\n readonly accountId: string;\n}\n\nexport type Stored<E, M extends EventMeta = EventMeta> = { readonly event: E; readonly meta: M };\n\nexport type StoredSalesEvent = Stored<Sales.PersistentEvent, SalesEventMeta>;\n\nexport interface AggregateMeta {\n readonly version: number;\n readonly createdAt: Date;\n readonly updatedAt: Date;\n}\n\nexport type Versioned<A, M extends AggregateMeta = AggregateMeta> = { readonly aggregate: A; readonly meta: M };\n\nexport interface OrderRepository {\n load(id: Sales.OrderId): Promise<Versioned<Sales.Order> | undefined>;\n save(order: Versioned<Sales.Order>, events: readonly Sales.OrderEvent[]): Promise<void>;\n}\n```\n\nMetadata that only some kinds of event carry can be keyed by the event's `type`:\n\n```ts\n// src/meta-by-event.ts — your code\nimport type { Sales } from '../generated/domain/index.js';\nimport type { EventMeta } from './stored.js';\n\ninterface MetaByEvent {\n OrderPlaced: { readonly channel: 'web' | 'store' };\n}\n\nexport type MetaOf<E extends { type: string }> = EventMeta & (E['type'] extends keyof MetaByEvent ? MetaByEvent[E['type']] : {});\n\n/** One envelope per kind of event, so that a union of events gives a union of envelopes. */\nexport type StoredEvent<E extends { type: string }> = E extends unknown ? { readonly event: E; readonly meta: MetaOf<E> } : never;\n\nexport const channelOf = (s: StoredEvent<Sales.OrderPlaced>): 'web' | 'store' => s.meta.channel;\nexport type StoredSalesEvents = StoredEvent<Sales.DomainEvent>;\n```\n\n### Output directories\n\nBy default every context goes to `generate.ts.out`. Contexts listed in `generate.ts.contexts` go to their own\ndirectory instead, e.g. a shared context into a package used by several applications. Each directory written to gets\nits own `_runtime.ts` and an `index.ts` re-exporting only the contexts in it; a module imports other contexts by\nrelative path (`import type * as Common from '../../packages/shared/src/generated/Common.js'`). The runtimes are\nidentical, so values typed with one are accepted where the other is expected.\n\nEach run replaces the files generated before (recognized by their header). The files written are recorded in\n`.domaintrail/generated.json` under the root, and generated files of earlier runs that are no longer written (an output\ndirectory moved, a context removed) are deleted, along with a directory left empty. Only recorded paths inside the root\nand not reached through a symlink are deleted; other entries in that file are ignored. Other files are never deleted —\nneither hand-written files nor generated files you edited — and generation stops instead of overwriting one.\n";
|
|
7603
8039
|
|
|
7604
8040
|
// src/cli/main.ts
|
|
7605
8041
|
var defaultIO = {
|