yarramate 0.11.0 → 0.12.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.
|
@@ -712,6 +712,9 @@ export function runLikeC4Cli(args, cwd = process.cwd()) {
|
|
|
712
712
|
? [
|
|
713
713
|
{
|
|
714
714
|
...(view.id === undefined ? {} : { id: view.id }),
|
|
715
|
+
...(view.folder === undefined
|
|
716
|
+
? {}
|
|
717
|
+
: { folder: view.folder }),
|
|
715
718
|
prepared,
|
|
716
719
|
...(view.compare === undefined
|
|
717
720
|
? {}
|
|
@@ -11,6 +11,7 @@ export interface LikeC4ProjectDefinition {
|
|
|
11
11
|
readonly views: ReadonlyArray<{
|
|
12
12
|
readonly id?: string;
|
|
13
13
|
readonly projection: string;
|
|
14
|
+
readonly folder?: string;
|
|
14
15
|
readonly compare?: {
|
|
15
16
|
readonly from: string;
|
|
16
17
|
readonly to: string;
|
|
@@ -40,6 +41,7 @@ export interface LikeC4Deployment {
|
|
|
40
41
|
export declare const loadLikeC4ProjectDefinition: (source: WorkspaceSource) => import("../source-document.js").SourceDocumentResult<LikeC4ProjectDefinition>;
|
|
41
42
|
export interface PreparedLikeC4ProjectView {
|
|
42
43
|
readonly id?: string;
|
|
44
|
+
readonly folder?: string;
|
|
43
45
|
readonly prepared: Extract<LikeC4PreparationResult, {
|
|
44
46
|
readonly ok: true;
|
|
45
47
|
}>;
|
|
@@ -8,6 +8,15 @@ const Ajv2020 = Ajv2020Module.default;
|
|
|
8
8
|
const validateLikeC4Project = new Ajv2020({ allErrors: true }).compile(likeC4ProjectSchema);
|
|
9
9
|
export const loadLikeC4ProjectDefinition = (source) => loadSourceDocument(source, validateLikeC4Project, 'LikeC4 project');
|
|
10
10
|
const quote = (value) => `'${value.replaceAll('\\', '\\\\').replaceAll("'", "\\'").replaceAll('\n', '\\n')}'`;
|
|
11
|
+
// A folder files the view in LikeC4's sidebar tree: the title becomes a
|
|
12
|
+
// path ('Folder / Title') whose last segment is the displayed title (ADR
|
|
13
|
+
// 0067). A view without a declared title still needs a title line to
|
|
14
|
+
// carry the path, so the view id stands in as the leaf.
|
|
15
|
+
const titleLines = (folder, title, viewId) => folder === undefined
|
|
16
|
+
? title === undefined
|
|
17
|
+
? []
|
|
18
|
+
: [` title ${quote(title)}`]
|
|
19
|
+
: [` title ${quote(`${folder} / ${title ?? viewId}`)}`];
|
|
11
20
|
const unionProjection = (project, views) => ({
|
|
12
21
|
format: 'yarramate/projection-result/v1',
|
|
13
22
|
projection: `${project.id}@${project.version}`,
|
|
@@ -28,7 +37,7 @@ const unionProjection = (project, views) => ({
|
|
|
28
37
|
...new Map(views.flatMap(({ prepared }) => prepared.projection.claims.map((claim) => [claim.id, claim]))).values(),
|
|
29
38
|
].sort((left, right) => left.id.localeCompare(right.id)),
|
|
30
39
|
});
|
|
31
|
-
const viewBody = ({ id, prepared, dynamic, deployment, }, gitChange) => {
|
|
40
|
+
const viewBody = ({ id, folder, prepared, dynamic, deployment, }, gitChange) => {
|
|
32
41
|
const source = prepared.source;
|
|
33
42
|
const startToken = '\nviews {\n';
|
|
34
43
|
const start = source.indexOf(startToken);
|
|
@@ -58,9 +67,7 @@ const viewBody = ({ id, prepared, dynamic, deployment, }, gitChange) => {
|
|
|
58
67
|
const viewId = id ?? prepared.projection.projection.split('@')[0];
|
|
59
68
|
return [
|
|
60
69
|
` deployment view ${viewId} {`,
|
|
61
|
-
...(prepared.projection.presentation?.title
|
|
62
|
-
? []
|
|
63
|
-
: [` title ${quote(prepared.projection.presentation.title)}`]),
|
|
70
|
+
...titleLines(folder, prepared.projection.presentation?.title, viewId),
|
|
64
71
|
...(prepared.projection.presentation?.description === undefined
|
|
65
72
|
? []
|
|
66
73
|
: [
|
|
@@ -105,9 +112,7 @@ const viewBody = ({ id, prepared, dynamic, deployment, }, gitChange) => {
|
|
|
105
112
|
const viewId = id ?? prepared.projection.projection.split('@')[0];
|
|
106
113
|
return [
|
|
107
114
|
` dynamic view ${viewId} {`,
|
|
108
|
-
...(prepared.projection.presentation?.title
|
|
109
|
-
? []
|
|
110
|
-
: [` title ${quote(prepared.projection.presentation.title)}`]),
|
|
115
|
+
...titleLines(folder, prepared.projection.presentation?.title, viewId),
|
|
111
116
|
...(prepared.projection.presentation?.description === undefined
|
|
112
117
|
? []
|
|
113
118
|
: [
|
|
@@ -140,10 +145,17 @@ const viewBody = ({ id, prepared, dynamic, deployment, }, gitChange) => {
|
|
|
140
145
|
...relationshipRules,
|
|
141
146
|
...overlayRules,
|
|
142
147
|
].join('\n');
|
|
143
|
-
|
|
148
|
+
const viewId = id ?? prepared.projection.projection.split('@')[0];
|
|
149
|
+
const body = source
|
|
144
150
|
.slice(start + startToken.length, end)
|
|
145
|
-
.replace(/^ view [A-Za-z_][A-Za-z0-9_-]* \{/, ` view ${
|
|
151
|
+
.replace(/^ view [A-Za-z_][A-Za-z0-9_-]* \{/, ` view ${viewId} {`)
|
|
146
152
|
.replace(' include *', membershipRules);
|
|
153
|
+
if (folder === undefined)
|
|
154
|
+
return body;
|
|
155
|
+
const title = prepared.projection.presentation?.title;
|
|
156
|
+
return title === undefined
|
|
157
|
+
? body.replace(` view ${viewId} {`, ` view ${viewId} {\n${titleLines(folder, undefined, viewId).join('\n')}`)
|
|
158
|
+
: body.replace(` title ${quote(title)}`, titleLines(folder, title, viewId).join('\n'));
|
|
147
159
|
};
|
|
148
160
|
const deploymentBody = ({ deployment, prepared, }) => {
|
|
149
161
|
if (deployment === undefined)
|
package/package.json
CHANGED
|
@@ -72,6 +72,11 @@
|
|
|
72
72
|
"projection": {
|
|
73
73
|
"$ref": "#/$defs/path"
|
|
74
74
|
},
|
|
75
|
+
"folder": {
|
|
76
|
+
"type": "string",
|
|
77
|
+
"description": "Sidebar folder for the rendered view, emitted as a LikeC4 title path ('Folder / Title'). Nest with '/' separators; folders appear in the order their first view appears in the views list.",
|
|
78
|
+
"pattern": "^[^/]+(?:/[^/]+)*$"
|
|
79
|
+
},
|
|
75
80
|
"compare": {
|
|
76
81
|
"$ref": "#/$defs/comparison"
|
|
77
82
|
},
|