@agilewallaby/c4-model 2.5.0 → 2.7.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/package.json +1 -1
- package/src/buildModel.d.ts +4 -2
- package/src/container.d.ts +6 -6
- package/src/core.d.ts +6 -3
- package/src/index.cjs +33 -21
- package/src/index.d.ts +34 -30
- package/src/index.js +33 -21
- package/src/model.d.ts +14 -14
- package/src/softwareSystem.d.ts +6 -6
package/package.json
CHANGED
package/src/buildModel.d.ts
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
import { Model } from './model';
|
|
2
|
+
import { ElementArchetype, RelationshipArchetype } from './archetype';
|
|
2
3
|
type Catalog = Record<string, unknown>;
|
|
3
4
|
type RootCatalog = Record<string, Catalog>;
|
|
4
5
|
export interface AnyC4Module {
|
|
5
6
|
readonly key: string;
|
|
6
|
-
registerDefinitions(model: Model): Catalog;
|
|
7
|
-
buildRelationships(local: Catalog, dependencies: RootCatalog): void;
|
|
7
|
+
registerDefinitions(model: Model, archetypes: Record<string, ElementArchetype | RelationshipArchetype>): Catalog;
|
|
8
|
+
buildRelationships(local: Catalog, dependencies: RootCatalog, archetypes: Record<string, ElementArchetype | RelationshipArchetype>): void;
|
|
8
9
|
}
|
|
9
10
|
export interface BuildModelOptions {
|
|
10
11
|
modelName?: string;
|
|
11
12
|
modules?: ReadonlyArray<AnyC4Module>;
|
|
12
13
|
globPath?: string;
|
|
13
14
|
searchRoot?: string;
|
|
15
|
+
archetypes?: Record<string, ElementArchetype | RelationshipArchetype>;
|
|
14
16
|
}
|
|
15
17
|
export declare function buildModelWithCatalog<TRoot>(options?: BuildModelOptions): Promise<{
|
|
16
18
|
model: Model;
|
package/src/container.d.ts
CHANGED
|
@@ -3,23 +3,23 @@ import { Component, ComponentDefinition } from './component';
|
|
|
3
3
|
import { ElementArchetype } from './archetype';
|
|
4
4
|
export type ContainerDefinition = TechnologyDefinition;
|
|
5
5
|
interface DefineComponent {
|
|
6
|
-
|
|
6
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
7
7
|
}
|
|
8
|
-
export declare class ContainerGroup extends Group implements DefineComponent {
|
|
8
|
+
export declare class ContainerGroup extends Group<Component> implements DefineComponent {
|
|
9
9
|
readonly name: string;
|
|
10
10
|
private readonly container;
|
|
11
11
|
private _components;
|
|
12
12
|
constructor(name: string, container: DefineComponent);
|
|
13
|
-
|
|
13
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
14
14
|
getComponents(): ReadonlyArray<Component>;
|
|
15
15
|
}
|
|
16
|
-
export declare class Container extends TechnicalElement implements DefineComponent {
|
|
16
|
+
export declare class Container extends TechnicalElement<Component> implements DefineComponent {
|
|
17
17
|
readonly name: string;
|
|
18
18
|
private _components;
|
|
19
19
|
private _groups;
|
|
20
20
|
constructor(name: string, definition?: ContainerDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
22
|
+
group(groupName: string): ContainerGroup;
|
|
23
23
|
getGroups(): ReadonlyArray<ContainerGroup>;
|
|
24
24
|
getComponentsNotInGroups(): ReadonlyArray<Component>;
|
|
25
25
|
getChildElements(): ReadonlyArray<Element>;
|
package/src/core.d.ts
CHANGED
|
@@ -6,7 +6,7 @@ export interface Definition {
|
|
|
6
6
|
export interface TechnologyDefinition extends Definition {
|
|
7
7
|
technology?: string;
|
|
8
8
|
}
|
|
9
|
-
export declare abstract class Element {
|
|
9
|
+
export declare abstract class Element<TChild extends Element = never> {
|
|
10
10
|
readonly name: string;
|
|
11
11
|
readonly description?: string;
|
|
12
12
|
readonly tags: ReadonlyArray<string>;
|
|
@@ -17,11 +17,12 @@ export declare abstract class Element {
|
|
|
17
17
|
get canonicalName(): string;
|
|
18
18
|
uses(otherElement: Element, archetypeOrDef?: RelationshipArchetype | TechnologyDefinition, override?: TechnologyDefinition): void;
|
|
19
19
|
get relationships(): ReadonlyArray<Relationship>;
|
|
20
|
+
with<TChildren extends Record<string, TChild>>(callback: (self: this) => TChildren): this & TChildren;
|
|
20
21
|
abstract getChildElements(): ReadonlyArray<Element>;
|
|
21
22
|
getRelationshipsInHierarchy(): ReadonlyArray<Relationship>;
|
|
22
23
|
getChildElementNames(path?: string): ReadonlyArray<string>;
|
|
23
24
|
}
|
|
24
|
-
export declare abstract class TechnicalElement extends Element {
|
|
25
|
+
export declare abstract class TechnicalElement<TChild extends Element = never> extends Element<TChild> {
|
|
25
26
|
readonly technology?: string;
|
|
26
27
|
constructor(name: string, defaultTags?: string[], definition?: TechnologyDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
27
28
|
}
|
|
@@ -35,7 +36,9 @@ export declare class Relationship {
|
|
|
35
36
|
readonly overrideDefinition?: TechnologyDefinition;
|
|
36
37
|
constructor(source: Element, destination: Element, definition?: TechnologyDefinition, archetype?: RelationshipArchetype, overrideDefinition?: TechnologyDefinition);
|
|
37
38
|
}
|
|
38
|
-
export declare class Group {
|
|
39
|
+
export declare class Group<TChild extends Element | Group = never> {
|
|
39
40
|
readonly name: string;
|
|
40
41
|
constructor(name: string);
|
|
42
|
+
get canonicalName(): string;
|
|
43
|
+
with<TChildren extends Record<string, TChild>>(callback: (self: this) => TChildren): this & TChildren;
|
|
41
44
|
}
|
package/src/index.cjs
CHANGED
|
@@ -214,6 +214,10 @@ var Element = class {
|
|
|
214
214
|
get relationships() {
|
|
215
215
|
return this._relationships;
|
|
216
216
|
}
|
|
217
|
+
with(callback) {
|
|
218
|
+
const children = callback(this);
|
|
219
|
+
return Object.assign(this, children);
|
|
220
|
+
}
|
|
217
221
|
getRelationshipsInHierarchy() {
|
|
218
222
|
return this._relationships.concat(this.getChildElements().flatMap((element) => element.getRelationshipsInHierarchy()));
|
|
219
223
|
}
|
|
@@ -252,6 +256,13 @@ var Group = class {
|
|
|
252
256
|
constructor(name) {
|
|
253
257
|
this.name = name;
|
|
254
258
|
}
|
|
259
|
+
get canonicalName() {
|
|
260
|
+
return camelCase(this.name);
|
|
261
|
+
}
|
|
262
|
+
with(callback) {
|
|
263
|
+
const children = callback(this);
|
|
264
|
+
return Object.assign(this, children);
|
|
265
|
+
}
|
|
255
266
|
// TODO: Implement this in some useful way?
|
|
256
267
|
// public addToGroup(groupCollection: string, groupMember: T) {}
|
|
257
268
|
};
|
|
@@ -275,8 +286,8 @@ var ContainerGroup = class extends Group {
|
|
|
275
286
|
this.container = container;
|
|
276
287
|
}
|
|
277
288
|
_components = /* @__PURE__ */ new Map();
|
|
278
|
-
|
|
279
|
-
const component = this.container.
|
|
289
|
+
component(name, archetypeOrDef, override) {
|
|
290
|
+
const component = this.container.component(name, archetypeOrDef, override);
|
|
280
291
|
this._components.set(name, component);
|
|
281
292
|
return component;
|
|
282
293
|
}
|
|
@@ -291,7 +302,7 @@ var Container = class extends TechnicalElement {
|
|
|
291
302
|
}
|
|
292
303
|
_components = /* @__PURE__ */ new Map();
|
|
293
304
|
_groups = /* @__PURE__ */ new Map();
|
|
294
|
-
|
|
305
|
+
component(name, archetypeOrDef, override) {
|
|
295
306
|
if (this._components.has(name)) {
|
|
296
307
|
throw Error(`A Component named '${name}' is defined elsewhere in this Container. A Component can be defined only once.`);
|
|
297
308
|
}
|
|
@@ -307,7 +318,7 @@ var Container = class extends TechnicalElement {
|
|
|
307
318
|
this._components.set(name, component);
|
|
308
319
|
return component;
|
|
309
320
|
}
|
|
310
|
-
|
|
321
|
+
group(groupName) {
|
|
311
322
|
let group = this._groups.get(groupName);
|
|
312
323
|
if (!group) {
|
|
313
324
|
group = new ContainerGroup(groupName, this);
|
|
@@ -335,8 +346,8 @@ var SoftwareSystemGroup = class extends Group {
|
|
|
335
346
|
this.softwareSystem = softwareSystem;
|
|
336
347
|
}
|
|
337
348
|
_containers = /* @__PURE__ */ new Map();
|
|
338
|
-
|
|
339
|
-
const container = this.softwareSystem.
|
|
349
|
+
container(name, archetypeOrDef, override) {
|
|
350
|
+
const container = this.softwareSystem.container(name, archetypeOrDef, override);
|
|
340
351
|
this._containers.set(name, container);
|
|
341
352
|
return container;
|
|
342
353
|
}
|
|
@@ -351,7 +362,7 @@ var SoftwareSystem = class extends Element {
|
|
|
351
362
|
}
|
|
352
363
|
_containers = /* @__PURE__ */ new Map();
|
|
353
364
|
_groups = /* @__PURE__ */ new Map();
|
|
354
|
-
|
|
365
|
+
container(name, archetypeOrDef, override) {
|
|
355
366
|
if (this._containers.has(name)) {
|
|
356
367
|
throw Error(`A Container named '${name}' is defined elsewhere in this SoftwareSystem. A Container can be defined only once.`);
|
|
357
368
|
}
|
|
@@ -367,7 +378,7 @@ var SoftwareSystem = class extends Element {
|
|
|
367
378
|
this._containers.set(name, container);
|
|
368
379
|
return container;
|
|
369
380
|
}
|
|
370
|
-
|
|
381
|
+
group(groupName) {
|
|
371
382
|
let group = this._groups.get(groupName);
|
|
372
383
|
if (!group) {
|
|
373
384
|
group = new SoftwareSystemGroup(groupName, this);
|
|
@@ -407,13 +418,13 @@ var ModelGroup = class extends Group {
|
|
|
407
418
|
}
|
|
408
419
|
softwareSystems = /* @__PURE__ */ new Map();
|
|
409
420
|
people = /* @__PURE__ */ new Map();
|
|
410
|
-
|
|
411
|
-
const softwareSystem = this.model.
|
|
421
|
+
softwareSystem(name, archetypeOrDef, override) {
|
|
422
|
+
const softwareSystem = this.model.softwareSystem(name, archetypeOrDef, override);
|
|
412
423
|
this.softwareSystems.set(name, softwareSystem);
|
|
413
424
|
return softwareSystem;
|
|
414
425
|
}
|
|
415
|
-
|
|
416
|
-
const person = this.model.
|
|
426
|
+
person(name, archetypeOrDef, override) {
|
|
427
|
+
const person = this.model.person(name, archetypeOrDef, override);
|
|
417
428
|
this.people.set(name, person);
|
|
418
429
|
return person;
|
|
419
430
|
}
|
|
@@ -431,7 +442,7 @@ var Model = class {
|
|
|
431
442
|
softwareSystems = /* @__PURE__ */ new Map();
|
|
432
443
|
people = /* @__PURE__ */ new Map();
|
|
433
444
|
groups = /* @__PURE__ */ new Map();
|
|
434
|
-
|
|
445
|
+
softwareSystem(name, archetypeOrDef, override) {
|
|
435
446
|
if (this.softwareSystems.has(name)) {
|
|
436
447
|
throw Error(`A SoftwareSystem named '${name}' is defined elsewhere in this Model. A SoftwareSystem can be defined only once.`);
|
|
437
448
|
}
|
|
@@ -448,7 +459,7 @@ var Model = class {
|
|
|
448
459
|
return system;
|
|
449
460
|
}
|
|
450
461
|
// TODO:Should be a Group<SoftwareSystem | Person> if that is added back in
|
|
451
|
-
|
|
462
|
+
group(groupName) {
|
|
452
463
|
let group = this.groups.get(groupName);
|
|
453
464
|
if (!group) {
|
|
454
465
|
group = new ModelGroup(groupName, this);
|
|
@@ -456,7 +467,7 @@ var Model = class {
|
|
|
456
467
|
}
|
|
457
468
|
return group;
|
|
458
469
|
}
|
|
459
|
-
|
|
470
|
+
person(name, archetypeOrDef, override) {
|
|
460
471
|
if (this.people.has(name)) {
|
|
461
472
|
throw Error(`A Person named '${name}' is defined elsewhere in this Model. A Person can be defined only once.`);
|
|
462
473
|
}
|
|
@@ -472,6 +483,7 @@ var Model = class {
|
|
|
472
483
|
this.people.set(name, person);
|
|
473
484
|
return person;
|
|
474
485
|
}
|
|
486
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
475
487
|
validate() {
|
|
476
488
|
}
|
|
477
489
|
getPeople() {
|
|
@@ -698,7 +710,7 @@ var StructurizrDSLWriter = class {
|
|
|
698
710
|
}
|
|
699
711
|
writeContainerGroup(group, level) {
|
|
700
712
|
let containerGroupDsl = "";
|
|
701
|
-
containerGroupDsl += this.writeLine(`${group.
|
|
713
|
+
containerGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
702
714
|
group.getComponents().forEach((component) => {
|
|
703
715
|
containerGroupDsl += this.writeComponent(component, level + 1);
|
|
704
716
|
});
|
|
@@ -722,7 +734,7 @@ var StructurizrDSLWriter = class {
|
|
|
722
734
|
}
|
|
723
735
|
writeSoftwareSystemGroup(group, level) {
|
|
724
736
|
let softwareSystemGroupDsl = "";
|
|
725
|
-
softwareSystemGroupDsl += this.writeLine(`${group.
|
|
737
|
+
softwareSystemGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
726
738
|
group.getContainers().forEach((container) => {
|
|
727
739
|
softwareSystemGroupDsl += this.writeContainer(container, level + 1);
|
|
728
740
|
});
|
|
@@ -780,7 +792,7 @@ var StructurizrDSLWriter = class {
|
|
|
780
792
|
}
|
|
781
793
|
writeModelGroup(group, level) {
|
|
782
794
|
let modelGroupDsl = "";
|
|
783
|
-
modelGroupDsl += this.writeLine(`${group.
|
|
795
|
+
modelGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
784
796
|
group.getPeople().forEach((person) => {
|
|
785
797
|
modelGroupDsl += this.writeElement("person", person, level + 1);
|
|
786
798
|
});
|
|
@@ -866,7 +878,7 @@ var import_url = require("url");
|
|
|
866
878
|
var import_meta = {};
|
|
867
879
|
var _dirname = typeof __dirname !== "undefined" ? __dirname : (0, import_path.dirname)((0, import_url.fileURLToPath)(import_meta.url));
|
|
868
880
|
async function buildModelWithCatalog(options = {}) {
|
|
869
|
-
const { modelName = "model", modules: explicitModules } = options;
|
|
881
|
+
const { modelName = "model", modules: explicitModules, archetypes = {} } = options;
|
|
870
882
|
const model = new Model(modelName);
|
|
871
883
|
let c4Modules;
|
|
872
884
|
if (explicitModules) {
|
|
@@ -886,13 +898,13 @@ async function buildModelWithCatalog(options = {}) {
|
|
|
886
898
|
const registrations = [];
|
|
887
899
|
const rootCatalog = {};
|
|
888
900
|
for (const instance of c4Modules) {
|
|
889
|
-
const local = instance.registerDefinitions(model);
|
|
901
|
+
const local = instance.registerDefinitions(model, archetypes);
|
|
890
902
|
rootCatalog[instance.key] = local;
|
|
891
903
|
registrations.push({ instance, key: instance.key, local });
|
|
892
904
|
}
|
|
893
905
|
for (const { instance, key, local } of registrations) {
|
|
894
906
|
const dependencies = Object.fromEntries(Object.entries(rootCatalog).filter(([k]) => k !== key));
|
|
895
|
-
instance.buildRelationships(local, dependencies);
|
|
907
|
+
instance.buildRelationships(local, dependencies, archetypes);
|
|
896
908
|
}
|
|
897
909
|
return { model, catalog: rootCatalog };
|
|
898
910
|
}
|
package/src/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@ export interface Definition {
|
|
|
7
7
|
export interface TechnologyDefinition extends Definition {
|
|
8
8
|
technology?: string;
|
|
9
9
|
}
|
|
10
|
-
declare abstract class Element$1 {
|
|
10
|
+
declare abstract class Element$1<TChild extends Element$1 = never> {
|
|
11
11
|
readonly name: string;
|
|
12
12
|
readonly description?: string;
|
|
13
13
|
readonly tags: ReadonlyArray<string>;
|
|
@@ -18,11 +18,12 @@ declare abstract class Element$1 {
|
|
|
18
18
|
get canonicalName(): string;
|
|
19
19
|
uses(otherElement: Element$1, archetypeOrDef?: RelationshipArchetype | TechnologyDefinition, override?: TechnologyDefinition): void;
|
|
20
20
|
get relationships(): ReadonlyArray<Relationship>;
|
|
21
|
+
with<TChildren extends Record<string, TChild>>(callback: (self: this) => TChildren): this & TChildren;
|
|
21
22
|
abstract getChildElements(): ReadonlyArray<Element$1>;
|
|
22
23
|
getRelationshipsInHierarchy(): ReadonlyArray<Relationship>;
|
|
23
24
|
getChildElementNames(path?: string): ReadonlyArray<string>;
|
|
24
25
|
}
|
|
25
|
-
declare abstract class TechnicalElement extends Element$1 {
|
|
26
|
+
declare abstract class TechnicalElement<TChild extends Element$1 = never> extends Element$1<TChild> {
|
|
26
27
|
readonly technology?: string;
|
|
27
28
|
constructor(name: string, defaultTags?: string[], definition?: TechnologyDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
28
29
|
}
|
|
@@ -36,9 +37,11 @@ declare class Relationship {
|
|
|
36
37
|
readonly overrideDefinition?: TechnologyDefinition;
|
|
37
38
|
constructor(source: Element$1, destination: Element$1, definition?: TechnologyDefinition, archetype?: RelationshipArchetype, overrideDefinition?: TechnologyDefinition);
|
|
38
39
|
}
|
|
39
|
-
declare class Group {
|
|
40
|
+
declare class Group<TChild extends Element$1 | Group = never> {
|
|
40
41
|
readonly name: string;
|
|
41
42
|
constructor(name: string);
|
|
43
|
+
get canonicalName(): string;
|
|
44
|
+
with<TChildren extends Record<string, TChild>>(callback: (self: this) => TChildren): this & TChildren;
|
|
42
45
|
}
|
|
43
46
|
export type ElementKind = "person" | "softwareSystem" | "container" | "component";
|
|
44
47
|
export declare class ElementArchetype {
|
|
@@ -77,49 +80,49 @@ export declare class Component extends TechnicalElement {
|
|
|
77
80
|
}
|
|
78
81
|
export type ContainerDefinition = TechnologyDefinition;
|
|
79
82
|
export interface DefineComponent {
|
|
80
|
-
|
|
83
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
81
84
|
}
|
|
82
|
-
export declare class ContainerGroup extends Group implements DefineComponent {
|
|
85
|
+
export declare class ContainerGroup extends Group<Component> implements DefineComponent {
|
|
83
86
|
readonly name: string;
|
|
84
87
|
private readonly container;
|
|
85
88
|
private _components;
|
|
86
89
|
constructor(name: string, container: DefineComponent);
|
|
87
|
-
|
|
90
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
88
91
|
getComponents(): ReadonlyArray<Component>;
|
|
89
92
|
}
|
|
90
|
-
export declare class Container extends TechnicalElement implements DefineComponent {
|
|
93
|
+
export declare class Container extends TechnicalElement<Component> implements DefineComponent {
|
|
91
94
|
readonly name: string;
|
|
92
95
|
private _components;
|
|
93
96
|
private _groups;
|
|
94
97
|
constructor(name: string, definition?: ContainerDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
95
|
-
|
|
96
|
-
|
|
98
|
+
component(name: string, archetypeOrDef?: ElementArchetype | ComponentDefinition, override?: ComponentDefinition): Component;
|
|
99
|
+
group(groupName: string): ContainerGroup;
|
|
97
100
|
getGroups(): ReadonlyArray<ContainerGroup>;
|
|
98
101
|
getComponentsNotInGroups(): ReadonlyArray<Component>;
|
|
99
102
|
getChildElements(): ReadonlyArray<Element$1>;
|
|
100
103
|
}
|
|
101
104
|
export type SoftwareSystemDefinition = Definition;
|
|
102
105
|
export interface DefineContainer {
|
|
103
|
-
|
|
106
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
104
107
|
}
|
|
105
108
|
export interface SoftwareSystemReference {
|
|
106
109
|
name: string;
|
|
107
110
|
}
|
|
108
|
-
export declare class SoftwareSystemGroup extends Group implements DefineContainer {
|
|
111
|
+
export declare class SoftwareSystemGroup extends Group<Container> implements DefineContainer {
|
|
109
112
|
readonly name: string;
|
|
110
113
|
private readonly softwareSystem;
|
|
111
114
|
private _containers;
|
|
112
115
|
constructor(name: string, softwareSystem: DefineContainer);
|
|
113
|
-
|
|
116
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
114
117
|
getContainers(): ReadonlyArray<Container>;
|
|
115
118
|
}
|
|
116
|
-
export declare class SoftwareSystem extends Element$1 implements DefineContainer {
|
|
119
|
+
export declare class SoftwareSystem extends Element$1<Container> implements DefineContainer {
|
|
117
120
|
readonly name: string;
|
|
118
121
|
private _containers;
|
|
119
122
|
private _groups;
|
|
120
123
|
constructor(name: string, definition?: SoftwareSystemDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
121
|
-
|
|
122
|
-
|
|
124
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
125
|
+
group(groupName: string): SoftwareSystemGroup;
|
|
123
126
|
getGroups(): ReadonlyArray<SoftwareSystemGroup>;
|
|
124
127
|
getChildElements(): ReadonlyArray<Element$1>;
|
|
125
128
|
getContainersNotInGroups(): ReadonlyArray<Container>;
|
|
@@ -134,31 +137,31 @@ export type CatalogKeyOf<TRoot, TModule> = {
|
|
|
134
137
|
[K in keyof TRoot]: TRoot[K] extends TModule ? K : never;
|
|
135
138
|
}[keyof TRoot];
|
|
136
139
|
export type Dependencies<TRoot, TModule> = Omit<TRoot, CatalogKeyOf<TRoot, TModule>>;
|
|
137
|
-
export interface C4Module<TRoot, TLocal
|
|
140
|
+
export interface C4Module<TRoot, TLocal, TArchetypes = Record<string, ElementArchetype | RelationshipArchetype>> {
|
|
138
141
|
readonly key: CatalogKeyOf<TRoot, TLocal>;
|
|
139
|
-
registerDefinitions(model: Model): TLocal;
|
|
140
|
-
buildRelationships(local: TLocal, dependencies: Dependencies<TRoot, TLocal
|
|
142
|
+
registerDefinitions(model: Model, archetypes: TArchetypes): TLocal;
|
|
143
|
+
buildRelationships(local: TLocal, dependencies: Dependencies<TRoot, TLocal>, archetypes: TArchetypes): void;
|
|
141
144
|
}
|
|
142
145
|
export interface DefineSoftwareSystem {
|
|
143
|
-
|
|
146
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
144
147
|
}
|
|
145
148
|
export interface DefinePerson {
|
|
146
|
-
|
|
149
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
147
150
|
}
|
|
148
|
-
export declare class ModelGroup extends Group implements DefineSoftwareSystem, DefinePerson {
|
|
151
|
+
export declare class ModelGroup extends Group<Person | SoftwareSystem> implements DefineSoftwareSystem, DefinePerson {
|
|
149
152
|
readonly name: string;
|
|
150
153
|
private readonly model;
|
|
151
154
|
private softwareSystems;
|
|
152
155
|
private people;
|
|
153
156
|
constructor(name: string, model: DefineSoftwareSystem & DefinePerson);
|
|
154
|
-
|
|
155
|
-
|
|
157
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
158
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
156
159
|
getSoftwareSystems(): ReadonlyArray<SoftwareSystem>;
|
|
157
160
|
getPeople(): ReadonlyArray<Person>;
|
|
158
161
|
}
|
|
159
162
|
export interface ModelDefinitions {
|
|
160
|
-
|
|
161
|
-
|
|
163
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
164
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
162
165
|
}
|
|
163
166
|
export declare class Model {
|
|
164
167
|
name: string;
|
|
@@ -166,9 +169,9 @@ export declare class Model {
|
|
|
166
169
|
private softwareSystems;
|
|
167
170
|
private people;
|
|
168
171
|
private groups;
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
173
|
+
group(groupName: string): Group & ModelDefinitions;
|
|
174
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
172
175
|
validate(): void;
|
|
173
176
|
getPeople(): ReadonlyArray<Person>;
|
|
174
177
|
getSoftwareSystems(): ReadonlyArray<SoftwareSystem>;
|
|
@@ -235,14 +238,15 @@ export type Catalog = Record<string, unknown>;
|
|
|
235
238
|
export type RootCatalog = Record<string, Catalog>;
|
|
236
239
|
export interface AnyC4Module {
|
|
237
240
|
readonly key: string;
|
|
238
|
-
registerDefinitions(model: Model): Catalog;
|
|
239
|
-
buildRelationships(local: Catalog, dependencies: RootCatalog): void;
|
|
241
|
+
registerDefinitions(model: Model, archetypes: Record<string, ElementArchetype | RelationshipArchetype>): Catalog;
|
|
242
|
+
buildRelationships(local: Catalog, dependencies: RootCatalog, archetypes: Record<string, ElementArchetype | RelationshipArchetype>): void;
|
|
240
243
|
}
|
|
241
244
|
export interface BuildModelOptions {
|
|
242
245
|
modelName?: string;
|
|
243
246
|
modules?: ReadonlyArray<AnyC4Module>;
|
|
244
247
|
globPath?: string;
|
|
245
248
|
searchRoot?: string;
|
|
249
|
+
archetypes?: Record<string, ElementArchetype | RelationshipArchetype>;
|
|
246
250
|
}
|
|
247
251
|
export declare function buildModelWithCatalog<TRoot>(options?: BuildModelOptions): Promise<{
|
|
248
252
|
model: Model;
|
package/src/index.js
CHANGED
|
@@ -162,6 +162,10 @@ var Element = class {
|
|
|
162
162
|
get relationships() {
|
|
163
163
|
return this._relationships;
|
|
164
164
|
}
|
|
165
|
+
with(callback) {
|
|
166
|
+
const children = callback(this);
|
|
167
|
+
return Object.assign(this, children);
|
|
168
|
+
}
|
|
165
169
|
getRelationshipsInHierarchy() {
|
|
166
170
|
return this._relationships.concat(this.getChildElements().flatMap((element) => element.getRelationshipsInHierarchy()));
|
|
167
171
|
}
|
|
@@ -200,6 +204,13 @@ var Group = class {
|
|
|
200
204
|
constructor(name) {
|
|
201
205
|
this.name = name;
|
|
202
206
|
}
|
|
207
|
+
get canonicalName() {
|
|
208
|
+
return camelCase(this.name);
|
|
209
|
+
}
|
|
210
|
+
with(callback) {
|
|
211
|
+
const children = callback(this);
|
|
212
|
+
return Object.assign(this, children);
|
|
213
|
+
}
|
|
203
214
|
// TODO: Implement this in some useful way?
|
|
204
215
|
// public addToGroup(groupCollection: string, groupMember: T) {}
|
|
205
216
|
};
|
|
@@ -223,8 +234,8 @@ var ContainerGroup = class extends Group {
|
|
|
223
234
|
this.container = container;
|
|
224
235
|
}
|
|
225
236
|
_components = /* @__PURE__ */ new Map();
|
|
226
|
-
|
|
227
|
-
const component = this.container.
|
|
237
|
+
component(name, archetypeOrDef, override) {
|
|
238
|
+
const component = this.container.component(name, archetypeOrDef, override);
|
|
228
239
|
this._components.set(name, component);
|
|
229
240
|
return component;
|
|
230
241
|
}
|
|
@@ -239,7 +250,7 @@ var Container = class extends TechnicalElement {
|
|
|
239
250
|
}
|
|
240
251
|
_components = /* @__PURE__ */ new Map();
|
|
241
252
|
_groups = /* @__PURE__ */ new Map();
|
|
242
|
-
|
|
253
|
+
component(name, archetypeOrDef, override) {
|
|
243
254
|
if (this._components.has(name)) {
|
|
244
255
|
throw Error(`A Component named '${name}' is defined elsewhere in this Container. A Component can be defined only once.`);
|
|
245
256
|
}
|
|
@@ -255,7 +266,7 @@ var Container = class extends TechnicalElement {
|
|
|
255
266
|
this._components.set(name, component);
|
|
256
267
|
return component;
|
|
257
268
|
}
|
|
258
|
-
|
|
269
|
+
group(groupName) {
|
|
259
270
|
let group = this._groups.get(groupName);
|
|
260
271
|
if (!group) {
|
|
261
272
|
group = new ContainerGroup(groupName, this);
|
|
@@ -283,8 +294,8 @@ var SoftwareSystemGroup = class extends Group {
|
|
|
283
294
|
this.softwareSystem = softwareSystem;
|
|
284
295
|
}
|
|
285
296
|
_containers = /* @__PURE__ */ new Map();
|
|
286
|
-
|
|
287
|
-
const container = this.softwareSystem.
|
|
297
|
+
container(name, archetypeOrDef, override) {
|
|
298
|
+
const container = this.softwareSystem.container(name, archetypeOrDef, override);
|
|
288
299
|
this._containers.set(name, container);
|
|
289
300
|
return container;
|
|
290
301
|
}
|
|
@@ -299,7 +310,7 @@ var SoftwareSystem = class extends Element {
|
|
|
299
310
|
}
|
|
300
311
|
_containers = /* @__PURE__ */ new Map();
|
|
301
312
|
_groups = /* @__PURE__ */ new Map();
|
|
302
|
-
|
|
313
|
+
container(name, archetypeOrDef, override) {
|
|
303
314
|
if (this._containers.has(name)) {
|
|
304
315
|
throw Error(`A Container named '${name}' is defined elsewhere in this SoftwareSystem. A Container can be defined only once.`);
|
|
305
316
|
}
|
|
@@ -315,7 +326,7 @@ var SoftwareSystem = class extends Element {
|
|
|
315
326
|
this._containers.set(name, container);
|
|
316
327
|
return container;
|
|
317
328
|
}
|
|
318
|
-
|
|
329
|
+
group(groupName) {
|
|
319
330
|
let group = this._groups.get(groupName);
|
|
320
331
|
if (!group) {
|
|
321
332
|
group = new SoftwareSystemGroup(groupName, this);
|
|
@@ -355,13 +366,13 @@ var ModelGroup = class extends Group {
|
|
|
355
366
|
}
|
|
356
367
|
softwareSystems = /* @__PURE__ */ new Map();
|
|
357
368
|
people = /* @__PURE__ */ new Map();
|
|
358
|
-
|
|
359
|
-
const softwareSystem = this.model.
|
|
369
|
+
softwareSystem(name, archetypeOrDef, override) {
|
|
370
|
+
const softwareSystem = this.model.softwareSystem(name, archetypeOrDef, override);
|
|
360
371
|
this.softwareSystems.set(name, softwareSystem);
|
|
361
372
|
return softwareSystem;
|
|
362
373
|
}
|
|
363
|
-
|
|
364
|
-
const person = this.model.
|
|
374
|
+
person(name, archetypeOrDef, override) {
|
|
375
|
+
const person = this.model.person(name, archetypeOrDef, override);
|
|
365
376
|
this.people.set(name, person);
|
|
366
377
|
return person;
|
|
367
378
|
}
|
|
@@ -379,7 +390,7 @@ var Model = class {
|
|
|
379
390
|
softwareSystems = /* @__PURE__ */ new Map();
|
|
380
391
|
people = /* @__PURE__ */ new Map();
|
|
381
392
|
groups = /* @__PURE__ */ new Map();
|
|
382
|
-
|
|
393
|
+
softwareSystem(name, archetypeOrDef, override) {
|
|
383
394
|
if (this.softwareSystems.has(name)) {
|
|
384
395
|
throw Error(`A SoftwareSystem named '${name}' is defined elsewhere in this Model. A SoftwareSystem can be defined only once.`);
|
|
385
396
|
}
|
|
@@ -396,7 +407,7 @@ var Model = class {
|
|
|
396
407
|
return system;
|
|
397
408
|
}
|
|
398
409
|
// TODO:Should be a Group<SoftwareSystem | Person> if that is added back in
|
|
399
|
-
|
|
410
|
+
group(groupName) {
|
|
400
411
|
let group = this.groups.get(groupName);
|
|
401
412
|
if (!group) {
|
|
402
413
|
group = new ModelGroup(groupName, this);
|
|
@@ -404,7 +415,7 @@ var Model = class {
|
|
|
404
415
|
}
|
|
405
416
|
return group;
|
|
406
417
|
}
|
|
407
|
-
|
|
418
|
+
person(name, archetypeOrDef, override) {
|
|
408
419
|
if (this.people.has(name)) {
|
|
409
420
|
throw Error(`A Person named '${name}' is defined elsewhere in this Model. A Person can be defined only once.`);
|
|
410
421
|
}
|
|
@@ -420,6 +431,7 @@ var Model = class {
|
|
|
420
431
|
this.people.set(name, person);
|
|
421
432
|
return person;
|
|
422
433
|
}
|
|
434
|
+
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
423
435
|
validate() {
|
|
424
436
|
}
|
|
425
437
|
getPeople() {
|
|
@@ -646,7 +658,7 @@ var StructurizrDSLWriter = class {
|
|
|
646
658
|
}
|
|
647
659
|
writeContainerGroup(group, level) {
|
|
648
660
|
let containerGroupDsl = "";
|
|
649
|
-
containerGroupDsl += this.writeLine(`${group.
|
|
661
|
+
containerGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
650
662
|
group.getComponents().forEach((component) => {
|
|
651
663
|
containerGroupDsl += this.writeComponent(component, level + 1);
|
|
652
664
|
});
|
|
@@ -670,7 +682,7 @@ var StructurizrDSLWriter = class {
|
|
|
670
682
|
}
|
|
671
683
|
writeSoftwareSystemGroup(group, level) {
|
|
672
684
|
let softwareSystemGroupDsl = "";
|
|
673
|
-
softwareSystemGroupDsl += this.writeLine(`${group.
|
|
685
|
+
softwareSystemGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
674
686
|
group.getContainers().forEach((container) => {
|
|
675
687
|
softwareSystemGroupDsl += this.writeContainer(container, level + 1);
|
|
676
688
|
});
|
|
@@ -728,7 +740,7 @@ var StructurizrDSLWriter = class {
|
|
|
728
740
|
}
|
|
729
741
|
writeModelGroup(group, level) {
|
|
730
742
|
let modelGroupDsl = "";
|
|
731
|
-
modelGroupDsl += this.writeLine(`${group.
|
|
743
|
+
modelGroupDsl += this.writeLine(`${group.canonicalName} = group "${group.name}" {`, level);
|
|
732
744
|
group.getPeople().forEach((person) => {
|
|
733
745
|
modelGroupDsl += this.writeElement("person", person, level + 1);
|
|
734
746
|
});
|
|
@@ -813,7 +825,7 @@ import { join, dirname } from "path";
|
|
|
813
825
|
import { fileURLToPath } from "url";
|
|
814
826
|
var _dirname = typeof __dirname !== "undefined" ? __dirname : dirname(fileURLToPath(import.meta.url));
|
|
815
827
|
async function buildModelWithCatalog(options = {}) {
|
|
816
|
-
const { modelName = "model", modules: explicitModules } = options;
|
|
828
|
+
const { modelName = "model", modules: explicitModules, archetypes = {} } = options;
|
|
817
829
|
const model = new Model(modelName);
|
|
818
830
|
let c4Modules;
|
|
819
831
|
if (explicitModules) {
|
|
@@ -833,13 +845,13 @@ async function buildModelWithCatalog(options = {}) {
|
|
|
833
845
|
const registrations = [];
|
|
834
846
|
const rootCatalog = {};
|
|
835
847
|
for (const instance of c4Modules) {
|
|
836
|
-
const local = instance.registerDefinitions(model);
|
|
848
|
+
const local = instance.registerDefinitions(model, archetypes);
|
|
837
849
|
rootCatalog[instance.key] = local;
|
|
838
850
|
registrations.push({ instance, key: instance.key, local });
|
|
839
851
|
}
|
|
840
852
|
for (const { instance, key, local } of registrations) {
|
|
841
853
|
const dependencies = Object.fromEntries(Object.entries(rootCatalog).filter(([k]) => k !== key));
|
|
842
|
-
instance.buildRelationships(local, dependencies);
|
|
854
|
+
instance.buildRelationships(local, dependencies, archetypes);
|
|
843
855
|
}
|
|
844
856
|
return { model, catalog: rootCatalog };
|
|
845
857
|
}
|
package/src/model.d.ts
CHANGED
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import { Group } from './core';
|
|
2
2
|
import { SoftwareSystem, SoftwareSystemDefinition } from './softwareSystem';
|
|
3
3
|
import { Person, PersonDefinition } from './person';
|
|
4
|
-
import { ElementArchetype } from './archetype';
|
|
4
|
+
import { ElementArchetype, RelationshipArchetype } from './archetype';
|
|
5
5
|
export type CatalogKeyOf<TRoot, TModule> = {
|
|
6
6
|
[K in keyof TRoot]: TRoot[K] extends TModule ? K : never;
|
|
7
7
|
}[keyof TRoot];
|
|
8
8
|
export type Dependencies<TRoot, TModule> = Omit<TRoot, CatalogKeyOf<TRoot, TModule>>;
|
|
9
|
-
export interface C4Module<TRoot, TLocal
|
|
9
|
+
export interface C4Module<TRoot, TLocal, TArchetypes = Record<string, ElementArchetype | RelationshipArchetype>> {
|
|
10
10
|
readonly key: CatalogKeyOf<TRoot, TLocal>;
|
|
11
|
-
registerDefinitions(model: Model): TLocal;
|
|
12
|
-
buildRelationships(local: TLocal, dependencies: Dependencies<TRoot, TLocal
|
|
11
|
+
registerDefinitions(model: Model, archetypes: TArchetypes): TLocal;
|
|
12
|
+
buildRelationships(local: TLocal, dependencies: Dependencies<TRoot, TLocal>, archetypes: TArchetypes): void;
|
|
13
13
|
}
|
|
14
14
|
interface DefineSoftwareSystem {
|
|
15
|
-
|
|
15
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
16
16
|
}
|
|
17
17
|
interface DefinePerson {
|
|
18
|
-
|
|
18
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
19
19
|
}
|
|
20
|
-
export declare class ModelGroup extends Group implements DefineSoftwareSystem, DefinePerson {
|
|
20
|
+
export declare class ModelGroup extends Group<Person | SoftwareSystem> implements DefineSoftwareSystem, DefinePerson {
|
|
21
21
|
readonly name: string;
|
|
22
22
|
private readonly model;
|
|
23
23
|
private softwareSystems;
|
|
24
24
|
private people;
|
|
25
25
|
constructor(name: string, model: DefineSoftwareSystem & DefinePerson);
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
27
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
28
28
|
getSoftwareSystems(): ReadonlyArray<SoftwareSystem>;
|
|
29
29
|
getPeople(): ReadonlyArray<Person>;
|
|
30
30
|
}
|
|
31
31
|
export interface ModelDefinitions {
|
|
32
|
-
|
|
33
|
-
|
|
32
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
33
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
34
34
|
}
|
|
35
35
|
export declare class Model {
|
|
36
36
|
name: string;
|
|
@@ -38,9 +38,9 @@ export declare class Model {
|
|
|
38
38
|
private softwareSystems;
|
|
39
39
|
private people;
|
|
40
40
|
private groups;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
41
|
+
softwareSystem(name: string, archetypeOrDef?: ElementArchetype | SoftwareSystemDefinition, override?: SoftwareSystemDefinition): SoftwareSystem;
|
|
42
|
+
group(groupName: string): Group & ModelDefinitions;
|
|
43
|
+
person(name: string, archetypeOrDef?: ElementArchetype | PersonDefinition, override?: PersonDefinition): Person;
|
|
44
44
|
validate(): void;
|
|
45
45
|
getPeople(): ReadonlyArray<Person>;
|
|
46
46
|
getSoftwareSystems(): ReadonlyArray<SoftwareSystem>;
|
package/src/softwareSystem.d.ts
CHANGED
|
@@ -3,26 +3,26 @@ import { Container, ContainerDefinition } from './container';
|
|
|
3
3
|
import { ElementArchetype } from './archetype';
|
|
4
4
|
export type SoftwareSystemDefinition = Definition;
|
|
5
5
|
interface DefineContainer {
|
|
6
|
-
|
|
6
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
7
7
|
}
|
|
8
8
|
export interface SoftwareSystemReference {
|
|
9
9
|
name: string;
|
|
10
10
|
}
|
|
11
|
-
export declare class SoftwareSystemGroup extends Group implements DefineContainer {
|
|
11
|
+
export declare class SoftwareSystemGroup extends Group<Container> implements DefineContainer {
|
|
12
12
|
readonly name: string;
|
|
13
13
|
private readonly softwareSystem;
|
|
14
14
|
private _containers;
|
|
15
15
|
constructor(name: string, softwareSystem: DefineContainer);
|
|
16
|
-
|
|
16
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
17
17
|
getContainers(): ReadonlyArray<Container>;
|
|
18
18
|
}
|
|
19
|
-
export declare class SoftwareSystem extends Element implements DefineContainer {
|
|
19
|
+
export declare class SoftwareSystem extends Element<Container> implements DefineContainer {
|
|
20
20
|
readonly name: string;
|
|
21
21
|
private _containers;
|
|
22
22
|
private _groups;
|
|
23
23
|
constructor(name: string, definition?: SoftwareSystemDefinition, archetype?: ElementArchetype, overrideDefinition?: TechnologyDefinition);
|
|
24
|
-
|
|
25
|
-
|
|
24
|
+
container(name: string, archetypeOrDef?: ElementArchetype | ContainerDefinition, override?: ContainerDefinition): Container;
|
|
25
|
+
group(groupName: string): SoftwareSystemGroup;
|
|
26
26
|
getGroups(): ReadonlyArray<SoftwareSystemGroup>;
|
|
27
27
|
getChildElements(): ReadonlyArray<Element>;
|
|
28
28
|
getContainersNotInGroups(): ReadonlyArray<Container>;
|