@documentation-robotics/cli 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.
Files changed (169) hide show
  1. package/PYTHON_CLI_PARITY.md +265 -0
  2. package/PYTHON_CLI_STRUCTURE_UPDATE.md +246 -0
  3. package/README.md +926 -0
  4. package/biome.json +42 -0
  5. package/bunfig.toml +3 -0
  6. package/dist/ai/claude-client.js +71 -0
  7. package/dist/ai/claude-client.js.map +7 -0
  8. package/dist/ai/context-provider.js +129 -0
  9. package/dist/ai/context-provider.js.map +7 -0
  10. package/dist/ai/tools.js +231 -0
  11. package/dist/ai/tools.js.map +7 -0
  12. package/dist/cli.js +224 -0
  13. package/dist/cli.js.map +7 -0
  14. package/dist/commands/add.js +51 -0
  15. package/dist/commands/add.js.map +7 -0
  16. package/dist/commands/changeset.js +174 -0
  17. package/dist/commands/changeset.js.map +7 -0
  18. package/dist/commands/chat.js +111 -0
  19. package/dist/commands/chat.js.map +7 -0
  20. package/dist/commands/conformance.js +132 -0
  21. package/dist/commands/conformance.js.map +7 -0
  22. package/dist/commands/delete.js +31 -0
  23. package/dist/commands/delete.js.map +7 -0
  24. package/dist/commands/element.js +28 -0
  25. package/dist/commands/element.js.map +7 -0
  26. package/dist/commands/export.js +65 -0
  27. package/dist/commands/export.js.map +7 -0
  28. package/dist/commands/info.js +40 -0
  29. package/dist/commands/info.js.map +7 -0
  30. package/dist/commands/init.js +45 -0
  31. package/dist/commands/init.js.map +7 -0
  32. package/dist/commands/list.js +32 -0
  33. package/dist/commands/list.js.map +7 -0
  34. package/dist/commands/migrate.js +36 -0
  35. package/dist/commands/migrate.js.map +7 -0
  36. package/dist/commands/project.js +74 -0
  37. package/dist/commands/project.js.map +7 -0
  38. package/dist/commands/relationship.js +118 -0
  39. package/dist/commands/relationship.js.map +7 -0
  40. package/dist/commands/search.js +48 -0
  41. package/dist/commands/search.js.map +7 -0
  42. package/dist/commands/show.js +38 -0
  43. package/dist/commands/show.js.map +7 -0
  44. package/dist/commands/trace.js +60 -0
  45. package/dist/commands/trace.js.map +7 -0
  46. package/dist/commands/update.js +37 -0
  47. package/dist/commands/update.js.map +7 -0
  48. package/dist/commands/upgrade.js +152 -0
  49. package/dist/commands/upgrade.js.map +7 -0
  50. package/dist/commands/validate.js +71 -0
  51. package/dist/commands/validate.js.map +7 -0
  52. package/dist/commands/version.js +20 -0
  53. package/dist/commands/version.js.map +7 -0
  54. package/dist/commands/visualize.js +51 -0
  55. package/dist/commands/visualize.js.map +7 -0
  56. package/dist/core/active-changeset.js +52 -0
  57. package/dist/core/active-changeset.js.map +7 -0
  58. package/dist/core/changeset.js +244 -0
  59. package/dist/core/changeset.js.map +7 -0
  60. package/dist/core/dependency-tracker.js +322 -0
  61. package/dist/core/dependency-tracker.js.map +7 -0
  62. package/dist/core/element.js +65 -0
  63. package/dist/core/element.js.map +7 -0
  64. package/dist/core/layer.js +75 -0
  65. package/dist/core/layer.js.map +7 -0
  66. package/dist/core/manifest.js +57 -0
  67. package/dist/core/manifest.js.map +7 -0
  68. package/dist/core/migration-registry.js +131 -0
  69. package/dist/core/migration-registry.js.map +7 -0
  70. package/dist/core/model.js +455 -0
  71. package/dist/core/model.js.map +7 -0
  72. package/dist/core/projection-engine.js +288 -0
  73. package/dist/core/projection-engine.js.map +7 -0
  74. package/dist/core/reference-registry.js +188 -0
  75. package/dist/core/reference-registry.js.map +7 -0
  76. package/dist/core/relationship-registry.js +114 -0
  77. package/dist/core/relationship-registry.js.map +7 -0
  78. package/dist/core/relationships.js +78 -0
  79. package/dist/core/relationships.js.map +7 -0
  80. package/dist/export/archimate-exporter.js +111 -0
  81. package/dist/export/archimate-exporter.js.map +7 -0
  82. package/dist/export/export-manager.js +63 -0
  83. package/dist/export/export-manager.js.map +7 -0
  84. package/dist/export/graphml-exporter.js +39 -0
  85. package/dist/export/graphml-exporter.js.map +7 -0
  86. package/dist/export/index.js +17 -0
  87. package/dist/export/index.js.map +7 -0
  88. package/dist/export/json-schema-exporter.js +60 -0
  89. package/dist/export/json-schema-exporter.js.map +7 -0
  90. package/dist/export/markdown-exporter.js +99 -0
  91. package/dist/export/markdown-exporter.js.map +7 -0
  92. package/dist/export/openapi-exporter.js +85 -0
  93. package/dist/export/openapi-exporter.js.map +7 -0
  94. package/dist/export/plantuml-exporter.js +60 -0
  95. package/dist/export/plantuml-exporter.js.map +7 -0
  96. package/dist/export/types.js +36 -0
  97. package/dist/export/types.js.map +7 -0
  98. package/dist/schemas/bundled/01-motivation-layer.schema.json +942 -0
  99. package/dist/schemas/bundled/02-business-layer.schema.json +1293 -0
  100. package/dist/schemas/bundled/03-security-layer.schema.json +2177 -0
  101. package/dist/schemas/bundled/04-application-layer.schema.json +1328 -0
  102. package/dist/schemas/bundled/05-technology-layer.schema.json +1465 -0
  103. package/dist/schemas/bundled/06-api-layer.schema.json +1743 -0
  104. package/dist/schemas/bundled/07-data-model-layer.schema.json +1253 -0
  105. package/dist/schemas/bundled/08-datastore-layer.schema.json +892 -0
  106. package/dist/schemas/bundled/09-ux-layer.schema.json +1506 -0
  107. package/dist/schemas/bundled/10-navigation-layer.schema.json +843 -0
  108. package/dist/schemas/bundled/11-apm-observability-layer.schema.json +1430 -0
  109. package/dist/schemas/bundled/12-testing-layer.schema.json +1091 -0
  110. package/dist/schemas/bundled/common/layer-extensions.schema.json +266 -0
  111. package/dist/schemas/bundled/common/predicates.schema.json +493 -0
  112. package/dist/schemas/bundled/common/relationships.schema.json +791 -0
  113. package/dist/schemas/bundled/common/source-references.schema.json +71 -0
  114. package/dist/schemas/bundled/link-registry.json +1839 -0
  115. package/dist/schemas/bundled/link-registry.schema.json +339 -0
  116. package/dist/schemas/bundled/relationship-catalog.json +1302 -0
  117. package/dist/schemas/bundled/relationship-type.schema.json +221 -0
  118. package/dist/server/server.js +1207 -0
  119. package/dist/server/server.js.map +7 -0
  120. package/dist/server/telemetry-middleware.js +24 -0
  121. package/dist/server/telemetry-middleware.js.map +7 -0
  122. package/dist/telemetry/console-interceptor.js +34 -0
  123. package/dist/telemetry/console-interceptor.js.map +7 -0
  124. package/dist/telemetry/index.js +54 -0
  125. package/dist/telemetry/index.js.map +7 -0
  126. package/dist/telemetry/resilient-exporter.js +41 -0
  127. package/dist/telemetry/resilient-exporter.js.map +7 -0
  128. package/dist/telemetry/resilient-log-exporter.js +41 -0
  129. package/dist/telemetry/resilient-log-exporter.js.map +7 -0
  130. package/dist/telemetry/test-instrumentation.js +32 -0
  131. package/dist/telemetry/test-instrumentation.js.map +7 -0
  132. package/dist/types/index.js +1 -0
  133. package/dist/types/index.js.map +7 -0
  134. package/dist/utils/element-utils.js +11 -0
  135. package/dist/utils/element-utils.js.map +7 -0
  136. package/dist/utils/errors.js +105 -0
  137. package/dist/utils/errors.js.map +7 -0
  138. package/dist/utils/file-io.js +69 -0
  139. package/dist/utils/file-io.js.map +7 -0
  140. package/dist/utils/globals.js +28 -0
  141. package/dist/utils/globals.js.map +7 -0
  142. package/dist/utils/model-path.js +22 -0
  143. package/dist/utils/model-path.js.map +7 -0
  144. package/dist/utils/project-paths.js +45 -0
  145. package/dist/utils/project-paths.js.map +7 -0
  146. package/dist/utils/spec-installer.js +85 -0
  147. package/dist/utils/spec-installer.js.map +7 -0
  148. package/dist/utils/spec-version.js +33 -0
  149. package/dist/utils/spec-version.js.map +7 -0
  150. package/dist/validators/index.js +15 -0
  151. package/dist/validators/index.js.map +7 -0
  152. package/dist/validators/naming-validator.js +82 -0
  153. package/dist/validators/naming-validator.js.map +7 -0
  154. package/dist/validators/reference-validator.js +106 -0
  155. package/dist/validators/reference-validator.js.map +7 -0
  156. package/dist/validators/schema-validator.js +148 -0
  157. package/dist/validators/schema-validator.js.map +7 -0
  158. package/dist/validators/semantic-validator.js +80 -0
  159. package/dist/validators/semantic-validator.js.map +7 -0
  160. package/dist/validators/types.js +48 -0
  161. package/dist/validators/types.js.map +7 -0
  162. package/dist/validators/validator.js +67 -0
  163. package/dist/validators/validator.js.map +7 -0
  164. package/docs/TEST-INSTRUMENTATION.md +405 -0
  165. package/docs/telemetry.md +427 -0
  166. package/package.json +70 -0
  167. package/test-debug.js +33 -0
  168. package/test-special.mjs +46 -0
  169. package/test_runner.ts +7 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/relationship-registry.ts"],
4
+ "sourcesContent": ["import type { Relationship } from \"../types/index.js\";\n\n/**\n * Relationship type metadata\n */\nexport interface RelationshipTypeMetadata {\n id: string;\n predicate: string;\n inversePredicate?: string;\n category: string;\n description?: string;\n applicable_layers?: string[];\n}\n\n/**\n * Relationship registry - manages intra-layer relationships and their catalog\n */\nexport class RelationshipRegistry {\n private relationships: Map<string, Relationship[]>;\n private relationshipTypes: Map<string, RelationshipTypeMetadata>;\n private predicateMap: Map<string, RelationshipTypeMetadata>;\n private layerIndex: Map<string, Relationship[]>;\n\n constructor() {\n this.relationships = new Map();\n this.relationshipTypes = new Map();\n this.predicateMap = new Map();\n this.layerIndex = new Map();\n }\n\n /**\n * Register a relationship type\n */\n registerType(metadata: RelationshipTypeMetadata): void {\n this.relationshipTypes.set(metadata.id, metadata);\n this.predicateMap.set(metadata.predicate, metadata);\n }\n\n /**\n * Get relationship type by ID\n */\n getType(id: string): RelationshipTypeMetadata | undefined {\n return this.relationshipTypes.get(id);\n }\n\n /**\n * Get relationship type by predicate\n */\n getTypeByPredicate(predicate: string): RelationshipTypeMetadata | undefined {\n return this.predicateMap.get(predicate);\n }\n\n /**\n * Add a relationship to the registry\n */\n addRelationship(relationship: Relationship): void {\n // Extract layer from element ID (format: {layer}-{type}-{kebab-case-name})\n const sourceParts = relationship.source.split(\"-\");\n const layerKey = sourceParts[0]; // Get layer prefix\n\n // Add to source index\n if (!this.relationships.has(relationship.source)) {\n this.relationships.set(relationship.source, []);\n }\n this.relationships.get(relationship.source)!.push(relationship);\n\n // Add to layer index\n if (!this.layerIndex.has(layerKey)) {\n this.layerIndex.set(layerKey, []);\n }\n this.layerIndex.get(layerKey)!.push(relationship);\n }\n\n /**\n * Get all relationships from a source element\n */\n getRelationshipsFrom(sourceId: string): Relationship[] {\n return this.relationships.get(sourceId) ?? [];\n }\n\n /**\n * Get all relationships in a layer\n */\n getRelationshipsByLayer(layerPrefix: string): Relationship[] {\n return this.layerIndex.get(layerPrefix) ?? [];\n }\n\n /**\n * Get all relationships with a specific predicate\n */\n getRelationshipsByPredicate(predicate: string): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels.filter(rel => rel.predicate === predicate));\n }\n return allRels;\n }\n\n /**\n * Check if a relationship exists\n */\n hasRelationship(sourceId: string, targetId: string, predicate: string): boolean {\n const rels = this.relationships.get(sourceId) ?? [];\n return rels.some(\n rel => rel.target === targetId && rel.predicate === predicate\n );\n }\n\n /**\n * Get all relationships\n */\n getAllRelationships(): Relationship[] {\n const allRels: Relationship[] = [];\n for (const rels of this.relationships.values()) {\n allRels.push(...rels);\n }\n return allRels;\n }\n\n /**\n * Get all relationship types\n */\n getAllTypes(): RelationshipTypeMetadata[] {\n return Array.from(this.relationshipTypes.values());\n }\n\n /**\n * Check if a predicate is valid\n */\n isValidPredicate(predicate: string): boolean {\n return this.predicateMap.has(predicate);\n }\n\n /**\n * Get valid predicates for a layer\n */\n getValidPredicatesForLayer(layer: string): string[] {\n const layerPrefix = layer.split(\"-\")[0];\n return this.getAllTypes()\n .filter(type =>\n !type.applicable_layers || type.applicable_layers.includes(layerPrefix)\n )\n .map(type => type.predicate);\n }\n\n /**\n * Clear all relationships and types\n */\n clear(): void {\n this.relationships.clear();\n this.relationshipTypes.clear();\n this.predicateMap.clear();\n this.layerIndex.clear();\n }\n\n /**\n * Get statistics about registered relationships\n */\n getStats(): {\n totalRelationships: number;\n uniquePredicates: number;\n uniqueLayers: number;\n totalTypes: number;\n } {\n const predicates = new Set<string>();\n for (const rels of this.relationships.values()) {\n for (const rel of rels) {\n predicates.add(rel.predicate);\n }\n }\n\n return {\n totalRelationships: this.getAllRelationships().length,\n uniquePredicates: predicates.size,\n uniqueLayers: this.layerIndex.size,\n totalTypes: this.relationshipTypes.size,\n };\n }\n}\n"],
5
+ "mappings": "AAiBM,MAAO,qBAAoB;EACvB;EACA;EACA;EACA;EAER,cAAA;AACE,SAAK,gBAAgB,oBAAI,IAAG,GAC5B,KAAK,oBAAoB,oBAAI,IAAG,GAChC,KAAK,eAAe,oBAAI,IAAG,GAC3B,KAAK,aAAa,oBAAI,IAAG;EAC3B;;;;EAKA,aAAa,UAAkC;AAC7C,SAAK,kBAAkB,IAAI,SAAS,IAAI,QAAQ,GAChD,KAAK,aAAa,IAAI,SAAS,WAAW,QAAQ;EACpD;;;;EAKA,QAAQ,IAAU;AAChB,WAAO,KAAK,kBAAkB,IAAI,EAAE;EACtC;;;;EAKA,mBAAmB,WAAiB;AAClC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,gBAAgB,cAA0B;AAGxC,UAAM,WADc,aAAa,OAAO,MAAM,GAAG,EACpB,CAAC;AAG9B,IAAK,KAAK,cAAc,IAAI,aAAa,MAAM,KAC7C,KAAK,cAAc,IAAI,aAAa,QAAQ,CAAA,CAAE,GAEhD,KAAK,cAAc,IAAI,aAAa,MAAM,EAAG,KAAK,YAAY,GAGzD,KAAK,WAAW,IAAI,QAAQ,KAC/B,KAAK,WAAW,IAAI,UAAU,CAAA,CAAE,GAElC,KAAK,WAAW,IAAI,QAAQ,EAAG,KAAK,YAAY;EAClD;;;;EAKA,qBAAqB,UAAgB;AACnC,WAAO,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA;EAC7C;;;;EAKA,wBAAwB,aAAmB;AACzC,WAAO,KAAK,WAAW,IAAI,WAAW,KAAK,CAAA;EAC7C;;;;EAKA,4BAA4B,WAAiB;AAC3C,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,KAAK,OAAO,SAAO,IAAI,cAAc,SAAS,CAAC;AAEjE,WAAO;EACT;;;;EAKA,gBAAgB,UAAkB,UAAkB,WAAiB;AAEnE,YADa,KAAK,cAAc,IAAI,QAAQ,KAAK,CAAA,GACrC,KACV,SAAO,IAAI,WAAW,YAAY,IAAI,cAAc,SAAS;EAEjE;;;;EAKA,sBAAmB;AACjB,UAAM,UAA0B,CAAA;AAChC,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,cAAQ,KAAK,GAAG,IAAI;AAEtB,WAAO;EACT;;;;EAKA,cAAW;AACT,WAAO,MAAM,KAAK,KAAK,kBAAkB,OAAM,CAAE;EACnD;;;;EAKA,iBAAiB,WAAiB;AAChC,WAAO,KAAK,aAAa,IAAI,SAAS;EACxC;;;;EAKA,2BAA2B,OAAa;AACtC,UAAM,cAAc,MAAM,MAAM,GAAG,EAAE,CAAC;AACtC,WAAO,KAAK,YAAW,EACpB,OAAO,UACN,CAAC,KAAK,qBAAqB,KAAK,kBAAkB,SAAS,WAAW,CAAC,EAExE,IAAI,UAAQ,KAAK,SAAS;EAC/B;;;;EAKA,QAAK;AACH,SAAK,cAAc,MAAK,GACxB,KAAK,kBAAkB,MAAK,GAC5B,KAAK,aAAa,MAAK,GACvB,KAAK,WAAW,MAAK;EACvB;;;;EAKA,WAAQ;AAMN,UAAM,aAAa,oBAAI,IAAG;AAC1B,eAAW,QAAQ,KAAK,cAAc,OAAM;AAC1C,iBAAW,OAAO;AAChB,mBAAW,IAAI,IAAI,SAAS;AAIhC,WAAO;MACL,oBAAoB,KAAK,oBAAmB,EAAG;MAC/C,kBAAkB,WAAW;MAC7B,cAAc,KAAK,WAAW;MAC9B,YAAY,KAAK,kBAAkB;;EAEvC;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,78 @@
1
+ class Relationships {
2
+ relationships = [];
3
+ dirty = !1;
4
+ constructor(relationships = []) {
5
+ this.relationships = relationships;
6
+ }
7
+ /**
8
+ * Add a relationship
9
+ */
10
+ add(relationship) {
11
+ this.relationships.push(relationship), this.dirty = !0;
12
+ }
13
+ /**
14
+ * Delete relationships matching criteria
15
+ */
16
+ delete(source, target, predicate) {
17
+ const initialLength = this.relationships.length;
18
+ this.relationships = this.relationships.filter((rel) => !(rel.source === source && rel.target === target && (!predicate || rel.predicate === predicate)));
19
+ const deletedCount = initialLength - this.relationships.length;
20
+ return deletedCount > 0 && (this.dirty = !0), deletedCount;
21
+ }
22
+ /**
23
+ * Delete all relationships involving an element (as source or target)
24
+ */
25
+ deleteForElement(elementId) {
26
+ const initialLength = this.relationships.length;
27
+ this.relationships = this.relationships.filter((rel) => rel.source !== elementId && rel.target !== elementId);
28
+ const deletedCount = initialLength - this.relationships.length;
29
+ return this.dirty = !0, deletedCount;
30
+ }
31
+ /**
32
+ * Get all relationships for an element
33
+ */
34
+ getForElement(elementId) {
35
+ const outgoing = this.relationships.filter((rel) => rel.source === elementId), incoming = this.relationships.filter((rel) => rel.target === elementId);
36
+ return { outgoing, incoming };
37
+ }
38
+ /**
39
+ * Get all relationships
40
+ */
41
+ getAll() {
42
+ return [...this.relationships];
43
+ }
44
+ /**
45
+ * Find relationships between two elements
46
+ */
47
+ find(source, target, predicate) {
48
+ return this.relationships.filter((rel) => rel.source === source && rel.target === target && (!predicate || rel.predicate === predicate));
49
+ }
50
+ /**
51
+ * Check if relationships have unsaved changes
52
+ */
53
+ isDirty() {
54
+ return this.dirty;
55
+ }
56
+ /**
57
+ * Mark relationships as clean (no unsaved changes)
58
+ */
59
+ markClean() {
60
+ this.dirty = !1;
61
+ }
62
+ /**
63
+ * Serialize to array for YAML
64
+ */
65
+ toArray() {
66
+ return this.relationships;
67
+ }
68
+ /**
69
+ * Load from array (from YAML)
70
+ */
71
+ static fromArray(data) {
72
+ return new Relationships(data);
73
+ }
74
+ }
75
+ export {
76
+ Relationships
77
+ };
78
+ //# sourceMappingURL=relationships.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/core/relationships.ts"],
4
+ "sourcesContent": ["/**\n * Relationships management for intra-layer and cross-layer relationships\n */\n\nexport interface Relationship {\n source: string;\n predicate: string;\n target: string;\n category?: 'structural' | 'behavioral';\n layer: string;\n targetLayer?: string;\n properties?: Record<string, unknown>;\n}\n\n/**\n * Relationships class for managing the central relationships.yaml file\n */\nexport class Relationships {\n private relationships: Relationship[] = [];\n private dirty: boolean = false;\n\n constructor(relationships: Relationship[] = []) {\n this.relationships = relationships;\n }\n\n /**\n * Add a relationship\n */\n add(relationship: Relationship): void {\n this.relationships.push(relationship);\n this.dirty = true;\n }\n\n /**\n * Delete relationships matching criteria\n */\n delete(source: string, target: string, predicate?: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) =>\n !(\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n )\n );\n const deletedCount = initialLength - this.relationships.length;\n if (deletedCount > 0) {\n this.dirty = true;\n }\n return deletedCount;\n }\n\n /**\n * Delete all relationships involving an element (as source or target)\n */\n deleteForElement(elementId: string): number {\n const initialLength = this.relationships.length;\n this.relationships = this.relationships.filter(\n (rel) => rel.source !== elementId && rel.target !== elementId\n );\n const deletedCount = initialLength - this.relationships.length;\n // Always mark as dirty to ensure file is rewritten (Python CLI behavior)\n this.dirty = true;\n return deletedCount;\n }\n\n /**\n * Get all relationships for an element\n */\n getForElement(elementId: string): {\n outgoing: Relationship[];\n incoming: Relationship[];\n } {\n const outgoing = this.relationships.filter((rel) => rel.source === elementId);\n const incoming = this.relationships.filter((rel) => rel.target === elementId);\n return { outgoing, incoming };\n }\n\n /**\n * Get all relationships\n */\n getAll(): Relationship[] {\n return [...this.relationships];\n }\n\n /**\n * Find relationships between two elements\n */\n find(source: string, target: string, predicate?: string): Relationship[] {\n return this.relationships.filter(\n (rel) =>\n rel.source === source &&\n rel.target === target &&\n (!predicate || rel.predicate === predicate)\n );\n }\n\n /**\n * Check if relationships have unsaved changes\n */\n isDirty(): boolean {\n return this.dirty;\n }\n\n /**\n * Mark relationships as clean (no unsaved changes)\n */\n markClean(): void {\n this.dirty = false;\n }\n\n /**\n * Serialize to array for YAML\n */\n toArray(): Relationship[] {\n return this.relationships;\n }\n\n /**\n * Load from array (from YAML)\n */\n static fromArray(data: Relationship[]): Relationships {\n return new Relationships(data);\n }\n}\n"],
5
+ "mappings": "AAiBM,MAAO,cAAa;EAChB,gBAAgC,CAAA;EAChC,QAAiB;EAEzB,YAAY,gBAAgC,CAAA,GAAE;AAC5C,SAAK,gBAAgB;EACvB;;;;EAKA,IAAI,cAA0B;AAC5B,SAAK,cAAc,KAAK,YAAY,GACpC,KAAK,QAAQ;EACf;;;;EAKA,OAAO,QAAgB,QAAgB,WAAkB;AACvD,UAAM,gBAAgB,KAAK,cAAc;AACzC,SAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,QACC,EACE,IAAI,WAAW,UACf,IAAI,WAAW,WACd,CAAC,aAAa,IAAI,cAAc,WAClC;AAEL,UAAM,eAAe,gBAAgB,KAAK,cAAc;AACxD,WAAI,eAAe,MACjB,KAAK,QAAQ,KAER;EACT;;;;EAKA,iBAAiB,WAAiB;AAChC,UAAM,gBAAgB,KAAK,cAAc;AACzC,SAAK,gBAAgB,KAAK,cAAc,OACtC,CAAC,QAAQ,IAAI,WAAW,aAAa,IAAI,WAAW,SAAS;AAE/D,UAAM,eAAe,gBAAgB,KAAK,cAAc;AAExD,gBAAK,QAAQ,IACN;EACT;;;;EAKA,cAAc,WAAiB;AAI7B,UAAM,WAAW,KAAK,cAAc,OAAO,CAAC,QAAQ,IAAI,WAAW,SAAS,GACtE,WAAW,KAAK,cAAc,OAAO,CAAC,QAAQ,IAAI,WAAW,SAAS;AAC5E,WAAO,EAAE,UAAU,SAAQ;EAC7B;;;;EAKA,SAAM;AACJ,WAAO,CAAC,GAAG,KAAK,aAAa;EAC/B;;;;EAKA,KAAK,QAAgB,QAAgB,WAAkB;AACrD,WAAO,KAAK,cAAc,OACxB,CAAC,QACC,IAAI,WAAW,UACf,IAAI,WAAW,WACd,CAAC,aAAa,IAAI,cAAc,UAAU;EAEjD;;;;EAKA,UAAO;AACL,WAAO,KAAK;EACd;;;;EAKA,YAAS;AACP,SAAK,QAAQ;EACf;;;;EAKA,UAAO;AACL,WAAO,KAAK;EACd;;;;EAKA,OAAO,UAAU,MAAoB;AACnC,WAAO,IAAI,cAAc,IAAI;EAC/B;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,111 @@
1
+ import { escapeXml } from "./types.js";
2
+ class ArchiMateExporter {
3
+ name = "ArchiMate";
4
+ supportedLayers = ["motivation", "business", "application", "technology"];
5
+ async export(model, options = {}) {
6
+ const lines = [];
7
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>'), lines.push('<model xmlns="http://www.opengroup.org/xsd/archimate/3.0/"'), lines.push(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'), lines.push(' xsi:schemaLocation="http://www.opengroup.org/xsd/archimate/3.0/ http://www.opengroup.org/xsd/archimate/3.1/archimate3_Diagram.xsd">'), lines.push(` <name>${escapeXml(model.manifest.name)}</name>`), model.manifest.description && lines.push(` <documentation>${escapeXml(model.manifest.description)}</documentation>`), lines.push(" <elements>");
8
+ const layersToExport = options.layers || this.supportedLayers, elements = [];
9
+ for (const layerName of layersToExport) {
10
+ if (!this.supportedLayers.includes(layerName))
11
+ continue;
12
+ const layer = await model.getLayer(layerName);
13
+ if (layer)
14
+ for (const element of layer.listElements())
15
+ elements.push({ layer: layerName, element });
16
+ }
17
+ for (const { layer, element } of elements) {
18
+ const archiType = this.mapToArchiMateType(element.type, layer);
19
+ lines.push(` <element identifier="${element.id}" xsi:type="${archiType}">`), lines.push(` <name>${escapeXml(element.name)}</name>`), element.description && lines.push(` <documentation>${escapeXml(element.description)}</documentation>`);
20
+ const propKeys = Object.keys(element.properties);
21
+ if (propKeys.length > 0) {
22
+ const propsStr = propKeys.map((key) => {
23
+ const val = element.properties[key];
24
+ return `${key}: ${this.valueToString(val)}`;
25
+ }).join("; ");
26
+ propsStr && lines.push(` <documentation>Properties: ${escapeXml(propsStr)}</documentation>`);
27
+ }
28
+ lines.push(" </element>");
29
+ }
30
+ lines.push(" </elements>"), lines.push(" <relationships>");
31
+ for (const { element } of elements) {
32
+ for (const ref of element.references)
33
+ lines.push(` <relationship identifier="${this.escapeId(element.id)}-ref-${this.escapeId(ref.target)}" `), lines.push(` source="${element.id}" target="${ref.target}" `), lines.push(' xsi:type="Association">'), ref.description && lines.push(` <documentation>${escapeXml(ref.description)}</documentation>`), lines.push(` <name>${ref.type}</name>`), lines.push(" </relationship>");
34
+ for (const rel of element.relationships)
35
+ lines.push(` <relationship identifier="${this.escapeId(element.id)}-${this.escapeId(rel.predicate)}-${this.escapeId(rel.target)}" `), lines.push(` source="${element.id}" target="${rel.target}" `), lines.push(' xsi:type="Association">'), lines.push(` <name>${rel.predicate}</name>`), lines.push(" </relationship>");
36
+ }
37
+ return lines.push(" </relationships>"), lines.push("</model>"), lines.join(`
38
+ `);
39
+ }
40
+ /**
41
+ * Map element type and layer to ArchiMate type
42
+ */
43
+ mapToArchiMateType(type, layer) {
44
+ return {
45
+ motivation: {
46
+ stakeholder: "Stakeholder",
47
+ driver: "Driver",
48
+ assessment: "Assessment",
49
+ goal: "Goal",
50
+ outcome: "Outcome",
51
+ principle: "Principle",
52
+ requirement: "Requirement",
53
+ constraint: "Constraint"
54
+ },
55
+ business: {
56
+ "business-actor": "BusinessActor",
57
+ "business-role": "BusinessRole",
58
+ "business-collaboration": "BusinessCollaboration",
59
+ "business-interface": "BusinessInterface",
60
+ "business-process": "BusinessProcess",
61
+ "business-function": "BusinessFunction",
62
+ "business-interaction": "BusinessInteraction",
63
+ "business-event": "BusinessEvent",
64
+ "business-service": "BusinessService",
65
+ "business-object": "BusinessObject"
66
+ },
67
+ application: {
68
+ "application-component": "ApplicationComponent",
69
+ "application-collaboration": "ApplicationCollaboration",
70
+ "application-interface": "ApplicationInterface",
71
+ "application-function": "ApplicationFunction",
72
+ "application-interaction": "ApplicationInteraction",
73
+ "application-process": "ApplicationProcess",
74
+ "application-event": "ApplicationEvent",
75
+ "application-service": "ApplicationService",
76
+ "data-object": "DataObject"
77
+ },
78
+ technology: {
79
+ node: "Node",
80
+ device: "Device",
81
+ "system-software": "SystemSoftware",
82
+ "technology-collaboration": "TechnologyCollaboration",
83
+ "technology-interface": "TechnologyInterface",
84
+ path: "Path",
85
+ "communication-network": "CommunicationNetwork",
86
+ "technology-function": "TechnologyFunction",
87
+ "technology-process": "TechnologyProcess",
88
+ "technology-interaction": "TechnologyInteraction",
89
+ "technology-event": "TechnologyEvent",
90
+ "technology-service": "TechnologyService",
91
+ artifact: "Artifact"
92
+ }
93
+ }[layer]?.[type] || "Element";
94
+ }
95
+ /**
96
+ * Escape ID characters for use in identifiers
97
+ */
98
+ escapeId(str) {
99
+ return str.replace(/[^a-zA-Z0-9_-]/g, "_");
100
+ }
101
+ /**
102
+ * Convert value to string representation
103
+ */
104
+ valueToString(value) {
105
+ return typeof value == "string" ? value : typeof value == "number" || typeof value == "boolean" ? String(value) : Array.isArray(value) ? `[${value.map((v) => this.valueToString(v)).join(", ")}]` : value && typeof value == "object" ? JSON.stringify(value) : String(value);
106
+ }
107
+ }
108
+ export {
109
+ ArchiMateExporter
110
+ };
111
+ //# sourceMappingURL=archimate-exporter.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/export/archimate-exporter.ts"],
4
+ "sourcesContent": ["import type { Model } from \"../core/model.js\";\nimport type { Exporter, ExportOptions } from \"./types.js\";\nimport { escapeXml } from \"./types.js\";\n\n/**\n * ArchiMate XML Exporter for layers 1, 2, 4, 5\n * Generates valid ArchiMate 3.2 XML format\n */\nexport class ArchiMateExporter implements Exporter {\n name = \"ArchiMate\";\n supportedLayers = [\"motivation\", \"business\", \"application\", \"technology\"];\n\n async export(model: Model, options: ExportOptions = {}): Promise<string> {\n const lines: string[] = [];\n\n // XML declaration\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n\n // Root element with namespaces\n lines.push(\n '<model xmlns=\"http://www.opengroup.org/xsd/archimate/3.0/\"'\n );\n lines.push(\n ' xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"'\n );\n lines.push(\n ' xsi:schemaLocation=\"http://www.opengroup.org/xsd/archimate/3.0/ http://www.opengroup.org/xsd/archimate/3.1/archimate3_Diagram.xsd\">'\n );\n\n // Model metadata\n lines.push(` <name>${escapeXml(model.manifest.name)}</name>`);\n if (model.manifest.description) {\n lines.push(\n ` <documentation>${escapeXml(model.manifest.description)}</documentation>`\n );\n }\n\n // Export elements\n lines.push(\" <elements>\");\n\n const layersToExport = options.layers || this.supportedLayers;\n const elements: Array<{ layer: string; element: any }> = [];\n\n for (const layerName of layersToExport) {\n if (!this.supportedLayers.includes(layerName)) continue;\n\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n\n for (const element of layer.listElements()) {\n elements.push({ layer: layerName, element });\n }\n }\n\n for (const { layer, element } of elements) {\n const archiType = this.mapToArchiMateType(element.type, layer);\n lines.push(` <element identifier=\"${element.id}\" xsi:type=\"${archiType}\">`);\n lines.push(` <name>${escapeXml(element.name)}</name>`);\n\n if (element.description) {\n lines.push(\n ` <documentation>${escapeXml(element.description)}</documentation>`\n );\n }\n\n // Add properties as additional attributes or documentation\n const propKeys = Object.keys(element.properties);\n if (propKeys.length > 0) {\n const propsStr = propKeys\n .map((key) => {\n const val = element.properties[key];\n return `${key}: ${this.valueToString(val)}`;\n })\n .join(\"; \");\n if (propsStr) {\n lines.push(\n ` <documentation>Properties: ${escapeXml(propsStr)}</documentation>`\n );\n }\n }\n\n lines.push(\" </element>\");\n }\n\n lines.push(\" </elements>\");\n\n // Export relationships and references\n lines.push(\" <relationships>\");\n\n for (const { element } of elements) {\n // Handle cross-layer references\n for (const ref of element.references) {\n lines.push(\n ` <relationship identifier=\"${this.escapeId(element.id)}-ref-${this.escapeId(ref.target)}\" `\n );\n lines.push(` source=\"${element.id}\" target=\"${ref.target}\" `);\n lines.push(` xsi:type=\"Association\">`);\n if (ref.description) {\n lines.push(\n ` <documentation>${escapeXml(ref.description)}</documentation>`\n );\n }\n lines.push(` <name>${ref.type}</name>`);\n lines.push(` </relationship>`);\n }\n\n // Handle intra-layer relationships\n for (const rel of element.relationships) {\n lines.push(\n ` <relationship identifier=\"${this.escapeId(element.id)}-${this.escapeId(rel.predicate)}-${this.escapeId(rel.target)}\" `\n );\n lines.push(` source=\"${element.id}\" target=\"${rel.target}\" `);\n lines.push(` xsi:type=\"Association\">`);\n lines.push(` <name>${rel.predicate}</name>`);\n lines.push(` </relationship>`);\n }\n }\n\n lines.push(\" </relationships>\");\n lines.push(\"</model>\");\n\n return lines.join(\"\\n\");\n }\n\n /**\n * Map element type and layer to ArchiMate type\n */\n private mapToArchiMateType(type: string, layer: string): string {\n const mapping: Record<string, Record<string, string>> = {\n motivation: {\n stakeholder: \"Stakeholder\",\n driver: \"Driver\",\n assessment: \"Assessment\",\n goal: \"Goal\",\n outcome: \"Outcome\",\n principle: \"Principle\",\n requirement: \"Requirement\",\n constraint: \"Constraint\",\n },\n business: {\n \"business-actor\": \"BusinessActor\",\n \"business-role\": \"BusinessRole\",\n \"business-collaboration\": \"BusinessCollaboration\",\n \"business-interface\": \"BusinessInterface\",\n \"business-process\": \"BusinessProcess\",\n \"business-function\": \"BusinessFunction\",\n \"business-interaction\": \"BusinessInteraction\",\n \"business-event\": \"BusinessEvent\",\n \"business-service\": \"BusinessService\",\n \"business-object\": \"BusinessObject\",\n },\n application: {\n \"application-component\": \"ApplicationComponent\",\n \"application-collaboration\": \"ApplicationCollaboration\",\n \"application-interface\": \"ApplicationInterface\",\n \"application-function\": \"ApplicationFunction\",\n \"application-interaction\": \"ApplicationInteraction\",\n \"application-process\": \"ApplicationProcess\",\n \"application-event\": \"ApplicationEvent\",\n \"application-service\": \"ApplicationService\",\n \"data-object\": \"DataObject\",\n },\n technology: {\n node: \"Node\",\n device: \"Device\",\n \"system-software\": \"SystemSoftware\",\n \"technology-collaboration\": \"TechnologyCollaboration\",\n \"technology-interface\": \"TechnologyInterface\",\n path: \"Path\",\n \"communication-network\": \"CommunicationNetwork\",\n \"technology-function\": \"TechnologyFunction\",\n \"technology-process\": \"TechnologyProcess\",\n \"technology-interaction\": \"TechnologyInteraction\",\n \"technology-event\": \"TechnologyEvent\",\n \"technology-service\": \"TechnologyService\",\n artifact: \"Artifact\",\n },\n };\n\n return mapping[layer]?.[type] || \"Element\";\n }\n\n /**\n * Escape ID characters for use in identifiers\n */\n private escapeId(str: string): string {\n return str.replace(/[^a-zA-Z0-9_-]/g, \"_\");\n }\n\n /**\n * Convert value to string representation\n */\n private valueToString(value: unknown): string {\n if (typeof value === \"string\") return value;\n if (typeof value === \"number\") return String(value);\n if (typeof value === \"boolean\") return String(value);\n if (Array.isArray(value)) return `[${value.map((v) => this.valueToString(v)).join(\", \")}]`;\n if (value && typeof value === \"object\") {\n return JSON.stringify(value);\n }\n return String(value);\n }\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }
@@ -0,0 +1,63 @@
1
+ class ExportManager {
2
+ exporters = /* @__PURE__ */ new Map();
3
+ formatInfo = /* @__PURE__ */ new Map();
4
+ /**
5
+ * Register an exporter for a specific format
6
+ */
7
+ register(format, exporter, info) {
8
+ this.exporters.set(format, exporter), this.formatInfo.set(format, {
9
+ format,
10
+ name: exporter.name,
11
+ supportedLayers: exporter.supportedLayers,
12
+ ...info
13
+ });
14
+ }
15
+ /**
16
+ * Check if a format is registered
17
+ */
18
+ hasFormat(format) {
19
+ return this.exporters.has(format);
20
+ }
21
+ /**
22
+ * Export model to specified format
23
+ */
24
+ async export(model, format, options = {}) {
25
+ const exporter = this.exporters.get(format);
26
+ if (!exporter)
27
+ throw new Error(`Unknown export format: ${format}`);
28
+ if (options.layers) {
29
+ const unsupported = options.layers.filter((layer) => !exporter.supportedLayers.includes(layer));
30
+ if (unsupported.length > 0)
31
+ throw new Error(`Format '${format}' does not support layers: ${unsupported.join(", ")}. Supported layers: ${exporter.supportedLayers.join(", ")}`);
32
+ }
33
+ return await exporter.export(model, options);
34
+ }
35
+ /**
36
+ * Get list of available formats
37
+ */
38
+ listFormats() {
39
+ return Array.from(this.exporters.keys()).sort();
40
+ }
41
+ /**
42
+ * Get metadata about a format
43
+ */
44
+ getFormatInfo(format) {
45
+ return this.formatInfo.get(format);
46
+ }
47
+ /**
48
+ * Get supported layers for a format
49
+ */
50
+ getSupportedLayers(format) {
51
+ return this.exporters.get(format)?.supportedLayers ?? [];
52
+ }
53
+ /**
54
+ * Get all registered formats with metadata
55
+ */
56
+ getAllFormats() {
57
+ return Array.from(this.formatInfo.values()).sort((a, b) => a.format.localeCompare(b.format));
58
+ }
59
+ }
60
+ export {
61
+ ExportManager
62
+ };
63
+ //# sourceMappingURL=export-manager.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/export/export-manager.ts"],
4
+ "sourcesContent": ["import type { Model } from \"../core/model.js\";\nimport type { Exporter, ExportOptions, ExportFormatInfo } from \"./types.js\";\n\n/**\n * ExportManager - Registry and dispatcher for format-specific exporters\n */\nexport class ExportManager {\n private exporters: Map<string, Exporter> = new Map();\n private formatInfo: Map<string, ExportFormatInfo> = new Map();\n\n /**\n * Register an exporter for a specific format\n */\n register(\n format: string,\n exporter: Exporter,\n info: Omit<ExportFormatInfo, 'format' | 'name' | 'supportedLayers'>\n ): void {\n this.exporters.set(format, exporter);\n this.formatInfo.set(format, {\n format,\n name: exporter.name,\n supportedLayers: exporter.supportedLayers,\n ...info,\n });\n }\n\n /**\n * Check if a format is registered\n */\n hasFormat(format: string): boolean {\n return this.exporters.has(format);\n }\n\n /**\n * Export model to specified format\n */\n async export(\n model: Model,\n format: string,\n options: ExportOptions = {}\n ): Promise<string> {\n const exporter = this.exporters.get(format);\n if (!exporter) {\n throw new Error(`Unknown export format: ${format}`);\n }\n\n // Validate that requested layers are supported\n if (options.layers) {\n const unsupported = options.layers.filter(\n (layer) => !exporter.supportedLayers.includes(layer)\n );\n if (unsupported.length > 0) {\n throw new Error(\n `Format '${format}' does not support layers: ${unsupported.join(', ')}. ` +\n `Supported layers: ${exporter.supportedLayers.join(', ')}`\n );\n }\n }\n\n return await exporter.export(model, options);\n }\n\n /**\n * Get list of available formats\n */\n listFormats(): string[] {\n return Array.from(this.exporters.keys()).sort();\n }\n\n /**\n * Get metadata about a format\n */\n getFormatInfo(format: string): ExportFormatInfo | undefined {\n return this.formatInfo.get(format);\n }\n\n /**\n * Get supported layers for a format\n */\n getSupportedLayers(format: string): string[] {\n const exporter = this.exporters.get(format);\n return exporter?.supportedLayers ?? [];\n }\n\n /**\n * Get all registered formats with metadata\n */\n getAllFormats(): ExportFormatInfo[] {\n return Array.from(this.formatInfo.values()).sort((a, b) =>\n a.format.localeCompare(b.format)\n );\n }\n}\n"],
5
+ "mappings": "AAMM,MAAO,cAAa;EAChB,YAAmC,oBAAI,IAAG;EAC1C,aAA4C,oBAAI,IAAG;;;;EAK3D,SACE,QACA,UACA,MAAmE;AAEnE,SAAK,UAAU,IAAI,QAAQ,QAAQ,GACnC,KAAK,WAAW,IAAI,QAAQ;MAC1B;MACA,MAAM,SAAS;MACf,iBAAiB,SAAS;MAC1B,GAAG;KACJ;EACH;;;;EAKA,UAAU,QAAc;AACtB,WAAO,KAAK,UAAU,IAAI,MAAM;EAClC;;;;EAKA,MAAM,OACJ,OACA,QACA,UAAyB,CAAA,GAAE;AAE3B,UAAM,WAAW,KAAK,UAAU,IAAI,MAAM;AAC1C,QAAI,CAAC;AACH,YAAM,IAAI,MAAM,0BAA0B,MAAM,EAAE;AAIpD,QAAI,QAAQ,QAAQ;AAClB,YAAM,cAAc,QAAQ,OAAO,OACjC,CAAC,UAAU,CAAC,SAAS,gBAAgB,SAAS,KAAK,CAAC;AAEtD,UAAI,YAAY,SAAS;AACvB,cAAM,IAAI,MACR,WAAW,MAAM,8BAA8B,YAAY,KAAK,IAAI,CAAC,uBAChD,SAAS,gBAAgB,KAAK,IAAI,CAAC,EAAE;IAGhE;AAEA,WAAO,MAAM,SAAS,OAAO,OAAO,OAAO;EAC7C;;;;EAKA,cAAW;AACT,WAAO,MAAM,KAAK,KAAK,UAAU,KAAI,CAAE,EAAE,KAAI;EAC/C;;;;EAKA,cAAc,QAAc;AAC1B,WAAO,KAAK,WAAW,IAAI,MAAM;EACnC;;;;EAKA,mBAAmB,QAAc;AAE/B,WADiB,KAAK,UAAU,IAAI,MAAM,GACzB,mBAAmB,CAAA;EACtC;;;;EAKA,gBAAa;AACX,WAAO,MAAM,KAAK,KAAK,WAAW,OAAM,CAAE,EAAE,KAAK,CAAC,GAAG,MACnD,EAAE,OAAO,cAAc,EAAE,MAAM,CAAC;EAEpC;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,39 @@
1
+ import { ALL_LAYERS, LAYER_COLORS, escapeXml } from "./types.js";
2
+ class GraphMLExporter {
3
+ name = "GraphML";
4
+ supportedLayers = ALL_LAYERS;
5
+ async export(model, options = {}) {
6
+ const lines = [];
7
+ lines.push('<?xml version="1.0" encoding="UTF-8"?>'), lines.push('<graphml xmlns="http://graphml.graphdrawing.org/xmlns"'), lines.push(' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'), lines.push(' xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"'), lines.push(' edgedefault="directed">'), lines.push(' <key id="node_description" for="node" attr.name="description" attr.type="string"/>'), lines.push(' <key id="node_layer" for="node" attr.name="layer" attr.type="string"/>'), lines.push(' <key id="node_type" for="node" attr.name="type" attr.type="string"/>'), lines.push(' <key id="edge_type" for="edge" attr.name="type" attr.type="string"/>'), lines.push(' <graph id="model" edgedefault="directed">'), lines.push(` <data key="name">${escapeXml(model.manifest.name)}</data>`);
8
+ const layersToExport = options.layers || this.supportedLayers, elementMap = /* @__PURE__ */ new Map();
9
+ for (const layerName of layersToExport) {
10
+ const layer = await model.getLayer(layerName);
11
+ if (layer)
12
+ for (const element of layer.listElements()) {
13
+ const color = `#${LAYER_COLORS[layerName] || "FFFFFF"}`;
14
+ lines.push(` <node id="${element.id}">`), lines.push(` <data key="name">${escapeXml(element.name)}</data>`), lines.push(` <data key="node_layer">${layerName}</data>`), lines.push(` <data key="node_type">${element.type}</data>`), element.description && lines.push(` <data key="node_description">${escapeXml(element.description)}</data>`), lines.push(` <graphics x="0" y="0" w="150" h="50" fill="${color}" type="rectangle"/>`), lines.push(' <data key="d6">'), lines.push(" <y:ShapeNode>"), lines.push(` <y:NodeLabel>${escapeXml(element.name)}</y:NodeLabel>`), lines.push(" </y:ShapeNode>"), lines.push(" </data>"), lines.push(" </node>"), elementMap.set(element.id, {
15
+ layer: layerName,
16
+ type: element.type,
17
+ description: element.description
18
+ });
19
+ }
20
+ }
21
+ let edgeCounter = 0;
22
+ for (const layerName of layersToExport) {
23
+ const layer = await model.getLayer(layerName);
24
+ if (layer)
25
+ for (const element of layer.listElements()) {
26
+ for (const ref of element.references)
27
+ elementMap.has(ref.target) && (lines.push(` <edge id="e${edgeCounter}" source="${element.id}" target="${ref.target}">`), lines.push(` <data key="edge_type">${ref.type}</data>`), lines.push(` <data key="name">${escapeXml(ref.type)}</data>`), ref.description && lines.push(` <data key="description">${escapeXml(ref.description)}</data>`), lines.push(" </edge>"), edgeCounter++);
28
+ for (const rel of element.relationships)
29
+ elementMap.has(rel.target) && (lines.push(` <edge id="e${edgeCounter}" source="${element.id}" target="${rel.target}">`), lines.push(` <data key="edge_type">${rel.predicate}</data>`), lines.push(` <data key="name">${escapeXml(rel.predicate)}</data>`), lines.push(" </edge>"), edgeCounter++);
30
+ }
31
+ }
32
+ return lines.push(" </graph>"), lines.push("</graphml>"), lines.join(`
33
+ `);
34
+ }
35
+ }
36
+ export {
37
+ GraphMLExporter
38
+ };
39
+ //# sourceMappingURL=graphml-exporter.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/export/graphml-exporter.ts"],
4
+ "sourcesContent": ["import type { Model } from \"../core/model.js\";\nimport type { Exporter, ExportOptions } from \"./types.js\";\nimport { ALL_LAYERS, LAYER_COLORS, escapeXml } from \"./types.js\";\n\n/**\n * GraphML Exporter - generates GraphML format for graph visualization tools\n * GraphML is an XML-based format supported by tools like yEd, Cytoscape, etc.\n */\nexport class GraphMLExporter implements Exporter {\n name = \"GraphML\";\n supportedLayers = ALL_LAYERS;\n\n async export(model: Model, options: ExportOptions = {}): Promise<string> {\n const lines: string[] = [];\n\n // XML declaration\n lines.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n\n // GraphML root element\n lines.push(\n '<graphml xmlns=\"http://graphml.graphdrawing.org/xmlns\"'\n );\n lines.push(\n ' xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"'\n );\n lines.push(\n ' xsi:schemaLocation=\"http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd\"'\n );\n lines.push(' edgedefault=\"directed\">');\n\n // Define graph attributes\n lines.push(' <key id=\"node_description\" for=\"node\" attr.name=\"description\" attr.type=\"string\"/>');\n lines.push(' <key id=\"node_layer\" for=\"node\" attr.name=\"layer\" attr.type=\"string\"/>');\n lines.push(' <key id=\"node_type\" for=\"node\" attr.name=\"type\" attr.type=\"string\"/>');\n lines.push(' <key id=\"edge_type\" for=\"edge\" attr.name=\"type\" attr.type=\"string\"/>');\n\n // Create main graph\n lines.push(\n ` <graph id=\"model\" edgedefault=\"directed\">`\n );\n lines.push(\n ` <data key=\"name\">${escapeXml(model.manifest.name)}</data>`\n );\n\n const layersToExport = options.layers || this.supportedLayers;\n const elementMap = new Map<string, { layer: string; type: string; description?: string }>();\n\n // Add all nodes (elements)\n for (const layerName of layersToExport) {\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n\n for (const element of layer.listElements()) {\n const color = `#${LAYER_COLORS[layerName] || \"FFFFFF\"}`;\n\n lines.push(` <node id=\"${element.id}\">`);\n lines.push(` <data key=\"name\">${escapeXml(element.name)}</data>`);\n lines.push(` <data key=\"node_layer\">${layerName}</data>`);\n lines.push(` <data key=\"node_type\">${element.type}</data>`);\n\n if (element.description) {\n lines.push(\n ` <data key=\"node_description\">${escapeXml(element.description)}</data>`\n );\n }\n\n // Add visualization hints using yEd extensions (optional)\n lines.push(` <graphics x=\"0\" y=\"0\" w=\"150\" h=\"50\" fill=\"${color}\" type=\"rectangle\"/>`);\n lines.push(` <data key=\"d6\">`);\n lines.push(` <y:ShapeNode>`);\n lines.push(` <y:NodeLabel>${escapeXml(element.name)}</y:NodeLabel>`);\n lines.push(` </y:ShapeNode>`);\n lines.push(` </data>`);\n\n lines.push(` </node>`);\n\n elementMap.set(element.id, {\n layer: layerName,\n type: element.type,\n description: element.description,\n });\n }\n }\n\n // Add all edges (relationships and references)\n let edgeCounter = 0;\n\n for (const layerName of layersToExport) {\n const layer = await model.getLayer(layerName);\n if (!layer) continue;\n\n for (const element of layer.listElements()) {\n // Cross-layer references\n for (const ref of element.references) {\n if (!elementMap.has(ref.target)) {\n // Log warning for dangling reference (in verbose mode this could be extended)\n continue;\n }\n lines.push(\n ` <edge id=\"e${edgeCounter}\" source=\"${element.id}\" target=\"${ref.target}\">`\n );\n lines.push(` <data key=\"edge_type\">${ref.type}</data>`);\n lines.push(` <data key=\"name\">${escapeXml(ref.type)}</data>`);\n\n if (ref.description) {\n lines.push(\n ` <data key=\"description\">${escapeXml(ref.description)}</data>`\n );\n }\n\n lines.push(` </edge>`);\n edgeCounter++;\n }\n\n // Intra-layer relationships\n for (const rel of element.relationships) {\n if (!elementMap.has(rel.target)) {\n // Skip relationships to non-existent targets\n continue;\n }\n lines.push(\n ` <edge id=\"e${edgeCounter}\" source=\"${element.id}\" target=\"${rel.target}\">`\n );\n lines.push(` <data key=\"edge_type\">${rel.predicate}</data>`);\n lines.push(` <data key=\"name\">${escapeXml(rel.predicate)}</data>`);\n lines.push(` </edge>`);\n edgeCounter++;\n }\n }\n }\n\n lines.push(` </graph>`);\n lines.push(`</graphml>`);\n\n return lines.join(\"\\n\");\n }\n}\n"],
5
+ "mappings": "AAEA,SAAS,YAAY,cAAc,iBAAiB;AAM9C,MAAO,gBAAe;EAC1B,OAAO;EACP,kBAAkB;EAElB,MAAM,OAAO,OAAc,UAAyB,CAAA,GAAE;AACpD,UAAM,QAAkB,CAAA;AAGxB,UAAM,KAAK,wCAAwC,GAGnD,MAAM,KACJ,wDAAwD,GAE1D,MAAM,KACJ,gEAAgE,GAElE,MAAM,KACJ,qFAAqF,GAEvF,MAAM,KAAK,kCAAkC,GAG7C,MAAM,KAAK,sFAAsF,GACjG,MAAM,KAAK,0EAA0E,GACrF,MAAM,KAAK,wEAAwE,GACnF,MAAM,KAAK,wEAAwE,GAGnF,MAAM,KACJ,6CAA6C,GAE/C,MAAM,KACJ,wBAAwB,UAAU,MAAM,SAAS,IAAI,CAAC,SAAS;AAGjE,UAAM,iBAAiB,QAAQ,UAAU,KAAK,iBACxC,aAAa,oBAAI,IAAG;AAG1B,eAAW,aAAa,gBAAgB;AACtC,YAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,UAAK;AAEL,mBAAW,WAAW,MAAM,aAAY,GAAI;AAC1C,gBAAM,QAAQ,IAAI,aAAa,SAAS,KAAK,QAAQ;AAErD,gBAAM,KAAK,iBAAiB,QAAQ,EAAE,IAAI,GAC1C,MAAM,KAAK,0BAA0B,UAAU,QAAQ,IAAI,CAAC,SAAS,GACrE,MAAM,KAAK,gCAAgC,SAAS,SAAS,GAC7D,MAAM,KAAK,+BAA+B,QAAQ,IAAI,SAAS,GAE3D,QAAQ,eACV,MAAM,KACJ,sCAAsC,UAAU,QAAQ,WAAW,CAAC,SAAS,GAKjF,MAAM,KAAK,oDAAoD,KAAK,sBAAsB,GAC1F,MAAM,KAAK,uBAAuB,GAClC,MAAM,KAAK,uBAAuB,GAClC,MAAM,KAAK,0BAA0B,UAAU,QAAQ,IAAI,CAAC,gBAAgB,GAC5E,MAAM,KAAK,wBAAwB,GACnC,MAAM,KAAK,eAAe,GAE1B,MAAM,KAAK,aAAa,GAExB,WAAW,IAAI,QAAQ,IAAI;YACzB,OAAO;YACP,MAAM,QAAQ;YACd,aAAa,QAAQ;WACtB;QACH;IACF;AAGA,QAAI,cAAc;AAElB,eAAW,aAAa,gBAAgB;AACtC,YAAM,QAAQ,MAAM,MAAM,SAAS,SAAS;AAC5C,UAAK;AAEL,mBAAW,WAAW,MAAM,aAAY,GAAI;AAE1C,qBAAW,OAAO,QAAQ;AACxB,YAAK,WAAW,IAAI,IAAI,MAAM,MAI9B,MAAM,KACJ,kBAAkB,WAAW,aAAa,QAAQ,EAAE,aAAa,IAAI,MAAM,IAAI,GAEjF,MAAM,KAAK,+BAA+B,IAAI,IAAI,SAAS,GAC3D,MAAM,KAAK,0BAA0B,UAAU,IAAI,IAAI,CAAC,SAAS,GAE7D,IAAI,eACN,MAAM,KACJ,iCAAiC,UAAU,IAAI,WAAW,CAAC,SAAS,GAIxE,MAAM,KAAK,aAAa,GACxB;AAIF,qBAAW,OAAO,QAAQ;AACxB,YAAK,WAAW,IAAI,IAAI,MAAM,MAI9B,MAAM,KACJ,kBAAkB,WAAW,aAAa,QAAQ,EAAE,aAAa,IAAI,MAAM,IAAI,GAEjF,MAAM,KAAK,+BAA+B,IAAI,SAAS,SAAS,GAChE,MAAM,KAAK,0BAA0B,UAAU,IAAI,SAAS,CAAC,SAAS,GACtE,MAAM,KAAK,aAAa,GACxB;QAEJ;IACF;AAEA,iBAAM,KAAK,YAAY,GACvB,MAAM,KAAK,YAAY,GAEhB,MAAM,KAAK;CAAI;EACxB;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,17 @@
1
+ import { ExportManager } from "./export-manager.js";
2
+ import { ArchiMateExporter } from "./archimate-exporter.js";
3
+ import { OpenAPIExporter } from "./openapi-exporter.js";
4
+ import { JsonSchemaExporter } from "./json-schema-exporter.js";
5
+ import { PlantUMLExporter } from "./plantuml-exporter.js";
6
+ import { GraphMLExporter } from "./graphml-exporter.js";
7
+ import { MarkdownExporter } from "./markdown-exporter.js";
8
+ export {
9
+ ArchiMateExporter,
10
+ ExportManager,
11
+ GraphMLExporter,
12
+ JsonSchemaExporter,
13
+ MarkdownExporter,
14
+ OpenAPIExporter,
15
+ PlantUMLExporter
16
+ };
17
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/export/index.ts"],
4
+ "sourcesContent": ["export { ExportManager } from \"./export-manager.js\";\nexport type { Exporter, ExportOptions, ExportFormatInfo } from \"./types.js\";\nexport { ArchiMateExporter } from \"./archimate-exporter.js\";\nexport { OpenAPIExporter } from \"./openapi-exporter.js\";\nexport { JsonSchemaExporter } from \"./json-schema-exporter.js\";\nexport { PlantUMLExporter } from \"./plantuml-exporter.js\";\nexport { GraphMLExporter } from \"./graphml-exporter.js\";\nexport { MarkdownExporter } from \"./markdown-exporter.js\";\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAE9B,SAAS,yBAAyB;AAClC,SAAS,uBAAuB;AAChC,SAAS,0BAA0B;AACnC,SAAS,wBAAwB;AACjC,SAAS,uBAAuB;AAChC,SAAS,wBAAwB;",
6
+ "names": []
7
+ }
@@ -0,0 +1,60 @@
1
+ class JsonSchemaExporter {
2
+ name = "JSON Schema";
3
+ supportedLayers = ["data-model", "data_model"];
4
+ async export(model, _options = {}) {
5
+ let layer = await model.getLayer("data-model");
6
+ if (layer || (layer = await model.getLayer("data_model")), !layer)
7
+ throw new Error("No Data Model layer found in model");
8
+ const rootSchema = {
9
+ $schema: "http://json-schema.org/draft-07/schema#",
10
+ $id: `${model.manifest.name.toLowerCase().replace(/\s+/g, "-")}-schema`,
11
+ title: model.manifest.name,
12
+ description: model.manifest.description || "Data model schema",
13
+ type: "object",
14
+ definitions: {}
15
+ };
16
+ for (const element of layer.listElements())
17
+ if (element.type === "entity") {
18
+ const entityName = element.name, properties = element.getProperty("properties"), required = element.getProperty("required"), description = element.description, entitySchema = {
19
+ title: entityName,
20
+ ...description && { description },
21
+ type: "object",
22
+ ...properties && { properties },
23
+ ...required && { required }
24
+ }, additionalProperties = element.getProperty("additionalProperties");
25
+ additionalProperties !== void 0 && (entitySchema.additionalProperties = additionalProperties);
26
+ const constraints = element.getProperty("constraints");
27
+ constraints && Object.assign(entitySchema, constraints), rootSchema.definitions[element.id] = entitySchema;
28
+ }
29
+ const relationships = {};
30
+ for (const element of layer.listElements())
31
+ if (element.type === "entity") {
32
+ for (const ref of element.references) {
33
+ const refKey = `${element.id}-references`;
34
+ relationships[refKey] || (relationships[refKey] = []), relationships[refKey].push({
35
+ target: ref.target,
36
+ type: ref.type
37
+ });
38
+ }
39
+ for (const rel of element.relationships) {
40
+ const relKey = `${element.id}-${rel.predicate}`;
41
+ relationships[relKey] || (relationships[relKey] = []), relationships[relKey].push({
42
+ target: rel.target
43
+ });
44
+ }
45
+ }
46
+ Object.keys(relationships).length > 0 && (rootSchema.relationships = relationships);
47
+ const metadata = {
48
+ version: model.manifest.version || "1.0.0",
49
+ ...model.manifest.author && { author: model.manifest.author },
50
+ ...model.manifest.created && { created: model.manifest.created },
51
+ ...model.manifest.modified && { modified: model.manifest.modified },
52
+ entityCount: Array.from(layer.listElements()).filter((e) => e.type === "entity").length
53
+ };
54
+ return rootSchema.metadata = metadata, JSON.stringify(rootSchema, null, 2);
55
+ }
56
+ }
57
+ export {
58
+ JsonSchemaExporter
59
+ };
60
+ //# sourceMappingURL=json-schema-exporter.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/export/json-schema-exporter.ts"],
4
+ "sourcesContent": ["import type { Model } from \"../core/model.js\";\nimport type { Exporter, ExportOptions } from \"./types.js\";\n\n/**\n * JSON Schema Draft 7 Exporter for layer 7 (Data Model)\n */\nexport class JsonSchemaExporter implements Exporter {\n name = \"JSON Schema\";\n supportedLayers = [\"data-model\", \"data_model\"];\n\n async export(model: Model, _options: ExportOptions = {}): Promise<string> {\n // Try both naming conventions for data model layer\n let layer = await model.getLayer(\"data-model\");\n if (!layer) {\n layer = await model.getLayer(\"data_model\");\n }\n if (!layer) {\n throw new Error(\"No Data Model layer found in model\");\n }\n\n // Create a root schema that references all entities\n const rootSchema: Record<string, unknown> = {\n $schema: \"http://json-schema.org/draft-07/schema#\",\n $id: `${model.manifest.name.toLowerCase().replace(/\\s+/g, \"-\")}-schema`,\n title: model.manifest.name,\n description: model.manifest.description || \"Data model schema\",\n type: \"object\",\n definitions: {},\n };\n\n // Process each entity in the data model layer\n for (const element of layer.listElements()) {\n if (element.type === \"entity\") {\n const entityName = element.name;\n const properties = element.getProperty<Record<string, unknown>>(\n \"properties\"\n );\n const required = element.getProperty<string[]>(\"required\");\n const description = element.description;\n\n const entitySchema: Record<string, unknown> = {\n title: entityName,\n ...(description && { description }),\n type: \"object\",\n ...(properties && { properties }),\n ...(required && { required }),\n };\n\n // Add additional metadata\n const additionalProperties = element.getProperty<boolean>(\n \"additionalProperties\"\n );\n if (additionalProperties !== undefined) {\n entitySchema.additionalProperties = additionalProperties;\n }\n\n // Add constraints if present\n const constraints = element.getProperty<Record<string, unknown>>(\n \"constraints\"\n );\n if (constraints) {\n Object.assign(entitySchema, constraints);\n }\n\n (rootSchema.definitions as Record<string, unknown>)[element.id] = entitySchema;\n }\n }\n\n // Add relationships as references between entities\n const relationships: Record<string, unknown> = {};\n for (const element of layer.listElements()) {\n if (element.type === \"entity\") {\n for (const ref of element.references) {\n // Cross-layer reference - document it\n const refKey = `${element.id}-references`;\n if (!relationships[refKey]) {\n relationships[refKey] = [];\n }\n (relationships[refKey] as Array<{ target: string; type: string }>).push({\n target: ref.target,\n type: ref.type,\n });\n }\n\n for (const rel of element.relationships) {\n // Intra-layer relationship\n const relKey = `${element.id}-${rel.predicate}`;\n if (!relationships[relKey]) {\n relationships[relKey] = [];\n }\n (relationships[relKey] as Array<{ target: string }>).push({\n target: rel.target,\n });\n }\n }\n }\n\n if (Object.keys(relationships).length > 0) {\n rootSchema.relationships = relationships;\n }\n\n // Add metadata section\n const metadata: Record<string, unknown> = {\n version: model.manifest.version || \"1.0.0\",\n ...(model.manifest.author && { author: model.manifest.author }),\n ...(model.manifest.created && { created: model.manifest.created }),\n ...(model.manifest.modified && { modified: model.manifest.modified }),\n entityCount: Array.from(layer.listElements()).filter(\n (e) => e.type === \"entity\"\n ).length,\n };\n rootSchema.metadata = metadata;\n\n return JSON.stringify(rootSchema, null, 2);\n }\n}\n"],
5
+ "mappings": "AAMM,MAAO,mBAAkB;EAC7B,OAAO;EACP,kBAAkB,CAAC,cAAc,YAAY;EAE7C,MAAM,OAAO,OAAc,WAA0B,CAAA,GAAE;AAErD,QAAI,QAAQ,MAAM,MAAM,SAAS,YAAY;AAI7C,QAHK,UACH,QAAQ,MAAM,MAAM,SAAS,YAAY,IAEvC,CAAC;AACH,YAAM,IAAI,MAAM,oCAAoC;AAItD,UAAM,aAAsC;MAC1C,SAAS;MACT,KAAK,GAAG,MAAM,SAAS,KAAK,YAAW,EAAG,QAAQ,QAAQ,GAAG,CAAC;MAC9D,OAAO,MAAM,SAAS;MACtB,aAAa,MAAM,SAAS,eAAe;MAC3C,MAAM;MACN,aAAa,CAAA;;AAIf,eAAW,WAAW,MAAM,aAAY;AACtC,UAAI,QAAQ,SAAS,UAAU;AAC7B,cAAM,aAAa,QAAQ,MACrB,aAAa,QAAQ,YACzB,YAAY,GAER,WAAW,QAAQ,YAAsB,UAAU,GACnD,cAAc,QAAQ,aAEtB,eAAwC;UAC5C,OAAO;UACP,GAAI,eAAe,EAAE,YAAW;UAChC,MAAM;UACN,GAAI,cAAc,EAAE,WAAU;UAC9B,GAAI,YAAY,EAAE,SAAQ;WAItB,uBAAuB,QAAQ,YACnC,sBAAsB;AAExB,QAAI,yBAAyB,WAC3B,aAAa,uBAAuB;AAItC,cAAM,cAAc,QAAQ,YAC1B,aAAa;AAEf,QAAI,eACF,OAAO,OAAO,cAAc,WAAW,GAGxC,WAAW,YAAwC,QAAQ,EAAE,IAAI;MACpE;AAIF,UAAM,gBAAyC,CAAA;AAC/C,eAAW,WAAW,MAAM,aAAY;AACtC,UAAI,QAAQ,SAAS,UAAU;AAC7B,mBAAW,OAAO,QAAQ,YAAY;AAEpC,gBAAM,SAAS,GAAG,QAAQ,EAAE;AAC5B,UAAK,cAAc,MAAM,MACvB,cAAc,MAAM,IAAI,CAAA,IAEzB,cAAc,MAAM,EAA8C,KAAK;YACtE,QAAQ,IAAI;YACZ,MAAM,IAAI;WACX;QACH;AAEA,mBAAW,OAAO,QAAQ,eAAe;AAEvC,gBAAM,SAAS,GAAG,QAAQ,EAAE,IAAI,IAAI,SAAS;AAC7C,UAAK,cAAc,MAAM,MACvB,cAAc,MAAM,IAAI,CAAA,IAEzB,cAAc,MAAM,EAAgC,KAAK;YACxD,QAAQ,IAAI;WACb;QACH;MACF;AAGF,IAAI,OAAO,KAAK,aAAa,EAAE,SAAS,MACtC,WAAW,gBAAgB;AAI7B,UAAM,WAAoC;MACxC,SAAS,MAAM,SAAS,WAAW;MACnC,GAAI,MAAM,SAAS,UAAU,EAAE,QAAQ,MAAM,SAAS,OAAM;MAC5D,GAAI,MAAM,SAAS,WAAW,EAAE,SAAS,MAAM,SAAS,QAAO;MAC/D,GAAI,MAAM,SAAS,YAAY,EAAE,UAAU,MAAM,SAAS,SAAQ;MAClE,aAAa,MAAM,KAAK,MAAM,aAAY,CAAE,EAAE,OAC5C,CAAC,MAAM,EAAE,SAAS,QAAQ,EAC1B;;AAEJ,sBAAW,WAAW,UAEf,KAAK,UAAU,YAAY,MAAM,CAAC;EAC3C;;",
6
+ "names": []
7
+ }
@@ -0,0 +1,99 @@
1
+ import { ALL_LAYERS } from "./types.js";
2
+ class MarkdownExporter {
3
+ name = "Markdown";
4
+ supportedLayers = ALL_LAYERS;
5
+ layerDescriptions = {
6
+ motivation: "Goals, requirements, drivers, and strategic outcomes of the architecture.",
7
+ business: "Business processes, functions, roles, and services.",
8
+ security: "Authentication, authorization, security threats, and controls.",
9
+ application: "Application components, services, and interactions.",
10
+ technology: "Infrastructure, platforms, systems, and technology components.",
11
+ api: "REST APIs, operations, endpoints, and API integrations.",
12
+ "data-model": "Data entities, relationships, and data structure definitions.",
13
+ "data-store": "Databases, data stores, and persistence mechanisms.",
14
+ ux: "User interface components, screens, and user experience elements.",
15
+ navigation: "Application routing, navigation flows, and page structures.",
16
+ apm: "Observability, monitoring, metrics, logging, and tracing.",
17
+ testing: "Test strategies, test cases, test data, and test coverage."
18
+ };
19
+ async export(model, options = {}) {
20
+ const lines = [];
21
+ lines.push(`# ${this.escapeMarkdown(model.manifest.name)}`), lines.push(""), model.manifest.description && (lines.push(`${model.manifest.description}`), lines.push("")), lines.push("## Model Information"), lines.push(""), lines.push("| Property | Value |"), lines.push("| -------- | ----- |"), lines.push(`| Version | ${model.manifest.version || "1.0.0"} |`), model.manifest.author && lines.push(`| Author | ${this.escapeMarkdown(model.manifest.author)} |`), model.manifest.created && lines.push(`| Created | ${model.manifest.created} |`), model.manifest.modified && lines.push(`| Modified | ${model.manifest.modified} |`), lines.push("");
22
+ const layersToExport = options.layers || this.supportedLayers;
23
+ for (const layerName of layersToExport) {
24
+ const layer = await model.getLayer(layerName);
25
+ if (!layer)
26
+ continue;
27
+ const elements = Array.from(layer.listElements());
28
+ if (elements.length === 0)
29
+ continue;
30
+ lines.push(`## Layer: ${this.formatLayerName(layerName)}`), lines.push("");
31
+ const description = this.layerDescriptions[layerName];
32
+ description && (lines.push(`*${description}*`), lines.push("")), lines.push(`### Elements (${elements.length})`), lines.push(""), lines.push("| ID | Name | Type | Description |"), lines.push("| -- | ---- | ---- | ----------- |");
33
+ for (const element of elements) {
34
+ const id = this.escapeMarkdown(element.id), name = this.escapeMarkdown(element.name), type = this.escapeMarkdown(element.type), desc = element.description ? this.escapeMarkdown(element.description).substring(0, 100) : "";
35
+ lines.push(`| \`${id}\` | ${name} | ${type} | ${desc} |`);
36
+ }
37
+ lines.push(""), lines.push("### Element Details"), lines.push("");
38
+ for (const element of elements) {
39
+ if (lines.push(`#### ${this.escapeMarkdown(element.name)} (\`${element.id}\`)`), lines.push(""), element.description && (lines.push(`${element.description}`), lines.push("")), lines.push("**Type:** " + element.type), lines.push(""), Object.keys(element.properties).length > 0) {
40
+ lines.push("**Properties:**"), lines.push(""), lines.push("| Property | Value |"), lines.push("| -------- | ----- |");
41
+ for (const [key, value] of Object.entries(element.properties)) {
42
+ const displayValue = this.valueToMarkdown(value);
43
+ lines.push(`| \`${key}\` | ${displayValue} |`);
44
+ }
45
+ lines.push("");
46
+ }
47
+ if (element.references.length > 0) {
48
+ lines.push("**Cross-Layer References:**"), lines.push("");
49
+ for (const ref of element.references) {
50
+ const refDesc = ref.description ? ` - ${this.escapeMarkdown(ref.description)}` : "";
51
+ lines.push(`- **${ref.type}**: \`${ref.target}\`${refDesc}`);
52
+ }
53
+ lines.push("");
54
+ }
55
+ if (element.relationships.length > 0) {
56
+ lines.push("**Relationships:**"), lines.push("");
57
+ for (const rel of element.relationships)
58
+ lines.push(`- **${rel.predicate}**: \`${rel.target}\``);
59
+ lines.push("");
60
+ }
61
+ }
62
+ lines.push("### Layer Summary"), lines.push(""), lines.push(`- **Total Elements:** ${elements.length}`);
63
+ const refCount = elements.reduce((sum, e) => sum + e.references.length, 0), relCount = elements.reduce((sum, e) => sum + e.relationships.length, 0);
64
+ lines.push(`- **Cross-Layer References:** ${refCount}`), lines.push(`- **Relationships:** ${relCount}`), lines.push(""), lines.push("---"), lines.push("");
65
+ }
66
+ lines.push("## Architecture Summary"), lines.push("");
67
+ let totalElements = 0, totalReferences = 0, totalRelationships = 0;
68
+ for (const layerName of layersToExport) {
69
+ const layer = await model.getLayer(layerName);
70
+ if (layer)
71
+ for (const element of layer.listElements())
72
+ totalElements++, totalReferences += element.references.length, totalRelationships += element.relationships.length;
73
+ }
74
+ return lines.push("| Metric | Count |"), lines.push("| ------ | ----- |"), lines.push(`| Total Elements | ${totalElements} |`), lines.push(`| Cross-Layer References | ${totalReferences} |`), lines.push(`| Relationships | ${totalRelationships} |`), lines.push(""), lines.join(`
75
+ `);
76
+ }
77
+ /**
78
+ * Escape markdown special characters
79
+ */
80
+ escapeMarkdown(str) {
81
+ return str.replace(/\\/g, "\\\\").replace(/\|/g, "\\|").replace(/\*/g, "\\*").replace(/\[/g, "\\[").replace(/\]/g, "\\]").replace(/\{/g, "\\{").replace(/\}/g, "\\}");
82
+ }
83
+ /**
84
+ * Format layer name for display
85
+ */
86
+ formatLayerName(name) {
87
+ return name.split("-").map((word) => word.charAt(0).toUpperCase() + word.slice(1)).join(" ");
88
+ }
89
+ /**
90
+ * Convert value to markdown representation
91
+ */
92
+ valueToMarkdown(value) {
93
+ return typeof value == "string" ? this.escapeMarkdown(value) : typeof value == "number" || typeof value == "boolean" ? String(value) : Array.isArray(value) ? `[${value.map((v) => this.valueToMarkdown(v)).join(", ")}]` : value && typeof value == "object" ? `\`${this.escapeMarkdown(JSON.stringify(value))}\`` : String(value);
94
+ }
95
+ }
96
+ export {
97
+ MarkdownExporter
98
+ };
99
+ //# sourceMappingURL=markdown-exporter.js.map