@miragon/design-iq-validator 5.5.0 → 5.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -7
- package/dist/cli.js +1 -1
- package/dist/{content-Bsv9ZLFd.js → content-Bu1bNrez.js} +16 -13
- package/dist/{content-wjC_epKd.js → content-CE4SulnP.js} +1 -1
- package/dist/{validate-DjtZJTGk.js → validate-BqkEd0ma.js} +160 -13
- package/dist/validate.js +1 -1
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -3,13 +3,47 @@
|
|
|
3
3
|
Deterministic validator for designIQ content repositories: `designiq.yml` discovery, BPMN
|
|
4
4
|
structural checks (flow soundness, complete BPMNDI coverage), DMN structure and DMNDI coverage,
|
|
5
5
|
the generic cross-model reference rule (every required reference — `callActivity` calls,
|
|
6
|
-
`businessRuleTask` decides — must resolve in the repo),
|
|
7
|
-
every other registered notation (a
|
|
8
|
-
lenient by design; a `mermaid` fence in a
|
|
9
|
-
|
|
10
|
-
document's line). Every finding
|
|
11
|
-
`refs/dangling`). It treats the target
|
|
12
|
-
Exit code 0 = no errors (warnings
|
|
6
|
+
`businessRuleTask` decides — must resolve in the repo), the schema check of the Miragon JSON
|
|
7
|
+
notations, and a per-mediaKind parse baseline for every other registered notation (a file that
|
|
8
|
+
is no JSON or XML is an ERROR; DSL notations are lenient by design; a `mermaid` fence in a
|
|
9
|
+
Markdown document that does not start with a diagram type such as `flowchart` or
|
|
10
|
+
`sequenceDiagram` is a WARN, `mermaid/diagram-type`, naming the document's line). Every finding
|
|
11
|
+
carries a stable `ruleId` (e.g. `bpmn/flow`, `dmn/di`, `refs/dangling`). It treats the target
|
|
12
|
+
repo as pure data — it never executes content-repo code. Exit code 0 = no errors (warnings
|
|
13
|
+
allowed), 1 = errors.
|
|
14
|
+
|
|
15
|
+
## Team Topologies, Context Maps and Value Chains
|
|
16
|
+
|
|
17
|
+
A `.tt`/`.ttm.json`, `.cm.json` or `.vc.json` file is parsed with the schema model its canvas
|
|
18
|
+
opens it with (`@miragon/team-topologies-schema-model`, `@miragon/context-maps-schema-model`,
|
|
19
|
+
`@miragon/value-chain-schema-model`). Whatever the schema model refuses, the canvas cannot open,
|
|
20
|
+
so each refusal is an ERROR (`team-topology/schema`, `context-map/schema`,
|
|
21
|
+
`value-chain/schema`) that names the offending value by its JSON path, e.g.
|
|
22
|
+
`nodes.1.id: duplicate id "a"`. Refused among others:
|
|
23
|
+
|
|
24
|
+
- a duplicate id, and the ids the diagram keeps for itself: `tt-root`, `cm-root`, `vc-root`,
|
|
25
|
+
every id starting with `__implicitroot`, and `assoc_<annotation id>` in a Team Topology;
|
|
26
|
+
- in all three notations, an id that names a built-in JavaScript object property such as
|
|
27
|
+
`constructor`, `toString` or `__proto__`: the canvas keeps its elements in a plain object and
|
|
28
|
+
cannot import it. The Team Topology and Context Map schema models still take these ids, so the
|
|
29
|
+
validator refuses them itself, under the same rule;
|
|
30
|
+
- in a Context Map: a JSON list instead of an object, a `version` newer than 1, coordinates or
|
|
31
|
+
sizes beyond 1,000,000;
|
|
32
|
+
- in a Value Chain: keys other than `x`, `y`, `width`, `height` in `bounds` and other than `x`,
|
|
33
|
+
`y` in a waypoint, coordinates beyond ±1e9, and a `__proto__` key anywhere.
|
|
34
|
+
|
|
35
|
+
A Context Map's strategic-DDD rules (`validateDocument`, e.g. `protect-or-conform`,
|
|
36
|
+
`endpoints-on-map`) are WARNs, `context-map/semantics`, with the rule named at the end of the
|
|
37
|
+
message: the canvas opens such a map and marks the finding. A repeated id is the exception: the
|
|
38
|
+
canvas refuses it, so it is an ERROR (`context-map/schema`) at the path of the repeat, e.g.
|
|
39
|
+
`contexts.2.id: Duplicate id "a". (unique-ids)`.
|
|
40
|
+
|
|
41
|
+
Paths count in the document as the schema model reads it. A Team Topology drops a legacy
|
|
42
|
+
interaction without `position` or `size` before the check, so the index of a later interaction
|
|
43
|
+
counts without it. Some rules only run once the document's shape is valid: the id rules of a Team
|
|
44
|
+
Topology and a Value Chain, and in a Context Map the repeated ids and the strategic-DDD rules.
|
|
45
|
+
Fixing the reported errors can therefore bring up further ones, so check again until the file is
|
|
46
|
+
clean.
|
|
13
47
|
|
|
14
48
|
## Usage
|
|
15
49
|
|
package/dist/cli.js
CHANGED
|
@@ -537,20 +537,23 @@ function extractWardley(raw) {
|
|
|
537
537
|
}
|
|
538
538
|
function extractTeamTopology(raw) {
|
|
539
539
|
const data = JSON.parse(raw);
|
|
540
|
+
const list = (v) => Array.isArray(v) ? v : [];
|
|
541
|
+
const teams = list(data.nodes).map((n) => ({
|
|
542
|
+
id: n.id,
|
|
543
|
+
type: n.type ?? "team",
|
|
544
|
+
name: n.label ?? n.name,
|
|
545
|
+
extra: n.description ? { description: n.description } : void 0
|
|
546
|
+
}));
|
|
547
|
+
const interactions = list(data.interactions).filter((i) => i !== null && typeof i === "object" && "position" in i && "size" in i).map((i) => ({
|
|
548
|
+
id: i.id,
|
|
549
|
+
type: "interaction",
|
|
550
|
+
name: i.label,
|
|
551
|
+
extra: { mode: i.mode }
|
|
552
|
+
}));
|
|
540
553
|
return {
|
|
541
554
|
notation: "team-topology",
|
|
542
|
-
nodes:
|
|
543
|
-
|
|
544
|
-
type: n.type ?? "team",
|
|
545
|
-
name: n.label ?? n.name,
|
|
546
|
-
extra: n.description ? { description: n.description } : void 0
|
|
547
|
-
})),
|
|
548
|
-
edges: (data.edges ?? []).map((e, i) => ({
|
|
549
|
-
id: e.id ?? `edge-${i}`,
|
|
550
|
-
from: e.source ?? e.from,
|
|
551
|
-
to: e.target ?? e.to,
|
|
552
|
-
kind: e.interaction ?? e.type ?? "interaction"
|
|
553
|
-
}))
|
|
555
|
+
nodes: [...teams, ...interactions],
|
|
556
|
+
edges: []
|
|
554
557
|
};
|
|
555
558
|
}
|
|
556
559
|
const STORM_ID_PREFIX = {
|
|
@@ -801,7 +804,7 @@ function extractValueChain(raw) {
|
|
|
801
804
|
nodes: (data.elements ?? []).map((el) => ({
|
|
802
805
|
id: el.id,
|
|
803
806
|
type: el.elementType ?? "element",
|
|
804
|
-
name: el.
|
|
807
|
+
name: el.name
|
|
805
808
|
})),
|
|
806
809
|
edges: (data.connections ?? []).map((c, i) => ({
|
|
807
810
|
id: c.id ?? `conn-${i}`,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as CONTENT_CONFIG_FILE, i as contentConfigConflict, a as discoverModels, o as legacyContentConfigFile, s as loadContentConfig } from "./content-
|
|
1
|
+
export { t as CONTENT_CONFIG_FILE, i as contentConfigConflict, a as discoverModels, o as legacyContentConfigFile, s as loadContentConfig } from "./content-Bu1bNrez.js";
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { _ as byId, c as resolveContentConfigFile, d as extractModelGraph, f as parseXml, g as byExtension, h as kindOf, l as XMLValidator, m as requirementHref, p as readBpmn, r as CONTENT_CONFIG_NAMES, u as asArray } from "./content-
|
|
1
|
+
import { _ as byId, c as resolveContentConfigFile, d as extractModelGraph, f as parseXml, g as byExtension, h as kindOf, l as XMLValidator, m as requirementHref, p as readBpmn, r as CONTENT_CONFIG_NAMES, u as asArray } from "./content-Bu1bNrez.js";
|
|
2
2
|
import { readFileSync } from "node:fs";
|
|
3
3
|
import { relative, resolve } from "node:path";
|
|
4
|
+
import { parseDocumentText, validateDocument } from "@miragon/context-maps-schema-model";
|
|
5
|
+
import { parseDocument } from "@miragon/team-topologies-schema-model";
|
|
6
|
+
import { documentIssues } from "@miragon/value-chain-schema-model";
|
|
4
7
|
//#region ../notations/refs.ts
|
|
5
8
|
const REF_EMITTERS = { bpmn: (graph) => {
|
|
6
9
|
const refs = [];
|
|
@@ -718,7 +721,7 @@ function checkBpmnXml(raw, opts = {}) {
|
|
|
718
721
|
*
|
|
719
722
|
* Deliberately NOT here: FEEL semantics, hit-policy reachability, dead wiring.
|
|
720
723
|
* Those need the FEEL engine and live in @designiq/decisions (`analyze_decision`),
|
|
721
|
-
* which would drag a browser-side dependency into this
|
|
724
|
+
* which would drag a browser-side dependency into this CLI.
|
|
722
725
|
*/
|
|
723
726
|
function checkDmnXml(raw, opts = {}) {
|
|
724
727
|
const file = opts.file ?? "<dmn>";
|
|
@@ -809,8 +812,8 @@ function mermaidFenceProblem(content, line) {
|
|
|
809
812
|
* notation that is not .bpmn/.dmn): a discovered model must at minimum parse
|
|
810
813
|
* per its notation's mediaKind — a broken .tt/.vc.json used to pass
|
|
811
814
|
* validation untouched. Pure: no filesystem, no process.exit. Deliberately
|
|
812
|
-
* mechanical: notation-specific structure checks
|
|
813
|
-
* checkers (epic #118, step 3).
|
|
815
|
+
* mechanical: notation-specific structure checks are the per-notation
|
|
816
|
+
* checkers' (epic #118, step 3; checkSchemaModel runs this gate first).
|
|
814
817
|
*/
|
|
815
818
|
function checkModelBaseline(raw, opts) {
|
|
816
819
|
const file = opts.file ?? `<${opts.notation}>`;
|
|
@@ -856,18 +859,162 @@ function checkModelBaseline(raw, opts) {
|
|
|
856
859
|
}
|
|
857
860
|
return findings;
|
|
858
861
|
}
|
|
862
|
+
/** a schema model's issue location as the canvases print it ("nodes.1.id"),
|
|
863
|
+
* "(root)" for the document itself */
|
|
864
|
+
const issuePath = (path) => path.join(".") || "(root)";
|
|
865
|
+
const schemaError = (ruleId, file) => (issue) => ({
|
|
866
|
+
severity: "ERROR",
|
|
867
|
+
ruleId,
|
|
868
|
+
file,
|
|
869
|
+
message: `${issuePath(issue.path)}: ${issue.message}`
|
|
870
|
+
});
|
|
871
|
+
/**
|
|
872
|
+
* The ids a Team Topology or Context Map canvas cannot hold although its
|
|
873
|
+
* schema model takes them: diagram-js keeps its elements in a plain object,
|
|
874
|
+
* so an id that names a built-in object property ("constructor",
|
|
875
|
+
* "__proto__") reads as already added and the import fails. The Value Chain
|
|
876
|
+
* schema model refuses these ids itself; the other two do not yet.
|
|
877
|
+
*/
|
|
878
|
+
function builtInPropertyIds(collections) {
|
|
879
|
+
return Object.entries(collections).flatMap(([collection, elements]) => (Array.isArray(elements) ? elements : []).flatMap((element, index) => {
|
|
880
|
+
const id = element?.id;
|
|
881
|
+
return typeof id === "string" && Object.hasOwn(Object.prototype, id) ? [{
|
|
882
|
+
path: [
|
|
883
|
+
collection,
|
|
884
|
+
index,
|
|
885
|
+
"id"
|
|
886
|
+
],
|
|
887
|
+
message: `the id "${id}" is reserved: it names a built-in property of JavaScript objects`
|
|
888
|
+
}] : [];
|
|
889
|
+
}));
|
|
890
|
+
}
|
|
891
|
+
/**
|
|
892
|
+
* The context-map rules the canvas enforces itself: its importer refuses a
|
|
893
|
+
* repeated id (CmImporter.assertImportable), so the file does not open. The
|
|
894
|
+
* other strategic-DDD rules are advisory there: the canvas opens the map and
|
|
895
|
+
* marks the finding, so a save must not refuse it either.
|
|
896
|
+
*/
|
|
897
|
+
const CONTEXT_MAP_REFUSED_RULES = /* @__PURE__ */ new Set(["unique-ids"]);
|
|
898
|
+
/** the path of every repeated id, in the order validateDocument's unique-ids
|
|
899
|
+
* rule reports them (contexts, then relationships): its findings name no
|
|
900
|
+
* position, and an agent must know which of two entries to change */
|
|
901
|
+
function repeatedIdPaths({ contexts, relationships }) {
|
|
902
|
+
const seen = /* @__PURE__ */ new Set();
|
|
903
|
+
return Object.entries({
|
|
904
|
+
contexts,
|
|
905
|
+
relationships
|
|
906
|
+
}).flatMap(([collection, elements]) => elements.flatMap(({ id }, index) => {
|
|
907
|
+
const repeated = seen.has(id);
|
|
908
|
+
seen.add(id);
|
|
909
|
+
return repeated ? [issuePath([
|
|
910
|
+
collection,
|
|
911
|
+
index,
|
|
912
|
+
"id"
|
|
913
|
+
])] : [];
|
|
914
|
+
}));
|
|
915
|
+
}
|
|
916
|
+
function checkTeamTopology(raw, file) {
|
|
917
|
+
const parsed = parseDocument(JSON.parse(raw));
|
|
918
|
+
if (!parsed.ok) return parsed.issues.map(schemaError("team-topology/schema", file));
|
|
919
|
+
const { nodes, interactions, flows, annotations } = parsed.document;
|
|
920
|
+
return builtInPropertyIds({
|
|
921
|
+
nodes,
|
|
922
|
+
interactions,
|
|
923
|
+
flows,
|
|
924
|
+
annotations
|
|
925
|
+
}).map(schemaError("team-topology/schema", file));
|
|
926
|
+
}
|
|
927
|
+
function checkContextMap(raw, file) {
|
|
928
|
+
const parsed = parseDocumentText(raw);
|
|
929
|
+
const issues = parsed.ok ? [] : parsed.issues ?? [{
|
|
930
|
+
path: [],
|
|
931
|
+
message: parsed.error
|
|
932
|
+
}];
|
|
933
|
+
if (issues.some(({ path }) => path.length === 0 || path[0] === "version")) return issues.map(schemaError("context-map/schema", file));
|
|
934
|
+
const { contexts, relationships } = JSON.parse(raw);
|
|
935
|
+
const schemaFindings = [...issues, ...builtInPropertyIds({
|
|
936
|
+
contexts,
|
|
937
|
+
relationships
|
|
938
|
+
})].map(schemaError("context-map/schema", file));
|
|
939
|
+
if (!parsed.ok) return schemaFindings;
|
|
940
|
+
const repeatedIds = repeatedIdPaths(parsed.document);
|
|
941
|
+
const subject = (finding) => {
|
|
942
|
+
const path = finding.rule === "unique-ids" ? repeatedIds.shift() : void 0;
|
|
943
|
+
if (path) return `${path}: `;
|
|
944
|
+
return finding.relationshipId === void 0 ? "" : `relationship "${finding.relationshipId}": `;
|
|
945
|
+
};
|
|
946
|
+
const { errors, warnings } = validateDocument(parsed.document);
|
|
947
|
+
return [...schemaFindings, ...[...errors, ...warnings].map((finding) => {
|
|
948
|
+
const refused = CONTEXT_MAP_REFUSED_RULES.has(finding.rule);
|
|
949
|
+
return {
|
|
950
|
+
severity: refused ? "ERROR" : "WARN",
|
|
951
|
+
ruleId: refused ? "context-map/schema" : "context-map/semantics",
|
|
952
|
+
file,
|
|
953
|
+
message: `${subject(finding)}${finding.message} (${finding.rule})`
|
|
954
|
+
};
|
|
955
|
+
})];
|
|
956
|
+
}
|
|
957
|
+
function checkValueChain(raw, file) {
|
|
958
|
+
return documentIssues(JSON.parse(raw)).map(schemaError("value-chain/schema", file));
|
|
959
|
+
}
|
|
960
|
+
/** each JSON notation's schema model, read the way its canvas reads the file
|
|
961
|
+
* (a Map, not an object: the notation id may be a caller's free text such
|
|
962
|
+
* as "constructor") */
|
|
963
|
+
const SCHEMA_CHECKS = /* @__PURE__ */ new Map([
|
|
964
|
+
["team-topology", {
|
|
965
|
+
ruleId: "team-topology/schema",
|
|
966
|
+
check: checkTeamTopology
|
|
967
|
+
}],
|
|
968
|
+
["context-map", {
|
|
969
|
+
ruleId: "context-map/schema",
|
|
970
|
+
check: checkContextMap
|
|
971
|
+
}],
|
|
972
|
+
["value-chain", {
|
|
973
|
+
ruleId: "value-chain/schema",
|
|
974
|
+
check: checkValueChain
|
|
975
|
+
}]
|
|
976
|
+
]);
|
|
977
|
+
/**
|
|
978
|
+
* The schema check of a Miragon JSON notation (Team Topology, Context Map,
|
|
979
|
+
* Value Chain): the file is parsed with the notation's schema model, the
|
|
980
|
+
* same parse its canvas opens it with, so everything the model refuses (a
|
|
981
|
+
* duplicate or reserved id, a coordinate out of range, a newer version) is
|
|
982
|
+
* an ERROR — a save would otherwise land a file the canvas cannot open.
|
|
983
|
+
* Text that is no JSON keeps the baseline's finding, and a notation without
|
|
984
|
+
* a schema model gets the baseline alone. Pure: no filesystem, no
|
|
985
|
+
* process.exit.
|
|
986
|
+
*/
|
|
987
|
+
function checkSchemaModel(raw, opts) {
|
|
988
|
+
const baseline = checkModelBaseline(raw, opts);
|
|
989
|
+
const schema = SCHEMA_CHECKS.get(opts.notation);
|
|
990
|
+
if (!schema || baseline.length > 0 || byId(opts.notation)?.docShape === "structured") return baseline;
|
|
991
|
+
const file = opts.file ?? `<${opts.notation}>`;
|
|
992
|
+
try {
|
|
993
|
+
return schema.check(raw, file);
|
|
994
|
+
} catch (error) {
|
|
995
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
996
|
+
return [{
|
|
997
|
+
severity: "ERROR",
|
|
998
|
+
ruleId: schema.ruleId,
|
|
999
|
+
file,
|
|
1000
|
+
message: `(root): could not be checked: ${reason}`
|
|
1001
|
+
}];
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
859
1004
|
/**
|
|
860
1005
|
* THE one check dispatch: the platform check for whatever notation `ctx.path`
|
|
861
|
-
* is — full checkers for BPMN/DMN, the
|
|
862
|
-
*
|
|
863
|
-
*
|
|
864
|
-
* (the file is not a model;
|
|
865
|
-
*
|
|
1006
|
+
* is — full checkers for BPMN/DMN, the schema model for the Miragon JSON
|
|
1007
|
+
* notations, the mediaKind baseline for everything else, plus the generic
|
|
1008
|
+
* dangling-reference rule for ANY notation with a refs emitter; `undefined`
|
|
1009
|
+
* when the path matches no registered notation (the file is not a model;
|
|
1010
|
+
* nothing to check) or `ctx.notation` names none (a mistyped id must not
|
|
1011
|
+
* pass a file unchecked). Consumed by the CLI (runCli) AND the Live Host's
|
|
1012
|
+
* save gate (application/content.ts) so both always agree.
|
|
866
1013
|
*/
|
|
867
1014
|
function checkModel(raw, ctx) {
|
|
868
1015
|
const notation = ctx.notation ?? byExtension(ctx.path)?.id;
|
|
869
|
-
if (!notation) return void 0;
|
|
870
|
-
return [...notation === "bpmn" ? checkBpmnXml(raw, { file: ctx.path }).findings : notation === "dmn" ? checkDmnXml(raw, { file: ctx.path }).findings :
|
|
1016
|
+
if (!notation || !byId(notation)) return void 0;
|
|
1017
|
+
return [...notation === "bpmn" ? checkBpmnXml(raw, { file: ctx.path }).findings : notation === "dmn" ? checkDmnXml(raw, { file: ctx.path }).findings : checkSchemaModel(raw, {
|
|
871
1018
|
file: ctx.path,
|
|
872
1019
|
notation
|
|
873
1020
|
}), ...checkRefs(notation, raw, ctx)];
|
|
@@ -916,7 +1063,7 @@ async function runCli() {
|
|
|
916
1063
|
/** optional single-model filter (a model file stem) */
|
|
917
1064
|
const only = argv[0];
|
|
918
1065
|
const rel = (p) => p.startsWith("/") ? relative(ROOT, p) : p;
|
|
919
|
-
const { CONTENT_CONFIG_FILE, contentConfigConflict, discoverModels, legacyContentConfigFile, loadContentConfig } = await import("./content-
|
|
1066
|
+
const { CONTENT_CONFIG_FILE, contentConfigConflict, discoverModels, legacyContentConfigFile, loadContentConfig } = await import("./content-CE4SulnP.js");
|
|
920
1067
|
const cfg = loadContentConfig(ROOT);
|
|
921
1068
|
if (!cfg) {
|
|
922
1069
|
console.error(notContentRepoError(ROOT));
|
|
@@ -979,4 +1126,4 @@ async function runCli() {
|
|
|
979
1126
|
process.exit(errorCount === 0 ? 0 : 1);
|
|
980
1127
|
}
|
|
981
1128
|
//#endregion
|
|
982
|
-
export {
|
|
1129
|
+
export { checkSchemaModel as a, checkModelBaseline as i, checkDmnXml as n, runCli as o, checkModel as r, checkBpmnXml as t };
|
package/dist/validate.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export { t as checkBpmnXml, n as checkDmnXml, r as checkModel, i as checkModelBaseline, a as runCli } from "./validate-
|
|
1
|
+
export { t as checkBpmnXml, n as checkDmnXml, r as checkModel, i as checkModelBaseline, a as checkSchemaModel, o as runCli } from "./validate-BqkEd0ma.js";
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@miragon/design-iq-validator",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.6.0",
|
|
4
4
|
"type": "module",
|
|
5
|
-
"description": "Platform-owned validator for designIQ content repos — designiq.yml discovery, BPMN/DMN structure and diagram coverage, cross-model references, and a parse check for every other notation. Runs against any checkout via --root; never executes content-repo code.",
|
|
5
|
+
"description": "Platform-owned validator for designIQ content repos — designiq.yml discovery, BPMN/DMN structure and diagram coverage, cross-model references, the schema check of Team Topologies, Context Maps and Value Chains, and a parse check for every other notation. Runs against any checkout via --root; never executes content-repo code.",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"repository": {
|
|
8
8
|
"type": "git",
|
|
@@ -32,10 +32,14 @@
|
|
|
32
32
|
"publishConfig": {
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
|
-
"//": "fast-xml-parser stays a RUNTIME dependency although src/ no longer imports it directly: tsdown inlines @designiq/notations (whose extract.ts imports it) but keeps npm deps external, so the published dist/ resolves it from here. Removing it breaks the npm artifact at import time while the workspace keeps working.",
|
|
35
|
+
"//": "fast-xml-parser stays a RUNTIME dependency although src/ no longer imports it directly: tsdown inlines @designiq/notations (whose extract.ts imports it) but keeps npm deps external, so the published dist/ resolves it from here. Removing it breaks the npm artifact at import time while the workspace keeps working. zod is a RUNTIME dependency for the same reason: src/ never imports it, but the team-topologies and context-maps schema models take it as a peer, and the published package is what provides it.",
|
|
36
36
|
"dependencies": {
|
|
37
|
+
"@miragon/context-maps-schema-model": "0.3.0",
|
|
38
|
+
"@miragon/team-topologies-schema-model": "0.11.2",
|
|
39
|
+
"@miragon/value-chain-schema-model": "0.5.0",
|
|
37
40
|
"fast-xml-parser": "5.11.2",
|
|
38
|
-
"yaml": "2.9.1"
|
|
41
|
+
"yaml": "2.9.1",
|
|
42
|
+
"zod": "4.6.7"
|
|
39
43
|
},
|
|
40
44
|
"devDependencies": {
|
|
41
45
|
"tsdown": "0.23.1",
|