@likec4/generators 1.52.0 → 1.53.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/_chunks/chunk.mjs +11 -0
- package/dist/index.d.mts +18 -1
- package/dist/index.mjs +189 -47
- package/dist/likec4/index.d.mts +277169 -0
- package/dist/likec4/index.mjs +1799 -0
- package/likec4/package.json +4 -0
- package/package.json +22 -8
- package/src/drawio/generate-drawio.ts +73 -8
- package/src/drawio/index.ts +1 -0
- package/src/drawio/parse-drawio.ts +172 -18
- package/src/index.ts +2 -0
- package/src/likec4/generate-likec4.ts +72 -0
- package/src/likec4/index.ts +12 -0
- package/src/likec4/operators/base.ts +938 -0
- package/src/likec4/operators/deployment.ts +263 -0
- package/src/likec4/operators/expressions.ts +422 -0
- package/src/likec4/operators/index.ts +13 -0
- package/src/likec4/operators/likec4data.ts +33 -0
- package/src/likec4/operators/model.ts +222 -0
- package/src/likec4/operators/properties.ts +244 -0
- package/src/likec4/operators/specification.ts +119 -0
- package/src/likec4/operators/views.ts +390 -0
- package/src/likec4/schemas/common.ts +123 -0
- package/src/likec4/schemas/deployment.ts +113 -0
- package/src/likec4/schemas/expression.ts +218 -0
- package/src/likec4/schemas/index.ts +83 -0
- package/src/likec4/schemas/likec4data.ts +76 -0
- package/src/likec4/schemas/model.ts +127 -0
- package/src/likec4/schemas/specification.ts +83 -0
- package/src/likec4/schemas/views.ts +321 -0
- package/src/model/generate-likec4.ts +0 -5
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as z from 'zod/v4'
|
|
2
|
+
import { schemas } from '../schemas'
|
|
3
|
+
import { lines, property, zodOp } from './base'
|
|
4
|
+
import { deployment } from './deployment'
|
|
5
|
+
import { model } from './model'
|
|
6
|
+
import { specification } from './specification'
|
|
7
|
+
import { views } from './views'
|
|
8
|
+
|
|
9
|
+
const likec4dataSchema = z.object({
|
|
10
|
+
// ...schemas.likec4data.shape,
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
export const likec4data = zodOp(schemas.likec4data)(
|
|
14
|
+
lines(2)(
|
|
15
|
+
property(
|
|
16
|
+
'specification',
|
|
17
|
+
specification(),
|
|
18
|
+
),
|
|
19
|
+
model(),
|
|
20
|
+
property(
|
|
21
|
+
'deployment',
|
|
22
|
+
deployment(),
|
|
23
|
+
),
|
|
24
|
+
property(
|
|
25
|
+
'deployments',
|
|
26
|
+
deployment(),
|
|
27
|
+
),
|
|
28
|
+
property(
|
|
29
|
+
'views',
|
|
30
|
+
views(),
|
|
31
|
+
),
|
|
32
|
+
),
|
|
33
|
+
)
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import type { Fqn } from '@likec4/core/types'
|
|
2
|
+
import { nameFromFqn, parentFqn, sortParentsFirst } from '@likec4/core/utils'
|
|
3
|
+
import { isEmptyish, pipe, values } from 'remeda'
|
|
4
|
+
|
|
5
|
+
import { schemas } from '../schemas'
|
|
6
|
+
import {
|
|
7
|
+
type AnyOp,
|
|
8
|
+
type Ctx,
|
|
9
|
+
body,
|
|
10
|
+
foreach,
|
|
11
|
+
inlineText,
|
|
12
|
+
lines,
|
|
13
|
+
print,
|
|
14
|
+
property,
|
|
15
|
+
select,
|
|
16
|
+
spaceBetween,
|
|
17
|
+
when,
|
|
18
|
+
withctx,
|
|
19
|
+
zodOp,
|
|
20
|
+
} from './base'
|
|
21
|
+
import { fqnRef } from './expressions.ts'
|
|
22
|
+
import {
|
|
23
|
+
colorProperty,
|
|
24
|
+
descriptionProperty,
|
|
25
|
+
linksProperty,
|
|
26
|
+
metadataProperty,
|
|
27
|
+
styleProperties,
|
|
28
|
+
summaryProperty,
|
|
29
|
+
tagsProperty,
|
|
30
|
+
technologyProperty,
|
|
31
|
+
} from './properties'
|
|
32
|
+
|
|
33
|
+
// --- Tree building ---
|
|
34
|
+
|
|
35
|
+
type ElementData = schemas.model.element.Data
|
|
36
|
+
|
|
37
|
+
type ElementTreeNode = ElementData & {
|
|
38
|
+
children?: ElementTreeNode[]
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function buildTree(elements: ElementData[]): {
|
|
42
|
+
roots: readonly ElementTreeNode[]
|
|
43
|
+
nodes: ReadonlyMap<Fqn, ElementTreeNode>
|
|
44
|
+
exists: (fqn: Fqn) => boolean
|
|
45
|
+
} {
|
|
46
|
+
const nodes = new Map<Fqn, ElementTreeNode>()
|
|
47
|
+
const roots: ElementTreeNode[] = []
|
|
48
|
+
const sorted = pipe(
|
|
49
|
+
elements,
|
|
50
|
+
sortParentsFirst,
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
for (const element of sorted) {
|
|
54
|
+
const node: ElementTreeNode = { ...element, children: [] }
|
|
55
|
+
nodes.set(element.id, node)
|
|
56
|
+
|
|
57
|
+
const parentId = parentFqn(element.id)
|
|
58
|
+
const parent = parentId ? nodes.get(parentId) : undefined
|
|
59
|
+
|
|
60
|
+
if (parent) {
|
|
61
|
+
parent.children!.push(node)
|
|
62
|
+
} else {
|
|
63
|
+
roots.push(node)
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
return {
|
|
68
|
+
roots,
|
|
69
|
+
nodes,
|
|
70
|
+
exists: (fqn: Fqn) => nodes.has(fqn),
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// --- Predicates ---
|
|
75
|
+
|
|
76
|
+
function hasStyleProps(el: ElementData): boolean {
|
|
77
|
+
return !isEmptyish(el.style)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
function hasElementProps(el: ElementData): boolean {
|
|
81
|
+
return !!(
|
|
82
|
+
el.description || el.summary || el.technology || el.notation
|
|
83
|
+
|| (el.tags && el.tags.length > 0)
|
|
84
|
+
|| (el.links && el.links.length > 0)
|
|
85
|
+
|| !isEmptyish(el.metadata)
|
|
86
|
+
|| hasStyleProps(el)
|
|
87
|
+
)
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// --- Element ---
|
|
91
|
+
|
|
92
|
+
const elementProperties = zodOp(schemas.model.element)(
|
|
93
|
+
lines(
|
|
94
|
+
tagsProperty(),
|
|
95
|
+
technologyProperty(),
|
|
96
|
+
summaryProperty(),
|
|
97
|
+
descriptionProperty(),
|
|
98
|
+
linksProperty(),
|
|
99
|
+
metadataProperty(),
|
|
100
|
+
select(
|
|
101
|
+
e => hasStyleProps(e) ? e.style : undefined,
|
|
102
|
+
body('style')(
|
|
103
|
+
styleProperties(),
|
|
104
|
+
),
|
|
105
|
+
),
|
|
106
|
+
),
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
function elementTree() {
|
|
110
|
+
return function elementTreeNodeOp<E extends ElementTreeNode>(
|
|
111
|
+
{ ctx, out }: Ctx<E>,
|
|
112
|
+
): Ctx<E> {
|
|
113
|
+
const el = ctx
|
|
114
|
+
const needsBody = (ctx.children?.length ?? 0) > 0 || hasElementProps(el)
|
|
115
|
+
|
|
116
|
+
const name = nameFromFqn(el.id)
|
|
117
|
+
|
|
118
|
+
const inline: AnyOp[] = [
|
|
119
|
+
print(name),
|
|
120
|
+
print('='),
|
|
121
|
+
print(el.kind),
|
|
122
|
+
]
|
|
123
|
+
|
|
124
|
+
if (el.title && el.title !== name) {
|
|
125
|
+
inline.push(inlineText(el.title))
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (needsBody) {
|
|
129
|
+
inline.push(
|
|
130
|
+
body(
|
|
131
|
+
lines(2)(
|
|
132
|
+
withctx(el, elementProperties()),
|
|
133
|
+
...(ctx.children ?? []).map(node => withctx(node, elementTree())),
|
|
134
|
+
),
|
|
135
|
+
),
|
|
136
|
+
)
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return spaceBetween(...inline)({ ctx, out })
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// --- Relationship ---
|
|
144
|
+
|
|
145
|
+
function hasRelationStyle(rel: schemas.model.relationship.Data): boolean {
|
|
146
|
+
return !!(
|
|
147
|
+
rel.color || rel.line || rel.head || rel.tail
|
|
148
|
+
)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function hasRelationProps(rel: schemas.model.relationship.Data): boolean {
|
|
152
|
+
return !!(
|
|
153
|
+
rel.description || rel.summary || rel.technology
|
|
154
|
+
|| (rel.tags && rel.tags.length > 0)
|
|
155
|
+
|| (rel.links && rel.links.length > 0)
|
|
156
|
+
|| !isEmptyish(rel.metadata)
|
|
157
|
+
|| hasRelationStyle(rel)
|
|
158
|
+
|| rel.navigateTo
|
|
159
|
+
)
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export const relationship = zodOp(schemas.model.relationship)(
|
|
163
|
+
spaceBetween(
|
|
164
|
+
property('source', fqnRef()),
|
|
165
|
+
print(rel => rel.kind ? `-[${rel.kind}]->` : '->'),
|
|
166
|
+
property('target', fqnRef()),
|
|
167
|
+
property(
|
|
168
|
+
'title',
|
|
169
|
+
inlineText(),
|
|
170
|
+
),
|
|
171
|
+
when(
|
|
172
|
+
hasRelationProps,
|
|
173
|
+
body(
|
|
174
|
+
tagsProperty(),
|
|
175
|
+
technologyProperty(),
|
|
176
|
+
summaryProperty(),
|
|
177
|
+
descriptionProperty(),
|
|
178
|
+
property('navigateTo'),
|
|
179
|
+
linksProperty(),
|
|
180
|
+
metadataProperty(),
|
|
181
|
+
when(
|
|
182
|
+
hasRelationStyle,
|
|
183
|
+
body('style')(
|
|
184
|
+
colorProperty(),
|
|
185
|
+
property('line'),
|
|
186
|
+
property('head'),
|
|
187
|
+
property('tail'),
|
|
188
|
+
),
|
|
189
|
+
),
|
|
190
|
+
),
|
|
191
|
+
),
|
|
192
|
+
),
|
|
193
|
+
)
|
|
194
|
+
|
|
195
|
+
export const element = zodOp(schemas.model.element)(
|
|
196
|
+
elementTree(),
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
// --- Main ---
|
|
200
|
+
|
|
201
|
+
export const model = zodOp(schemas.model.schema)(
|
|
202
|
+
body('model')(
|
|
203
|
+
lines(2)(
|
|
204
|
+
select(
|
|
205
|
+
d => buildTree(d.elements ? values(d.elements) : []).roots,
|
|
206
|
+
lines(2)(
|
|
207
|
+
foreach(
|
|
208
|
+
elementTree(),
|
|
209
|
+
),
|
|
210
|
+
),
|
|
211
|
+
),
|
|
212
|
+
select(
|
|
213
|
+
d => d.relations ? values(d.relations) : undefined,
|
|
214
|
+
lines(2)(
|
|
215
|
+
foreach(
|
|
216
|
+
relationship(),
|
|
217
|
+
),
|
|
218
|
+
),
|
|
219
|
+
),
|
|
220
|
+
),
|
|
221
|
+
),
|
|
222
|
+
)
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { type Color, type ElementStyle, type Link, type MarkdownOrString, exact } from '@likec4/core/types'
|
|
2
|
+
import { entries, isArray, isNot, isString, piped } from 'remeda'
|
|
3
|
+
import type { ConditionalKeys } from 'type-fest'
|
|
4
|
+
import * as common from '../schemas/common'
|
|
5
|
+
import type { Op } from './base'
|
|
6
|
+
import {
|
|
7
|
+
body,
|
|
8
|
+
foreach,
|
|
9
|
+
foreachNewLine,
|
|
10
|
+
guard,
|
|
11
|
+
inlineText,
|
|
12
|
+
lines,
|
|
13
|
+
markdownOrString,
|
|
14
|
+
operation,
|
|
15
|
+
print,
|
|
16
|
+
property,
|
|
17
|
+
select,
|
|
18
|
+
separateNewLine,
|
|
19
|
+
spaceBetween,
|
|
20
|
+
text,
|
|
21
|
+
zodOp,
|
|
22
|
+
} from './base'
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Print a property from the context as a text.
|
|
26
|
+
*/
|
|
27
|
+
export function textProperty<A>(
|
|
28
|
+
propertyName: ConditionalKeys<NoInfer<A>, string | undefined | null>,
|
|
29
|
+
keyword?: string,
|
|
30
|
+
): Op<A> {
|
|
31
|
+
return select(
|
|
32
|
+
e => e[propertyName] as string,
|
|
33
|
+
spaceBetween(
|
|
34
|
+
print(keyword ?? propertyName as string),
|
|
35
|
+
text(),
|
|
36
|
+
),
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* Print a property from the context as a markdown string.
|
|
42
|
+
*/
|
|
43
|
+
export function markdownProperty<A>(
|
|
44
|
+
propertyName: ConditionalKeys<NoInfer<A>, string | MarkdownOrString | undefined | null>,
|
|
45
|
+
keyword?: string,
|
|
46
|
+
): Op<A> {
|
|
47
|
+
return select(
|
|
48
|
+
e => e[propertyName] as MarkdownOrString,
|
|
49
|
+
spaceBetween(
|
|
50
|
+
print(keyword ?? propertyName as string),
|
|
51
|
+
markdownOrString(),
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export const titleProperty = <A extends { title?: string | null | undefined }>(): Op<A> =>
|
|
57
|
+
property(
|
|
58
|
+
'title',
|
|
59
|
+
spaceBetween(
|
|
60
|
+
print('title'),
|
|
61
|
+
text(),
|
|
62
|
+
),
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
export const summaryProperty = <A extends { summary?: string | MarkdownOrString | null | undefined }>(): Op<A> =>
|
|
66
|
+
property(
|
|
67
|
+
'summary',
|
|
68
|
+
spaceBetween(
|
|
69
|
+
print('summary'),
|
|
70
|
+
markdownOrString(),
|
|
71
|
+
),
|
|
72
|
+
)
|
|
73
|
+
|
|
74
|
+
export const descriptionProperty = <A extends { description?: string | MarkdownOrString | null | undefined }>(): Op<
|
|
75
|
+
A
|
|
76
|
+
> =>
|
|
77
|
+
property(
|
|
78
|
+
'description',
|
|
79
|
+
spaceBetween(
|
|
80
|
+
print('description'),
|
|
81
|
+
markdownOrString(),
|
|
82
|
+
),
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
export const notesProperty = <A extends { notes?: string | MarkdownOrString | null | undefined }>(): Op<A> =>
|
|
86
|
+
property(
|
|
87
|
+
'notes',
|
|
88
|
+
spaceBetween(
|
|
89
|
+
print('notes'),
|
|
90
|
+
markdownOrString(),
|
|
91
|
+
),
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
export const technologyProperty = <A extends { technology?: string | null | undefined }>(): Op<A> =>
|
|
95
|
+
property(
|
|
96
|
+
'technology',
|
|
97
|
+
spaceBetween(
|
|
98
|
+
print('technology'),
|
|
99
|
+
text(),
|
|
100
|
+
),
|
|
101
|
+
)
|
|
102
|
+
|
|
103
|
+
export const notationProperty = <A extends { notation?: string | null | undefined }>(): Op<A> =>
|
|
104
|
+
property(
|
|
105
|
+
'notation',
|
|
106
|
+
spaceBetween(
|
|
107
|
+
print('notation'),
|
|
108
|
+
text(),
|
|
109
|
+
),
|
|
110
|
+
)
|
|
111
|
+
|
|
112
|
+
type MetadataValue = string | number | boolean
|
|
113
|
+
function printMetadataValue(): Op<MetadataValue> {
|
|
114
|
+
return operation(({ ctx, out }) => {
|
|
115
|
+
if (isString(ctx)) {
|
|
116
|
+
return text()({ ctx, out })
|
|
117
|
+
}
|
|
118
|
+
return print()({ ctx, out })
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function metadataValue(): Op<MetadataValue | MetadataValue[]> {
|
|
123
|
+
return piped(
|
|
124
|
+
guard(
|
|
125
|
+
isNot(isArray),
|
|
126
|
+
printMetadataValue(),
|
|
127
|
+
),
|
|
128
|
+
guard(
|
|
129
|
+
isArray,
|
|
130
|
+
body('[', ']')(
|
|
131
|
+
foreach(
|
|
132
|
+
printMetadataValue(),
|
|
133
|
+
{
|
|
134
|
+
appendNewLineIfNotEmpty: true,
|
|
135
|
+
suffix(element, index, isLast) {
|
|
136
|
+
return !isLast ? ',' : undefined
|
|
137
|
+
},
|
|
138
|
+
},
|
|
139
|
+
),
|
|
140
|
+
),
|
|
141
|
+
),
|
|
142
|
+
)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
export const metadataProperty = <A extends { metadata?: Record<string, MetadataValue | MetadataValue[]> | null }>(): Op<
|
|
146
|
+
A
|
|
147
|
+
> =>
|
|
148
|
+
select(
|
|
149
|
+
e => e.metadata ? entries(e.metadata) : undefined,
|
|
150
|
+
body('metadata')(
|
|
151
|
+
foreach(
|
|
152
|
+
spaceBetween(
|
|
153
|
+
print(v => v[0]),
|
|
154
|
+
property('1', metadataValue()),
|
|
155
|
+
),
|
|
156
|
+
separateNewLine(),
|
|
157
|
+
),
|
|
158
|
+
),
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
export const tagsProperty = <A extends { tags?: readonly string[] | undefined | null }>(): Op<A> =>
|
|
162
|
+
property(
|
|
163
|
+
'tags',
|
|
164
|
+
print(v => v.map(t => `#${t}`).join(', ')),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
type LinkLike = string | { url: string; title?: string | undefined }
|
|
168
|
+
|
|
169
|
+
export function linkProperty<A extends LinkLike>(): Op<A> {
|
|
170
|
+
return spaceBetween(
|
|
171
|
+
select(
|
|
172
|
+
(l): Link => typeof l === 'string' ? { url: l } : exact({ url: l.url, title: l.title }),
|
|
173
|
+
print('link'),
|
|
174
|
+
print(v => v.url),
|
|
175
|
+
property('title', inlineText()),
|
|
176
|
+
),
|
|
177
|
+
)
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export const linksProperty = <
|
|
181
|
+
A extends { links?: ReadonlyArray<LinkLike> | null | undefined },
|
|
182
|
+
>(): Op<A> =>
|
|
183
|
+
property(
|
|
184
|
+
'links',
|
|
185
|
+
foreachNewLine(
|
|
186
|
+
linkProperty(),
|
|
187
|
+
),
|
|
188
|
+
)
|
|
189
|
+
|
|
190
|
+
export function styleBlockProperty<A extends { style?: ElementStyle | undefined | null }>(): Op<A> {
|
|
191
|
+
return select(
|
|
192
|
+
e => e.style,
|
|
193
|
+
body('style')(
|
|
194
|
+
styleProperties(),
|
|
195
|
+
),
|
|
196
|
+
)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
export function colorProperty<A extends { color?: Color | undefined | null }>(): Op<A> {
|
|
200
|
+
return property(
|
|
201
|
+
'color',
|
|
202
|
+
spaceBetween(
|
|
203
|
+
print('color'),
|
|
204
|
+
print(),
|
|
205
|
+
),
|
|
206
|
+
)
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
export function opacityProperty<A extends { opacity?: number | undefined | null }>(): Op<A> {
|
|
210
|
+
return property(
|
|
211
|
+
'opacity',
|
|
212
|
+
spaceBetween(
|
|
213
|
+
print('opacity'),
|
|
214
|
+
print(v => `${v}%`),
|
|
215
|
+
),
|
|
216
|
+
)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export function iconProperty<A extends { icon?: string | undefined | null }>(): Op<A> {
|
|
220
|
+
return property(
|
|
221
|
+
'icon',
|
|
222
|
+
spaceBetween(
|
|
223
|
+
print('icon'),
|
|
224
|
+
print(),
|
|
225
|
+
),
|
|
226
|
+
)
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export const styleProperties = zodOp(common.style)(
|
|
230
|
+
lines(
|
|
231
|
+
property('shape'),
|
|
232
|
+
colorProperty(),
|
|
233
|
+
iconProperty(),
|
|
234
|
+
property('iconColor'),
|
|
235
|
+
property('iconSize'),
|
|
236
|
+
property('iconPosition'),
|
|
237
|
+
property('border'),
|
|
238
|
+
opacityProperty(),
|
|
239
|
+
property('size'),
|
|
240
|
+
property('padding'),
|
|
241
|
+
property('textSize'),
|
|
242
|
+
property('multiple'),
|
|
243
|
+
),
|
|
244
|
+
)
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { entries } from 'remeda'
|
|
2
|
+
import * as z from 'zod/v4'
|
|
3
|
+
import * as schemas from '../schemas/specification'
|
|
4
|
+
import {
|
|
5
|
+
body,
|
|
6
|
+
foreachNewLine,
|
|
7
|
+
lines,
|
|
8
|
+
print,
|
|
9
|
+
printProperty,
|
|
10
|
+
property,
|
|
11
|
+
select,
|
|
12
|
+
spaceBetween,
|
|
13
|
+
zodOp,
|
|
14
|
+
} from './base'
|
|
15
|
+
import {
|
|
16
|
+
colorProperty,
|
|
17
|
+
descriptionProperty,
|
|
18
|
+
linksProperty,
|
|
19
|
+
notationProperty,
|
|
20
|
+
styleProperties,
|
|
21
|
+
summaryProperty,
|
|
22
|
+
tagsProperty,
|
|
23
|
+
technologyProperty,
|
|
24
|
+
titleProperty,
|
|
25
|
+
} from './properties'
|
|
26
|
+
|
|
27
|
+
export const tagSpecification = zodOp(z.tuple([z.string(), schemas.tagSpec]))(
|
|
28
|
+
spaceBetween(
|
|
29
|
+
print('tag'),
|
|
30
|
+
printProperty('0'),
|
|
31
|
+
property(
|
|
32
|
+
'1',
|
|
33
|
+
property(
|
|
34
|
+
'color',
|
|
35
|
+
body(
|
|
36
|
+
spaceBetween(
|
|
37
|
+
print('color'),
|
|
38
|
+
print(),
|
|
39
|
+
),
|
|
40
|
+
),
|
|
41
|
+
),
|
|
42
|
+
),
|
|
43
|
+
),
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
export const elementKind = (keyword: 'element' | 'deploymentNode') =>
|
|
47
|
+
zodOp(z.tuple([z.string(), schemas.element]))(
|
|
48
|
+
spaceBetween(
|
|
49
|
+
print(keyword),
|
|
50
|
+
printProperty('0'),
|
|
51
|
+
property(
|
|
52
|
+
'1',
|
|
53
|
+
body(
|
|
54
|
+
tagsProperty(),
|
|
55
|
+
titleProperty(),
|
|
56
|
+
summaryProperty(),
|
|
57
|
+
descriptionProperty(),
|
|
58
|
+
technologyProperty(),
|
|
59
|
+
notationProperty(),
|
|
60
|
+
linksProperty(),
|
|
61
|
+
property(
|
|
62
|
+
'style',
|
|
63
|
+
body('style')(
|
|
64
|
+
styleProperties(),
|
|
65
|
+
),
|
|
66
|
+
),
|
|
67
|
+
),
|
|
68
|
+
),
|
|
69
|
+
),
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
export const relationshipKind = zodOp(z.tuple([z.string(), schemas.relationship]))(
|
|
73
|
+
spaceBetween(
|
|
74
|
+
print('relationship'),
|
|
75
|
+
printProperty('0'),
|
|
76
|
+
property(
|
|
77
|
+
'1',
|
|
78
|
+
body(
|
|
79
|
+
technologyProperty(),
|
|
80
|
+
notationProperty(),
|
|
81
|
+
colorProperty(),
|
|
82
|
+
property('line'),
|
|
83
|
+
property('head'),
|
|
84
|
+
property('tail'),
|
|
85
|
+
),
|
|
86
|
+
),
|
|
87
|
+
),
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
export const specification = zodOp(schemas.schema)(
|
|
91
|
+
body('specification')(
|
|
92
|
+
lines(2)(
|
|
93
|
+
select(
|
|
94
|
+
c => c.elements && entries(c.elements),
|
|
95
|
+
foreachNewLine(
|
|
96
|
+
elementKind('element')(),
|
|
97
|
+
),
|
|
98
|
+
),
|
|
99
|
+
select(
|
|
100
|
+
c => c.deployments && entries(c.deployments),
|
|
101
|
+
foreachNewLine(
|
|
102
|
+
elementKind('deploymentNode')(),
|
|
103
|
+
),
|
|
104
|
+
),
|
|
105
|
+
select(
|
|
106
|
+
c => c.relationships && entries(c.relationships),
|
|
107
|
+
foreachNewLine(
|
|
108
|
+
relationshipKind(),
|
|
109
|
+
),
|
|
110
|
+
),
|
|
111
|
+
select(
|
|
112
|
+
c => c.tags && entries(c.tags),
|
|
113
|
+
foreachNewLine(
|
|
114
|
+
tagSpecification(),
|
|
115
|
+
),
|
|
116
|
+
),
|
|
117
|
+
),
|
|
118
|
+
),
|
|
119
|
+
)
|