@eventcatalog/language-server 0.1.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 +71 -0
- package/SPEC.md +1939 -0
- package/dist/ast-utils.d.ts +96 -0
- package/dist/ast-utils.d.ts.map +1 -0
- package/dist/ast-utils.js +241 -0
- package/dist/ast-utils.js.map +1 -0
- package/dist/compiler.d.ts +7 -0
- package/dist/compiler.d.ts.map +1 -0
- package/dist/compiler.js +654 -0
- package/dist/compiler.js.map +1 -0
- package/dist/ec-completion-provider.d.ts +15 -0
- package/dist/ec-completion-provider.d.ts.map +1 -0
- package/dist/ec-completion-provider.js +202 -0
- package/dist/ec-completion-provider.js.map +1 -0
- package/dist/ec-module.d.ts +18 -0
- package/dist/ec-module.d.ts.map +1 -0
- package/dist/ec-module.js +27 -0
- package/dist/ec-module.js.map +1 -0
- package/dist/ec-scope-provider.d.ts +2 -0
- package/dist/ec-scope-provider.d.ts.map +1 -0
- package/dist/ec-scope-provider.js +2 -0
- package/dist/ec-scope-provider.js.map +1 -0
- package/dist/ec-scope.d.ts +10 -0
- package/dist/ec-scope.d.ts.map +1 -0
- package/dist/ec-scope.js +18 -0
- package/dist/ec-scope.js.map +1 -0
- package/dist/ec-validator.d.ts +9 -0
- package/dist/ec-validator.d.ts.map +1 -0
- package/dist/ec-validator.js +238 -0
- package/dist/ec-validator.js.map +1 -0
- package/dist/formatter.d.ts +6 -0
- package/dist/formatter.d.ts.map +1 -0
- package/dist/formatter.js +88 -0
- package/dist/formatter.js.map +1 -0
- package/dist/generated/ast.d.ts +970 -0
- package/dist/generated/ast.d.ts.map +1 -0
- package/dist/generated/ast.js +1537 -0
- package/dist/generated/ast.js.map +1 -0
- package/dist/generated/grammar.d.ts +7 -0
- package/dist/generated/grammar.d.ts.map +1 -0
- package/dist/generated/grammar.js +6062 -0
- package/dist/generated/grammar.js.map +1 -0
- package/dist/generated/module.d.ts +14 -0
- package/dist/generated/module.d.ts.map +1 -0
- package/dist/generated/module.js +21 -0
- package/dist/generated/module.js.map +1 -0
- package/dist/graph-types.d.ts +32 -0
- package/dist/graph-types.d.ts.map +1 -0
- package/dist/graph-types.js +2 -0
- package/dist/graph-types.js.map +1 -0
- package/dist/graph.d.ts +4 -0
- package/dist/graph.d.ts.map +1 -0
- package/dist/graph.js +931 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +10 -0
- package/dist/index.js.map +1 -0
- package/dist/main-browser.d.ts +2 -0
- package/dist/main-browser.d.ts.map +1 -0
- package/dist/main-browser.js +16 -0
- package/dist/main-browser.js.map +1 -0
- package/dist/main.d.ts +2 -0
- package/dist/main.d.ts.map +1 -0
- package/dist/main.js +15 -0
- package/dist/main.js.map +1 -0
- package/package.json +55 -0
- package/specification/00-overview.md +99 -0
- package/specification/01-domain.md +80 -0
- package/specification/02-service.md +50 -0
- package/specification/03-event.md +28 -0
- package/specification/04-command.md +25 -0
- package/specification/05-query.md +25 -0
- package/specification/06-channel.md +131 -0
- package/specification/08-container.md +54 -0
- package/specification/09-data-product.md +39 -0
- package/specification/10-flow.md +163 -0
- package/specification/11-diagram.md +3 -0
- package/specification/12-user.md +54 -0
- package/specification/13-team.md +62 -0
- package/specification/14-relationships.md +89 -0
- package/specification/15-versioning.md +41 -0
- package/specification/16-annotations.md +100 -0
- package/specification/17-examples.md +373 -0
- package/specification/18-grammar.md +242 -0
- package/specification/19-visualizer.md +197 -0
- package/specification/build-spec.sh +49 -0
- package/syntaxes/ec.tmLanguage.json +61 -0
package/dist/compiler.js
ADDED
|
@@ -0,0 +1,654 @@
|
|
|
1
|
+
import { isDomainDef, isServiceDef, isEventDef, isCommandDef, isQueryDef, isChannelDef, isContainerDef, isDataProductDef, isFlowDef, isDiagramDef, isUserDef, isTeamDef, isVisualizerDef, isNamedAnnotationArg, isPositionalAnnotationArg, isKeyValueAnnotationBlockItem, isParameterDescriptionProp, isParameterDefaultProp, isParameterEnumProp, isParameterExamplesProp, isStringAnnotationValue, isIdAnnotationValue, isNumberAnnotationValue, isBoolAnnotationValue, isVersionAnnotationValue, isKeywordAnnotationValue, } from "./generated/ast.js";
|
|
2
|
+
import { stripQuotes, getVersion, getName, getSummary, getOwners, getDeprecated, getDraft, getSchema, getServices, getSubdomains, getSends, getReceives, getAnnotations, getAddress, getProtocols, getParameters, getContainerType, getTechnology, getAuthoritative, getAccessMode, getClassification, getResidency, getRetention, getInputs, getOutputs, getFlowEntryChains, getFlowWhenBlocks, } from "./ast-utils.js";
|
|
3
|
+
export function compile(program) {
|
|
4
|
+
const outputs = [];
|
|
5
|
+
for (const def of program.definitions) {
|
|
6
|
+
compileDefinition(def, outputs);
|
|
7
|
+
}
|
|
8
|
+
return outputs;
|
|
9
|
+
}
|
|
10
|
+
function compileDefinition(def, outputs) {
|
|
11
|
+
if (isDomainDef(def))
|
|
12
|
+
compileDomain(def, outputs);
|
|
13
|
+
else if (isServiceDef(def)) {
|
|
14
|
+
compileService(def, outputs);
|
|
15
|
+
compileInlineMessages(def, outputs);
|
|
16
|
+
}
|
|
17
|
+
else if (isEventDef(def))
|
|
18
|
+
compileMessage(def, "events", outputs);
|
|
19
|
+
else if (isCommandDef(def))
|
|
20
|
+
compileMessage(def, "commands", outputs);
|
|
21
|
+
else if (isQueryDef(def))
|
|
22
|
+
compileMessage(def, "queries", outputs);
|
|
23
|
+
else if (isChannelDef(def))
|
|
24
|
+
compileChannel(def, outputs);
|
|
25
|
+
else if (isContainerDef(def))
|
|
26
|
+
compileContainer(def, outputs);
|
|
27
|
+
else if (isDataProductDef(def))
|
|
28
|
+
compileDataProduct(def, outputs);
|
|
29
|
+
else if (isFlowDef(def))
|
|
30
|
+
compileFlow(def, outputs);
|
|
31
|
+
else if (isDiagramDef(def))
|
|
32
|
+
compileDiagram(def, outputs);
|
|
33
|
+
else if (isUserDef(def))
|
|
34
|
+
compileUser(def, outputs);
|
|
35
|
+
else if (isTeamDef(def))
|
|
36
|
+
compileTeam(def, outputs);
|
|
37
|
+
else if (isVisualizerDef(def))
|
|
38
|
+
compileVisualizer(def, outputs);
|
|
39
|
+
// ActorDef and ExternalSystemDef are flow-only — no markdown output
|
|
40
|
+
}
|
|
41
|
+
// --- YAML helpers ---
|
|
42
|
+
function yamlValue(val) {
|
|
43
|
+
if (typeof val === "string")
|
|
44
|
+
return JSON.stringify(val);
|
|
45
|
+
if (typeof val === "boolean" || typeof val === "number")
|
|
46
|
+
return String(val);
|
|
47
|
+
return String(val);
|
|
48
|
+
}
|
|
49
|
+
function buildFrontmatter(fields) {
|
|
50
|
+
const lines = ["---"];
|
|
51
|
+
writeFrontmatterFields(lines, fields, 0);
|
|
52
|
+
lines.push("---");
|
|
53
|
+
return lines.join("\n");
|
|
54
|
+
}
|
|
55
|
+
function writeFrontmatterFields(lines, fields, indent) {
|
|
56
|
+
const prefix = " ".repeat(indent);
|
|
57
|
+
for (const [key, value] of Object.entries(fields)) {
|
|
58
|
+
if (value === undefined || value === null)
|
|
59
|
+
continue;
|
|
60
|
+
if (Array.isArray(value)) {
|
|
61
|
+
if (value.length === 0)
|
|
62
|
+
continue;
|
|
63
|
+
lines.push(`${prefix}${key}:`);
|
|
64
|
+
for (const item of value) {
|
|
65
|
+
if (typeof item === "object" && item !== null) {
|
|
66
|
+
const entries = Object.entries(item).filter(([, v]) => v !== undefined && v !== null);
|
|
67
|
+
if (entries.length > 0) {
|
|
68
|
+
const [firstKey, firstVal] = entries[0];
|
|
69
|
+
if (typeof firstVal === "object" && firstVal !== null) {
|
|
70
|
+
lines.push(`${prefix} - ${firstKey}:`);
|
|
71
|
+
writeFrontmatterFields(lines, firstVal, indent + 3);
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
lines.push(`${prefix} - ${firstKey}: ${yamlValue(firstVal)}`);
|
|
75
|
+
}
|
|
76
|
+
for (let i = 1; i < entries.length; i++) {
|
|
77
|
+
const [k, v] = entries[i];
|
|
78
|
+
if (typeof v === "object" && v !== null && !Array.isArray(v)) {
|
|
79
|
+
lines.push(`${prefix} ${k}:`);
|
|
80
|
+
writeFrontmatterFields(lines, v, indent + 3);
|
|
81
|
+
}
|
|
82
|
+
else if (Array.isArray(v)) {
|
|
83
|
+
lines.push(`${prefix} ${k}:`);
|
|
84
|
+
for (const subItem of v) {
|
|
85
|
+
if (typeof subItem === "object" && subItem !== null) {
|
|
86
|
+
const subEntries = Object.entries(subItem).filter(([, sv]) => sv !== undefined && sv !== null);
|
|
87
|
+
if (subEntries.length > 0) {
|
|
88
|
+
const [sk, sv] = subEntries[0];
|
|
89
|
+
lines.push(`${prefix} - ${sk}: ${yamlValue(sv)}`);
|
|
90
|
+
for (let j = 1; j < subEntries.length; j++) {
|
|
91
|
+
const [sk2, sv2] = subEntries[j];
|
|
92
|
+
lines.push(`${prefix} ${sk2}: ${yamlValue(sv2)}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
else {
|
|
97
|
+
lines.push(`${prefix} - ${yamlValue(subItem)}`);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
else {
|
|
102
|
+
lines.push(`${prefix} ${k}: ${yamlValue(v)}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
lines.push(`${prefix} - ${yamlValue(item)}`);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
else if (typeof value === "object" && value !== null) {
|
|
113
|
+
lines.push(`${prefix}${key}:`);
|
|
114
|
+
writeFrontmatterFields(lines, value, indent + 1);
|
|
115
|
+
}
|
|
116
|
+
else {
|
|
117
|
+
lines.push(`${prefix}${key}: ${yamlValue(value)}`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
// --- Annotation mapping ---
|
|
122
|
+
function getAnnotationArgValue(arg) {
|
|
123
|
+
const v = isNamedAnnotationArg(arg) ? arg.value : arg.value;
|
|
124
|
+
if (isStringAnnotationValue(v))
|
|
125
|
+
return stripQuotes(v.value);
|
|
126
|
+
if (isIdAnnotationValue(v))
|
|
127
|
+
return v.value;
|
|
128
|
+
if (isNumberAnnotationValue(v))
|
|
129
|
+
return parseInt(v.value, 10);
|
|
130
|
+
if (isBoolAnnotationValue(v))
|
|
131
|
+
return v.value;
|
|
132
|
+
if (isVersionAnnotationValue(v))
|
|
133
|
+
return v.value;
|
|
134
|
+
if (isKeywordAnnotationValue(v))
|
|
135
|
+
return v.value;
|
|
136
|
+
return "";
|
|
137
|
+
}
|
|
138
|
+
function mapAnnotations(annotations) {
|
|
139
|
+
if (annotations.length === 0)
|
|
140
|
+
return {};
|
|
141
|
+
const result = {};
|
|
142
|
+
for (const ann of annotations) {
|
|
143
|
+
switch (ann.name) {
|
|
144
|
+
case "badge": {
|
|
145
|
+
if (!result.badges)
|
|
146
|
+
result.badges = [];
|
|
147
|
+
const badge = {};
|
|
148
|
+
const contentArg = ann.args.find((a) => isPositionalAnnotationArg(a));
|
|
149
|
+
if (contentArg)
|
|
150
|
+
badge.content = String(getAnnotationArgValue(contentArg));
|
|
151
|
+
const bgArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "bg");
|
|
152
|
+
if (bgArg)
|
|
153
|
+
badge.backgroundColor = String(getAnnotationArgValue(bgArg));
|
|
154
|
+
const textArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "text");
|
|
155
|
+
if (textArg)
|
|
156
|
+
badge.textColor = String(getAnnotationArgValue(textArg));
|
|
157
|
+
result.badges.push(badge);
|
|
158
|
+
break;
|
|
159
|
+
}
|
|
160
|
+
case "note": {
|
|
161
|
+
if (!result.notes)
|
|
162
|
+
result.notes = [];
|
|
163
|
+
const note = {};
|
|
164
|
+
const noteContentArg = ann.args.find((a) => isPositionalAnnotationArg(a));
|
|
165
|
+
if (noteContentArg)
|
|
166
|
+
note.content = String(getAnnotationArgValue(noteContentArg));
|
|
167
|
+
const authorArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "author");
|
|
168
|
+
if (authorArg)
|
|
169
|
+
note.author = String(getAnnotationArgValue(authorArg));
|
|
170
|
+
const priorityArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "priority");
|
|
171
|
+
if (priorityArg)
|
|
172
|
+
note.priority = String(getAnnotationArgValue(priorityArg));
|
|
173
|
+
result.notes.push(note);
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
case "repository": {
|
|
177
|
+
const repo = {};
|
|
178
|
+
const urlArg = ann.args.find((a) => (isNamedAnnotationArg(a) && a.key === "url") ||
|
|
179
|
+
isPositionalAnnotationArg(a));
|
|
180
|
+
if (urlArg)
|
|
181
|
+
repo.url = String(getAnnotationArgValue(urlArg));
|
|
182
|
+
const langArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "language");
|
|
183
|
+
if (langArg)
|
|
184
|
+
repo.language = String(getAnnotationArgValue(langArg));
|
|
185
|
+
result.repository = repo;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
case "externalId": {
|
|
189
|
+
const idArg = ann.args.find((a) => isPositionalAnnotationArg(a));
|
|
190
|
+
if (idArg)
|
|
191
|
+
result.externalId = String(getAnnotationArgValue(idArg));
|
|
192
|
+
break;
|
|
193
|
+
}
|
|
194
|
+
case "specification":
|
|
195
|
+
case "specifications": {
|
|
196
|
+
if (!result.specifications)
|
|
197
|
+
result.specifications = [];
|
|
198
|
+
const spec = {};
|
|
199
|
+
const typeArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "type");
|
|
200
|
+
if (typeArg)
|
|
201
|
+
spec.type = String(getAnnotationArgValue(typeArg));
|
|
202
|
+
const pathArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "path");
|
|
203
|
+
if (pathArg)
|
|
204
|
+
spec.path = String(getAnnotationArgValue(pathArg));
|
|
205
|
+
const titleArg = ann.args.find((a) => isNamedAnnotationArg(a) && a.key === "title");
|
|
206
|
+
if (titleArg)
|
|
207
|
+
spec.title = String(getAnnotationArgValue(titleArg));
|
|
208
|
+
const urlArg = ann.args.find((a) => (isNamedAnnotationArg(a) && a.key === "url") ||
|
|
209
|
+
isPositionalAnnotationArg(a));
|
|
210
|
+
if (urlArg && !spec.path)
|
|
211
|
+
spec.url = String(getAnnotationArgValue(urlArg));
|
|
212
|
+
result.specifications.push(spec);
|
|
213
|
+
break;
|
|
214
|
+
}
|
|
215
|
+
case "sidebar": {
|
|
216
|
+
const sidebar = {};
|
|
217
|
+
for (const arg of ann.args) {
|
|
218
|
+
if (isNamedAnnotationArg(arg))
|
|
219
|
+
sidebar[arg.key] = getAnnotationArgValue(arg);
|
|
220
|
+
}
|
|
221
|
+
if (ann.block) {
|
|
222
|
+
for (const item of ann.block) {
|
|
223
|
+
if (isKeyValueAnnotationBlockItem(item)) {
|
|
224
|
+
sidebar[item.key] = item.value;
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
result.sidebar = sidebar;
|
|
229
|
+
break;
|
|
230
|
+
}
|
|
231
|
+
case "styles": {
|
|
232
|
+
const styles = {};
|
|
233
|
+
for (const arg of ann.args) {
|
|
234
|
+
if (isNamedAnnotationArg(arg))
|
|
235
|
+
styles[arg.key] = getAnnotationArgValue(arg);
|
|
236
|
+
}
|
|
237
|
+
result.styles = styles;
|
|
238
|
+
break;
|
|
239
|
+
}
|
|
240
|
+
default: {
|
|
241
|
+
if (ann.args.length === 1 && isPositionalAnnotationArg(ann.args[0])) {
|
|
242
|
+
result[ann.name] = getAnnotationArgValue(ann.args[0]);
|
|
243
|
+
}
|
|
244
|
+
else if (ann.args.length > 0) {
|
|
245
|
+
const obj = {};
|
|
246
|
+
for (const arg of ann.args) {
|
|
247
|
+
if (isNamedAnnotationArg(arg))
|
|
248
|
+
obj[arg.key] = getAnnotationArgValue(arg);
|
|
249
|
+
}
|
|
250
|
+
result[ann.name] = obj;
|
|
251
|
+
}
|
|
252
|
+
break;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
return result;
|
|
257
|
+
}
|
|
258
|
+
function commonFrontmatter(id, body) {
|
|
259
|
+
const fm = {
|
|
260
|
+
id,
|
|
261
|
+
name: getName(body) || id,
|
|
262
|
+
};
|
|
263
|
+
const version = getVersion(body);
|
|
264
|
+
if (version)
|
|
265
|
+
fm.version = version;
|
|
266
|
+
const owners = getOwners(body);
|
|
267
|
+
if (owners.length > 0) {
|
|
268
|
+
fm.owners = owners;
|
|
269
|
+
}
|
|
270
|
+
const schema = getSchema(body);
|
|
271
|
+
if (schema)
|
|
272
|
+
fm.schemaPath = schema;
|
|
273
|
+
const deprecated = getDeprecated(body);
|
|
274
|
+
if (deprecated)
|
|
275
|
+
fm.deprecated = deprecated;
|
|
276
|
+
const draft = getDraft(body);
|
|
277
|
+
if (draft)
|
|
278
|
+
fm.draft = draft;
|
|
279
|
+
const annFields = mapAnnotations(getAnnotations(body));
|
|
280
|
+
Object.assign(fm, annFields);
|
|
281
|
+
return fm;
|
|
282
|
+
}
|
|
283
|
+
function makeOutput(path, fm, body) {
|
|
284
|
+
const frontmatter = buildFrontmatter(fm);
|
|
285
|
+
const content = body ? `${frontmatter}\n${body}\n` : `${frontmatter}\n`;
|
|
286
|
+
return { path, content };
|
|
287
|
+
}
|
|
288
|
+
// --- Resource compilers ---
|
|
289
|
+
function compileDomain(domain, outputs) {
|
|
290
|
+
const body = domain.body;
|
|
291
|
+
const fm = commonFrontmatter(domain.name, body);
|
|
292
|
+
const summary = getSummary(body);
|
|
293
|
+
outputs.push(makeOutput(`domains/${domain.name}/index.md`, fm, summary));
|
|
294
|
+
for (const svc of getServices(body)) {
|
|
295
|
+
compileService(svc, outputs);
|
|
296
|
+
compileInlineMessages(svc, outputs);
|
|
297
|
+
}
|
|
298
|
+
for (const sub of getSubdomains(body)) {
|
|
299
|
+
const subBody = sub.body;
|
|
300
|
+
const subFm = commonFrontmatter(sub.name, subBody);
|
|
301
|
+
const subSummary = getSummary(subBody);
|
|
302
|
+
outputs.push(makeOutput(`domains/${domain.name}/domains/${sub.name}/index.md`, subFm, subSummary));
|
|
303
|
+
for (const svc of getServices(subBody)) {
|
|
304
|
+
compileService(svc, outputs);
|
|
305
|
+
compileInlineMessages(svc, outputs);
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function compileService(svc, outputs) {
|
|
310
|
+
const body = svc.body;
|
|
311
|
+
const fm = commonFrontmatter(svc.name, body);
|
|
312
|
+
const sends = getSends(body);
|
|
313
|
+
if (sends.length > 0) {
|
|
314
|
+
fm.sends = sends.map((s) => buildMessageRef(s));
|
|
315
|
+
}
|
|
316
|
+
const receives = getReceives(body);
|
|
317
|
+
if (receives.length > 0) {
|
|
318
|
+
fm.receives = receives.map((r) => buildMessageRef(r));
|
|
319
|
+
}
|
|
320
|
+
outputs.push(makeOutput(`services/${svc.name}/index.md`, fm, getSummary(body)));
|
|
321
|
+
}
|
|
322
|
+
function buildMessageRef(clause) {
|
|
323
|
+
const ref = { id: clause.messageName };
|
|
324
|
+
if (clause.version)
|
|
325
|
+
ref.version = clause.version;
|
|
326
|
+
// Check inline body for version
|
|
327
|
+
if (clause.body.length > 0) {
|
|
328
|
+
const inlineVersion = getVersion(clause.body);
|
|
329
|
+
if (inlineVersion)
|
|
330
|
+
ref.version = inlineVersion;
|
|
331
|
+
}
|
|
332
|
+
return ref;
|
|
333
|
+
}
|
|
334
|
+
function compileInlineMessages(svc, outputs) {
|
|
335
|
+
const body = svc.body;
|
|
336
|
+
const allClauses = [...getSends(body), ...getReceives(body)];
|
|
337
|
+
for (const clause of allClauses) {
|
|
338
|
+
if (clause.body.length > 0) {
|
|
339
|
+
const inlineBody = clause.body;
|
|
340
|
+
const msgType = clause.messageType;
|
|
341
|
+
const folder = msgType === "event"
|
|
342
|
+
? "events"
|
|
343
|
+
: msgType === "command"
|
|
344
|
+
? "commands"
|
|
345
|
+
: "queries";
|
|
346
|
+
const fm = commonFrontmatter(clause.messageName, inlineBody);
|
|
347
|
+
outputs.push(makeOutput(`${folder}/${clause.messageName}/index.md`, fm, getSummary(inlineBody)));
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
function compileMessage(msg, folder, outputs) {
|
|
352
|
+
const body = msg.body;
|
|
353
|
+
const fm = commonFrontmatter(msg.name, body);
|
|
354
|
+
outputs.push(makeOutput(`${folder}/${msg.name}/index.md`, fm, getSummary(body)));
|
|
355
|
+
}
|
|
356
|
+
function compileChannel(ch, outputs) {
|
|
357
|
+
const body = ch.body;
|
|
358
|
+
const fm = commonFrontmatter(ch.name, body);
|
|
359
|
+
const address = getAddress(body);
|
|
360
|
+
if (address)
|
|
361
|
+
fm.address = address;
|
|
362
|
+
const protocols = getProtocols(body);
|
|
363
|
+
if (protocols.length > 0)
|
|
364
|
+
fm.protocols = protocols;
|
|
365
|
+
const params = getParameters(body);
|
|
366
|
+
if (params.length > 0) {
|
|
367
|
+
fm.parameters = params.map((p) => {
|
|
368
|
+
const param = { name: p.name };
|
|
369
|
+
for (const prop of p.props) {
|
|
370
|
+
if (isParameterDescriptionProp(prop))
|
|
371
|
+
param.description = stripQuotes(prop.value);
|
|
372
|
+
if (isParameterDefaultProp(prop))
|
|
373
|
+
param.default = stripQuotes(prop.value);
|
|
374
|
+
if (isParameterEnumProp(prop))
|
|
375
|
+
param.enum = prop.value.items.map(stripQuotes);
|
|
376
|
+
if (isParameterExamplesProp(prop))
|
|
377
|
+
param.examples = prop.value.items.map(stripQuotes);
|
|
378
|
+
}
|
|
379
|
+
return param;
|
|
380
|
+
});
|
|
381
|
+
}
|
|
382
|
+
outputs.push(makeOutput(`channels/${ch.name}/index.md`, fm, getSummary(body)));
|
|
383
|
+
}
|
|
384
|
+
function compileContainer(cont, outputs) {
|
|
385
|
+
const body = cont.body;
|
|
386
|
+
const fm = commonFrontmatter(cont.name, body);
|
|
387
|
+
const ct = getContainerType(body);
|
|
388
|
+
if (ct)
|
|
389
|
+
fm.containerType = ct;
|
|
390
|
+
const tech = getTechnology(body);
|
|
391
|
+
if (tech)
|
|
392
|
+
fm.technology = tech;
|
|
393
|
+
const auth = getAuthoritative(body);
|
|
394
|
+
if (auth !== undefined)
|
|
395
|
+
fm.authoritative = auth;
|
|
396
|
+
const am = getAccessMode(body);
|
|
397
|
+
if (am)
|
|
398
|
+
fm.accessMode = am;
|
|
399
|
+
const cl = getClassification(body);
|
|
400
|
+
if (cl)
|
|
401
|
+
fm.classification = cl;
|
|
402
|
+
const res = getResidency(body);
|
|
403
|
+
if (res)
|
|
404
|
+
fm.residency = res;
|
|
405
|
+
const ret = getRetention(body);
|
|
406
|
+
if (ret)
|
|
407
|
+
fm.retention = ret;
|
|
408
|
+
outputs.push(makeOutput(`containers/${cont.name}/index.md`, fm, getSummary(body)));
|
|
409
|
+
}
|
|
410
|
+
function compileDataProduct(dp, outputs) {
|
|
411
|
+
const body = dp.body;
|
|
412
|
+
const fm = commonFrontmatter(dp.name, body);
|
|
413
|
+
const inputs = getInputs(body);
|
|
414
|
+
if (inputs.length > 0) {
|
|
415
|
+
fm.inputs = inputs.map((inp) => ({
|
|
416
|
+
id: inp.ref.name,
|
|
417
|
+
version: inp.ref.version,
|
|
418
|
+
}));
|
|
419
|
+
}
|
|
420
|
+
const outs = getOutputs(body);
|
|
421
|
+
if (outs.length > 0) {
|
|
422
|
+
fm.outputs = outs.map((out) => {
|
|
423
|
+
const o = { id: out.name };
|
|
424
|
+
if (out.contract) {
|
|
425
|
+
o.contract = {
|
|
426
|
+
path: stripQuotes(out.contract.path),
|
|
427
|
+
name: stripQuotes(out.contract.contractName),
|
|
428
|
+
...(out.contract.contractType
|
|
429
|
+
? { type: stripQuotes(out.contract.contractType) }
|
|
430
|
+
: {}),
|
|
431
|
+
};
|
|
432
|
+
}
|
|
433
|
+
return o;
|
|
434
|
+
});
|
|
435
|
+
}
|
|
436
|
+
outputs.push(makeOutput(`data-products/${dp.name}/index.md`, fm, getSummary(body)));
|
|
437
|
+
}
|
|
438
|
+
function compileFlow(flow, outputs) {
|
|
439
|
+
const body = flow.body;
|
|
440
|
+
const fm = commonFrontmatter(flow.name, body);
|
|
441
|
+
const entryChains = getFlowEntryChains(body);
|
|
442
|
+
const whenBlocks = getFlowWhenBlocks(body);
|
|
443
|
+
if (entryChains.length > 0 || whenBlocks.length > 0) {
|
|
444
|
+
const steps = compileFlowBody(entryChains, whenBlocks);
|
|
445
|
+
if (steps.length > 0) {
|
|
446
|
+
fm.steps = steps;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
outputs.push(makeOutput(`flows/${flow.name}/index.md`, fm, getSummary(body)));
|
|
450
|
+
}
|
|
451
|
+
function flowRefToStep(ref) {
|
|
452
|
+
return {
|
|
453
|
+
id: ref.name,
|
|
454
|
+
title: ref.label ? stripQuotes(ref.label) : ref.name,
|
|
455
|
+
};
|
|
456
|
+
}
|
|
457
|
+
function ensureStep(stepMap, nextMap, ref) {
|
|
458
|
+
if (!stepMap.has(ref.name)) {
|
|
459
|
+
stepMap.set(ref.name, flowRefToStep(ref));
|
|
460
|
+
}
|
|
461
|
+
if (!nextMap.has(ref.name)) {
|
|
462
|
+
nextMap.set(ref.name, []);
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
function addNext(nextMap, fromId, toId, label) {
|
|
466
|
+
const nexts = nextMap.get(fromId);
|
|
467
|
+
if (!nexts.some((n) => n.id === toId && n.label === label)) {
|
|
468
|
+
nexts.push({ id: toId, ...(label ? { label } : {}) });
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
function compileFlowBody(entryChains, whenBlocks) {
|
|
472
|
+
const stepMap = new Map();
|
|
473
|
+
const nextMap = new Map();
|
|
474
|
+
// Process entry chains (arrow sequences without 'when')
|
|
475
|
+
for (const chain of entryChains) {
|
|
476
|
+
const allRefs = [...chain.sources, ...chain.targets];
|
|
477
|
+
for (const ref of allRefs) {
|
|
478
|
+
ensureStep(stepMap, nextMap, ref);
|
|
479
|
+
}
|
|
480
|
+
const firstTarget = chain.targets[0];
|
|
481
|
+
if (firstTarget) {
|
|
482
|
+
for (const src of chain.sources) {
|
|
483
|
+
addNext(nextMap, src.name, firstTarget.name);
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
for (let i = 0; i < chain.targets.length - 1; i++) {
|
|
487
|
+
addNext(nextMap, chain.targets[i].name, chain.targets[i + 1].name);
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
// Process when blocks
|
|
491
|
+
for (const block of whenBlocks) {
|
|
492
|
+
// Ensure trigger refs exist
|
|
493
|
+
for (const trigger of block.triggers) {
|
|
494
|
+
ensureStep(stepMap, nextMap, trigger);
|
|
495
|
+
}
|
|
496
|
+
// Process each action in the when block
|
|
497
|
+
for (const action of block.actions) {
|
|
498
|
+
ensureStep(stepMap, nextMap, action.ref);
|
|
499
|
+
// Triggers connect to each action
|
|
500
|
+
for (const trigger of block.triggers) {
|
|
501
|
+
addNext(nextMap, trigger.name, action.ref.name);
|
|
502
|
+
}
|
|
503
|
+
// Action outputs (labeled or unlabeled)
|
|
504
|
+
for (const output of action.outputs) {
|
|
505
|
+
ensureStep(stepMap, nextMap, output.target);
|
|
506
|
+
addNext(nextMap, action.ref.name, output.target.name, output.label ? stripQuotes(output.label) : undefined);
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
// Build final steps array
|
|
511
|
+
const steps = [];
|
|
512
|
+
for (const [, step] of stepMap) {
|
|
513
|
+
const id = step.id;
|
|
514
|
+
const nexts = nextMap.get(id) || [];
|
|
515
|
+
if (nexts.length === 1 && !nexts[0].label) {
|
|
516
|
+
step.next_step = { id: nexts[0].id };
|
|
517
|
+
}
|
|
518
|
+
else if (nexts.length > 0) {
|
|
519
|
+
step.next_steps = nexts;
|
|
520
|
+
}
|
|
521
|
+
steps.push(step);
|
|
522
|
+
}
|
|
523
|
+
return steps;
|
|
524
|
+
}
|
|
525
|
+
function compileDiagram(diag, outputs) {
|
|
526
|
+
const body = diag.body;
|
|
527
|
+
const fm = commonFrontmatter(diag.name, body);
|
|
528
|
+
outputs.push(makeOutput(`diagrams/${diag.name}/index.md`, fm, getSummary(body)));
|
|
529
|
+
}
|
|
530
|
+
function compileUser(user, outputs) {
|
|
531
|
+
const fm = {
|
|
532
|
+
id: user.name,
|
|
533
|
+
name: user.name,
|
|
534
|
+
};
|
|
535
|
+
const annotations = [];
|
|
536
|
+
for (const prop of user.props) {
|
|
537
|
+
switch (prop.$type) {
|
|
538
|
+
case "UserNameProp":
|
|
539
|
+
fm.name = stripQuotes(prop.value);
|
|
540
|
+
break;
|
|
541
|
+
case "UserAvatarProp":
|
|
542
|
+
fm.avatar = stripQuotes(prop.value);
|
|
543
|
+
break;
|
|
544
|
+
case "UserRoleProp":
|
|
545
|
+
fm.role = stripQuotes(prop.value);
|
|
546
|
+
break;
|
|
547
|
+
case "UserEmailProp":
|
|
548
|
+
fm.email = stripQuotes(prop.value);
|
|
549
|
+
break;
|
|
550
|
+
case "UserSlackProp":
|
|
551
|
+
fm.slack = stripQuotes(prop.value);
|
|
552
|
+
break;
|
|
553
|
+
case "UserMsTeamsProp":
|
|
554
|
+
fm.msTeams = stripQuotes(prop.value);
|
|
555
|
+
break;
|
|
556
|
+
case "UserAnnotationProp":
|
|
557
|
+
annotations.push(prop.annotation);
|
|
558
|
+
break;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
const annFields = mapAnnotations(annotations);
|
|
562
|
+
Object.assign(fm, annFields);
|
|
563
|
+
outputs.push(makeOutput(`users/${user.name}.md`, fm));
|
|
564
|
+
}
|
|
565
|
+
function compileTeam(team, outputs) {
|
|
566
|
+
const fm = {
|
|
567
|
+
id: team.name,
|
|
568
|
+
name: team.name,
|
|
569
|
+
};
|
|
570
|
+
let summary;
|
|
571
|
+
const members = [];
|
|
572
|
+
const owns = [];
|
|
573
|
+
const annotations = [];
|
|
574
|
+
for (const prop of team.props) {
|
|
575
|
+
switch (prop.$type) {
|
|
576
|
+
case "TeamNameProp":
|
|
577
|
+
fm.name = stripQuotes(prop.value);
|
|
578
|
+
break;
|
|
579
|
+
case "TeamSummaryProp":
|
|
580
|
+
summary = stripQuotes(prop.value);
|
|
581
|
+
fm.summary = summary;
|
|
582
|
+
break;
|
|
583
|
+
case "TeamEmailProp":
|
|
584
|
+
fm.email = stripQuotes(prop.value);
|
|
585
|
+
break;
|
|
586
|
+
case "TeamSlackProp":
|
|
587
|
+
fm.slack = stripQuotes(prop.value);
|
|
588
|
+
break;
|
|
589
|
+
case "TeamMsTeamsProp":
|
|
590
|
+
fm.msTeams = stripQuotes(prop.value);
|
|
591
|
+
break;
|
|
592
|
+
case "TeamMemberProp":
|
|
593
|
+
members.push(prop.memberRef);
|
|
594
|
+
break;
|
|
595
|
+
case "TeamOwnsProp":
|
|
596
|
+
owns.push({ type: prop.owns.resourceType, id: prop.owns.resourceName });
|
|
597
|
+
break;
|
|
598
|
+
case "TeamAnnotationProp":
|
|
599
|
+
annotations.push(prop.annotation);
|
|
600
|
+
break;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
if (members.length > 0)
|
|
604
|
+
fm.members = members;
|
|
605
|
+
if (owns.length > 0)
|
|
606
|
+
fm.owns = owns;
|
|
607
|
+
const annFields = mapAnnotations(annotations);
|
|
608
|
+
Object.assign(fm, annFields);
|
|
609
|
+
outputs.push(makeOutput(`teams/${team.name}.md`, fm, summary));
|
|
610
|
+
}
|
|
611
|
+
function compileVisualizer(viz, outputs) {
|
|
612
|
+
// Visualizer wrapper does NOT produce its own markdown.
|
|
613
|
+
// Inline definitions inside it compile normally.
|
|
614
|
+
for (const item of viz.body) {
|
|
615
|
+
if (isDomainDef(item)) {
|
|
616
|
+
compileDomain(item, outputs);
|
|
617
|
+
continue;
|
|
618
|
+
}
|
|
619
|
+
if (isServiceDef(item)) {
|
|
620
|
+
compileService(item, outputs);
|
|
621
|
+
compileInlineMessages(item, outputs);
|
|
622
|
+
continue;
|
|
623
|
+
}
|
|
624
|
+
if (isEventDef(item) && item.body.length > 0) {
|
|
625
|
+
compileMessage(item, "events", outputs);
|
|
626
|
+
continue;
|
|
627
|
+
}
|
|
628
|
+
if (isCommandDef(item) && item.body.length > 0) {
|
|
629
|
+
compileMessage(item, "commands", outputs);
|
|
630
|
+
continue;
|
|
631
|
+
}
|
|
632
|
+
if (isQueryDef(item) && item.body.length > 0) {
|
|
633
|
+
compileMessage(item, "queries", outputs);
|
|
634
|
+
continue;
|
|
635
|
+
}
|
|
636
|
+
if (isChannelDef(item)) {
|
|
637
|
+
compileChannel(item, outputs);
|
|
638
|
+
continue;
|
|
639
|
+
}
|
|
640
|
+
if (isContainerDef(item)) {
|
|
641
|
+
compileContainer(item, outputs);
|
|
642
|
+
continue;
|
|
643
|
+
}
|
|
644
|
+
if (isDataProductDef(item)) {
|
|
645
|
+
compileDataProduct(item, outputs);
|
|
646
|
+
continue;
|
|
647
|
+
}
|
|
648
|
+
if (isFlowDef(item)) {
|
|
649
|
+
compileFlow(item, outputs);
|
|
650
|
+
continue;
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
//# sourceMappingURL=compiler.js.map
|