@likec4/generators 0.40.0 → 0.42.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/package.json +13 -15
- package/src/d2/generate-d2.ts +107 -0
- package/src/d2/index.ts +1 -0
- package/src/index.ts +4 -0
- package/src/mmd/generate-mmd.ts +106 -0
- package/src/mmd/index.ts +1 -0
- package/{dist/react/generate-react.js → src/react/generate-react.ts} +54 -34
- package/src/react/index.ts +1 -0
- package/{dist/views-data-ts/generate-views-data.js → src/views-data-ts/generate-views-data.ts} +60 -42
- package/src/views-data-ts/index.ts +1 -0
- package/dist/d2/generate-d2.d.ts +0 -2
- package/dist/d2/generate-d2.js +0 -82
- package/dist/d2/index.d.ts +0 -1
- package/dist/d2/index.js +0 -1
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/mmd/generate-mmd.d.ts +0 -2
- package/dist/mmd/generate-mmd.js +0 -86
- package/dist/mmd/index.d.ts +0 -1
- package/dist/mmd/index.js +0 -1
- package/dist/react/generate-react.d.ts +0 -3
- package/dist/react/index.d.ts +0 -1
- package/dist/react/index.js +0 -1
- package/dist/views-data-ts/generate-views-data.d.ts +0 -3
- package/dist/views-data-ts/index.d.ts +0 -1
- package/dist/views-data-ts/index.js +0 -1
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@likec4/generators",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.42.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"bugs": "https://github.com/likec4/likec4/issues",
|
|
6
6
|
"homepage": "https://likec4.dev",
|
|
7
7
|
"author": "Denis Davydkov <denis@davydkov.com>",
|
|
8
8
|
"files": [
|
|
9
|
-
"
|
|
10
|
-
"
|
|
9
|
+
"src",
|
|
10
|
+
"!**/__mocks__/**",
|
|
11
11
|
"!**/*.spec.*",
|
|
12
12
|
"!**/*.map"
|
|
13
13
|
],
|
|
@@ -19,36 +19,34 @@
|
|
|
19
19
|
"type": "module",
|
|
20
20
|
"sideEffects": false,
|
|
21
21
|
"exports": {
|
|
22
|
-
".":
|
|
23
|
-
"types": "./dist/index.d.ts",
|
|
24
|
-
"default": "./dist/index.js"
|
|
25
|
-
}
|
|
22
|
+
".": "./src/index.ts"
|
|
26
23
|
},
|
|
27
24
|
"publishConfig": {
|
|
28
25
|
"registry": "https://registry.npmjs.org",
|
|
29
26
|
"access": "public"
|
|
30
27
|
},
|
|
31
28
|
"scripts": {
|
|
32
|
-
"typecheck": "tsc --
|
|
33
|
-
"build:watch": "tsc --watch",
|
|
29
|
+
"typecheck": "tsc --noEmit",
|
|
34
30
|
"build": "unbuild",
|
|
35
|
-
"
|
|
31
|
+
"prepack": "unbuild",
|
|
36
32
|
"lint": "run -T eslint src/ --fix",
|
|
37
33
|
"clean": "run -T rimraf dist",
|
|
38
|
-
"test": "run -T vitest run"
|
|
39
|
-
"test:watch": "run -T vitest"
|
|
34
|
+
"test": "run -T vitest run"
|
|
40
35
|
},
|
|
41
36
|
"dependencies": {
|
|
42
|
-
"@likec4/core": "0.
|
|
37
|
+
"@likec4/core": "0.42.0",
|
|
43
38
|
"json5": "^2.2.3",
|
|
44
39
|
"langium": "^2.0.2",
|
|
45
40
|
"rambdax": "^9.1.1"
|
|
46
41
|
},
|
|
47
42
|
"devDependencies": {
|
|
48
|
-
"@types/node": "^
|
|
43
|
+
"@types/node": "^20.8.7",
|
|
49
44
|
"typescript": "^5.2.2",
|
|
50
45
|
"unbuild": "^2.0.0",
|
|
51
46
|
"vitest": "^0.34.6"
|
|
52
47
|
},
|
|
53
|
-
"packageManager": "yarn@3.6.
|
|
48
|
+
"packageManager": "yarn@3.6.4",
|
|
49
|
+
"volta": {
|
|
50
|
+
"extends": "../../package.json"
|
|
51
|
+
}
|
|
54
52
|
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import type { ComputedEdge, ComputedNode, ComputedView, NodeId } from '@likec4/core'
|
|
2
|
+
import { CompositeGeneratorNode, NL, joinToNode, toString } from 'langium'
|
|
3
|
+
import { isNil } from 'rambdax'
|
|
4
|
+
|
|
5
|
+
const capitalizeFirstLetter = (value: string) =>
|
|
6
|
+
value.charAt(0).toLocaleUpperCase() + value.slice(1)
|
|
7
|
+
|
|
8
|
+
const fqnName = (nodeId: string): string => nodeId.split('.').map(capitalizeFirstLetter).join('')
|
|
9
|
+
|
|
10
|
+
const nodeName = (node: ComputedNode): string => {
|
|
11
|
+
return fqnName(node.parent ? node.id.slice(node.parent.length + 1) : node.id)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const d2direction = ({ autoLayout }: ComputedView) => {
|
|
15
|
+
switch (autoLayout) {
|
|
16
|
+
case 'TB': {
|
|
17
|
+
return 'down'
|
|
18
|
+
}
|
|
19
|
+
case 'BT': {
|
|
20
|
+
return 'up'
|
|
21
|
+
}
|
|
22
|
+
case 'LR': {
|
|
23
|
+
return 'right'
|
|
24
|
+
}
|
|
25
|
+
case 'RL': {
|
|
26
|
+
return 'left'
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const d2shape = ({ shape }: ComputedNode) => {
|
|
32
|
+
switch (shape) {
|
|
33
|
+
case 'queue':
|
|
34
|
+
case 'cylinder':
|
|
35
|
+
case 'rectangle':
|
|
36
|
+
case 'person': {
|
|
37
|
+
return shape
|
|
38
|
+
}
|
|
39
|
+
case 'storage': {
|
|
40
|
+
return 'stored_data' as const
|
|
41
|
+
}
|
|
42
|
+
case 'mobile':
|
|
43
|
+
case 'browser': {
|
|
44
|
+
return 'rectangle' as const
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function generateD2<V extends ComputedView>(view: V) {
|
|
50
|
+
const { nodes, edges } = view
|
|
51
|
+
const names = new Map<NodeId, string>()
|
|
52
|
+
|
|
53
|
+
const printNode = (node: ComputedNode, parentName?: string): CompositeGeneratorNode => {
|
|
54
|
+
const name = nodeName(node)
|
|
55
|
+
const fqnName = (parentName ? parentName + '.' : '') + name
|
|
56
|
+
names.set(node.id, fqnName)
|
|
57
|
+
|
|
58
|
+
const label = node.title.replaceAll('\n', '\\n')
|
|
59
|
+
const shape = d2shape(node)
|
|
60
|
+
|
|
61
|
+
return new CompositeGeneratorNode()
|
|
62
|
+
.append(name, ': {', NL)
|
|
63
|
+
.indent({
|
|
64
|
+
indentedChildren: indent =>
|
|
65
|
+
indent
|
|
66
|
+
.append('label: "', label, '"', NL)
|
|
67
|
+
.appendIf(shape !== 'rectangle', 'shape: ', shape, NL)
|
|
68
|
+
.appendIf(
|
|
69
|
+
node.children.length > 0,
|
|
70
|
+
NL,
|
|
71
|
+
joinToNode(
|
|
72
|
+
nodes.filter(n => n.parent === node.id),
|
|
73
|
+
n => printNode(n, fqnName)
|
|
74
|
+
)
|
|
75
|
+
),
|
|
76
|
+
indentation: 2
|
|
77
|
+
})
|
|
78
|
+
.append('}', NL)
|
|
79
|
+
}
|
|
80
|
+
// return `${names.get(edge.source)} -> ${names.get(edge.target)}${edge.label ? ': ' + edge.label : ''}`
|
|
81
|
+
const printEdge = (edge: ComputedEdge): CompositeGeneratorNode => {
|
|
82
|
+
return new CompositeGeneratorNode()
|
|
83
|
+
.append(names.get(edge.source), ' -> ', names.get(edge.target))
|
|
84
|
+
.append(out => edge.label && out.append(': ', edge.label.replaceAll('\n', '\\n')))
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return toString(
|
|
88
|
+
new CompositeGeneratorNode()
|
|
89
|
+
.append('direction: ', d2direction(view), NL, NL)
|
|
90
|
+
.append(
|
|
91
|
+
joinToNode(
|
|
92
|
+
nodes.filter(n => isNil(n.parent)),
|
|
93
|
+
n => printNode(n),
|
|
94
|
+
{
|
|
95
|
+
appendNewLineIfNotEmpty: true
|
|
96
|
+
}
|
|
97
|
+
)
|
|
98
|
+
)
|
|
99
|
+
.appendIf(
|
|
100
|
+
edges.length > 0,
|
|
101
|
+
NL,
|
|
102
|
+
joinToNode(edges, e => printEdge(e), {
|
|
103
|
+
appendNewLineIfNotEmpty: true
|
|
104
|
+
})
|
|
105
|
+
)
|
|
106
|
+
)
|
|
107
|
+
}
|
package/src/d2/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './generate-d2'
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ComputedEdge, ComputedNode, ComputedView, NodeId } from '@likec4/core'
|
|
2
|
+
import { CompositeGeneratorNode, NL, joinToNode, toString } from 'langium'
|
|
3
|
+
import { isNil } from 'rambdax'
|
|
4
|
+
|
|
5
|
+
const capitalizeFirstLetter = (value: string) =>
|
|
6
|
+
value.charAt(0).toLocaleUpperCase() + value.slice(1)
|
|
7
|
+
|
|
8
|
+
const fqnName = (nodeId: string): string => nodeId.split('.').map(capitalizeFirstLetter).join('')
|
|
9
|
+
|
|
10
|
+
const nodeName = (node: ComputedNode): string => {
|
|
11
|
+
return fqnName(node.parent ? node.id.slice(node.parent.length + 1) : node.id)
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const mmdshape = ({ shape }: ComputedNode): [start: string, end: string] => {
|
|
15
|
+
switch (shape) {
|
|
16
|
+
case 'queue':
|
|
17
|
+
case 'cylinder':
|
|
18
|
+
return ['[(', ')]']
|
|
19
|
+
case 'person': {
|
|
20
|
+
return ['[fa:fa-user ', ']']
|
|
21
|
+
}
|
|
22
|
+
case 'storage':
|
|
23
|
+
return ['([', '])']
|
|
24
|
+
case 'mobile':
|
|
25
|
+
case 'browser':
|
|
26
|
+
case 'rectangle': {
|
|
27
|
+
return ['[', ']']
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
export function generateMermaid<V extends ComputedView>(view: V) {
|
|
33
|
+
const { nodes, edges } = view
|
|
34
|
+
const names = new Map<NodeId, string>()
|
|
35
|
+
|
|
36
|
+
const printNode = (node: ComputedNode, parentName?: string): CompositeGeneratorNode => {
|
|
37
|
+
const name = nodeName(node)
|
|
38
|
+
const fqnName = (parentName ? parentName + '.' : '') + name
|
|
39
|
+
names.set(node.id, fqnName)
|
|
40
|
+
|
|
41
|
+
const label = node.title.replaceAll('\n', '\\n')
|
|
42
|
+
const shape = mmdshape(node)
|
|
43
|
+
|
|
44
|
+
const baseNode = new CompositeGeneratorNode()
|
|
45
|
+
if (node.children.length > 0) {
|
|
46
|
+
baseNode
|
|
47
|
+
.append('subgraph ', fqnName, '["', label, '"]', NL)
|
|
48
|
+
.indent({
|
|
49
|
+
indentedChildren: indent =>
|
|
50
|
+
indent.appendIf(
|
|
51
|
+
node.children.length > 0,
|
|
52
|
+
NL,
|
|
53
|
+
joinToNode(
|
|
54
|
+
nodes.filter(n => n.parent === node.id),
|
|
55
|
+
n => printNode(n, fqnName)
|
|
56
|
+
)
|
|
57
|
+
),
|
|
58
|
+
indentation: 2
|
|
59
|
+
})
|
|
60
|
+
.append('end', NL)
|
|
61
|
+
} else {
|
|
62
|
+
baseNode.append(fqnName, shape[0], label, shape[1], NL)
|
|
63
|
+
}
|
|
64
|
+
return baseNode
|
|
65
|
+
}
|
|
66
|
+
// return `${names.get(edge.source)} -> ${names.get(edge.target)}${edge.label ? ': ' + edge.label : ''}`
|
|
67
|
+
const printEdge = (edge: ComputedEdge): CompositeGeneratorNode => {
|
|
68
|
+
return new CompositeGeneratorNode().append(
|
|
69
|
+
names.get(edge.source),
|
|
70
|
+
' --',
|
|
71
|
+
edge.label ? '"' + edge.label.replaceAll('\n', '\\n') + '"--' : '',
|
|
72
|
+
'> ',
|
|
73
|
+
names.get(edge.target)
|
|
74
|
+
)
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
return toString(
|
|
78
|
+
new CompositeGeneratorNode()
|
|
79
|
+
.appendIf(
|
|
80
|
+
view.title !== null && view.title.length > 0,
|
|
81
|
+
'---',
|
|
82
|
+
NL,
|
|
83
|
+
`title: ${view.title}`,
|
|
84
|
+
NL,
|
|
85
|
+
'---',
|
|
86
|
+
NL
|
|
87
|
+
)
|
|
88
|
+
.append('graph ', view.autoLayout, NL, NL)
|
|
89
|
+
.append(
|
|
90
|
+
joinToNode(
|
|
91
|
+
nodes.filter(n => isNil(n.parent)),
|
|
92
|
+
n => printNode(n),
|
|
93
|
+
{
|
|
94
|
+
appendNewLineIfNotEmpty: true
|
|
95
|
+
}
|
|
96
|
+
)
|
|
97
|
+
)
|
|
98
|
+
.appendIf(
|
|
99
|
+
edges.length > 0,
|
|
100
|
+
NL,
|
|
101
|
+
joinToNode(edges, e => printEdge(e), {
|
|
102
|
+
appendNewLineIfNotEmpty: true
|
|
103
|
+
})
|
|
104
|
+
)
|
|
105
|
+
)
|
|
106
|
+
}
|
package/src/mmd/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './generate-mmd'
|
|
@@ -1,23 +1,29 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
|
|
1
|
+
import type { DiagramView } from '@likec4/core'
|
|
2
|
+
import JSON5 from 'json5'
|
|
3
|
+
import { CompositeGeneratorNode, NL, expandToNode, joinToNode, toString } from 'langium'
|
|
4
|
+
|
|
5
|
+
const componentName = (value: string): string => {
|
|
4
6
|
if (!value.charAt(0).match(/[a-zA-Z]/)) {
|
|
5
|
-
value =
|
|
7
|
+
value = 'View' + value
|
|
6
8
|
}
|
|
7
|
-
value = value.replaceAll(
|
|
8
|
-
return value.charAt(0).toLocaleUpperCase() + value.slice(1)
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
9
|
+
value = value.replaceAll('_', '')
|
|
10
|
+
return value.charAt(0).toLocaleUpperCase() + value.slice(1)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export const generateViewId = (views: DiagramView[]) =>
|
|
14
|
+
joinToNode(views, view => expandToNode`'${view.id}'`, {
|
|
15
|
+
separator: ' | '
|
|
16
|
+
})
|
|
17
|
+
|
|
18
|
+
export function generateReact(views: DiagramView[]) {
|
|
14
19
|
const components = views.map(({ id }) => {
|
|
15
20
|
return {
|
|
16
21
|
id,
|
|
17
22
|
name: componentName(id)
|
|
18
|
-
}
|
|
19
|
-
})
|
|
20
|
-
|
|
23
|
+
}
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
const out = new CompositeGeneratorNode()
|
|
21
27
|
out.appendTemplate`
|
|
22
28
|
/******************************************************************************
|
|
23
29
|
* This file was generated
|
|
@@ -27,39 +33,52 @@ export function generateReact(views) {
|
|
|
27
33
|
|
|
28
34
|
import type { DiagramView } from '@likec4/diagrams'
|
|
29
35
|
import { LikeC4 } from '@likec4/diagrams'
|
|
30
|
-
`.append(NL, NL)
|
|
36
|
+
`.append(NL, NL)
|
|
37
|
+
|
|
31
38
|
if (components.length == 0) {
|
|
32
|
-
out.append(
|
|
33
|
-
return toString(out)
|
|
39
|
+
out.append('export {}', NL)
|
|
40
|
+
return toString(out)
|
|
34
41
|
}
|
|
35
|
-
out.appendTemplate`
|
|
36
42
|
|
|
43
|
+
out.appendTemplate`
|
|
37
44
|
export type LikeC4ViewId = ${generateViewId(views)};
|
|
38
45
|
export const LikeC4Views = {
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
indented
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
46
|
+
`
|
|
47
|
+
.indent({
|
|
48
|
+
indentation: 2,
|
|
49
|
+
indentedChildren(indented) {
|
|
50
|
+
indented.appendNewLineIf(views.length > 1).append(
|
|
51
|
+
joinToNode(
|
|
52
|
+
views,
|
|
53
|
+
view =>
|
|
54
|
+
expandToNode`${JSON5.stringify(view.id)}: (${JSON5.stringify(
|
|
55
|
+
view
|
|
56
|
+
)} as unknown) as DiagramView`,
|
|
57
|
+
{
|
|
58
|
+
separator: ',',
|
|
59
|
+
appendNewLineIfNotEmpty: true
|
|
60
|
+
}
|
|
61
|
+
)
|
|
50
62
|
)
|
|
51
|
-
|
|
52
|
-
}
|
|
53
|
-
|
|
63
|
+
}
|
|
64
|
+
})
|
|
65
|
+
.append('} as const satisfies Record<LikeC4ViewId, DiagramView>', NL, NL).appendTemplate`
|
|
54
66
|
export type LikeC4Views = typeof LikeC4Views
|
|
55
67
|
|
|
56
68
|
export const {
|
|
69
|
+
// guard
|
|
57
70
|
isViewId,
|
|
71
|
+
// React hook to use location hash for ViewId
|
|
58
72
|
useViewId,
|
|
73
|
+
// React component to display diagram
|
|
59
74
|
Diagram,
|
|
75
|
+
// React component to display diagram in responsive container
|
|
60
76
|
Responsive,
|
|
77
|
+
// React component to display diagram in fullscreen container
|
|
61
78
|
Fullscreen,
|
|
79
|
+
// React component to embed diagram and open browser on click
|
|
62
80
|
Embedded,
|
|
81
|
+
// React component to browse diagrams in fullscreen container
|
|
63
82
|
Browser,
|
|
64
83
|
} = LikeC4.create<LikeC4ViewId>(LikeC4Views)
|
|
65
84
|
|
|
@@ -86,6 +105,7 @@ export function generateReact(views) {
|
|
|
86
105
|
DiagramLabel,
|
|
87
106
|
DiagramView
|
|
88
107
|
} from '@likec4/diagrams'
|
|
89
|
-
`.append(NL
|
|
90
|
-
|
|
108
|
+
`.append(NL)
|
|
109
|
+
|
|
110
|
+
return toString(out)
|
|
91
111
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './generate-react'
|
package/{dist/views-data-ts/generate-views-data.js → src/views-data-ts/generate-views-data.ts}
RENAMED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import {
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
import type { DiagramView } from '@likec4/core'
|
|
2
|
+
import JSON5 from 'json5'
|
|
3
|
+
import { CompositeGeneratorNode, NL, expandToNode, joinToNode, toString } from 'langium'
|
|
4
|
+
import { generateViewId } from '../react/generate-react'
|
|
5
|
+
|
|
6
|
+
export function generateViewsDataJs(views: DiagramView[]) {
|
|
7
|
+
const out = new CompositeGeneratorNode()
|
|
6
8
|
out.appendTemplate`
|
|
7
9
|
/******************************************************************************
|
|
8
10
|
* This file was generated
|
|
@@ -10,24 +12,32 @@ export function generateViewsDataJs(views) {
|
|
|
10
12
|
******************************************************************************/
|
|
11
13
|
/* eslint-disable */
|
|
12
14
|
|
|
13
|
-
`.append(NL, NL)
|
|
15
|
+
`.append(NL, NL)
|
|
16
|
+
|
|
14
17
|
if (views.length == 0) {
|
|
15
|
-
out.append(
|
|
16
|
-
return toString(out)
|
|
18
|
+
out.append('export const LikeC4Views = {}', NL)
|
|
19
|
+
return toString(out)
|
|
17
20
|
}
|
|
21
|
+
|
|
18
22
|
out.appendTemplate`
|
|
19
23
|
export const LikeC4Views = {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
indented
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
24
|
+
`
|
|
25
|
+
.indent({
|
|
26
|
+
indentation: 2,
|
|
27
|
+
indentedChildren(indented) {
|
|
28
|
+
indented.appendNewLineIf(views.length > 1).append(
|
|
29
|
+
joinToNode(
|
|
30
|
+
views,
|
|
31
|
+
view => expandToNode`${JSON5.stringify(view.id)}: ${JSON5.stringify(view)}`,
|
|
32
|
+
{
|
|
33
|
+
separator: ',',
|
|
34
|
+
appendNewLineIfNotEmpty: true
|
|
35
|
+
}
|
|
36
|
+
)
|
|
37
|
+
)
|
|
38
|
+
}
|
|
39
|
+
})
|
|
40
|
+
.append('}', NL, NL).appendTemplate`
|
|
31
41
|
|
|
32
42
|
export function isLikeC4ViewId(value) {
|
|
33
43
|
return (
|
|
@@ -36,11 +46,12 @@ export function generateViewsDataJs(views) {
|
|
|
36
46
|
Object.prototype.hasOwnProperty.call(LikeC4Views, value)
|
|
37
47
|
)
|
|
38
48
|
}
|
|
39
|
-
`.append(NL, NL)
|
|
40
|
-
return toString(out)
|
|
49
|
+
`.append(NL, NL)
|
|
50
|
+
return toString(out)
|
|
41
51
|
}
|
|
42
|
-
|
|
43
|
-
|
|
52
|
+
|
|
53
|
+
export function generateViewsDataTs(views: DiagramView[]) {
|
|
54
|
+
const out = new CompositeGeneratorNode()
|
|
44
55
|
out.appendTemplate`
|
|
45
56
|
/******************************************************************************
|
|
46
57
|
* This file was generated
|
|
@@ -49,29 +60,36 @@ export function generateViewsDataTs(views) {
|
|
|
49
60
|
/* eslint-disable */
|
|
50
61
|
|
|
51
62
|
import type { DiagramView } from '@likec4/core'
|
|
52
|
-
`.append(NL, NL)
|
|
63
|
+
`.append(NL, NL)
|
|
64
|
+
|
|
53
65
|
if (views.length == 0) {
|
|
54
|
-
out.append(
|
|
55
|
-
return toString(out)
|
|
66
|
+
out.append('export {}', NL)
|
|
67
|
+
return toString(out)
|
|
56
68
|
}
|
|
69
|
+
|
|
57
70
|
out.appendTemplate`
|
|
58
71
|
export type LikeC4ViewId = ${generateViewId(views)};
|
|
59
72
|
export const LikeC4Views = {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
indented
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
73
|
+
`
|
|
74
|
+
.indent({
|
|
75
|
+
indentation: 2,
|
|
76
|
+
indentedChildren(indented) {
|
|
77
|
+
indented.appendNewLineIf(views.length > 1).append(
|
|
78
|
+
joinToNode(
|
|
79
|
+
views,
|
|
80
|
+
view =>
|
|
81
|
+
expandToNode`${JSON5.stringify(view.id)}: (${JSON5.stringify(
|
|
82
|
+
view
|
|
83
|
+
)} as unknown) as DiagramView`,
|
|
84
|
+
{
|
|
85
|
+
separator: ',',
|
|
86
|
+
appendNewLineIfNotEmpty: true
|
|
87
|
+
}
|
|
88
|
+
)
|
|
71
89
|
)
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
|
|
90
|
+
}
|
|
91
|
+
})
|
|
92
|
+
.append('} as const satisfies Record<LikeC4ViewId, DiagramView>', NL, NL).appendTemplate`
|
|
75
93
|
export type LikeC4Views = typeof LikeC4Views
|
|
76
94
|
|
|
77
95
|
export function isLikeC4ViewId(value: unknown): value is LikeC4ViewId {
|
|
@@ -98,6 +116,6 @@ export function generateViewsDataTs(views) {
|
|
|
98
116
|
DiagramEdge,
|
|
99
117
|
DiagramLabel
|
|
100
118
|
} from '@likec4/core'
|
|
101
|
-
`.append(NL, NL)
|
|
102
|
-
return toString(out)
|
|
119
|
+
`.append(NL, NL)
|
|
120
|
+
return toString(out)
|
|
103
121
|
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './generate-views-data'
|
package/dist/d2/generate-d2.d.ts
DELETED
package/dist/d2/generate-d2.js
DELETED
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import { CompositeGeneratorNode, NL, joinToNode, toString } from "langium";
|
|
2
|
-
import { isNil } from "rambdax";
|
|
3
|
-
const capitalizeFirstLetter = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
|
|
4
|
-
const fqnName = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter).join("");
|
|
5
|
-
const nodeName = (node) => {
|
|
6
|
-
return fqnName(node.parent ? node.id.slice(node.parent.length + 1) : node.id);
|
|
7
|
-
};
|
|
8
|
-
const d2direction = ({ autoLayout }) => {
|
|
9
|
-
switch (autoLayout) {
|
|
10
|
-
case "TB": {
|
|
11
|
-
return "down";
|
|
12
|
-
}
|
|
13
|
-
case "BT": {
|
|
14
|
-
return "up";
|
|
15
|
-
}
|
|
16
|
-
case "LR": {
|
|
17
|
-
return "right";
|
|
18
|
-
}
|
|
19
|
-
case "RL": {
|
|
20
|
-
return "left";
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
};
|
|
24
|
-
const d2shape = ({ shape }) => {
|
|
25
|
-
switch (shape) {
|
|
26
|
-
case "queue":
|
|
27
|
-
case "cylinder":
|
|
28
|
-
case "rectangle":
|
|
29
|
-
case "person": {
|
|
30
|
-
return shape;
|
|
31
|
-
}
|
|
32
|
-
case "storage": {
|
|
33
|
-
return "stored_data";
|
|
34
|
-
}
|
|
35
|
-
case "mobile":
|
|
36
|
-
case "browser": {
|
|
37
|
-
return "rectangle";
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
};
|
|
41
|
-
export function generateD2(view) {
|
|
42
|
-
const { nodes, edges } = view;
|
|
43
|
-
const names = /* @__PURE__ */ new Map();
|
|
44
|
-
const printNode = (node, parentName) => {
|
|
45
|
-
const name = nodeName(node);
|
|
46
|
-
const fqnName2 = (parentName ? parentName + "." : "") + name;
|
|
47
|
-
names.set(node.id, fqnName2);
|
|
48
|
-
const label = node.title.replaceAll("\n", "\\n");
|
|
49
|
-
const shape = d2shape(node);
|
|
50
|
-
return new CompositeGeneratorNode().append(name, ": {", NL).indent({
|
|
51
|
-
indentedChildren: (indent) => indent.append('label: "', label, '"', NL).appendIf(shape !== "rectangle", "shape: ", shape, NL).appendIf(
|
|
52
|
-
node.children.length > 0,
|
|
53
|
-
NL,
|
|
54
|
-
joinToNode(
|
|
55
|
-
nodes.filter((n) => n.parent === node.id),
|
|
56
|
-
(n) => printNode(n, fqnName2)
|
|
57
|
-
)
|
|
58
|
-
),
|
|
59
|
-
indentation: 2
|
|
60
|
-
}).append("}", NL);
|
|
61
|
-
};
|
|
62
|
-
const printEdge = (edge) => {
|
|
63
|
-
return new CompositeGeneratorNode().append(names.get(edge.source), " -> ", names.get(edge.target)).append((out) => edge.label && out.append(": ", edge.label.replaceAll("\n", "\\n")));
|
|
64
|
-
};
|
|
65
|
-
return toString(
|
|
66
|
-
new CompositeGeneratorNode().append("direction: ", d2direction(view), NL, NL).append(
|
|
67
|
-
joinToNode(
|
|
68
|
-
nodes.filter((n) => isNil(n.parent)),
|
|
69
|
-
(n) => printNode(n),
|
|
70
|
-
{
|
|
71
|
-
appendNewLineIfNotEmpty: true
|
|
72
|
-
}
|
|
73
|
-
)
|
|
74
|
-
).appendIf(
|
|
75
|
-
edges.length > 0,
|
|
76
|
-
NL,
|
|
77
|
-
joinToNode(edges, (e) => printEdge(e), {
|
|
78
|
-
appendNewLineIfNotEmpty: true
|
|
79
|
-
})
|
|
80
|
-
)
|
|
81
|
-
);
|
|
82
|
-
}
|
package/dist/d2/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-d2';
|
package/dist/d2/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./generate-d2.js";
|
package/dist/index.d.ts
DELETED
package/dist/index.js
DELETED
package/dist/mmd/generate-mmd.js
DELETED
|
@@ -1,86 +0,0 @@
|
|
|
1
|
-
import { CompositeGeneratorNode, NL, joinToNode, toString } from "langium";
|
|
2
|
-
import { isNil } from "rambdax";
|
|
3
|
-
const capitalizeFirstLetter = (value) => value.charAt(0).toLocaleUpperCase() + value.slice(1);
|
|
4
|
-
const fqnName = (nodeId) => nodeId.split(".").map(capitalizeFirstLetter).join("");
|
|
5
|
-
const nodeName = (node) => {
|
|
6
|
-
return fqnName(node.parent ? node.id.slice(node.parent.length + 1) : node.id);
|
|
7
|
-
};
|
|
8
|
-
const mmdshape = ({ shape }) => {
|
|
9
|
-
switch (shape) {
|
|
10
|
-
case "queue":
|
|
11
|
-
case "cylinder":
|
|
12
|
-
return ["[(", ")]"];
|
|
13
|
-
case "person": {
|
|
14
|
-
return ["[fa:fa-user ", "]"];
|
|
15
|
-
}
|
|
16
|
-
case "storage":
|
|
17
|
-
return ["([", "])"];
|
|
18
|
-
case "mobile":
|
|
19
|
-
case "browser":
|
|
20
|
-
case "rectangle": {
|
|
21
|
-
return ["[", "]"];
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
};
|
|
25
|
-
export function generateMermaid(view) {
|
|
26
|
-
const { nodes, edges } = view;
|
|
27
|
-
const names = /* @__PURE__ */ new Map();
|
|
28
|
-
const printNode = (node, parentName) => {
|
|
29
|
-
const name = nodeName(node);
|
|
30
|
-
const fqnName2 = (parentName ? parentName + "." : "") + name;
|
|
31
|
-
names.set(node.id, fqnName2);
|
|
32
|
-
const label = node.title.replaceAll("\n", "\\n");
|
|
33
|
-
const shape = mmdshape(node);
|
|
34
|
-
const baseNode = new CompositeGeneratorNode();
|
|
35
|
-
if (node.children.length > 0) {
|
|
36
|
-
baseNode.append("subgraph ", fqnName2, '["', label, '"]', NL).indent({
|
|
37
|
-
indentedChildren: (indent) => indent.appendIf(
|
|
38
|
-
node.children.length > 0,
|
|
39
|
-
NL,
|
|
40
|
-
joinToNode(
|
|
41
|
-
nodes.filter((n) => n.parent === node.id),
|
|
42
|
-
(n) => printNode(n, fqnName2)
|
|
43
|
-
)
|
|
44
|
-
),
|
|
45
|
-
indentation: 2
|
|
46
|
-
}).append("end", NL);
|
|
47
|
-
} else {
|
|
48
|
-
baseNode.append(fqnName2, shape[0], label, shape[1], NL);
|
|
49
|
-
}
|
|
50
|
-
return baseNode;
|
|
51
|
-
};
|
|
52
|
-
const printEdge = (edge) => {
|
|
53
|
-
return new CompositeGeneratorNode().append(
|
|
54
|
-
names.get(edge.source),
|
|
55
|
-
" --",
|
|
56
|
-
edge.label ? '"' + edge.label.replaceAll("\n", "\\n") + '"--' : "",
|
|
57
|
-
"> ",
|
|
58
|
-
names.get(edge.target)
|
|
59
|
-
);
|
|
60
|
-
};
|
|
61
|
-
return toString(
|
|
62
|
-
new CompositeGeneratorNode().appendIf(
|
|
63
|
-
view.title !== null && view.title.length > 0,
|
|
64
|
-
"---",
|
|
65
|
-
NL,
|
|
66
|
-
`title: ${view.title}`,
|
|
67
|
-
NL,
|
|
68
|
-
"---",
|
|
69
|
-
NL
|
|
70
|
-
).append("graph ", view.autoLayout, NL, NL).append(
|
|
71
|
-
joinToNode(
|
|
72
|
-
nodes.filter((n) => isNil(n.parent)),
|
|
73
|
-
(n) => printNode(n),
|
|
74
|
-
{
|
|
75
|
-
appendNewLineIfNotEmpty: true
|
|
76
|
-
}
|
|
77
|
-
)
|
|
78
|
-
).appendIf(
|
|
79
|
-
edges.length > 0,
|
|
80
|
-
NL,
|
|
81
|
-
joinToNode(edges, (e) => printEdge(e), {
|
|
82
|
-
appendNewLineIfNotEmpty: true
|
|
83
|
-
})
|
|
84
|
-
)
|
|
85
|
-
);
|
|
86
|
-
}
|
package/dist/mmd/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-mmd';
|
package/dist/mmd/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./generate-mmd.js";
|
package/dist/react/index.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-react';
|
package/dist/react/index.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./generate-react.js";
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from './generate-views-data';
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./generate-views-data.js";
|