@likec4/generators 0.2.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.
@@ -0,0 +1,2 @@
1
+ import type { ComputedView } from '@likec4/core/types';
2
+ export declare function generateD2<V extends ComputedView>({ nodes, edges }: V): string;
@@ -0,0 +1,56 @@
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 d2shape = ({ shape }) => {
9
+ switch (shape) {
10
+ case 'queue':
11
+ case 'cylinder':
12
+ case 'rectangle':
13
+ case 'person': {
14
+ return shape;
15
+ }
16
+ case 'storage': {
17
+ return 'stored_data';
18
+ }
19
+ case 'browser': {
20
+ return 'rectangle';
21
+ }
22
+ }
23
+ };
24
+ export function generateD2({ nodes, edges }) {
25
+ const names = new Map();
26
+ const printNode = (node, parentName) => {
27
+ const name = nodeName(node);
28
+ const fqnName = (parentName ? parentName + '.' : '') + name;
29
+ names.set(node.id, fqnName);
30
+ const label = node.title.replaceAll('\n', '\\n');
31
+ const shape = d2shape(node);
32
+ return new CompositeGeneratorNode()
33
+ .append(name, ': {', NL)
34
+ .indent({
35
+ indentedChildren: (indent) => indent
36
+ .append('label: "', label, '"', NL)
37
+ .append('shape: ', shape, NL)
38
+ .appendIf(node.children.length > 0, NL, joinToNode(nodes.filter(n => n.parent === node.id), n => printNode(n, fqnName))),
39
+ indentation: 2
40
+ })
41
+ .append('}', NL);
42
+ };
43
+ // return `${names.get(edge.source)} -> ${names.get(edge.target)}${edge.label ? ': ' + edge.label : ''}`
44
+ const printEdge = (edge) => {
45
+ return new CompositeGeneratorNode()
46
+ .append(names.get(edge.source), ' -> ', names.get(edge.target))
47
+ .append(out => edge.label && out.append(': ', edge.label.replaceAll('\n', '\\n')));
48
+ };
49
+ return toString(new CompositeGeneratorNode()
50
+ .append(joinToNode(nodes.filter(n => isNil(n.parent)), n => printNode(n), {
51
+ appendNewLineIfNotEmpty: true,
52
+ }))
53
+ .appendIf(edges.length > 0, NL, joinToNode(edges, e => printEdge(e), {
54
+ appendNewLineIfNotEmpty: true,
55
+ })));
56
+ }
@@ -0,0 +1 @@
1
+ export * from './generate-d2';
@@ -0,0 +1 @@
1
+ export * from './generate-d2';
@@ -0,0 +1,2 @@
1
+ export { generateReact } from './react/generate-react';
2
+ export { generateD2 } from './d2/generate-d2';
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export { generateReact } from './react/generate-react';
2
+ export { generateD2 } from './d2/generate-d2';
@@ -0,0 +1,2 @@
1
+ import type { DiagramView } from '@likec4/core/types';
2
+ export declare function generateReact(views: DiagramView[]): string;
@@ -0,0 +1,61 @@
1
+ import JSON5 from 'json5';
2
+ import { CompositeGeneratorNode, NL, expandToNode, joinToNode, toString } from 'langium';
3
+ const componentName = (value) => {
4
+ if (!value.charAt(0).match(/[a-zA-Z]/)) {
5
+ value = 'View' + value;
6
+ }
7
+ value = value.replaceAll('_', '');
8
+ return value.charAt(0).toLocaleUpperCase() + value.slice(1);
9
+ };
10
+ export function generateReact(views) {
11
+ const components = views.map(({ id }) => {
12
+ return {
13
+ id,
14
+ name: componentName(id),
15
+ };
16
+ });
17
+ const out = new CompositeGeneratorNode();
18
+ out
19
+ .appendTemplate `
20
+ /******************************************************************************
21
+ * This file was generated
22
+ * DO NOT EDIT MANUALLY!
23
+ ******************************************************************************/
24
+ /* eslint-disable */
25
+
26
+ import type { DiagramView, EmbeddedDiagramProps } from '@likec4/diagrams'
27
+ import { EmbeddedDiagram } from '@likec4/diagrams'
28
+ `
29
+ .append(NL, NL);
30
+ if (components.length == 0) {
31
+ out.append('export {}', NL);
32
+ return toString(out);
33
+ }
34
+ out
35
+ .append('export const LikeC4ViewData = {', NL)
36
+ .indent(indent => {
37
+ indent.append(joinToNode(views, view => expandToNode `'${view.id}': (${JSON5.stringify(view)} as any) as DiagramView`, {
38
+ separator: ',',
39
+ appendNewLineIfNotEmpty: true
40
+ }));
41
+ })
42
+ .append('} as const', NL, NL)
43
+ .appendTemplate `
44
+ export type ViewId = keyof typeof LikeC4ViewData
45
+ export function isViewId(value: unknown): value is ViewId {
46
+ return typeof value === 'string' && value in LikeC4ViewData
47
+ }
48
+
49
+ export type LikeC4ViewProps = Omit<EmbeddedDiagramProps, 'diagram'>;
50
+ export function LikeC4View({viewId, ...rest}: LikeC4ViewProps & { viewId: ViewId }) {
51
+ return <EmbeddedDiagram diagram={LikeC4ViewData[viewId]} {...rest}/>
52
+ }
53
+ `
54
+ .append(NL, NL, joinToNode(components, ({ id, name }) => expandToNode `
55
+ LikeC4View['${name}'] = (props: LikeC4ViewProps) => <EmbeddedDiagram diagram={LikeC4ViewData['${id}']} {...props}/>
56
+ `, {
57
+ separator: ',',
58
+ appendNewLineIfNotEmpty: true
59
+ }), NL);
60
+ return toString(out);
61
+ }
@@ -0,0 +1 @@
1
+ export * from './generate-react';
@@ -0,0 +1 @@
1
+ export * from './generate-react';
package/dist/util.d.ts ADDED
@@ -0,0 +1,7 @@
1
+ /******************************************************************************
2
+ * Copyright 2021 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ import type { GeneratorNode } from 'langium';
7
+ export declare function generatedHeader(): GeneratorNode;
package/dist/util.js ADDED
@@ -0,0 +1,11 @@
1
+ /******************************************************************************
2
+ * Copyright 2021 TypeFox GmbH
3
+ * This program and the accompanying materials are made available under the
4
+ * terms of the MIT License, which is available in the project root.
5
+ ******************************************************************************/
6
+ import { CompositeGeneratorNode, NL } from 'langium';
7
+ export function generatedHeader() {
8
+ const node = new CompositeGeneratorNode();
9
+ node.contents.push('/******************************************************************************', NL, ' * This file was generated', NL, ' * DO NOT EDIT MANUALLY!', NL, ' ******************************************************************************/', NL, NL, '/* eslint-disable */', NL);
10
+ return node;
11
+ }
package/package.json ADDED
@@ -0,0 +1,80 @@
1
+ {
2
+ "name": "@likec4/generators",
3
+ "version": "0.2.0",
4
+ "bugs": "https://github.com/likec4/likec4/issues",
5
+ "homepage": "https://like-c4.dev",
6
+ "author": "Denis Davydkov <denis@davydkov.com>",
7
+ "files": [
8
+ "dist"
9
+ ],
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/likec4/likec4.git"
13
+ },
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "type": "module",
17
+ "sideEffects": false,
18
+ "exports": {
19
+ ".": {
20
+ "types": "./dist/index.d.ts",
21
+ "import": "./dist/index.js",
22
+ "require": "./dist/index.cjs"
23
+ },
24
+ "./react": {
25
+ "types": "./dist/react/index.d.ts",
26
+ "import": "./dist/react/index.js",
27
+ "require": "./dist/react/index.cjs"
28
+ },
29
+ "./d2": {
30
+ "types": "./dist/d2/index.d.ts",
31
+ "import": "./dist/d2/index.js",
32
+ "require": "./dist/d2/index.cjs"
33
+ }
34
+ },
35
+ "publishConfig": {
36
+ "registry": "https://registry.npmjs.org",
37
+ "access": "public",
38
+ "main": "./dist/index.js",
39
+ "types": "./dist/index.d.ts",
40
+ "exports": {
41
+ ".": {
42
+ "types": "./dist/index.d.ts",
43
+ "import": "./dist/index.js",
44
+ "require": "./dist/index.cjs"
45
+ },
46
+ "./react": {
47
+ "types": "./dist/react/index.d.ts",
48
+ "import": "./dist/react/index.js",
49
+ "require": "./dist/react/index.cjs"
50
+ },
51
+ "./d2": {
52
+ "types": "./dist/d2/index.d.ts",
53
+ "import": "./dist/d2/index.js",
54
+ "require": "./dist/d2/index.cjs"
55
+ }
56
+ }
57
+ },
58
+ "scripts": {
59
+ "compile": "",
60
+ "release:build": "tsc -p tsconfig.esm.json",
61
+ "build": "tsc",
62
+ "dev": "tsc --watch",
63
+ "lint": "run -T eslint src/ --fix",
64
+ "clean": "rimraf dist",
65
+ "test": "vitest run",
66
+ "test:watch": "vitest"
67
+ },
68
+ "dependencies": {
69
+ "@likec4/core": "0.2.1",
70
+ "json5": "^2.2.3",
71
+ "langium": "^1.1.0",
72
+ "rambdax": "^9.1.0"
73
+ },
74
+ "devDependencies": {
75
+ "@types/node": "^18.15.6",
76
+ "typescript": "^5.0.3",
77
+ "vite": "^4.2.1",
78
+ "vitest": "^0.29.8"
79
+ }
80
+ }