@derive-ltd/sysml-emitter 1.0.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/dist/emitters/connection-emitter.d.ts +4 -0
- package/dist/emitters/connection-emitter.d.ts.map +1 -0
- package/dist/emitters/connection-emitter.js +33 -0
- package/dist/emitters/connection-emitter.js.map +1 -0
- package/dist/emitters/constraint-emitter.d.ts +4 -0
- package/dist/emitters/constraint-emitter.d.ts.map +1 -0
- package/dist/emitters/constraint-emitter.js +22 -0
- package/dist/emitters/constraint-emitter.js.map +1 -0
- package/dist/emitters/hazard-emitter.d.ts +4 -0
- package/dist/emitters/hazard-emitter.d.ts.map +1 -0
- package/dist/emitters/hazard-emitter.js +28 -0
- package/dist/emitters/hazard-emitter.js.map +1 -0
- package/dist/emitters/interface-emitter.d.ts +4 -0
- package/dist/emitters/interface-emitter.d.ts.map +1 -0
- package/dist/emitters/interface-emitter.js +30 -0
- package/dist/emitters/interface-emitter.js.map +1 -0
- package/dist/emitters/package-emitter.d.ts +4 -0
- package/dist/emitters/package-emitter.d.ts.map +1 -0
- package/dist/emitters/package-emitter.js +12 -0
- package/dist/emitters/package-emitter.js.map +1 -0
- package/dist/emitters/part-emitter.d.ts +4 -0
- package/dist/emitters/part-emitter.d.ts.map +1 -0
- package/dist/emitters/part-emitter.js +70 -0
- package/dist/emitters/part-emitter.js.map +1 -0
- package/dist/emitters/requirement-emitter.d.ts +4 -0
- package/dist/emitters/requirement-emitter.d.ts.map +1 -0
- package/dist/emitters/requirement-emitter.js +68 -0
- package/dist/emitters/requirement-emitter.js.map +1 -0
- package/dist/emitters/stakeholder-emitter.d.ts +4 -0
- package/dist/emitters/stakeholder-emitter.d.ts.map +1 -0
- package/dist/emitters/stakeholder-emitter.js +22 -0
- package/dist/emitters/stakeholder-emitter.js.map +1 -0
- package/dist/emitters/state-emitter.d.ts +4 -0
- package/dist/emitters/state-emitter.d.ts.map +1 -0
- package/dist/emitters/state-emitter.js +38 -0
- package/dist/emitters/state-emitter.js.map +1 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/types.d.ts +52 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/identifier.d.ts +11 -0
- package/dist/utils/identifier.d.ts.map +1 -0
- package/dist/utils/identifier.js +31 -0
- package/dist/utils/identifier.js.map +1 -0
- package/dist/utils/indent.d.ts +5 -0
- package/dist/utils/indent.d.ts.map +1 -0
- package/dist/utils/indent.js +14 -0
- package/dist/utils/indent.js.map +1 -0
- package/dist/utils/parse-fact.d.ts +10 -0
- package/dist/utils/parse-fact.d.ts.map +1 -0
- package/dist/utils/parse-fact.js +51 -0
- package/dist/utils/parse-fact.js.map +1 -0
- package/package.json +20 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/connection-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,aAAa,EAAE,UAAU,EAAE,GAAG,MAAM,CA4BnE"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { toSysmlId, toLowerCamel } from '../utils/identifier.js';
|
|
2
|
+
import { parsePipeFact } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit connection definitions and port definitions from CONNECTS facts */
|
|
4
|
+
export function emitConnections(connectsFacts) {
|
|
5
|
+
if (connectsFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === Connections ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
for (const f of connectsFacts) {
|
|
11
|
+
const parsed = parsePipeFact(f.object);
|
|
12
|
+
const targetName = parsed.name || parsed.description || f.object.split('|')[0].trim();
|
|
13
|
+
const sourceId = toSysmlId(f.subject);
|
|
14
|
+
const targetId = toSysmlId(targetName);
|
|
15
|
+
const connId = `${sourceId}To${targetId}`;
|
|
16
|
+
const flowType = parsed.flowtype ?? parsed['flow-type'] ?? 'data';
|
|
17
|
+
const protocol = parsed.protocol;
|
|
18
|
+
const rate = parsed.rate;
|
|
19
|
+
lines.push(` connection def ${connId} {`);
|
|
20
|
+
lines.push(` end ${toLowerCamel(sourceId)} : ${sourceId};`);
|
|
21
|
+
lines.push(` end ${toLowerCamel(targetId)} : ${targetId};`);
|
|
22
|
+
if (flowType)
|
|
23
|
+
lines.push(` attribute flowType = "${flowType}";`);
|
|
24
|
+
if (protocol)
|
|
25
|
+
lines.push(` attribute protocol = "${protocol}";`);
|
|
26
|
+
if (rate)
|
|
27
|
+
lines.push(` attribute rate = "${rate}";`);
|
|
28
|
+
lines.push(` }`);
|
|
29
|
+
lines.push('');
|
|
30
|
+
}
|
|
31
|
+
return lines.join('\n');
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=connection-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"connection-emitter.js","sourceRoot":"","sources":["../../src/emitters/connection-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,2EAA2E;AAC3E,MAAM,UAAU,eAAe,CAAC,aAA2B;IACzD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE1C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC9B,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,UAAU,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACtF,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,SAAS,CAAC,UAAU,CAAC,CAAC;QACvC,MAAM,MAAM,GAAG,GAAG,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,IAAI,MAAM,CAAC,WAAW,CAAC,IAAI,MAAM,CAAC;QAClE,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;QAEzB,KAAK,CAAC,IAAI,CAAC,sBAAsB,MAAM,IAAI,CAAC,CAAC;QAC7C,KAAK,CAAC,IAAI,CAAC,eAAe,YAAY,CAAC,QAAQ,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;QACnE,KAAK,CAAC,IAAI,CAAC,eAAe,YAAY,CAAC,QAAQ,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC;QACnE,IAAI,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,iCAAiC,QAAQ,IAAI,CAAC,CAAC;QACxE,IAAI,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,iCAAiC,QAAQ,IAAI,CAAC,CAAC;QACxE,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,6BAA6B,IAAI,IAAI,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/constraint-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,4DAA4D;AAC5D,wBAAgB,eAAe,CAAC,eAAe,EAAE,UAAU,EAAE,GAAG,MAAM,CAoBrE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
import { parsePipeFact } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit constraint definitions from HAS_CONSTRAINT facts */
|
|
4
|
+
export function emitConstraints(constraintFacts) {
|
|
5
|
+
if (constraintFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === Constraints ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
for (const f of constraintFacts) {
|
|
11
|
+
const parsed = parsePipeFact(f.object);
|
|
12
|
+
const name = parsed.name || `Constraint${lines.length}`;
|
|
13
|
+
const desc = parsed.description || f.object;
|
|
14
|
+
const id = toSysmlId(name);
|
|
15
|
+
lines.push(` constraint def ${id} {`);
|
|
16
|
+
lines.push(` doc /* ${desc.replace(/\*\//g, '* /')} */`);
|
|
17
|
+
lines.push(` }`);
|
|
18
|
+
lines.push('');
|
|
19
|
+
}
|
|
20
|
+
return lines.join('\n');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=constraint-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constraint-emitter.js","sourceRoot":"","sources":["../../src/emitters/constraint-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,4DAA4D;AAC5D,MAAM,UAAU,eAAe,CAAC,eAA6B;IAC3D,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE5C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,aAAa,KAAK,CAAC,MAAM,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC;QAC5C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,sBAAsB,EAAE,IAAI,CAAC,CAAC;QACzC,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazard-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/hazard-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,qDAAqD;AACrD,wBAAgB,WAAW,CAAC,WAAW,EAAE,UAAU,EAAE,GAAG,MAAM,CAsB7D"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
import { parseHazard } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit concern definitions from HAS_HAZARD facts */
|
|
4
|
+
export function emitHazards(hazardFacts) {
|
|
5
|
+
if (hazardFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === Hazards ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
for (const f of hazardFacts) {
|
|
11
|
+
const h = parseHazard(f.subject, f.object);
|
|
12
|
+
const id = toSysmlId(h.id);
|
|
13
|
+
lines.push(` concern def ${id} {`);
|
|
14
|
+
lines.push(` doc /* ${h.description.replace(/\*\//g, '* /')} */`);
|
|
15
|
+
if (h.severity)
|
|
16
|
+
lines.push(` attribute severity = "${h.severity.toLowerCase()}";`);
|
|
17
|
+
if (h.frequency)
|
|
18
|
+
lines.push(` attribute frequency = "${h.frequency.toLowerCase()}";`);
|
|
19
|
+
if (h.sil)
|
|
20
|
+
lines.push(` attribute sil = ${h.sil};`);
|
|
21
|
+
if (h.safeState)
|
|
22
|
+
lines.push(` attribute safeState = "${h.safeState.replace(/"/g, '\\"')}";`);
|
|
23
|
+
lines.push(` }`);
|
|
24
|
+
lines.push('');
|
|
25
|
+
}
|
|
26
|
+
return lines.join('\n');
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=hazard-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hazard-emitter.js","sourceRoot":"","sources":["../../src/emitters/hazard-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAGrD,qDAAqD;AACrD,MAAM,UAAU,WAAW,CAAC,WAAyB;IACnD,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,wBAAwB,CAAC,CAAC;IACrC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,MAAM,CAAC,GAAG,WAAW,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC3C,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC;QACtC,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,WAAW,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QACzE,IAAI,CAAC,CAAC,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC1F,IAAI,CAAC,CAAC,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,SAAS,CAAC,WAAW,EAAE,IAAI,CAAC,CAAC;QAC7F,IAAI,CAAC,CAAC,GAAG;YAAE,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;QAC3D,IAAI,CAAC,CAAC,SAAS;YAAE,KAAK,CAAC,IAAI,CAAC,kCAAkC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACpG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/interface-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,4DAA4D;AAC5D,wBAAgB,cAAc,CAAC,cAAc,EAAE,UAAU,EAAE,GAAG,MAAM,CA0BnE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
import { parsePipeFact } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit interface definitions from INTERFACES_WITH facts */
|
|
4
|
+
export function emitInterfaces(interfaceFacts) {
|
|
5
|
+
if (interfaceFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === External Interfaces ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
for (const f of interfaceFacts) {
|
|
11
|
+
const parsed = parsePipeFact(f.object);
|
|
12
|
+
const extSystem = parsed.name || parsed.description || f.object.split(':')[0].trim();
|
|
13
|
+
const extId = toSysmlId(extSystem);
|
|
14
|
+
const desc = parsed.description || f.object;
|
|
15
|
+
const protocol = parsed.protocol;
|
|
16
|
+
const rate = parsed.rate ?? parsed.datarate;
|
|
17
|
+
lines.push(` interface def ${extId}Interface {`);
|
|
18
|
+
lines.push(` doc /* ${f.subject} interfaces with ${desc.replace(/\*\//g, '* /')} */`);
|
|
19
|
+
lines.push(` end system : ${toSysmlId(f.subject)};`);
|
|
20
|
+
lines.push(` end external : ${extId};`);
|
|
21
|
+
if (protocol)
|
|
22
|
+
lines.push(` attribute protocol = "${protocol}";`);
|
|
23
|
+
if (rate)
|
|
24
|
+
lines.push(` attribute dataRate = "${rate}";`);
|
|
25
|
+
lines.push(` }`);
|
|
26
|
+
lines.push('');
|
|
27
|
+
}
|
|
28
|
+
return lines.join('\n');
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=interface-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"interface-emitter.js","sourceRoot":"","sources":["../../src/emitters/interface-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,4DAA4D;AAC5D,MAAM,UAAU,cAAc,CAAC,cAA4B;IACzD,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE3C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,oCAAoC,CAAC,CAAC;IACjD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,cAAc,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,SAAS,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QACrF,MAAM,KAAK,GAAG,SAAS,CAAC,SAAS,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC;QAC5C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC;QACjC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,QAAQ,CAAC;QAE5C,KAAK,CAAC,IAAI,CAAC,qBAAqB,KAAK,aAAa,CAAC,CAAC;QACpD,KAAK,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,OAAO,oBAAoB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7F,KAAK,CAAC,IAAI,CAAC,wBAAwB,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC5D,KAAK,CAAC,IAAI,CAAC,0BAA0B,KAAK,GAAG,CAAC,CAAC;QAC/C,IAAI,QAAQ;YAAE,KAAK,CAAC,IAAI,CAAC,iCAAiC,QAAQ,IAAI,CAAC,CAAC;QACxE,IAAI,IAAI;YAAE,KAAK,CAAC,IAAI,CAAC,iCAAiC,IAAI,IAAI,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/package-emitter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,kDAAkD;AAClD,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQxE"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
/** Emit the top-level SysML v2 package wrapper */
|
|
3
|
+
export function emitPackage(project, body) {
|
|
4
|
+
const id = toSysmlId(project.name);
|
|
5
|
+
return `package ${id} {
|
|
6
|
+
doc /* Generated from Derive SE project ${project.slug} */
|
|
7
|
+
|
|
8
|
+
${body}
|
|
9
|
+
}
|
|
10
|
+
`;
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=package-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-emitter.js","sourceRoot":"","sources":["../../src/emitters/package-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,kDAAkD;AAClD,MAAM,UAAU,WAAW,CAAC,OAAsB,EAAE,IAAY;IAC9D,MAAM,EAAE,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;IACnC,OAAO,WAAW,EAAE;8CACwB,OAAO,CAAC,IAAI;;EAExD,IAAI;;CAEL,CAAC;AACF,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"part-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/part-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AA6C5D,8DAA8D;AAC9D,wBAAgB,SAAS,CAAC,WAAW,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,YAAY,EAAE,GAAG,MAAM,CAuCrF"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { toSysmlId, toLowerCamel } from '../utils/identifier.js';
|
|
2
|
+
/** Build a tree from PART_OF facts */
|
|
3
|
+
function buildTree(partOfFacts, entities) {
|
|
4
|
+
const entityMap = new Map(entities.map(e => [e.name.toLowerCase(), e]));
|
|
5
|
+
const childToParent = new Map();
|
|
6
|
+
const allNames = new Set();
|
|
7
|
+
for (const f of partOfFacts) {
|
|
8
|
+
childToParent.set(f.subject, f.object);
|
|
9
|
+
allNames.add(f.subject);
|
|
10
|
+
allNames.add(f.object);
|
|
11
|
+
}
|
|
12
|
+
// Find roots (parents that are not children of anything)
|
|
13
|
+
const roots = new Set();
|
|
14
|
+
for (const name of allNames) {
|
|
15
|
+
if (!childToParent.has(name))
|
|
16
|
+
roots.add(name);
|
|
17
|
+
}
|
|
18
|
+
// Build children map
|
|
19
|
+
const childrenMap = new Map();
|
|
20
|
+
for (const [child, parent] of childToParent) {
|
|
21
|
+
const list = childrenMap.get(parent) ?? [];
|
|
22
|
+
list.push(child);
|
|
23
|
+
childrenMap.set(parent, list);
|
|
24
|
+
}
|
|
25
|
+
function buildNode(name) {
|
|
26
|
+
return {
|
|
27
|
+
name,
|
|
28
|
+
children: (childrenMap.get(name) ?? []).map(buildNode),
|
|
29
|
+
entity: entityMap.get(name.toLowerCase()),
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return [...roots].map(buildNode);
|
|
33
|
+
}
|
|
34
|
+
/** Emit part definitions and usages from PART_OF hierarchy */
|
|
35
|
+
export function emitParts(partOfFacts, entities) {
|
|
36
|
+
if (partOfFacts.length === 0)
|
|
37
|
+
return '';
|
|
38
|
+
const trees = buildTree(partOfFacts, entities);
|
|
39
|
+
const lines = [];
|
|
40
|
+
const emitted = new Set();
|
|
41
|
+
function emitDef(node, level) {
|
|
42
|
+
const id = toSysmlId(node.name);
|
|
43
|
+
if (emitted.has(id))
|
|
44
|
+
return;
|
|
45
|
+
emitted.add(id);
|
|
46
|
+
// Emit child definitions first (bottom-up)
|
|
47
|
+
for (const child of node.children) {
|
|
48
|
+
emitDef(child, level);
|
|
49
|
+
}
|
|
50
|
+
// Emit this node's definition
|
|
51
|
+
const parts = node.children.map(c => {
|
|
52
|
+
const childId = toSysmlId(c.name);
|
|
53
|
+
const usageName = toLowerCamel(childId);
|
|
54
|
+
return ` part ${usageName} : ${childId};`;
|
|
55
|
+
});
|
|
56
|
+
lines.push(` part def ${id} {`);
|
|
57
|
+
if (parts.length > 0) {
|
|
58
|
+
lines.push(...parts);
|
|
59
|
+
}
|
|
60
|
+
lines.push(` }`);
|
|
61
|
+
lines.push('');
|
|
62
|
+
}
|
|
63
|
+
lines.push(' // === Part Definitions (structural decomposition) ===');
|
|
64
|
+
lines.push('');
|
|
65
|
+
for (const root of trees) {
|
|
66
|
+
emitDef(root, 1);
|
|
67
|
+
}
|
|
68
|
+
return lines.join('\n');
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=part-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"part-emitter.js","sourceRoot":"","sources":["../../src/emitters/part-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAUjE,sCAAsC;AACtC,SAAS,SAAS,CAAC,WAAyB,EAAE,QAAwB;IACpE,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACxE,MAAM,aAAa,GAAG,IAAI,GAAG,EAAkB,CAAC;IAChD,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAU,CAAC;IAEnC,KAAK,MAAM,CAAC,IAAI,WAAW,EAAE,CAAC;QAC5B,aAAa,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QACxB,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;IAED,yDAAyD;IACzD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAU,CAAC;IAChC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC,IAAI,CAAC;YAAE,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAChD,CAAC;IAED,qBAAqB;IACrB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAoB,CAAC;IAChD,KAAK,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,IAAI,aAAa,EAAE,CAAC;QAC5C,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACjB,WAAW,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;IAChC,CAAC;IAED,SAAS,SAAS,CAAC,IAAY;QAC7B,OAAO;YACL,IAAI;YACJ,QAAQ,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC;YACtD,MAAM,EAAE,SAAS,CAAC,GAAG,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;SAC1C,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;AACnC,CAAC;AAED,8DAA8D;AAC9D,MAAM,UAAU,SAAS,CAAC,WAAyB,EAAE,QAAwB;IAC3E,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAExC,MAAM,KAAK,GAAG,SAAS,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;IAC/C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,SAAS,OAAO,CAAC,IAAc,EAAE,KAAa;QAC5C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAChC,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAAE,OAAO;QAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,2CAA2C;QAC3C,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAClC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACxB,CAAC;QAED,8BAA8B;QAC9B,MAAM,KAAK,GAAG,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE;YAClC,MAAM,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAClC,MAAM,SAAS,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;YACxC,OAAO,gBAAgB,SAAS,MAAM,OAAO,GAAG,CAAC;QACnD,CAAC,CAAC,CAAC;QAEH,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC,CAAC;QACvB,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,4DAA4D,CAAC,CAAC;IACzE,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DeriveRequirement, DeriveTraceLink } from '../types.js';
|
|
2
|
+
/** Emit requirement definitions and trace relationships */
|
|
3
|
+
export declare function emitRequirements(requirements: DeriveRequirement[], traceLinks: DeriveTraceLink[]): string;
|
|
4
|
+
//# sourceMappingURL=requirement-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/requirement-emitter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAWtE,2DAA2D;AAC3D,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,iBAAiB,EAAE,EACjC,UAAU,EAAE,eAAe,EAAE,GAC5B,MAAM,CAgER"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import { refToId } from '../utils/identifier.js';
|
|
2
|
+
const DOC_LABELS = {
|
|
3
|
+
'stakeholder-requirements': 'Stakeholder Requirements',
|
|
4
|
+
'system-requirements': 'System Requirements',
|
|
5
|
+
'subsystem-requirements': 'Subsystem Requirements',
|
|
6
|
+
'interface-requirements': 'Interface Requirements',
|
|
7
|
+
'verification-requirements': 'Verification Requirements',
|
|
8
|
+
'architecture-decisions': 'Architecture Decisions',
|
|
9
|
+
};
|
|
10
|
+
/** Emit requirement definitions and trace relationships */
|
|
11
|
+
export function emitRequirements(requirements, traceLinks) {
|
|
12
|
+
if (requirements.length === 0)
|
|
13
|
+
return '';
|
|
14
|
+
const lines = [];
|
|
15
|
+
// Group by document type
|
|
16
|
+
const byDoc = new Map();
|
|
17
|
+
for (const r of requirements) {
|
|
18
|
+
const list = byDoc.get(r.document) ?? [];
|
|
19
|
+
list.push(r);
|
|
20
|
+
byDoc.set(r.document, list);
|
|
21
|
+
}
|
|
22
|
+
// Emit requirement definitions grouped by document
|
|
23
|
+
for (const [doc, reqs] of byDoc) {
|
|
24
|
+
const label = DOC_LABELS[doc] ?? doc;
|
|
25
|
+
lines.push(` // --- ${label} ---`);
|
|
26
|
+
lines.push('');
|
|
27
|
+
for (const r of reqs) {
|
|
28
|
+
const id = refToId(r.ref);
|
|
29
|
+
const escapedText = r.text.replace(/\*\//g, '* /');
|
|
30
|
+
lines.push(` requirement def ${id} {`);
|
|
31
|
+
lines.push(` doc /* ${r.ref}: ${escapedText} */`);
|
|
32
|
+
if (r.verification) {
|
|
33
|
+
lines.push(` attribute verificationMethod = "${r.verification}";`);
|
|
34
|
+
}
|
|
35
|
+
if (r.rationale) {
|
|
36
|
+
const escapedRationale = r.rationale.replace(/\*\//g, '* /').slice(0, 200);
|
|
37
|
+
lines.push(` attribute rationale = "${escapedRationale}";`);
|
|
38
|
+
}
|
|
39
|
+
// SIL tag
|
|
40
|
+
const silTag = r.tags?.find(t => /^sil-\d$/.test(t));
|
|
41
|
+
if (silTag) {
|
|
42
|
+
lines.push(` attribute sil = ${silTag.replace('sil-', '')};`);
|
|
43
|
+
}
|
|
44
|
+
lines.push(` }`);
|
|
45
|
+
lines.push('');
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Emit trace links
|
|
49
|
+
const derives = traceLinks.filter(l => l.type === 'derives');
|
|
50
|
+
const verifies = traceLinks.filter(l => l.type === 'verifies');
|
|
51
|
+
if (derives.length > 0 || verifies.length > 0) {
|
|
52
|
+
lines.push(' // === Traceability ===');
|
|
53
|
+
lines.push('');
|
|
54
|
+
for (const l of derives) {
|
|
55
|
+
const targetId = refToId(l.target);
|
|
56
|
+
const sourceId = refToId(l.source);
|
|
57
|
+
lines.push(` dependency derive ${targetId} from ${sourceId};`);
|
|
58
|
+
}
|
|
59
|
+
for (const l of verifies) {
|
|
60
|
+
const sourceId = refToId(l.source);
|
|
61
|
+
const targetId = refToId(l.target);
|
|
62
|
+
lines.push(` dependency verify ${targetId} by ${sourceId};`);
|
|
63
|
+
}
|
|
64
|
+
lines.push('');
|
|
65
|
+
}
|
|
66
|
+
return lines.join('\n');
|
|
67
|
+
}
|
|
68
|
+
//# sourceMappingURL=requirement-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"requirement-emitter.js","sourceRoot":"","sources":["../../src/emitters/requirement-emitter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stakeholder-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/stakeholder-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,gBAAgB,EAAE,UAAU,EAAE,GAAG,MAAM,CAoBvE"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
import { parsePipeFact } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit stakeholder/actor definitions from HAS_STAKEHOLDER facts */
|
|
4
|
+
export function emitStakeholders(stakeholderFacts) {
|
|
5
|
+
if (stakeholderFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === Stakeholders ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
for (const f of stakeholderFacts) {
|
|
11
|
+
const parsed = parsePipeFact(f.object);
|
|
12
|
+
const role = parsed.name || f.object.split(':')[0].trim();
|
|
13
|
+
const desc = parsed.description || f.object;
|
|
14
|
+
const id = toSysmlId(role);
|
|
15
|
+
lines.push(` part def ${id} {`);
|
|
16
|
+
lines.push(` doc /* ${desc.replace(/\*\//g, '* /')} */`);
|
|
17
|
+
lines.push(` }`);
|
|
18
|
+
lines.push('');
|
|
19
|
+
}
|
|
20
|
+
return lines.join('\n');
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=stakeholder-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"stakeholder-emitter.js","sourceRoot":"","sources":["../../src/emitters/stakeholder-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAGvD,oEAAoE;AACpE,MAAM,UAAU,gBAAgB,CAAC,gBAA8B;IAC7D,IAAI,gBAAgB,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAE7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,6BAA6B,CAAC,CAAC;IAC1C,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,KAAK,MAAM,CAAC,IAAI,gBAAgB,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,IAAI,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC1D,MAAM,IAAI,GAAG,MAAM,CAAC,WAAW,IAAI,CAAC,CAAC,MAAM,CAAC;QAC5C,MAAM,EAAE,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;QAE3B,KAAK,CAAC,IAAI,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC;QACnC,KAAK,CAAC,IAAI,CAAC,kBAAkB,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DeriveFact } from '../types.js';
|
|
2
|
+
/** Emit state machine definition from HAS_MODE and MODE_TRANSITION facts */
|
|
3
|
+
export declare function emitStateMachine(modeFacts: DeriveFact[], transitionFacts: DeriveFact[], systemName: string): string;
|
|
4
|
+
//# sourceMappingURL=state-emitter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-emitter.d.ts","sourceRoot":"","sources":["../../src/emitters/state-emitter.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,4EAA4E;AAC5E,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,UAAU,EAAE,EACvB,eAAe,EAAE,UAAU,EAAE,EAC7B,UAAU,EAAE,MAAM,GACjB,MAAM,CAoCR"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { toSysmlId } from '../utils/identifier.js';
|
|
2
|
+
import { parseTransition } from '../utils/parse-fact.js';
|
|
3
|
+
/** Emit state machine definition from HAS_MODE and MODE_TRANSITION facts */
|
|
4
|
+
export function emitStateMachine(modeFacts, transitionFacts, systemName) {
|
|
5
|
+
if (modeFacts.length === 0)
|
|
6
|
+
return '';
|
|
7
|
+
const lines = [];
|
|
8
|
+
lines.push(' // === Operating Modes (State Machine) ===');
|
|
9
|
+
lines.push('');
|
|
10
|
+
lines.push(` state def ${toSysmlId(systemName)}Modes {`);
|
|
11
|
+
// Emit states
|
|
12
|
+
for (const f of modeFacts) {
|
|
13
|
+
const modeName = f.object.split(':')[0].trim();
|
|
14
|
+
const modeId = toSysmlId(modeName);
|
|
15
|
+
const desc = f.object.includes(':') ? f.object.split(':').slice(1).join(':').trim() : '';
|
|
16
|
+
lines.push(` state ${modeId};`);
|
|
17
|
+
}
|
|
18
|
+
lines.push('');
|
|
19
|
+
// Emit transitions
|
|
20
|
+
for (const f of transitionFacts) {
|
|
21
|
+
const t = parseTransition(f.subject, f.object);
|
|
22
|
+
const sourceId = toSysmlId(t.sourceMode);
|
|
23
|
+
const targetId = toSysmlId(t.targetMode);
|
|
24
|
+
const attrs = [];
|
|
25
|
+
if (t.trigger)
|
|
26
|
+
attrs.push(`trigger: ${t.trigger}`);
|
|
27
|
+
if (t.guard)
|
|
28
|
+
attrs.push(`guard: ${t.guard}`);
|
|
29
|
+
if (t.timing)
|
|
30
|
+
attrs.push(`timing: ${t.timing}ms`);
|
|
31
|
+
const comment = attrs.length > 0 ? ` /* ${attrs.join(', ')} */` : '';
|
|
32
|
+
lines.push(` transition ${sourceId} to ${targetId};${comment}`);
|
|
33
|
+
}
|
|
34
|
+
lines.push(` }`);
|
|
35
|
+
lines.push('');
|
|
36
|
+
return lines.join('\n');
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=state-emitter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"state-emitter.js","sourceRoot":"","sources":["../../src/emitters/state-emitter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAGzD,4EAA4E;AAC5E,MAAM,UAAU,gBAAgB,CAC9B,SAAuB,EACvB,eAA6B,EAC7B,UAAkB;IAElB,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IAEtC,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,gDAAgD,CAAC,CAAC;IAC7D,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,iBAAiB,SAAS,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;IAE5D,cAAc;IACd,KAAK,MAAM,CAAC,IAAI,SAAS,EAAE,CAAC;QAC1B,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC/C,MAAM,MAAM,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QACzF,KAAK,CAAC,IAAI,CAAC,iBAAiB,MAAM,GAAG,CAAC,CAAC;IACzC,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,mBAAmB;IACnB,KAAK,MAAM,CAAC,IAAI,eAAe,EAAE,CAAC;QAChC,MAAM,CAAC,GAAG,eAAe,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC;QAC/C,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;QACzC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,OAAO;YAAE,KAAK,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;QACnD,IAAI,CAAC,CAAC,KAAK;YAAE,KAAK,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;QAC7C,IAAI,CAAC,CAAC,MAAM;YAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC;QAElD,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QACrE,KAAK,CAAC,IAAI,CAAC,sBAAsB,QAAQ,OAAO,QAAQ,IAAI,OAAO,EAAE,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACpB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type { DeriveProject, DeriveRequirement, DeriveTraceLink, DeriveFact, DeriveEntity, ParsedHazard, ParsedTransition } from './types.js';
|
|
2
|
+
export { toSysmlId, refToId, toLowerCamel } from './utils/identifier.js';
|
|
3
|
+
export { parsePipeFact, parseHazard, parseTransition } from './utils/parse-fact.js';
|
|
4
|
+
import type { DeriveProject } from './types.js';
|
|
5
|
+
/**
|
|
6
|
+
* Emit a complete SysML v2 package from a Derive project.
|
|
7
|
+
* Pure function: data in, .sysml text out.
|
|
8
|
+
*/
|
|
9
|
+
export declare function emitProject(project: DeriveProject): string;
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,YAAY,EAAE,aAAa,EAAE,iBAAiB,EAAE,eAAe,EAAE,UAAU,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9I,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACzE,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAEpF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAgBhD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,aAAa,GAAG,MAAM,CAwC1D"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export { toSysmlId, refToId, toLowerCamel } from './utils/identifier.js';
|
|
2
|
+
export { parsePipeFact, parseHazard, parseTransition } from './utils/parse-fact.js';
|
|
3
|
+
import { emitPackage } from './emitters/package-emitter.js';
|
|
4
|
+
import { emitParts } from './emitters/part-emitter.js';
|
|
5
|
+
import { emitRequirements } from './emitters/requirement-emitter.js';
|
|
6
|
+
import { emitConnections } from './emitters/connection-emitter.js';
|
|
7
|
+
import { emitStateMachine } from './emitters/state-emitter.js';
|
|
8
|
+
import { emitHazards } from './emitters/hazard-emitter.js';
|
|
9
|
+
import { emitConstraints } from './emitters/constraint-emitter.js';
|
|
10
|
+
import { emitInterfaces } from './emitters/interface-emitter.js';
|
|
11
|
+
import { emitStakeholders } from './emitters/stakeholder-emitter.js';
|
|
12
|
+
/** Filter facts by predicate */
|
|
13
|
+
function factsOf(facts, predicate) {
|
|
14
|
+
return facts.filter(f => f.predicate === predicate);
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Emit a complete SysML v2 package from a Derive project.
|
|
18
|
+
* Pure function: data in, .sysml text out.
|
|
19
|
+
*/
|
|
20
|
+
export function emitProject(project) {
|
|
21
|
+
const sections = [];
|
|
22
|
+
// Stakeholders
|
|
23
|
+
const stakeholders = emitStakeholders(factsOf(project.facts, 'HAS_STAKEHOLDER'));
|
|
24
|
+
if (stakeholders)
|
|
25
|
+
sections.push(stakeholders);
|
|
26
|
+
// Part definitions (structural decomposition)
|
|
27
|
+
const parts = emitParts(factsOf(project.facts, 'PART_OF'), project.entities);
|
|
28
|
+
if (parts)
|
|
29
|
+
sections.push(parts);
|
|
30
|
+
// Connections
|
|
31
|
+
const connections = emitConnections(factsOf(project.facts, 'CONNECTS'));
|
|
32
|
+
if (connections)
|
|
33
|
+
sections.push(connections);
|
|
34
|
+
// External interfaces
|
|
35
|
+
const interfaces = emitInterfaces(factsOf(project.facts, 'INTERFACES_WITH'));
|
|
36
|
+
if (interfaces)
|
|
37
|
+
sections.push(interfaces);
|
|
38
|
+
// Requirements + traceability
|
|
39
|
+
const reqs = emitRequirements(project.requirements, project.traceLinks);
|
|
40
|
+
if (reqs)
|
|
41
|
+
sections.push(reqs);
|
|
42
|
+
// State machine
|
|
43
|
+
const states = emitStateMachine(factsOf(project.facts, 'HAS_MODE'), factsOf(project.facts, 'MODE_TRANSITION'), project.name);
|
|
44
|
+
if (states)
|
|
45
|
+
sections.push(states);
|
|
46
|
+
// Hazards
|
|
47
|
+
const hazards = emitHazards(factsOf(project.facts, 'HAS_HAZARD'));
|
|
48
|
+
if (hazards)
|
|
49
|
+
sections.push(hazards);
|
|
50
|
+
// Constraints
|
|
51
|
+
const constraints = emitConstraints(factsOf(project.facts, 'HAS_CONSTRAINT'));
|
|
52
|
+
if (constraints)
|
|
53
|
+
sections.push(constraints);
|
|
54
|
+
return emitPackage(project, sections.join('\n'));
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/** Input types matching Derive MCP tool outputs */
|
|
2
|
+
export interface DeriveProject {
|
|
3
|
+
slug: string;
|
|
4
|
+
name: string;
|
|
5
|
+
requirements: DeriveRequirement[];
|
|
6
|
+
traceLinks: DeriveTraceLink[];
|
|
7
|
+
facts: DeriveFact[];
|
|
8
|
+
entities: DeriveEntity[];
|
|
9
|
+
}
|
|
10
|
+
export interface DeriveRequirement {
|
|
11
|
+
ref: string;
|
|
12
|
+
text: string;
|
|
13
|
+
rationale?: string;
|
|
14
|
+
verification?: string;
|
|
15
|
+
document: string;
|
|
16
|
+
tags?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface DeriveTraceLink {
|
|
19
|
+
source: string;
|
|
20
|
+
target: string;
|
|
21
|
+
type: 'derives' | 'verifies';
|
|
22
|
+
description?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface DeriveFact {
|
|
25
|
+
subject: string;
|
|
26
|
+
predicate: string;
|
|
27
|
+
object: string;
|
|
28
|
+
}
|
|
29
|
+
export interface DeriveEntity {
|
|
30
|
+
name: string;
|
|
31
|
+
hexCode?: string;
|
|
32
|
+
namespace?: string;
|
|
33
|
+
}
|
|
34
|
+
/** Parsed hazard from pipe-delimited HAS_HAZARD fact object */
|
|
35
|
+
export interface ParsedHazard {
|
|
36
|
+
id: string;
|
|
37
|
+
description: string;
|
|
38
|
+
severity?: string;
|
|
39
|
+
frequency?: string;
|
|
40
|
+
sil?: string;
|
|
41
|
+
safeState?: string;
|
|
42
|
+
}
|
|
43
|
+
/** Parsed mode transition from MODE_TRANSITION fact */
|
|
44
|
+
export interface ParsedTransition {
|
|
45
|
+
sourceMode: string;
|
|
46
|
+
targetMode: string;
|
|
47
|
+
trigger?: string;
|
|
48
|
+
guard?: string;
|
|
49
|
+
timing?: string;
|
|
50
|
+
sil?: string;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mDAAmD;AAEnD,MAAM,WAAW,aAAa;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,UAAU,EAAE,eAAe,EAAE,CAAC;IAC9B,KAAK,EAAE,UAAU,EAAE,CAAC;IACpB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,iBAAiB;IAChC,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,SAAS,GAAG,UAAU,CAAC;IAC7B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,+DAA+D;AAC/D,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,uDAAuD;AACvD,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,mDAAmD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a human-readable name to a valid SysML v2 identifier.
|
|
3
|
+
* SysML identifiers must start with a letter or underscore and contain
|
|
4
|
+
* only letters, digits, and underscores. We use PascalCase.
|
|
5
|
+
*/
|
|
6
|
+
export declare function toSysmlId(name: string): string;
|
|
7
|
+
/** Convert a requirement ref like "SYS-REQ-001" to a SysML identifier like "SysReq001" */
|
|
8
|
+
export declare function refToId(ref: string): string;
|
|
9
|
+
/** Lowercase first character (for usage names) */
|
|
10
|
+
export declare function toLowerCamel(id: string): string;
|
|
11
|
+
//# sourceMappingURL=identifier.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifier.d.ts","sourceRoot":"","sources":["../../src/utils/identifier.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAO9C;AAED,0FAA0F;AAC1F,wBAAgB,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS3C;AAED,kDAAkD;AAClD,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM,CAE/C"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convert a human-readable name to a valid SysML v2 identifier.
|
|
3
|
+
* SysML identifiers must start with a letter or underscore and contain
|
|
4
|
+
* only letters, digits, and underscores. We use PascalCase.
|
|
5
|
+
*/
|
|
6
|
+
export function toSysmlId(name) {
|
|
7
|
+
return name
|
|
8
|
+
.replace(/[^a-zA-Z0-9\s]/g, '')
|
|
9
|
+
.split(/\s+/)
|
|
10
|
+
.filter(Boolean)
|
|
11
|
+
.map(w => w.charAt(0).toUpperCase() + w.slice(1).toLowerCase())
|
|
12
|
+
.join('');
|
|
13
|
+
}
|
|
14
|
+
/** Convert a requirement ref like "SYS-REQ-001" to a SysML identifier like "SysReq001" */
|
|
15
|
+
export function refToId(ref) {
|
|
16
|
+
return ref
|
|
17
|
+
.split('-')
|
|
18
|
+
.map((part, i) => {
|
|
19
|
+
if (i === 0)
|
|
20
|
+
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
21
|
+
if (/^\d+$/.test(part))
|
|
22
|
+
return part;
|
|
23
|
+
return part.charAt(0).toUpperCase() + part.slice(1).toLowerCase();
|
|
24
|
+
})
|
|
25
|
+
.join('');
|
|
26
|
+
}
|
|
27
|
+
/** Lowercase first character (for usage names) */
|
|
28
|
+
export function toLowerCamel(id) {
|
|
29
|
+
return id.charAt(0).toLowerCase() + id.slice(1);
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=identifier.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"identifier.js","sourceRoot":"","sources":["../../src/utils/identifier.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,IAAI;SACR,OAAO,CAAC,iBAAiB,EAAE,EAAE,CAAC;SAC9B,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,OAAO,CAAC;SACf,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;SAC9D,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,0FAA0F;AAC1F,MAAM,UAAU,OAAO,CAAC,GAAW;IACjC,OAAO,GAAG;SACP,KAAK,CAAC,GAAG,CAAC;SACV,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QACf,IAAI,CAAC,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;QAC/E,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;IACpE,CAAC,CAAC;SACD,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,YAAY,CAAC,EAAU;IACrC,OAAO,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,EAAE,GAAG,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
/** Indent every line by N levels (4 spaces each) */
|
|
2
|
+
export declare function indent(text: string, level: number): string;
|
|
3
|
+
/** Wrap text as a SysML doc comment */
|
|
4
|
+
export declare function docComment(text: string, level: number): string;
|
|
5
|
+
//# sourceMappingURL=indent.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indent.d.ts","sourceRoot":"","sources":["../../src/utils/indent.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,wBAAgB,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,uCAAuC;AACvC,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAG9D"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** Indent every line by N levels (4 spaces each) */
|
|
2
|
+
export function indent(text, level) {
|
|
3
|
+
const prefix = ' '.repeat(level);
|
|
4
|
+
return text
|
|
5
|
+
.split('\n')
|
|
6
|
+
.map(line => (line.trim() ? prefix + line : ''))
|
|
7
|
+
.join('\n');
|
|
8
|
+
}
|
|
9
|
+
/** Wrap text as a SysML doc comment */
|
|
10
|
+
export function docComment(text, level) {
|
|
11
|
+
const prefix = ' '.repeat(level);
|
|
12
|
+
return `${prefix}doc /* ${text.replace(/\*\//g, '* /')} */`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=indent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"indent.js","sourceRoot":"","sources":["../../src/utils/indent.ts"],"names":[],"mappings":"AAAA,oDAAoD;AACpD,MAAM,UAAU,MAAM,CAAC,IAAY,EAAE,KAAa;IAChD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,IAAI;SACR,KAAK,CAAC,IAAI,CAAC;SACX,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;SAC/C,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC;AAED,uCAAuC;AACvC,MAAM,UAAU,UAAU,CAAC,IAAY,EAAE,KAAa;IACpD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACpC,OAAO,GAAG,MAAM,UAAU,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC;AAC9D,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ParsedHazard, ParsedTransition } from '../types.js';
|
|
2
|
+
/** Parse a pipe-delimited fact object into key-value pairs.
|
|
3
|
+
* Format: "Primary: description | key1:value1 | key2:value2"
|
|
4
|
+
*/
|
|
5
|
+
export declare function parsePipeFact(object: string): Record<string, string>;
|
|
6
|
+
/** Parse a HAS_HAZARD fact object */
|
|
7
|
+
export declare function parseHazard(subject: string, object: string): ParsedHazard;
|
|
8
|
+
/** Parse a MODE_TRANSITION fact object */
|
|
9
|
+
export declare function parseTransition(sourceMode: string, object: string): ParsedTransition;
|
|
10
|
+
//# sourceMappingURL=parse-fact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-fact.d.ts","sourceRoot":"","sources":["../../src/utils/parse-fact.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAElE;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAqBpE;AAED,qCAAqC;AACrC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,YAAY,CAUzE;AAED,0CAA0C;AAC1C,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,gBAAgB,CAUpF"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/** Parse a pipe-delimited fact object into key-value pairs.
|
|
2
|
+
* Format: "Primary: description | key1:value1 | key2:value2"
|
|
3
|
+
*/
|
|
4
|
+
export function parsePipeFact(object) {
|
|
5
|
+
const result = {};
|
|
6
|
+
const parts = object.split('|').map(p => p.trim());
|
|
7
|
+
if (parts.length > 0) {
|
|
8
|
+
const [name, ...descParts] = parts[0].split(':');
|
|
9
|
+
if (descParts.length > 0) {
|
|
10
|
+
result.name = name.trim();
|
|
11
|
+
result.description = descParts.join(':').trim();
|
|
12
|
+
}
|
|
13
|
+
else {
|
|
14
|
+
result.description = parts[0];
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
for (let i = 1; i < parts.length; i++) {
|
|
18
|
+
const colonIdx = parts[i].indexOf(':');
|
|
19
|
+
if (colonIdx > 0) {
|
|
20
|
+
const key = parts[i].slice(0, colonIdx).trim().replace(/-/g, '');
|
|
21
|
+
const val = parts[i].slice(colonIdx + 1).trim();
|
|
22
|
+
result[key] = val;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return result;
|
|
26
|
+
}
|
|
27
|
+
/** Parse a HAS_HAZARD fact object */
|
|
28
|
+
export function parseHazard(subject, object) {
|
|
29
|
+
const p = parsePipeFact(object);
|
|
30
|
+
return {
|
|
31
|
+
id: p.name ?? subject,
|
|
32
|
+
description: p.description ?? object,
|
|
33
|
+
severity: p.severity,
|
|
34
|
+
frequency: p.frequency,
|
|
35
|
+
sil: p.SIL ?? p.sil,
|
|
36
|
+
safeState: p.safestate ?? p['safe-state'] ?? p.safeState,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Parse a MODE_TRANSITION fact object */
|
|
40
|
+
export function parseTransition(sourceMode, object) {
|
|
41
|
+
const p = parsePipeFact(object);
|
|
42
|
+
return {
|
|
43
|
+
sourceMode,
|
|
44
|
+
targetMode: p.name ?? p.description ?? object.split('|')[0].trim(),
|
|
45
|
+
trigger: p.trigger,
|
|
46
|
+
guard: p.guard,
|
|
47
|
+
timing: p.timing,
|
|
48
|
+
sil: p.SIL ?? p.sil,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=parse-fact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-fact.js","sourceRoot":"","sources":["../../src/utils/parse-fact.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc;IAC1C,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;IACnD,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,CAAC,IAAI,EAAE,GAAG,SAAS,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QACjD,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB,MAAM,CAAC,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;YAC1B,MAAM,CAAC,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;QAClD,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,WAAW,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAChC,CAAC;IACH,CAAC;IACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACvC,IAAI,QAAQ,GAAG,CAAC,EAAE,CAAC;YACjB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;YACjE,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAChD,MAAM,CAAC,GAAG,CAAC,GAAG,GAAG,CAAC;QACpB,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,qCAAqC;AACrC,MAAM,UAAU,WAAW,CAAC,OAAe,EAAE,MAAc;IACzD,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,OAAO;QACrB,WAAW,EAAE,CAAC,CAAC,WAAW,IAAI,MAAM;QACpC,QAAQ,EAAE,CAAC,CAAC,QAAQ;QACpB,SAAS,EAAE,CAAC,CAAC,SAAS;QACtB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG;QACnB,SAAS,EAAE,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC,SAAS;KACzD,CAAC;AACJ,CAAC;AAED,0CAA0C;AAC1C,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,MAAc;IAChE,MAAM,CAAC,GAAG,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,OAAO;QACL,UAAU;QACV,UAAU,EAAE,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,WAAW,IAAI,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAClE,OAAO,EAAE,CAAC,CAAC,OAAO;QAClB,KAAK,EAAE,CAAC,CAAC,KAAK;QACd,MAAM,EAAE,CAAC,CAAC,MAAM;QAChB,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG;KACpB,CAAC;AACJ,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@derive-ltd/sysml-emitter",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Derive project → SysML v2 textual notation emitter (a DERIVE LTD product).",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist"
|
|
10
|
+
],
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "node --test dist/test/*.test.js"
|
|
14
|
+
},
|
|
15
|
+
"license": "MIT",
|
|
16
|
+
"author": "DERIVE LTD",
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"typescript": "^5.9.3"
|
|
19
|
+
}
|
|
20
|
+
}
|