yarramate 1.21.0 → 1.22.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/fold-tree.d.ts +21 -8
- package/dist/fold-tree.js +118 -23
- package/dist/projection.d.ts +11 -0
- package/dist/projection.js +4 -0
- package/dist/schema-validators.generated.js +34 -22
- package/dist/visual-app/assets/index-C0nYrzna.js +395 -0
- package/dist/visual-app/index.html +1 -1
- package/dist/visual-app-lib/editor.js +26862 -26734
- package/dist/visual-app-lib/types/fold-tree.d.ts +21 -8
- package/dist/visual-app-lib/types/projection.d.ts +11 -0
- package/dist/visual-app-lib/types/visual-app/constraint-rows.d.ts +70 -0
- package/dist/visual-app-lib/types/visual-app/graph-canvas.d.ts +13 -2
- package/dist/visual-app-lib/types/visual-app/query-fields.d.ts +3 -2
- package/dist/visual-app-lib/types/visual-app/query-panel.d.ts +10 -3
- package/dist/visual-app-lib/types/visual-app/workspace-state.d.ts +8 -1
- package/package.json +1 -1
- package/schema/yarramate-projection.schema.json +4 -0
- package/dist/visual-app/assets/index-Ch27Sr5z.js +0 -394
package/dist/fold-tree.d.ts
CHANGED
|
@@ -110,15 +110,28 @@ export declare function nestingTree(edges: readonly FoldEdge[], nesting: readonl
|
|
|
110
110
|
/**
|
|
111
111
|
* The containment tree: what a view nests, plus what a pattern owns.
|
|
112
112
|
*
|
|
113
|
-
* A slot member joins the tree only when all
|
|
114
|
-
* a different way of getting the answer wrong:
|
|
113
|
+
* A slot member joins the tree only when all of these hold, and each condition
|
|
114
|
+
* is a different way of getting the answer wrong:
|
|
115
115
|
*
|
|
116
|
-
* - **
|
|
117
|
-
*
|
|
118
|
-
*
|
|
119
|
-
* the
|
|
120
|
-
*
|
|
121
|
-
*
|
|
116
|
+
* - **Held inside one box.** A member's HOLDERS are every instance whose slots
|
|
117
|
+
* name it. One holder puts the member in that holder. Several put it in their
|
|
118
|
+
* lowest common ancestor, which is the level at which the holders diverge and
|
|
119
|
+
* therefore the innermost box that contains all of them. Holders with no
|
|
120
|
+
* common ancestor leave the member outside, because there is no one box it
|
|
121
|
+
* sits within and a single-parent tree would have to pick.
|
|
122
|
+
*
|
|
123
|
+
* This AMENDS ADR 0143's "Exclusive" rule, which kept every shared subject
|
|
124
|
+
* outside (#473 phase 3, ADR 0145, Nabeel's decision of 2026-09-05). The
|
|
125
|
+
* original reasoning was that two owners force a silent choice; it is only
|
|
126
|
+
* true when the owners sit in different boxes. Where both already sit under
|
|
127
|
+
* one box there is nothing to choose, and the old rule left 14 of the
|
|
128
|
+
* reference Landscape's 30 data objects outside the single application whose
|
|
129
|
+
* own parts were the things binding them.
|
|
130
|
+
* - **`owned` or `unwired`, never `context` alone.** A context slot names
|
|
131
|
+
* something the instance USES and does not contain — the upstream API it
|
|
132
|
+
* calls, the plane it runs on. Folding those would swallow half the landscape
|
|
133
|
+
* into whichever box happened to reference it. At least one binding must be
|
|
134
|
+
* `owned` or `unwired` for the member to fold at all.
|
|
122
135
|
* - **Not a ruling.** See {@link RULING_CORE_KINDS}.
|
|
123
136
|
*
|
|
124
137
|
* A view's own nesting wins where both apply: the view is the more specific
|
package/dist/fold-tree.js
CHANGED
|
@@ -127,6 +127,18 @@ export function nestingTree(edges, nesting, coreKindOf) {
|
|
|
127
127
|
* a straight-line ancestor of a cycle is still validly nested under its own
|
|
128
128
|
* non-cyclic parent. Mutates `parentOf` and returns what it removed.
|
|
129
129
|
*/
|
|
130
|
+
/** Whether `id` sits anywhere inside `ancestor` in the tree built so far. */
|
|
131
|
+
const isDescendantOf = (id, ancestor, parentOf) => {
|
|
132
|
+
const seen = new Set([id]);
|
|
133
|
+
let current = parentOf.get(id);
|
|
134
|
+
while (current !== undefined && !seen.has(current)) {
|
|
135
|
+
if (current === ancestor)
|
|
136
|
+
return true;
|
|
137
|
+
seen.add(current);
|
|
138
|
+
current = parentOf.get(current);
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
};
|
|
130
142
|
function unnestCycles(parentOf) {
|
|
131
143
|
const cycleMembers = new Set();
|
|
132
144
|
for (const start of parentOf.keys()) {
|
|
@@ -149,18 +161,59 @@ function unnestCycles(parentOf) {
|
|
|
149
161
|
parentOf.delete(id);
|
|
150
162
|
return [...cycleMembers];
|
|
151
163
|
}
|
|
164
|
+
/**
|
|
165
|
+
* The lowest node that contains every one of `ids`, counting each id as an
|
|
166
|
+
* ancestor of itself, or `undefined` when they do not share one.
|
|
167
|
+
*
|
|
168
|
+
* "Counting each id as an ancestor of itself" is the part that matters: where
|
|
169
|
+
* one holder already sits inside another, the answer is the outer holder rather
|
|
170
|
+
* than something above them both.
|
|
171
|
+
*/
|
|
172
|
+
const lowestCommonAncestor = (ids, parentOf) => {
|
|
173
|
+
const chainOf = (id) => {
|
|
174
|
+
const chain = [];
|
|
175
|
+
const seen = new Set();
|
|
176
|
+
let current = id;
|
|
177
|
+
while (current !== undefined && !seen.has(current)) {
|
|
178
|
+
seen.add(current);
|
|
179
|
+
chain.push(current);
|
|
180
|
+
current = parentOf.get(current);
|
|
181
|
+
}
|
|
182
|
+
return chain;
|
|
183
|
+
};
|
|
184
|
+
const [first, ...rest] = ids;
|
|
185
|
+
if (first === undefined)
|
|
186
|
+
return undefined;
|
|
187
|
+
const others = rest.map((id) => new Set(chainOf(id)));
|
|
188
|
+
// Walking the first chain from the node OUTWARDS makes the first hit the
|
|
189
|
+
// lowest by construction.
|
|
190
|
+
return chainOf(first).find((candidate) => others.every((chain) => chain.has(candidate)));
|
|
191
|
+
};
|
|
152
192
|
/**
|
|
153
193
|
* The containment tree: what a view nests, plus what a pattern owns.
|
|
154
194
|
*
|
|
155
|
-
* A slot member joins the tree only when all
|
|
156
|
-
* a different way of getting the answer wrong:
|
|
195
|
+
* A slot member joins the tree only when all of these hold, and each condition
|
|
196
|
+
* is a different way of getting the answer wrong:
|
|
157
197
|
*
|
|
158
|
-
* - **
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
* the
|
|
162
|
-
*
|
|
163
|
-
*
|
|
198
|
+
* - **Held inside one box.** A member's HOLDERS are every instance whose slots
|
|
199
|
+
* name it. One holder puts the member in that holder. Several put it in their
|
|
200
|
+
* lowest common ancestor, which is the level at which the holders diverge and
|
|
201
|
+
* therefore the innermost box that contains all of them. Holders with no
|
|
202
|
+
* common ancestor leave the member outside, because there is no one box it
|
|
203
|
+
* sits within and a single-parent tree would have to pick.
|
|
204
|
+
*
|
|
205
|
+
* This AMENDS ADR 0143's "Exclusive" rule, which kept every shared subject
|
|
206
|
+
* outside (#473 phase 3, ADR 0145, Nabeel's decision of 2026-09-05). The
|
|
207
|
+
* original reasoning was that two owners force a silent choice; it is only
|
|
208
|
+
* true when the owners sit in different boxes. Where both already sit under
|
|
209
|
+
* one box there is nothing to choose, and the old rule left 14 of the
|
|
210
|
+
* reference Landscape's 30 data objects outside the single application whose
|
|
211
|
+
* own parts were the things binding them.
|
|
212
|
+
* - **`owned` or `unwired`, never `context` alone.** A context slot names
|
|
213
|
+
* something the instance USES and does not contain — the upstream API it
|
|
214
|
+
* calls, the plane it runs on. Folding those would swallow half the landscape
|
|
215
|
+
* into whichever box happened to reference it. At least one binding must be
|
|
216
|
+
* `owned` or `unwired` for the member to fold at all.
|
|
164
217
|
* - **Not a ruling.** See {@link RULING_CORE_KINDS}.
|
|
165
218
|
*
|
|
166
219
|
* A view's own nesting wins where both apply: the view is the more specific
|
|
@@ -178,22 +231,64 @@ export function foldTree(input) {
|
|
|
178
231
|
else
|
|
179
232
|
instances.add(membership.instance);
|
|
180
233
|
}
|
|
181
|
-
|
|
234
|
+
// Whether ANY of a member's bindings is one the instance holds it out by. A
|
|
235
|
+
// member bound only through context slots never folds, however many hold it.
|
|
236
|
+
const heldOutSomewhere = new Set();
|
|
182
237
|
for (const membership of input.memberships) {
|
|
183
|
-
if (
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
// A
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
238
|
+
if (membership.wiring !== 'context')
|
|
239
|
+
heldOutSomewhere.add(membership.member);
|
|
240
|
+
}
|
|
241
|
+
const parentOf = new Map(fromNesting.parentOf);
|
|
242
|
+
const candidates = [
|
|
243
|
+
...new Set(input.memberships
|
|
244
|
+
.map(({ member }) => member)
|
|
245
|
+
.filter((member) =>
|
|
246
|
+
// A view's own nesting already placed it, and the view wins.
|
|
247
|
+
!parentOf.has(member) &&
|
|
248
|
+
heldOutSomewhere.has(member) &&
|
|
249
|
+
!RULING_CORE_KINDS.has(coreKindOf(member)) &&
|
|
250
|
+
// A node the input does not carry cannot be drawn inside anything.
|
|
251
|
+
coreKindById.has(member) &&
|
|
252
|
+
// Something that holds itself is not held by anything.
|
|
253
|
+
instancesOf.get(member)?.has(member) !== true)),
|
|
254
|
+
];
|
|
255
|
+
// Resolved in ROUNDS rather than one pass, because a member's holders may
|
|
256
|
+
// themselves be members whose own parents are decided here. Placing a member
|
|
257
|
+
// before its holders are settled would measure the lowest common ancestor
|
|
258
|
+
// against a tree that is still missing the levels that separate them, and the
|
|
259
|
+
// reference has five-deep chains (spec, mapping, call, client, application),
|
|
260
|
+
// so this is exercised rather than theoretical.
|
|
261
|
+
//
|
|
262
|
+
// A member is settled once it is placed or once it is known to stay outside.
|
|
263
|
+
// Whatever a round cannot decide it hands to the next; when a round decides
|
|
264
|
+
// nothing, what is left is a mutual dependency and stays outside, which is the
|
|
265
|
+
// same answer the cycle guard below would reach for it anyway.
|
|
266
|
+
let pending = candidates;
|
|
267
|
+
while (pending.length > 0) {
|
|
268
|
+
const deferred = [];
|
|
269
|
+
let decided = false;
|
|
270
|
+
for (const member of pending) {
|
|
271
|
+
const holders = [...(instancesOf.get(member) ?? [])];
|
|
272
|
+
if (holders.some((holder) => pending.includes(holder) && holder !== member)) {
|
|
273
|
+
deferred.push(member);
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
decided = true;
|
|
277
|
+
const parent = holders.length === 1
|
|
278
|
+
? holders[0]
|
|
279
|
+
: lowestCommonAncestor(holders, parentOf);
|
|
280
|
+
if (parent === undefined || parent === member)
|
|
281
|
+
continue;
|
|
282
|
+
// A member that already contains one of its holders cannot also sit
|
|
283
|
+
// inside it. The cycle guard below is the backstop, not the rule.
|
|
284
|
+
if (holders.some((holder) => isDescendantOf(holder, member, parentOf))) {
|
|
285
|
+
continue;
|
|
286
|
+
}
|
|
287
|
+
parentOf.set(member, parent);
|
|
288
|
+
}
|
|
289
|
+
if (!decided)
|
|
290
|
+
break;
|
|
291
|
+
pending = deferred;
|
|
197
292
|
}
|
|
198
293
|
// Slot membership can close a loop the view's nesting alone did not, so the
|
|
199
294
|
// guard runs again over the combined tree rather than trusting the first.
|
package/dist/projection.d.ts
CHANGED
|
@@ -78,6 +78,17 @@ export interface ProjectionDefinition {
|
|
|
78
78
|
readonly showLifecycle?: boolean;
|
|
79
79
|
readonly showEvidence?: boolean;
|
|
80
80
|
readonly showOwnership?: boolean;
|
|
81
|
+
/**
|
|
82
|
+
* Whether a bound RULING draws as a row inside its holder rather than as a
|
|
83
|
+
* node of its own (#473 phase 3, ADR 0145).
|
|
84
|
+
*
|
|
85
|
+
* On the reference this takes the whole model from 173 boxes to 91, because
|
|
86
|
+
* 82 of its rulings are bound into slots and every one of them was drawing
|
|
87
|
+
* as a box with a single association edge. Presentation only: the model,
|
|
88
|
+
* the query and the selected set do not move, and turning it off restores
|
|
89
|
+
* the boxes.
|
|
90
|
+
*/
|
|
91
|
+
readonly showConstraints?: boolean;
|
|
81
92
|
/**
|
|
82
93
|
* The folder this view files itself under in an editor's rail: a label the
|
|
83
94
|
* author declares, nested with `/`, never the directory the projection
|
package/dist/projection.js
CHANGED
|
@@ -66,6 +66,7 @@ export function canonicalProjection(projection) {
|
|
|
66
66
|
...(presentation.showLifecycle === undefined ? {} : { showLifecycle: presentation.showLifecycle }),
|
|
67
67
|
...(presentation.showEvidence === undefined ? {} : { showEvidence: presentation.showEvidence }),
|
|
68
68
|
...(presentation.showOwnership === undefined ? {} : { showOwnership: presentation.showOwnership }),
|
|
69
|
+
...(presentation.showConstraints === undefined ? {} : { showConstraints: presentation.showConstraints }),
|
|
69
70
|
...(presentation.notation === undefined ? {} : { notation: presentation.notation }),
|
|
70
71
|
},
|
|
71
72
|
}),
|
|
@@ -631,6 +632,9 @@ export function evaluateProjection(graph, projection, profileContext, membership
|
|
|
631
632
|
...(projection.presentation.showOwnership === undefined
|
|
632
633
|
? {}
|
|
633
634
|
: { showOwnership: projection.presentation.showOwnership }),
|
|
635
|
+
...(projection.presentation.showConstraints === undefined
|
|
636
|
+
? {}
|
|
637
|
+
: { showConstraints: projection.presentation.showConstraints }),
|
|
634
638
|
...(projection.presentation.notation === undefined
|
|
635
639
|
? {}
|
|
636
640
|
: { notation: projection.presentation.notation }),
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
// file and not a runtime one; the two pure helpers imported below are
|
|
10
10
|
// all the runtime still takes from ajv.
|
|
11
11
|
//
|
|
12
|
-
// schema/ sha256:
|
|
12
|
+
// schema/ sha256: cc9263e2df972b9fbeb51dd1e2572396c633aaa2b7eb74f0a70e82f7063ce0d4
|
|
13
13
|
import ajvRuntime0Module from 'ajv/dist/runtime/ucs2length.js';
|
|
14
14
|
const ajvRuntime0 = ajvRuntime0Module.default ?? ajvRuntime0Module;
|
|
15
15
|
import ajvRuntime1Module from 'ajv/dist/runtime/equal.js';
|
|
@@ -4476,7 +4476,7 @@ else {
|
|
|
4476
4476
|
} validate61.errors = vErrors; return errors === 0; }
|
|
4477
4477
|
validate61.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
4478
4478
|
export const validateProjection = validate62;
|
|
4479
|
-
const schema113 = { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://yarramate.org/schema/projection/v1", "title": "YarraMate semantic projection", "type": "object", "additionalProperties": false, "required": ["format", "id", "version", "query"], "properties": { "format": { "const": "yarramate/projection/v1" }, "id": { "$ref": "#/$defs/id" }, "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+$" }, "query": { "$ref": "#/$defs/query" }, "presentation": { "$ref": "#/$defs/presentation" } }, "$defs": { "query": { "type": "object", "additionalProperties": false, "properties": { "subjects": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "instances": { "description": "Pattern instances whose CONTENTS this query selects (#473, ADR 0144). Each id names an instance, and the facet selects that instance together with everything the fold tree would draw inside it: the same closure `presentation.fold: \"instances\"` collapses into one box, read through this view's own `nesting`. This is the one facet that ADDS rather than narrows. `subjects` and `instances` are a single identity facet spelled two ways and their values combine with OR, while every other field still ANDs over the union. Naming the instance rather than hand-listing its members is what keeps a view from going stale the next time the pattern binds a slot. An id that names nothing is refused (YM921); one that names a subject which is not a pattern instance is refused separately (YM922), because a typo and a category error send an author to different places.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "exclude": { "description": "Subjects this query would otherwise select and the author has taken out: the exception a rule cannot state (#267, ADR 0122). Applied after every other facet and after relationship expansion, so an excluded subject is out whichever way it would have come back in. Naming a subject no facet selects is allowed and inert until the model grows into the rule.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "documents": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/id" } }, "kinds": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "layers": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/layer" } }, "statuses": { "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "excludeStatuses": { "description": "Drop concepts carrying one of these lifecycle statuses while keeping concepts that declare no status at all - 'everything except retired' for viewpoint projections, where a bare statuses filter would wrongly drop unstatused actors and motivation elements.", "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "states": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "owners": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "constraints": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "relationshipKinds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "kindMatching": { "enum": ["exact", "descendants"] }, "relationships": { "enum": ["between", "connected", "none"] }, "isolatedConcepts": { "enum": ["include", "exclude"] } } }, "presentation": { "type": "object", "additionalProperties": false, "properties": { "title": { "$ref": "#/$defs/nonEmptyText" }, "description": { "$ref": "#/$defs/nonEmptyText" }, "layout": { "enum": ["layered"] }, "direction": { "enum": ["top-down", "left-right"] }, "nesting": { "type": "array", "uniqueItems": true, "items": { "enum": ["composition", "assignment"] } }, "fold": { "description": "Whether this view draws pattern instances FOLDED by default (#473). \"instances\" collapses every instance to a single node carrying its members, with the edges into and out of them lifted onto the box; \"none\", the default, draws everything. A reader opens what they want, so this says where to START rather than what may be seen. Folding reads the same containment tree nesting does, so a view declaring fold without \"assignment\" in nesting collapses less than its author probably expects; the editor says so rather than the loader refusing it, because a diagnostic has no warning severity and this is not an error.", "enum": ["instances", "none"] }, "showLifecycle": { "type": "boolean" }, "showEvidence": { "type": "boolean" }, "showOwnership": { "type": "boolean" }, "notation": { "enum": ["archimate"] }, "folder": { "type": "string", "description": "The folder this view files itself under in an editor's rail. A LABEL the author declares, never the directory the projection sits in: nest with '/' separators, and the filesystem is never consulted (ADR 0104).", "pattern": "^[^/]+(?:/[^/]+)*$", "minLength": 1 } } }, "id": { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "qualifiedKind": { "type": "string", "pattern": "^[a-z][a-z0-9-]*(?:/[a-z][a-z0-9-]*)+@[0-9]+\\.[0-9]+#[a-z][A-Za-z0-9-]*$" }, "subjectIdentity": { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "nonEmptyText": { "type": "string", "minLength": 1 }, "layer": { "enum": ["motivation", "strategy", "business", "application", "technology", "physical", "implementation", "composite"] } } };
|
|
4479
|
+
const schema113 = { "$schema": "https://json-schema.org/draft/2020-12/schema", "$id": "https://yarramate.org/schema/projection/v1", "title": "YarraMate semantic projection", "type": "object", "additionalProperties": false, "required": ["format", "id", "version", "query"], "properties": { "format": { "const": "yarramate/projection/v1" }, "id": { "$ref": "#/$defs/id" }, "version": { "type": "string", "pattern": "^[0-9]+\\.[0-9]+$" }, "query": { "$ref": "#/$defs/query" }, "presentation": { "$ref": "#/$defs/presentation" } }, "$defs": { "query": { "type": "object", "additionalProperties": false, "properties": { "subjects": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "instances": { "description": "Pattern instances whose CONTENTS this query selects (#473, ADR 0144). Each id names an instance, and the facet selects that instance together with everything the fold tree would draw inside it: the same closure `presentation.fold: \"instances\"` collapses into one box, read through this view's own `nesting`. This is the one facet that ADDS rather than narrows. `subjects` and `instances` are a single identity facet spelled two ways and their values combine with OR, while every other field still ANDs over the union. Naming the instance rather than hand-listing its members is what keeps a view from going stale the next time the pattern binds a slot. An id that names nothing is refused (YM921); one that names a subject which is not a pattern instance is refused separately (YM922), because a typo and a category error send an author to different places.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "exclude": { "description": "Subjects this query would otherwise select and the author has taken out: the exception a rule cannot state (#267, ADR 0122). Applied after every other facet and after relationship expansion, so an excluded subject is out whichever way it would have come back in. Naming a subject no facet selects is allowed and inert until the model grows into the rule.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "documents": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/id" } }, "kinds": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "layers": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/layer" } }, "statuses": { "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "excludeStatuses": { "description": "Drop concepts carrying one of these lifecycle statuses while keeping concepts that declare no status at all - 'everything except retired' for viewpoint projections, where a bare statuses filter would wrongly drop unstatused actors and motivation elements.", "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "states": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "owners": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "constraints": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "relationshipKinds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "kindMatching": { "enum": ["exact", "descendants"] }, "relationships": { "enum": ["between", "connected", "none"] }, "isolatedConcepts": { "enum": ["include", "exclude"] } } }, "presentation": { "type": "object", "additionalProperties": false, "properties": { "title": { "$ref": "#/$defs/nonEmptyText" }, "description": { "$ref": "#/$defs/nonEmptyText" }, "layout": { "enum": ["layered"] }, "direction": { "enum": ["top-down", "left-right"] }, "nesting": { "type": "array", "uniqueItems": true, "items": { "enum": ["composition", "assignment"] } }, "fold": { "description": "Whether this view draws pattern instances FOLDED by default (#473). \"instances\" collapses every instance to a single node carrying its members, with the edges into and out of them lifted onto the box; \"none\", the default, draws everything. A reader opens what they want, so this says where to START rather than what may be seen. Folding reads the same containment tree nesting does, so a view declaring fold without \"assignment\" in nesting collapses less than its author probably expects; the editor says so rather than the loader refusing it, because a diagnostic has no warning severity and this is not an error.", "enum": ["instances", "none"] }, "showLifecycle": { "type": "boolean" }, "showEvidence": { "type": "boolean" }, "showOwnership": { "type": "boolean" }, "showConstraints": { "description": "Whether this view draws a bound RULING as a row inside the instance that holds it rather than as a node of its own (#473 phase 3, ADR 0145). A constraint filling an unwired slot of a visible instance becomes a line in that instance's label block, carrying its slot, its name and its RULER, and its association edge to the owner is hidden with it. Constraints nothing binds stay nodes: a requirement with no holder has no box to sit in. Presentation only, exactly like the three toggles above it: the model, the query and the selected set are identical either way, and a reader turns it off to get the boxes back.", "type": "boolean" }, "notation": { "enum": ["archimate"] }, "folder": { "type": "string", "description": "The folder this view files itself under in an editor's rail. A LABEL the author declares, never the directory the projection sits in: nest with '/' separators, and the filesystem is never consulted (ADR 0104).", "pattern": "^[^/]+(?:/[^/]+)*$", "minLength": 1 } } }, "id": { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "qualifiedKind": { "type": "string", "pattern": "^[a-z][a-z0-9-]*(?:/[a-z][a-z0-9-]*)+@[0-9]+\\.[0-9]+#[a-z][A-Za-z0-9-]*$" }, "subjectIdentity": { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" }, "nonEmptyText": { "type": "string", "minLength": 1 }, "layer": { "enum": ["motivation", "strategy", "business", "application", "technology", "physical", "implementation", "composite"] } } };
|
|
4480
4480
|
const schema114 = { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" };
|
|
4481
4481
|
const schema115 = { "type": "object", "additionalProperties": false, "properties": { "subjects": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "instances": { "description": "Pattern instances whose CONTENTS this query selects (#473, ADR 0144). Each id names an instance, and the facet selects that instance together with everything the fold tree would draw inside it: the same closure `presentation.fold: \"instances\"` collapses into one box, read through this view's own `nesting`. This is the one facet that ADDS rather than narrows. `subjects` and `instances` are a single identity facet spelled two ways and their values combine with OR, while every other field still ANDs over the union. Naming the instance rather than hand-listing its members is what keeps a view from going stale the next time the pattern binds a slot. An id that names nothing is refused (YM921); one that names a subject which is not a pattern instance is refused separately (YM922), because a typo and a category error send an author to different places.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "exclude": { "description": "Subjects this query would otherwise select and the author has taken out: the exception a rule cannot state (#267, ADR 0122). Applied after every other facet and after relationship expansion, so an excluded subject is out whichever way it would have come back in. Naming a subject no facet selects is allowed and inert until the model grows into the rule.", "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "documents": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/id" } }, "kinds": { "type": "array", "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "layers": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/layer" } }, "statuses": { "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "excludeStatuses": { "description": "Drop concepts carrying one of these lifecycle statuses while keeping concepts that declare no status at all - 'everything except retired' for viewpoint projections, where a bare statuses filter would wrongly drop unstatused actors and motivation elements.", "type": "array", "uniqueItems": true, "items": { "enum": ["planned", "current", "retired"] } }, "states": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "owners": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "constraints": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/subjectIdentity" } }, "relationshipKinds": { "type": "array", "minItems": 1, "uniqueItems": true, "items": { "$ref": "#/$defs/qualifiedKind" } }, "kindMatching": { "enum": ["exact", "descendants"] }, "relationships": { "enum": ["between", "connected", "none"] }, "isolatedConcepts": { "enum": ["include", "exclude"] } } };
|
|
4482
4482
|
const schema116 = { "type": "string", "pattern": "^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$" };
|
|
@@ -5314,7 +5314,7 @@ else {
|
|
|
5314
5314
|
errors++;
|
|
5315
5315
|
} validate63.errors = vErrors; return errors === 0; }
|
|
5316
5316
|
validate63.evaluated = { "props": true, "dynamicProps": false, "dynamicItems": false };
|
|
5317
|
-
const schema126 = { "type": "object", "additionalProperties": false, "properties": { "title": { "$ref": "#/$defs/nonEmptyText" }, "description": { "$ref": "#/$defs/nonEmptyText" }, "layout": { "enum": ["layered"] }, "direction": { "enum": ["top-down", "left-right"] }, "nesting": { "type": "array", "uniqueItems": true, "items": { "enum": ["composition", "assignment"] } }, "fold": { "description": "Whether this view draws pattern instances FOLDED by default (#473). \"instances\" collapses every instance to a single node carrying its members, with the edges into and out of them lifted onto the box; \"none\", the default, draws everything. A reader opens what they want, so this says where to START rather than what may be seen. Folding reads the same containment tree nesting does, so a view declaring fold without \"assignment\" in nesting collapses less than its author probably expects; the editor says so rather than the loader refusing it, because a diagnostic has no warning severity and this is not an error.", "enum": ["instances", "none"] }, "showLifecycle": { "type": "boolean" }, "showEvidence": { "type": "boolean" }, "showOwnership": { "type": "boolean" }, "notation": { "enum": ["archimate"] }, "folder": { "type": "string", "description": "The folder this view files itself under in an editor's rail. A LABEL the author declares, never the directory the projection sits in: nest with '/' separators, and the filesystem is never consulted (ADR 0104).", "pattern": "^[^/]+(?:/[^/]+)*$", "minLength": 1 } } };
|
|
5317
|
+
const schema126 = { "type": "object", "additionalProperties": false, "properties": { "title": { "$ref": "#/$defs/nonEmptyText" }, "description": { "$ref": "#/$defs/nonEmptyText" }, "layout": { "enum": ["layered"] }, "direction": { "enum": ["top-down", "left-right"] }, "nesting": { "type": "array", "uniqueItems": true, "items": { "enum": ["composition", "assignment"] } }, "fold": { "description": "Whether this view draws pattern instances FOLDED by default (#473). \"instances\" collapses every instance to a single node carrying its members, with the edges into and out of them lifted onto the box; \"none\", the default, draws everything. A reader opens what they want, so this says where to START rather than what may be seen. Folding reads the same containment tree nesting does, so a view declaring fold without \"assignment\" in nesting collapses less than its author probably expects; the editor says so rather than the loader refusing it, because a diagnostic has no warning severity and this is not an error.", "enum": ["instances", "none"] }, "showLifecycle": { "type": "boolean" }, "showEvidence": { "type": "boolean" }, "showOwnership": { "type": "boolean" }, "showConstraints": { "description": "Whether this view draws a bound RULING as a row inside the instance that holds it rather than as a node of its own (#473 phase 3, ADR 0145). A constraint filling an unwired slot of a visible instance becomes a line in that instance's label block, carrying its slot, its name and its RULER, and its association edge to the owner is hidden with it. Constraints nothing binds stay nodes: a requirement with no holder has no box to sit in. Presentation only, exactly like the three toggles above it: the model, the query and the selected set are identical either way, and a reader turns it off to get the boxes back.", "type": "boolean" }, "notation": { "enum": ["archimate"] }, "folder": { "type": "string", "description": "The folder this view files itself under in an editor's rail. A LABEL the author declares, never the directory the projection sits in: nest with '/' separators, and the filesystem is never consulted (ADR 0104).", "pattern": "^[^/]+(?:/[^/]+)*$", "minLength": 1 } } };
|
|
5318
5318
|
const schema127 = { "type": "string", "minLength": 1 };
|
|
5319
5319
|
function validate65(data, { instancePath = "", parentData, parentDataProperty, rootData = data, dynamicAnchors = {} } = {}) { let vErrors = null; let errors = 0; const evaluated0 = validate65.evaluated; if (evaluated0.dynamicProps) {
|
|
5320
5320
|
evaluated0.props = undefined;
|
|
@@ -5505,9 +5505,9 @@ function validate65(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5505
5505
|
errors++;
|
|
5506
5506
|
}
|
|
5507
5507
|
}
|
|
5508
|
-
if (data.
|
|
5509
|
-
if (
|
|
5510
|
-
const err14 = { instancePath: instancePath + "/
|
|
5508
|
+
if (data.showConstraints !== undefined) {
|
|
5509
|
+
if (typeof data.showConstraints !== "boolean") {
|
|
5510
|
+
const err14 = { instancePath: instancePath + "/showConstraints", schemaPath: "#/properties/showConstraints/type", keyword: "type", params: { type: "boolean" }, message: "must be boolean" };
|
|
5511
5511
|
if (vErrors === null) {
|
|
5512
5512
|
vErrors = [err14];
|
|
5513
5513
|
}
|
|
@@ -5517,49 +5517,61 @@ function validate65(data, { instancePath = "", parentData, parentDataProperty, r
|
|
|
5517
5517
|
errors++;
|
|
5518
5518
|
}
|
|
5519
5519
|
}
|
|
5520
|
+
if (data.notation !== undefined) {
|
|
5521
|
+
if (!(data.notation === "archimate")) {
|
|
5522
|
+
const err15 = { instancePath: instancePath + "/notation", schemaPath: "#/properties/notation/enum", keyword: "enum", params: { allowedValues: schema126.properties.notation.enum }, message: "must be equal to one of the allowed values" };
|
|
5523
|
+
if (vErrors === null) {
|
|
5524
|
+
vErrors = [err15];
|
|
5525
|
+
}
|
|
5526
|
+
else {
|
|
5527
|
+
vErrors.push(err15);
|
|
5528
|
+
}
|
|
5529
|
+
errors++;
|
|
5530
|
+
}
|
|
5531
|
+
}
|
|
5520
5532
|
if (data.folder !== undefined) {
|
|
5521
|
-
let
|
|
5522
|
-
if (typeof
|
|
5523
|
-
if (func2(
|
|
5524
|
-
const
|
|
5533
|
+
let data12 = data.folder;
|
|
5534
|
+
if (typeof data12 === "string") {
|
|
5535
|
+
if (func2(data12) < 1) {
|
|
5536
|
+
const err16 = { instancePath: instancePath + "/folder", schemaPath: "#/properties/folder/minLength", keyword: "minLength", params: { limit: 1 }, message: "must NOT have fewer than 1 characters" };
|
|
5525
5537
|
if (vErrors === null) {
|
|
5526
|
-
vErrors = [
|
|
5538
|
+
vErrors = [err16];
|
|
5527
5539
|
}
|
|
5528
5540
|
else {
|
|
5529
|
-
vErrors.push(
|
|
5541
|
+
vErrors.push(err16);
|
|
5530
5542
|
}
|
|
5531
5543
|
errors++;
|
|
5532
5544
|
}
|
|
5533
|
-
if (!pattern15.test(
|
|
5534
|
-
const
|
|
5545
|
+
if (!pattern15.test(data12)) {
|
|
5546
|
+
const err17 = { instancePath: instancePath + "/folder", schemaPath: "#/properties/folder/pattern", keyword: "pattern", params: { pattern: "^[^/]+(?:/[^/]+)*$" }, message: "must match pattern \"" + "^[^/]+(?:/[^/]+)*$" + "\"" };
|
|
5535
5547
|
if (vErrors === null) {
|
|
5536
|
-
vErrors = [
|
|
5548
|
+
vErrors = [err17];
|
|
5537
5549
|
}
|
|
5538
5550
|
else {
|
|
5539
|
-
vErrors.push(
|
|
5551
|
+
vErrors.push(err17);
|
|
5540
5552
|
}
|
|
5541
5553
|
errors++;
|
|
5542
5554
|
}
|
|
5543
5555
|
}
|
|
5544
5556
|
else {
|
|
5545
|
-
const
|
|
5557
|
+
const err18 = { instancePath: instancePath + "/folder", schemaPath: "#/properties/folder/type", keyword: "type", params: { type: "string" }, message: "must be string" };
|
|
5546
5558
|
if (vErrors === null) {
|
|
5547
|
-
vErrors = [
|
|
5559
|
+
vErrors = [err18];
|
|
5548
5560
|
}
|
|
5549
5561
|
else {
|
|
5550
|
-
vErrors.push(
|
|
5562
|
+
vErrors.push(err18);
|
|
5551
5563
|
}
|
|
5552
5564
|
errors++;
|
|
5553
5565
|
}
|
|
5554
5566
|
}
|
|
5555
5567
|
}
|
|
5556
5568
|
else {
|
|
5557
|
-
const
|
|
5569
|
+
const err19 = { instancePath, schemaPath: "#/type", keyword: "type", params: { type: "object" }, message: "must be object" };
|
|
5558
5570
|
if (vErrors === null) {
|
|
5559
|
-
vErrors = [
|
|
5571
|
+
vErrors = [err19];
|
|
5560
5572
|
}
|
|
5561
5573
|
else {
|
|
5562
|
-
vErrors.push(
|
|
5574
|
+
vErrors.push(err19);
|
|
5563
5575
|
}
|
|
5564
5576
|
errors++;
|
|
5565
5577
|
} validate65.errors = vErrors; return errors === 0; }
|