dsh-model-everything 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.en-US.md +332 -0
- package/README.md +332 -3
- package/cordis.patch.yml +20 -0
- package/examples/README.md +48 -0
- package/examples/control-dispatcher.json +113 -0
- package/examples/control-dispatcher.overbudget.json +113 -0
- package/examples/ecommerce-data-model.json +185 -0
- package/examples/order-state-machine.after.json +116 -0
- package/examples/order-state-machine.before.json +101 -0
- package/examples/user-migration.after.json +29 -0
- package/examples/user-migration.before.json +29 -0
- package/gate/locale/en.json +6 -0
- package/gate/locale/zh.json +6 -0
- package/gate/package.json +5 -0
- package/lib/baseline.js +249 -0
- package/lib/compose-tool.js +80 -0
- package/lib/concurrency-tool.js +40 -0
- package/lib/concurrency.js +206 -0
- package/lib/data-engine.js +1141 -0
- package/lib/data-tool.js +87 -0
- package/lib/design-engine.js +1149 -0
- package/lib/design-tool.js +63 -0
- package/lib/engine.js +4343 -0
- package/lib/export-tool.js +78 -0
- package/lib/exporters.js +434 -0
- package/lib/gate.js +274 -0
- package/lib/granularity.js +237 -0
- package/lib/index.js +237 -0
- package/lib/json-value.js +18 -0
- package/lib/model-file.js +48 -0
- package/lib/option-shape.js +62 -0
- package/lib/report-diff-tool.js +63 -0
- package/lib/report-view.js +433 -0
- package/lib/structure-tool.js +91 -0
- package/lib/structure.js +711 -0
- package/lib/tool.js +94 -0
- package/lib/types/baseline.d.ts +65 -0
- package/lib/types/compose-tool.d.ts +7 -0
- package/lib/types/concurrency-tool.d.ts +8 -0
- package/lib/types/concurrency.d.ts +37 -0
- package/lib/types/data-engine.d.ts +211 -0
- package/lib/types/data-tool.d.ts +10 -0
- package/lib/types/design-engine.d.ts +215 -0
- package/lib/types/design-tool.d.ts +11 -0
- package/lib/types/engine.d.ts +494 -0
- package/lib/types/export-tool.d.ts +7 -0
- package/lib/types/exporters.d.ts +37 -0
- package/lib/types/gate.d.ts +91 -0
- package/lib/types/granularity.d.ts +106 -0
- package/lib/types/index.d.ts +45 -0
- package/lib/types/json-value.d.ts +21 -0
- package/lib/types/model-file.d.ts +7 -0
- package/lib/types/option-shape.d.ts +22 -0
- package/lib/types/report-diff-tool.d.ts +8 -0
- package/lib/types/report-view.d.ts +50 -0
- package/lib/types/structure-tool.d.ts +10 -0
- package/lib/types/structure.d.ts +152 -0
- package/lib/types/tool.d.ts +11 -0
- package/lib/types/uml-communication.d.ts +109 -0
- package/lib/types/uml-composite.d.ts +107 -0
- package/lib/types/uml-interaction-overview.d.ts +91 -0
- package/lib/types/uml-profile.d.ts +112 -0
- package/lib/types/uml-structure.d.ts +53 -0
- package/lib/types/uml-syntax.d.ts +296 -0
- package/lib/types/uml-timing.d.ts +152 -0
- package/lib/types/uml-tool.d.ts +12 -0
- package/lib/types/uml-usecase.d.ts +58 -0
- package/lib/types/uml.d.ts +303 -0
- package/lib/uml-communication.js +353 -0
- package/lib/uml-composite.js +442 -0
- package/lib/uml-interaction-overview.js +277 -0
- package/lib/uml-profile.js +373 -0
- package/lib/uml-structure.js +306 -0
- package/lib/uml-syntax.js +545 -0
- package/lib/uml-timing.js +974 -0
- package/lib/uml-tool.js +213 -0
- package/lib/uml-usecase.js +532 -0
- package/lib/uml.js +2110 -0
- package/locale/en.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +128 -6
- package/skills/model-everything/SKILL.md +450 -0
- package/skills/model-everything/references/dsh-model-schema.md +437 -0
- package/skills/model-everything/references/gap-routing-guide.md +42 -0
- package/skills/model-everything/references/hash-spec.md +152 -0
- package/skills/model-everything/references/logic-verification-guide.md +422 -0
- package/skills/model-everything-datamodel/SKILL.md +130 -0
- package/skills/model-everything-datamodel/references/data-model-guide.md +84 -0
- package/skills/model-everything-datamodel/references/data-model-schema.md +128 -0
- package/skills/model-everything-design/SKILL.md +115 -0
- package/skills/model-everything-interleaving/SKILL.md +63 -0
- package/skills/model-everything-interleaving/SKILL.zh-CN.md +60 -0
- package/skills/model-everything-interleaving/references/concurrency-risk-guide.md +63 -0
- package/skills/model-everything-report-reading/SKILL.md +137 -0
- package/skills/model-everything-report-reading/references/reading-a-report.md +166 -0
- package/skills/model-everything-report-reading/references/reading-a-report.mmd +59 -0
- package/skills/model-everything-structure/SKILL.md +96 -0
- package/skills/model-everything-structure/references/structure-review-guide.md +201 -0
- package/skills/model-everything-uml/SKILL.md +60 -0
- package/skills/model-everything-uml/references/uml-modeling-guide.md +551 -0
- package/src/baseline.ts +288 -0
- package/src/compose-tool.ts +82 -0
- package/src/concurrency-tool.ts +44 -0
- package/src/concurrency.ts +254 -0
- package/src/data-engine.ts +1208 -0
- package/src/data-tool.ts +91 -0
- package/src/design-engine.ts +1263 -0
- package/src/design-tool.ts +68 -0
- package/src/engine.ts +4564 -0
- package/src/export-tool.ts +81 -0
- package/src/exporters.ts +399 -0
- package/src/gate.ts +330 -0
- package/src/granularity.ts +312 -0
- package/src/index.ts +289 -0
- package/src/json-value.ts +20 -0
- package/src/model-file.ts +49 -0
- package/src/option-shape.ts +64 -0
- package/src/report-diff-tool.ts +67 -0
- package/src/report-view.ts +483 -0
- package/src/structure-tool.ts +93 -0
- package/src/structure.ts +786 -0
- package/src/tool.ts +103 -0
- package/src/uml-communication.ts +428 -0
- package/src/uml-composite.ts +520 -0
- package/src/uml-interaction-overview.ts +321 -0
- package/src/uml-profile.ts +439 -0
- package/src/uml-structure.ts +317 -0
- package/src/uml-syntax.ts +764 -0
- package/src/uml-timing.ts +1106 -0
- package/src/uml-tool.ts +230 -0
- package/src/uml-usecase.ts +566 -0
- package/src/uml.ts +2139 -0
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The interaction overview diagram module.
|
|
3
|
+
*
|
|
4
|
+
* An interaction overview is a control-flow graph whose nodes are interactions: a start, a
|
|
5
|
+
* decision, one or more references to interactions, and a stop. PlantUML has no page for it
|
|
6
|
+
* and no dedicated type, but the drawing is expressible with the activity diagram's
|
|
7
|
+
* vocabulary plus a reference node - `start`, `:ref Login sequence;`, `if (ok?) then (yes)`
|
|
8
|
+
* - which is what the notation research in this repository recorded as the manual form.
|
|
9
|
+
*
|
|
10
|
+
* So this family is drawn approximately, like the composite structure and the
|
|
11
|
+
* communication diagram, and for the same reason the family table used to refuse it on
|
|
12
|
+
* grounds that were simply wrong ("neither notation spells the inline interaction
|
|
13
|
+
* references": it does).
|
|
14
|
+
*
|
|
15
|
+
* Reading it back is partial, and the parser refuses the part it cannot do. A sequence and
|
|
16
|
+
* an `if`/`else` are spelled clearly enough to reconstruct. A `fork` is not: the notation
|
|
17
|
+
* opens a `fork` block, lists the flows, and closes it with `end fork`, and the closing
|
|
18
|
+
* marker carries no label tying it to the opening one, so nested or adjacent forks cannot
|
|
19
|
+
* be told apart. Rather than guess, a diagram containing one is refused with that reason.
|
|
20
|
+
*
|
|
21
|
+
* @module model-everything-uml-interaction-overview
|
|
22
|
+
*/
|
|
23
|
+
import { type UmlNotation, type UmlFamilyModule, type UmlFamilyParse, type UmlFamilyRender, type UmlFamilyFinding } from './uml-syntax.js';
|
|
24
|
+
/** What a node of the overview is. */
|
|
25
|
+
export type InteractionOverviewNodeKind = 'initial' | 'final' | 'decision' | 'merge' | 'interaction' | 'reference';
|
|
26
|
+
export interface InteractionOverviewNode {
|
|
27
|
+
id: string;
|
|
28
|
+
kind: InteractionOverviewNodeKind;
|
|
29
|
+
/** The interaction this node runs, inline (`interaction`) or by reference (`reference`). */
|
|
30
|
+
interaction?: string;
|
|
31
|
+
label?: string;
|
|
32
|
+
}
|
|
33
|
+
export interface InteractionOverviewEdge {
|
|
34
|
+
from: string;
|
|
35
|
+
to: string;
|
|
36
|
+
/** The condition on the branch, as the diagram writes it. */
|
|
37
|
+
condition?: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An interaction overview diagram as a model.
|
|
41
|
+
*
|
|
42
|
+
* The flow is what the diagram is: nodes and the edges between them. `interaction` and
|
|
43
|
+
* `reference` are kept apart because they are different facts - one is the interaction
|
|
44
|
+
* written here, the other is a name that points somewhere else and may not exist.
|
|
45
|
+
*/
|
|
46
|
+
export interface InteractionOverviewModelV1 {
|
|
47
|
+
schemaVersion: 1;
|
|
48
|
+
nodes: InteractionOverviewNode[];
|
|
49
|
+
edges: InteractionOverviewEdge[];
|
|
50
|
+
/** Ids an edge named that no node declaration introduced. */
|
|
51
|
+
undeclared?: string[];
|
|
52
|
+
narrative?: {
|
|
53
|
+
nodes?: Record<string, string>;
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate a candidate model and normalize it.
|
|
58
|
+
*
|
|
59
|
+
* One initial node, and every node reachable from it: an overview whose flow starts nowhere
|
|
60
|
+
* is a drawing, not a flow. That is a refusal rather than a finding because every later
|
|
61
|
+
* check would be reading a graph with no entry.
|
|
62
|
+
*/
|
|
63
|
+
export declare function validateInteractionOverviewModel(input: unknown): InteractionOverviewModelV1;
|
|
64
|
+
/**
|
|
65
|
+
* Render an interaction overview as Mermaid.
|
|
66
|
+
*
|
|
67
|
+
* Mermaid is the notation this family is drawn in, because the view is an activity graph
|
|
68
|
+
* and PlantUML's activity syntax is refused by this build (a structured flowchart language
|
|
69
|
+
* cannot carry a graph with merges or cycles without a while/if reconstruction). A Mermaid
|
|
70
|
+
* flowchart carries exactly what an overview is: nodes, labelled branches, and a start and
|
|
71
|
+
* an end.
|
|
72
|
+
*
|
|
73
|
+
* @param input - candidate `InteractionOverviewModelV1`.
|
|
74
|
+
* @param notation - only `mermaid` draws this family.
|
|
75
|
+
*/
|
|
76
|
+
export declare function renderInteractionOverview(input: unknown, notation: UmlNotation): UmlFamilyRender;
|
|
77
|
+
export declare function parseInteractionOverview(_text: string, _notation: UmlNotation): UmlFamilyParse<InteractionOverviewModelV1>;
|
|
78
|
+
export type InteractionOverviewFindingCode = 'UML069_OVERVIEW_NO_INITIAL' | 'UML070_OVERVIEW_NODE_UNREACHABLE' | 'UML071_OVERVIEW_DECISION_ONE_BRANCH' | 'UML072_OVERVIEW_REFERENCE_UNDECLARED' | 'UML073_OVERVIEW_NODE_WITHOUT_INTERACTION' | 'UML074_OVERVIEW_UNDOCUMENTED';
|
|
79
|
+
export declare const INTERACTION_OVERVIEW_FINDING_CODES: readonly InteractionOverviewFindingCode[];
|
|
80
|
+
/**
|
|
81
|
+
* What a reader would get wrong about an interaction overview.
|
|
82
|
+
*
|
|
83
|
+
* The overview's job is to say how the interactions fit together, so the checks are about
|
|
84
|
+
* the flow being a flow: one way in, every node on some path from it, a decision that
|
|
85
|
+
* actually decides. Whether the referenced interactions exist is a question about the other
|
|
86
|
+
* diagrams - this plugin holds no registry of them - so an undeclared reference is reported
|
|
87
|
+
* as a name nothing here can resolve, not as a missing interaction.
|
|
88
|
+
*/
|
|
89
|
+
export declare function reviewInteractionOverviewModel(model: InteractionOverviewModelV1, labels: Record<string, string>): UmlFamilyFinding[];
|
|
90
|
+
/** The interaction overview family, as the engine's registry expects it. */
|
|
91
|
+
export declare const interactionOverviewModule: UmlFamilyModule<InteractionOverviewModelV1>;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The profile diagram module.
|
|
3
|
+
*
|
|
4
|
+
* A profile is a package that extends the metamodel: stereotypes, the metaclasses they
|
|
5
|
+
* extend, and the profiles applied to a package. That is a shape of its own, so it has
|
|
6
|
+
* its own model rather than being flattened into a class diagram.
|
|
7
|
+
*
|
|
8
|
+
* PlantUML draws one *approximately*: it has `metaclass` and `stereotype` elements and
|
|
9
|
+
* `class X <<stereotype>>`, and the relation set of its class diagram, but no `profile`
|
|
10
|
+
* keyword and no Profile/ProfileApplication element. The drawing is therefore one-way.
|
|
11
|
+
* Reading the text back would have to guess which `--|>` is a stereotype extending a
|
|
12
|
+
* metaclass and which is one stereotype specialising another — two different facts about
|
|
13
|
+
* the profile, drawn identically — so the parse is refused by name instead of inventing
|
|
14
|
+
* the one the reader cannot see. That refusal is the family table's `parseable: false`.
|
|
15
|
+
*
|
|
16
|
+
* @module model-everything-uml-profile
|
|
17
|
+
*/
|
|
18
|
+
import { type UmlNotation, type UmlFamilyModule, type UmlFamilyRender, type UmlFamilyFinding } from './uml-syntax.js';
|
|
19
|
+
/** The profile itself: the package the stereotypes are defined in. */
|
|
20
|
+
export interface ProfileSpec {
|
|
21
|
+
id: string;
|
|
22
|
+
label?: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ProfileStereotype {
|
|
25
|
+
id: string;
|
|
26
|
+
/** Human-readable name, when the diagram gave one that differs from the id. */
|
|
27
|
+
label?: string;
|
|
28
|
+
}
|
|
29
|
+
/** `ExtensionEnd` multiplicity, as the specification spells it: `0..1` or `1`. */
|
|
30
|
+
export type ProfileMultiplicity = '0..1' | '1';
|
|
31
|
+
/** A stereotype extending a metaclass: the `Extension` of the metamodel. */
|
|
32
|
+
export interface ProfileExtension {
|
|
33
|
+
stereotype: string;
|
|
34
|
+
metaclass: string;
|
|
35
|
+
/** The composite end's multiplicity. Absent when the diagram did not say. */
|
|
36
|
+
multiplicity?: ProfileMultiplicity;
|
|
37
|
+
/** A role name on the extension end, when the profile gave one. */
|
|
38
|
+
label?: string;
|
|
39
|
+
}
|
|
40
|
+
/** A profile made available to a package: `ProfileApplication`. */
|
|
41
|
+
export interface ProfileApplication {
|
|
42
|
+
profile: string;
|
|
43
|
+
/** The package the profile applies to. */
|
|
44
|
+
applyTo: string;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* A profile diagram as a model.
|
|
48
|
+
*
|
|
49
|
+
* `applications` is carried even though this build's renderer leaves it to the
|
|
50
|
+
* directives: PlantUML has no ProfileApplication element, and a profile whose
|
|
51
|
+
* application is not written down is a profile nobody can tell is in use.
|
|
52
|
+
*/
|
|
53
|
+
export interface ProfileModelV1 {
|
|
54
|
+
schemaVersion: 1;
|
|
55
|
+
profile: ProfileSpec;
|
|
56
|
+
stereotypes: ProfileStereotype[];
|
|
57
|
+
metaclasses: ProfileStereotype[];
|
|
58
|
+
extensions: ProfileExtension[];
|
|
59
|
+
applications: ProfileApplication[];
|
|
60
|
+
/** Stereotype-to-stereotype specialisation; a different fact from an extension. */
|
|
61
|
+
generalizations: Array<{
|
|
62
|
+
general: string;
|
|
63
|
+
specific: string;
|
|
64
|
+
}>;
|
|
65
|
+
/** Ids a relation named that no declaration introduced; the review reports them. */
|
|
66
|
+
undeclared?: string[];
|
|
67
|
+
narrative?: {
|
|
68
|
+
profile?: string;
|
|
69
|
+
stereotypes?: Record<string, string>;
|
|
70
|
+
metaclasses?: Record<string, string>;
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
/**
|
|
74
|
+
* Validate a candidate model and normalize it.
|
|
75
|
+
*
|
|
76
|
+
* The contract every family keeps: an undeclared key or a wrong type is a refusal with
|
|
77
|
+
* `UML_INPUT`, never a silently dropped field.
|
|
78
|
+
*/
|
|
79
|
+
export declare function validateProfileModel(input: unknown): ProfileModelV1;
|
|
80
|
+
/**
|
|
81
|
+
* Render a profile as PlantUML.
|
|
82
|
+
*
|
|
83
|
+
* The drawing is the approximation the family table declares: stereotypes and
|
|
84
|
+
* metaclasses as the class diagram draws them, extensions and generalizations both as a
|
|
85
|
+
* `--|>` because the notation has no second arrow for the first. Everything the drawing
|
|
86
|
+
* cannot carry — which arrow is which, the extension multiplicity and role, the
|
|
87
|
+
* applications — is written as a directive, so the text is a faithful record of the
|
|
88
|
+
* model even though the picture is not.
|
|
89
|
+
*
|
|
90
|
+
* @param input - candidate `ProfileModelV1`.
|
|
91
|
+
* @param notation - only `plantuml` draws a profile; mermaid has no view of this family.
|
|
92
|
+
*/
|
|
93
|
+
export declare function renderProfile(input: unknown, notation: UmlNotation): UmlFamilyRender;
|
|
94
|
+
export type ProfileFindingCode = 'UML050_PROFILE_NO_STEREOTYPES' | 'UML051_PROFILE_UNUSED_STEREOTYPE' | 'UML052_PROFILE_EXTENSION_MISSING' | 'UML053_PROFILE_GENERALIZATION_CYCLE' | 'UML054_PROFILE_UNDECLARED_REFERENCE' | 'UML055_PROFILE_APPLICATION_MISSING' | 'UML056_PROFILE_UNDOCUMENTED';
|
|
95
|
+
export declare const PROFILE_FINDING_CODES: readonly ProfileFindingCode[];
|
|
96
|
+
/**
|
|
97
|
+
* What a reader would get wrong about a profile.
|
|
98
|
+
*
|
|
99
|
+
* The checks read the model alone. Whether a profile is *right* for the metamodel it
|
|
100
|
+
* extends is a question about the specification being profiled, and this does not answer
|
|
101
|
+
* it: the codes below are about the profile being internally complete and readable.
|
|
102
|
+
*/
|
|
103
|
+
export declare function reviewProfileModel(model: ProfileModelV1, labels: Record<string, string>): UmlFamilyFinding[];
|
|
104
|
+
/**
|
|
105
|
+
* The profile family, as the engine's registry expects it.
|
|
106
|
+
*
|
|
107
|
+
* `parse` refuses with the family table's own words. It has to exist because the module
|
|
108
|
+
* contract requires it, and it must refuse rather than return something: a parse would
|
|
109
|
+
* have to decide which `--|>` is an extension and which is a generalization, and the
|
|
110
|
+
* notation does not say.
|
|
111
|
+
*/
|
|
112
|
+
export declare const profileModule: UmlFamilyModule<ProfileModelV1>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The structure families: class, object, package, component and deployment diagrams.
|
|
3
|
+
*
|
|
4
|
+
* A structure diagram is not a machine and not a use case list: it is a graph of
|
|
5
|
+
* nodes and the edges between them. The five families differ in vocabulary, not in
|
|
6
|
+
* shape, so they share one module factory and one model.
|
|
7
|
+
*
|
|
8
|
+
* Parsing is not reimplemented here. `structure.ts` already reads this text as a
|
|
9
|
+
* dependency graph, and it is the single source for that reading: this module calls
|
|
10
|
+
* it, then gives the result the family's name. Reviewing does the same - the graph is
|
|
11
|
+
* rendered back and handed to `reviewStructure`, so a structure diagram reviewed
|
|
12
|
+
* through the UML front end and one reviewed through `uml_structure_verify`
|
|
13
|
+
* report the same defects with the same codes.
|
|
14
|
+
*
|
|
15
|
+
* @module model-everything-uml-structure
|
|
16
|
+
*/
|
|
17
|
+
import { type UmlNotation, type UmlFamilyModule, type UmlFamilyParse, type UmlFamilyRender, type UmlFamilyFinding } from './uml-syntax.js';
|
|
18
|
+
export type StructureFamilyId = 'class' | 'object' | 'package' | 'component' | 'deployment';
|
|
19
|
+
export interface StructureModelNode {
|
|
20
|
+
id: string;
|
|
21
|
+
/** The declaration the node came from: class, interface, component, node, ... */
|
|
22
|
+
kind: string;
|
|
23
|
+
label?: string;
|
|
24
|
+
/** The container this node was declared inside, when the diagram drew one. */
|
|
25
|
+
parent?: string;
|
|
26
|
+
}
|
|
27
|
+
export interface StructureModelEdge {
|
|
28
|
+
from: string;
|
|
29
|
+
to: string;
|
|
30
|
+
label?: string;
|
|
31
|
+
}
|
|
32
|
+
/** A structure diagram as a model: the nodes it declares and the edges it draws. */
|
|
33
|
+
export interface StructureModelV1 {
|
|
34
|
+
schemaVersion: 1;
|
|
35
|
+
family: StructureFamilyId;
|
|
36
|
+
nodes: StructureModelNode[];
|
|
37
|
+
edges: StructureModelEdge[];
|
|
38
|
+
}
|
|
39
|
+
export declare function validateStructureModel(input: unknown, family: StructureFamilyId): StructureModelV1;
|
|
40
|
+
export declare function parseStructureFamily(text: string, notation: UmlNotation, family: StructureFamilyId): UmlFamilyParse<StructureModelV1>;
|
|
41
|
+
export declare function renderStructureFamily(input: unknown, notation: UmlNotation, family: StructureFamilyId): UmlFamilyRender;
|
|
42
|
+
/**
|
|
43
|
+
* The review is the structure tool's, reached through a render.
|
|
44
|
+
*
|
|
45
|
+
* A structure diagram's defects are properties of its graph, and `reviewStructure`
|
|
46
|
+
* already checks them (isolated node, dangling endpoint, cycle, and the matrix rules
|
|
47
|
+
* when one is declared). Re-deriving them here would be a second implementation of
|
|
48
|
+
* the same checks, and the two would drift. So the model is rendered back and handed
|
|
49
|
+
* over, which also proves the round trip on the way.
|
|
50
|
+
*/
|
|
51
|
+
export declare function reviewStructureFamily(model: StructureModelV1, labels: Record<string, string>, notation: UmlNotation): UmlFamilyFinding[];
|
|
52
|
+
/** One module per structure family: they differ in vocabulary, not in shape. */
|
|
53
|
+
export declare function structureFamilyModule(family: StructureFamilyId): UmlFamilyModule<StructureModelV1>;
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The notation syntax engine.
|
|
3
|
+
*
|
|
4
|
+
* One place knows what Mermaid and PlantUML can spell, which UML 2.5 diagram type a
|
|
5
|
+
* piece of text is, and whether a requested (notation, family, action) cell exists at
|
|
6
|
+
* all. Family modules know what to do with the elements this engine finds.
|
|
7
|
+
*
|
|
8
|
+
* Before this module, detection fell through: any PlantUML text that was not a
|
|
9
|
+
* sequence diagram went to the state parser. A use case diagram drawn with
|
|
10
|
+
* `:Actor: --> (UseCase)` came back as a state machine with no finding, which is
|
|
11
|
+
* the false guarantee this plugin exists to prevent. Detection is now total. A text
|
|
12
|
+
* either names a family this engine knows, or it is refused by name.
|
|
13
|
+
*
|
|
14
|
+
* What lives here:
|
|
15
|
+
* - the notation table: comment prefixes, headers, chrome and edge operators;
|
|
16
|
+
* - the family table: all fourteen UML 2.5 diagram types, their group, and what each
|
|
17
|
+
* notation can express for them;
|
|
18
|
+
* - the capability decision: (notation, family, action) -> supported | refusal,
|
|
19
|
+
* separate from whether this build implements the family (that is the registry's
|
|
20
|
+
* job, in `uml.ts`);
|
|
21
|
+
* - notation-agnostic lexical primitives: directives, line scanning, edge splitting,
|
|
22
|
+
* identifier and label rules.
|
|
23
|
+
*
|
|
24
|
+
* What deliberately does not live here: family semantics. A family module turns the
|
|
25
|
+
* elements this engine finds into its own model, renders that model back, and reviews
|
|
26
|
+
* it. `uml-usecase.ts` is the first such module. The machine families (state,
|
|
27
|
+
* activity) and the trace family (sequence) predate the module contract and keep their
|
|
28
|
+
* own path in `uml.ts`.
|
|
29
|
+
*
|
|
30
|
+
* @module model-everything-uml-syntax
|
|
31
|
+
*/
|
|
32
|
+
/**
|
|
33
|
+
* A UML front-end refusal. `code` lets the tool report *why* it refused instead
|
|
34
|
+
* of collapsing every refusal into a generic input error.
|
|
35
|
+
*/
|
|
36
|
+
export declare class UmlError extends Error {
|
|
37
|
+
readonly code: string;
|
|
38
|
+
constructor(message: string, code?: string);
|
|
39
|
+
}
|
|
40
|
+
export type UmlNotation = 'mermaid' | 'plantuml';
|
|
41
|
+
export declare const UML_NOTATIONS: readonly UmlNotation[];
|
|
42
|
+
export declare function isUmlNotation(value: unknown): value is UmlNotation;
|
|
43
|
+
/** Mermaid node ids that cannot stand alone; the renderer aliases around them. */
|
|
44
|
+
export declare const MERMAID_RESERVED_NODE_IDS: ReadonlySet<string>;
|
|
45
|
+
/** Ids a notation can spell without an alias. */
|
|
46
|
+
export declare const UML_PLAIN_ID: RegExp;
|
|
47
|
+
/** Characters that would break a generated label, whichever notation is used. */
|
|
48
|
+
export declare const UML_UNSAFE_LABEL: RegExp;
|
|
49
|
+
/** The comment prefix each notation uses for its dsh-model-everything: directives. */
|
|
50
|
+
export declare function commentPrefix(notation: UmlNotation): string;
|
|
51
|
+
export declare function escapeRegExp(text: string): string;
|
|
52
|
+
export type UmlFamilyId = 'state' | 'activity' | 'sequence' | 'use-case' | 'class' | 'object' | 'package' | 'component' | 'composite-structure' | 'deployment' | 'profile' | 'communication' | 'interaction-overview' | 'timing';
|
|
53
|
+
/**
|
|
54
|
+
* How faithfully a notation expresses one UML diagram type.
|
|
55
|
+
*
|
|
56
|
+
* - `faithful`: the notation models this diagram type; a parse reconstructs it.
|
|
57
|
+
* - `approximate`: the notation can draw something in this area, but reading it
|
|
58
|
+
* back would produce a model of a *different* diagram. Rendering is allowed with a
|
|
59
|
+
* warning; parsing is refused.
|
|
60
|
+
* - `none`: the notation has no view of this diagram type at all.
|
|
61
|
+
*/
|
|
62
|
+
export type UmlFidelity = 'faithful' | 'approximate' | 'none';
|
|
63
|
+
export interface UmlNotationSupport {
|
|
64
|
+
fidelity: UmlFidelity;
|
|
65
|
+
/** Header keywords that declare the family outright (Mermaid: `classDiagram`). */
|
|
66
|
+
headers?: readonly string[];
|
|
67
|
+
/** Declaration keywords the family owns (PlantUML: `actor`, `usecase`). */
|
|
68
|
+
declarations?: readonly string[];
|
|
69
|
+
/** Why the fidelity is what it is, in the words the refusal uses. */
|
|
70
|
+
note?: string;
|
|
71
|
+
}
|
|
72
|
+
export interface UmlFamilySpec {
|
|
73
|
+
id: UmlFamilyId;
|
|
74
|
+
/** English name of the UML 2.5 diagram type. */
|
|
75
|
+
name: string;
|
|
76
|
+
/** Chinese name, for the bilingual documentation. */
|
|
77
|
+
nameZh: string;
|
|
78
|
+
group: 'structure' | 'behaviour' | 'interaction';
|
|
79
|
+
/**
|
|
80
|
+
* True when a faithful parse of this family is a LogicModelV1 the verification
|
|
81
|
+
* engine can run. False for every structure family and for the trace families.
|
|
82
|
+
*/
|
|
83
|
+
machine: boolean;
|
|
84
|
+
/**
|
|
85
|
+
* False when a parse could not reconstruct the diagram even in a faithful notation.
|
|
86
|
+
* A sequence diagram is a trace: it shows the paths that were walked, not the
|
|
87
|
+
* branches that were not.
|
|
88
|
+
*/
|
|
89
|
+
parseable: boolean;
|
|
90
|
+
/**
|
|
91
|
+
* Whether this build can read the family back out of a notation that only approximates
|
|
92
|
+
* it. Absent means no.
|
|
93
|
+
*
|
|
94
|
+
* This is not derivable from the notation's fidelity. `fidelity` says how much of the
|
|
95
|
+
* specification the drawing carries; this says whether what the model *does* carry
|
|
96
|
+
* survives a round trip, which is a measurement, not a label. A composite structure is
|
|
97
|
+
* drawn approximately and reads back exactly - nesting, port direction and both
|
|
98
|
+
* connector ends are all spelled - while a profile is drawn approximately and cannot be
|
|
99
|
+
* read back at all. Refusing the first because the second is impossible would leave a
|
|
100
|
+
* working view switched off.
|
|
101
|
+
*/
|
|
102
|
+
parseThroughApproximation?: boolean;
|
|
103
|
+
/** Why a parse is refused, when `parseable` is false. */
|
|
104
|
+
parseRefusal?: string;
|
|
105
|
+
/** Code the parse refusal carries; defaults to `UML_NOT_A_STATE_DIAGRAM`. */
|
|
106
|
+
parseRefusalCode?: string;
|
|
107
|
+
mermaid?: UmlNotationSupport;
|
|
108
|
+
plantuml?: UmlNotationSupport;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* The family table. Order matters twice: a Mermaid header is matched in this order,
|
|
112
|
+
* and a PlantUML declaration keyword is too. The machine families come first because
|
|
113
|
+
* their headers are the most specific.
|
|
114
|
+
*/
|
|
115
|
+
export declare const UML_FAMILIES: readonly UmlFamilySpec[];
|
|
116
|
+
export declare const UML_FAMILY_IDS: readonly UmlFamilyId[];
|
|
117
|
+
export declare function isUmlFamilyId(value: unknown): value is UmlFamilyId;
|
|
118
|
+
export declare function umlFamilySpec(id: UmlFamilyId): UmlFamilySpec;
|
|
119
|
+
/** What one notation can do with one family. `none` when the table says nothing. */
|
|
120
|
+
export declare function umlNotationSupport(notation: UmlNotation, family: UmlFamilyId): UmlNotationSupport;
|
|
121
|
+
/**
|
|
122
|
+
* Mermaid headers that name something other than a UML diagram type. Recognizing them
|
|
123
|
+
* matters: the text must not be reported as "cannot tell whether this is Mermaid or
|
|
124
|
+
* PlantUML", and it must not be parsed as a state diagram, whose every line would be
|
|
125
|
+
* ignored or misread. ER, gantt, mindmap and the C4 family are not UML 2.5 diagrams.
|
|
126
|
+
*/
|
|
127
|
+
export declare const FOREIGN_MERMAID_FAMILIES: readonly string[];
|
|
128
|
+
/** The non-UML Mermaid family this text declares, if any. */
|
|
129
|
+
export declare function foreignMermaidFamily(text: string): string | undefined;
|
|
130
|
+
/** Every Mermaid header this engine knows, for the "expected one of" message. */
|
|
131
|
+
export declare function mermaidHeaderList(): string;
|
|
132
|
+
export declare function detectUmlNotation(text: string): UmlNotation;
|
|
133
|
+
export interface UmlFamilyDetection {
|
|
134
|
+
family: UmlFamilyId;
|
|
135
|
+
/** The header or keyword that decided it, for the report. */
|
|
136
|
+
evidence: string;
|
|
137
|
+
}
|
|
138
|
+
export declare function plantumlUseCaseSyntax(text: string): boolean;
|
|
139
|
+
export declare function plantumlTimingSyntax(text: string): boolean;
|
|
140
|
+
export declare function plantumlCompositeSyntax(text: string): boolean;
|
|
141
|
+
export declare function plantumlErSyntax(text: string): boolean;
|
|
142
|
+
export declare function plantumlCommunicationSyntax(text: string): boolean;
|
|
143
|
+
export interface UmlDetectOptions {
|
|
144
|
+
/** The family a `dsh-model-everything:uml` directive declared, when the text carries one. */
|
|
145
|
+
hint?: UmlFamilyId;
|
|
146
|
+
}
|
|
147
|
+
/**
|
|
148
|
+
* Which UML diagram type this text is, in this notation.
|
|
149
|
+
*
|
|
150
|
+
* Total by construction: every branch either names a family or throws. A foreign
|
|
151
|
+
* Mermaid family (ER, gantt, mindmap, C4, ...) is refused by name, so the caller can
|
|
152
|
+
* report *what* the text is instead of blaming the notation.
|
|
153
|
+
*/
|
|
154
|
+
export declare function detectUmlFamily(text: string, notation: UmlNotation, options?: UmlDetectOptions): UmlFamilyDetection;
|
|
155
|
+
/** The four actions the UML front end offers. */
|
|
156
|
+
export type UmlIntentAction = 'render' | 'parse' | 'review' | 'labels';
|
|
157
|
+
export type UmlCapability = {
|
|
158
|
+
ok: true;
|
|
159
|
+
warning?: string;
|
|
160
|
+
} | {
|
|
161
|
+
ok: false;
|
|
162
|
+
errorCode: string;
|
|
163
|
+
message: string;
|
|
164
|
+
};
|
|
165
|
+
export interface UmlCapabilityOptions {
|
|
166
|
+
/**
|
|
167
|
+
* Whether this call needs a parse. A review of a *model* in a family the notation can
|
|
168
|
+
* only approximate does not, and refusing it for a reason that belongs to the diagram
|
|
169
|
+
* would be refusing the part that works.
|
|
170
|
+
*/
|
|
171
|
+
requireParse?: boolean;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Whether this (notation, family, action) cell exists.
|
|
175
|
+
*
|
|
176
|
+
* This is the notation's answer, not this build's: a family the table says is faithful
|
|
177
|
+
* is still refused when no module implements it, and that refusal belongs to the
|
|
178
|
+
* registry (see `uml.ts`). Keeping the two apart is what lets the engine document
|
|
179
|
+
* all fourteen diagram types while the implementation lands family by family.
|
|
180
|
+
*/
|
|
181
|
+
export declare function umlCapability(notation: UmlNotation, family: UmlFamilyId, action: UmlIntentAction, options?: UmlCapabilityOptions): UmlCapability;
|
|
182
|
+
/** `umlCapability`, as a throw. */
|
|
183
|
+
export declare function assertUmlCapability(notation: UmlNotation, family: UmlFamilyId, action: UmlIntentAction): UmlCapability;
|
|
184
|
+
export interface UmlFamilyParse<Model> {
|
|
185
|
+
model: Model;
|
|
186
|
+
/** Display labels found in the diagram, keyed by element id. */
|
|
187
|
+
labels: Record<string, string>;
|
|
188
|
+
warnings: string[];
|
|
189
|
+
/** Declarations the parser could not represent, with the line that carried them. */
|
|
190
|
+
discardedConstructs: Array<{
|
|
191
|
+
construct: string;
|
|
192
|
+
line: number;
|
|
193
|
+
text: string;
|
|
194
|
+
}>;
|
|
195
|
+
discardedEdges: number;
|
|
196
|
+
}
|
|
197
|
+
export interface UmlFamilyRenderOptions {
|
|
198
|
+
/** Cap on a trace length, for the families that render one. */
|
|
199
|
+
maxSteps: number;
|
|
200
|
+
}
|
|
201
|
+
export interface UmlFamilyRender {
|
|
202
|
+
primary: string;
|
|
203
|
+
warnings: string[];
|
|
204
|
+
}
|
|
205
|
+
export interface UmlFamilyFinding {
|
|
206
|
+
code: string;
|
|
207
|
+
severity: 'error' | 'warning' | 'info';
|
|
208
|
+
message: string;
|
|
209
|
+
detail?: string;
|
|
210
|
+
evidence?: Record<string, unknown>;
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* What a family module must provide. The engine finds the elements; the module gives
|
|
214
|
+
* them meaning, draws them back, and says what a reader would get wrong.
|
|
215
|
+
*/
|
|
216
|
+
export interface UmlFamilyModule<Model> {
|
|
217
|
+
id: UmlFamilyId;
|
|
218
|
+
/**
|
|
219
|
+
* The notation this family is drawn in, when only one can draw it.
|
|
220
|
+
*
|
|
221
|
+
* Absent means "either, as the caller asks", which is true for most families. A family
|
|
222
|
+
* whose table gives one notation `none` has exactly one answer, and saying it here is
|
|
223
|
+
* what lets a review of a *model* render the family instead of reporting that the model
|
|
224
|
+
* cannot be drawn at all.
|
|
225
|
+
*/
|
|
226
|
+
notation?: UmlNotation;
|
|
227
|
+
render(input: unknown, notation: UmlNotation, options: UmlFamilyRenderOptions): UmlFamilyRender;
|
|
228
|
+
parse(text: string, notation: UmlNotation): UmlFamilyParse<Model>;
|
|
229
|
+
/**
|
|
230
|
+
* The model in the family's own canonical shape, or undefined when the input is not one.
|
|
231
|
+
*
|
|
232
|
+
* Fidelity is checked by rendering a model and comparing what comes back with what went
|
|
233
|
+
* in. Where the parser necessarily normalizes - filling in a default the diagram always
|
|
234
|
+
* draws, or recording a drawn name as a label - comparing against the *raw* input reports
|
|
235
|
+
* the module's own convention as a mismatch. This is how a family says which model the
|
|
236
|
+
* comparison is about; a family that normalizes nothing can leave it out.
|
|
237
|
+
*/
|
|
238
|
+
normalize?(input: unknown): Model | undefined;
|
|
239
|
+
/** Family findings for the review: what the diagram itself gets wrong. */
|
|
240
|
+
review?(model: Model, labels: Record<string, string>, notation: UmlNotation): UmlFamilyFinding[];
|
|
241
|
+
}
|
|
242
|
+
/** Marker every generated diagram carries; renderers ignore it, the parser uses it. */
|
|
243
|
+
export declare const DIRECTIVE_NAMESPACE = "dsh-model-everything:";
|
|
244
|
+
/** The directive body of a comment line, or null when the line is not a directive. */
|
|
245
|
+
export declare function directiveBody(line: string, notation: UmlNotation): string | null;
|
|
246
|
+
/** One directive line, in the notation's own comment syntax. */
|
|
247
|
+
export declare function directiveLine(notation: UmlNotation, text: string): string;
|
|
248
|
+
export interface UmlDirectives {
|
|
249
|
+
/** What the `uml v1` header declared, when it carried one. */
|
|
250
|
+
declared: {
|
|
251
|
+
notation?: string;
|
|
252
|
+
family?: string;
|
|
253
|
+
diagram?: string;
|
|
254
|
+
};
|
|
255
|
+
/** Every other directive, keyed by its first word, values in file order. */
|
|
256
|
+
values: Map<string, string[]>;
|
|
257
|
+
/** The lines that are not directives. */
|
|
258
|
+
body: string[];
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Read the `dsh-model-everything:` directives out of a diagram.
|
|
262
|
+
*
|
|
263
|
+
* `diagram=` is the pre-family spelling and is still read: a file rendered by an
|
|
264
|
+
* earlier version must parse the same way it did.
|
|
265
|
+
*/
|
|
266
|
+
export declare function readUmlDirectives(lines: readonly string[], notation: UmlNotation): UmlDirectives;
|
|
267
|
+
/** The family a rendered diagram declares, in either spelling. */
|
|
268
|
+
export declare function declaredFamily(directives: UmlDirectives): UmlFamilyId | undefined;
|
|
269
|
+
export interface UmlSourceLine {
|
|
270
|
+
/** 1-based line number in the source text. */
|
|
271
|
+
number: number;
|
|
272
|
+
/** The line, trimmed. */
|
|
273
|
+
text: string;
|
|
274
|
+
}
|
|
275
|
+
/**
|
|
276
|
+
* The content lines of a diagram: blank lines, comments and notation chrome removed,
|
|
277
|
+
* each with its source line number. Chrome is what a renderer needs and a reader does
|
|
278
|
+
* not: `@startuml`, `@enduml`, `direction`, `classDef`, `skinparam`,
|
|
279
|
+
* `scale`, `title`, `hide` and `autonumber`.
|
|
280
|
+
*/
|
|
281
|
+
export declare function umlSourceLines(text: string, notation: UmlNotation, skip?: RegExp): UmlSourceLine[];
|
|
282
|
+
export interface UmlEdgeSplit {
|
|
283
|
+
from: string;
|
|
284
|
+
operator: string;
|
|
285
|
+
to: string;
|
|
286
|
+
label?: string;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Split one line into from / operator / to, with a trailing `: label` separated.
|
|
290
|
+
*
|
|
291
|
+
* The operator tables are the notation's, not the family's: a class diagram writes
|
|
292
|
+
* `A <|-- B` and a use case diagram writes `A --> B` in the same notation, and both
|
|
293
|
+
* come through here. Whether an operator *means* a dependency, an association or a
|
|
294
|
+
* generalization is the family module's call.
|
|
295
|
+
*/
|
|
296
|
+
export declare function splitUmlEdge(line: string, notation: UmlNotation): UmlEdgeSplit | undefined;
|