archyne 0.3.0-alpha.1 → 0.3.2-alpha.1
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/README.md +29 -10
- package/THIRD-PARTY-NOTICES.md +309 -309
- package/dist/assets/{abnfDiagram-N423BO3Z-DIXsDC-F.js → abnfDiagram-N423BO3Z-CWxCA29s.js} +1 -1
- package/dist/assets/{arc-Dj16AHPP.js → arc-BPhcgyOR.js} +1 -1
- package/dist/assets/{architectureDiagram-T3A2C74G-BVAWUfK9.js → architectureDiagram-T3A2C74G-DbJtNiJ8.js} +1 -1
- package/dist/assets/{blockDiagram-VBNYF7ZC-DWGHJV3z.js → blockDiagram-VBNYF7ZC-D14dxPQ6.js} +1 -1
- package/dist/assets/{c4Diagram-5PPSVZJV-BQxBb-eE.js → c4Diagram-5PPSVZJV-_Ru2AQyv.js} +1 -1
- package/dist/assets/channel-x2nnREdF.js +1 -0
- package/dist/assets/{chunk-2GRJ4B5K-DrxYcIKi.js → chunk-2GRJ4B5K-B45veiLl.js} +1 -1
- package/dist/assets/{chunk-2Q5K7J3B-qIYVNzfi.js → chunk-2Q5K7J3B-BYEJghF5.js} +1 -1
- package/dist/assets/{chunk-5RXB4S5H-BSkyDD2G.js → chunk-5RXB4S5H-D6PWk-Fh.js} +1 -1
- package/dist/assets/{chunk-5VM5RSS4-Doshgyjn.js → chunk-5VM5RSS4-DkT1fHDH.js} +1 -1
- package/dist/assets/{chunk-6Q2QTUOP-DY_ARIfs.js → chunk-6Q2QTUOP-DwN_ODU0.js} +1 -1
- package/dist/assets/{chunk-GF5L2VYU-wHUCmL_g.js → chunk-GF5L2VYU-CfLWnAFR.js} +1 -1
- package/dist/assets/{chunk-JWPE2WC7-BWaI0jmn.js → chunk-JWPE2WC7-Bvoco_OT.js} +1 -1
- package/dist/assets/{chunk-KBJHAD2P-JqxcXows.js → chunk-KBJHAD2P-Bl8ANVAT.js} +1 -1
- package/dist/assets/{chunk-RYQCIY6F-Cw5xJ0a1.js → chunk-RYQCIY6F-CUFEfSAp.js} +1 -1
- package/dist/assets/{chunk-XXDRQBXY-DTNNhjpS.js → chunk-XXDRQBXY-CqS46WpP.js} +1 -1
- package/dist/assets/classDiagram-JCYQIIEL-Dcqht9zY.js +1 -0
- package/dist/assets/classDiagram-v2-OCEON4UE-Dcqht9zY.js +1 -0
- package/dist/assets/{cose-bilkent-JH36ORCC-COsgTVVE.js → cose-bilkent-JH36ORCC-0fLdUP4n.js} +1 -1
- package/dist/assets/{cynefin-VYW2F7L2-Cro8QprN.js → cynefin-VYW2F7L2-CB-4Q2Uq.js} +1 -1
- package/dist/assets/{cynefinDiagram-MW4NZA55-Otk8wE3X.js → cynefinDiagram-MW4NZA55-m6YSI3Bh.js} +1 -1
- package/dist/assets/{dagre-VZM6K2ZE-CvTaqqHa.js → dagre-VZM6K2ZE-BsmbvCId.js} +1 -1
- package/dist/assets/{diagram-7IWD3JNH-BNe8ln_N.js → diagram-7IWD3JNH-iTWBScbD.js} +1 -1
- package/dist/assets/{diagram-B4RE2ZJO-Brnd7Tv6.js → diagram-B4RE2ZJO-DJ95aX4N.js} +1 -1
- package/dist/assets/{diagram-LBJQPF4R-CrEH36Uj.js → diagram-LBJQPF4R-D4V1ejJ0.js} +1 -1
- package/dist/assets/{diagram-Q27KOJAE-CBK1TZN-.js → diagram-Q27KOJAE-BJ2SnmJt.js} +1 -1
- package/dist/assets/{diagram-UB23O5K3-JUQ78M73.js → diagram-UB23O5K3-B33ky4tq.js} +1 -1
- package/dist/assets/{ebnfDiagram-BXEA7PRR-BdUTSTYX.js → ebnfDiagram-BXEA7PRR-B8YZxzzx.js} +1 -1
- package/dist/assets/{elk-api-CnmYJVU6.js → elk-api-BEoK8cSs.js} +1 -1
- package/dist/assets/{elk.bundled-C1NX_935.js → elk.bundled-g5J3chN5.js} +1 -1
- package/dist/assets/{erDiagram-JOGREHBK-D7fhJig7.js → erDiagram-JOGREHBK-B7RkeG0t.js} +1 -1
- package/dist/assets/{flowDiagram-UKHOOZJN-BUuw8Sra.js → flowDiagram-UKHOOZJN-Bhg1RufJ.js} +1 -1
- package/dist/assets/{fromDot-m2FS_XBS.js → fromDot-CQsAmWbW.js} +1 -1
- package/dist/assets/{fromDrawio-d2P5s3hv.js → fromDrawio-DEgkUjY8.js} +1 -1
- package/dist/assets/{fromExcalidraw-gkO8wk9U.js → fromExcalidraw-BzgOaI_g.js} +1 -1
- package/dist/assets/{fromPlantuml-DC6Ln4Kt.js → fromPlantuml-BXgnqEO6.js} +1 -1
- package/dist/assets/{fromSql-fjmDwmgj.js → fromSql-CgaUND0o.js} +1 -1
- package/dist/assets/{fromVsdx-BNwPKIKU.js → fromVsdx-_QnAzQCc.js} +1 -1
- package/dist/assets/{ganttDiagram-PKOTCBZU-0pMER0ej.js → ganttDiagram-PKOTCBZU-6q1OXMFs.js} +1 -1
- package/dist/assets/{gitGraphDiagram-DS77QQ5N-CdqG1WOl.js → gitGraphDiagram-DS77QQ5N-DBIluxD2.js} +1 -1
- package/dist/assets/{index-D2iswyef.js → index-D58D9MBA.js} +63 -63
- package/dist/assets/index-Kkii5lY5.css +1 -0
- package/dist/assets/{infoDiagram-6WML65LV-DPqvV8rB.js → infoDiagram-6WML65LV-BogiGFsC.js} +1 -1
- package/dist/assets/{ishikawaDiagram-WSZJBQD7-CSPXAP3s.js → ishikawaDiagram-WSZJBQD7-BnuS3rDr.js} +1 -1
- package/dist/assets/{journeyDiagram-NVQOT4AX-DTHQtGFh.js → journeyDiagram-NVQOT4AX-C1LbH3qg.js} +1 -1
- package/dist/assets/{kanban-definition-27J2QSJJ-B0DJ3-Na.js → kanban-definition-27J2QSJJ-CC4tpXS8.js} +1 -1
- package/dist/assets/{linear-B4AE5gzn.js → linear-nPRvbK9t.js} +1 -1
- package/dist/assets/{mermaid.core-cnu9Hu0H.js → mermaid.core-d3X_EolB.js} +4 -4
- package/dist/assets/{mindmap-definition-FAOFIHXS-qGpw5nKM.js → mindmap-definition-FAOFIHXS-BKw0CExu.js} +1 -1
- package/dist/assets/{pegDiagram-VL7TDLO6-BGT3Nw2y.js → pegDiagram-VL7TDLO6-C0crO6aC.js} +1 -1
- package/dist/assets/{pieDiagram-7S7Q4E2Y-Bc8ghniT.js → pieDiagram-7S7Q4E2Y-5YsXd83r.js} +1 -1
- package/dist/assets/{plantumlFamilies-DOJ5Zy3V.js → plantumlFamilies-BQWcuhsm.js} +1 -1
- package/dist/assets/{quadrantDiagram-CIZ2JOQS-BtlM_DOc.js → quadrantDiagram-CIZ2JOQS-BWRDIcFE.js} +1 -1
- package/dist/assets/{railroadDiagram-AXF67PYL-LYPvIKAL.js → railroadDiagram-AXF67PYL-BeJeN8NK.js} +1 -1
- package/dist/assets/{requirementDiagram-LRYGKXZP-BzJkmewZ.js → requirementDiagram-LRYGKXZP-lgxjjOkj.js} +1 -1
- package/dist/assets/{sankeyDiagram-W5VNT64P-DETZ9w-u.js → sankeyDiagram-W5VNT64P-BdDlQIjC.js} +1 -1
- package/dist/assets/{sequenceDiagram-SI44F4Z6-7KPCXxWm.js → sequenceDiagram-SI44F4Z6-CftqXzOB.js} +1 -1
- package/dist/assets/{sizeCapture-X5ZJPWSS-BM9d5oG-.js → sizeCapture-X5ZJPWSS-DqAD3Y1J.js} +1 -1
- package/dist/assets/{stateDiagram-OKZ733FA-a_7Vxmm-.js → stateDiagram-OKZ733FA-CsK1tZu_.js} +1 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DoKVKwvk.js +1 -0
- package/dist/assets/{swimlanes-SLNWSIFB-D3qzkF1P.js → swimlanes-SLNWSIFB-y49WYIGH.js} +2 -2
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-DdYZRZ7q.js +8 -0
- package/dist/assets/{timeline-definition-Z64GVDOM-CZq_A4Q0.js → timeline-definition-Z64GVDOM-dsSDjxsB.js} +1 -1
- package/dist/assets/{vennDiagram-T6HMQDX7-CDFzI8sR.js → vennDiagram-T6HMQDX7-D5ubu60T.js} +1 -1
- package/dist/assets/{wardleyDiagram-T6FBY63Y-D5fktD2X.js → wardleyDiagram-T6FBY63Y-DqlVsICK.js} +1 -1
- package/dist/assets/{xychartDiagram-ELKLHX3M-BSzrgaJ4.js → xychartDiagram-ELKLHX3M-Z5y_JujJ.js} +1 -1
- package/dist/index.html +29 -2
- package/dist/preview.png +0 -0
- package/package.json +134 -133
- package/desktop/main.cjs +0 -378
- package/dist/assets/channel-Dqh6JL_k.js +0 -1
- package/dist/assets/classDiagram-JCYQIIEL-BSai74_L.js +0 -1
- package/dist/assets/classDiagram-v2-OCEON4UE-BSai74_L.js +0 -1
- package/dist/assets/index-iS7lCiZ-.css +0 -1
- package/dist/assets/stateDiagram-v2-UEYNNEHI-DQz4hTBY.js +0 -1
- package/dist/assets/swimlanesDiagram-ULZ7WXOC-CuRyTLM3.js +0 -8
package/package.json
CHANGED
|
@@ -1,133 +1,134 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "archyne",
|
|
3
|
-
"version": "0.3.
|
|
4
|
-
"license": "MIT",
|
|
5
|
-
"type": "module",
|
|
6
|
-
"bin": {
|
|
7
|
-
"archyne": "bin/archyne.mjs"
|
|
8
|
-
},
|
|
9
|
-
"files": [
|
|
10
|
-
"bin",
|
|
11
|
-
"dist",
|
|
12
|
-
"LICENSE",
|
|
13
|
-
"NOTICE",
|
|
14
|
-
"README.md",
|
|
15
|
-
"THIRD-PARTY-NOTICES.md"
|
|
16
|
-
],
|
|
17
|
-
"engines": {
|
|
18
|
-
"node": ">=22"
|
|
19
|
-
},
|
|
20
|
-
"repository": {
|
|
21
|
-
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/dariodd/archyne.git"
|
|
23
|
-
},
|
|
24
|
-
"bugs": {
|
|
25
|
-
"url": "https://github.com/dariodd/archyne/issues"
|
|
26
|
-
},
|
|
27
|
-
"homepage": "https://dariodd.github.io/archyne/",
|
|
28
|
-
"keywords": [
|
|
29
|
-
"mermaid",
|
|
30
|
-
"diagram",
|
|
31
|
-
"diagram-editor",
|
|
32
|
-
"flowchart",
|
|
33
|
-
"uml",
|
|
34
|
-
"erd",
|
|
35
|
-
"c4-model",
|
|
36
|
-
"sequence-diagram",
|
|
37
|
-
"architecture-diagram",
|
|
38
|
-
"local-first",
|
|
39
|
-
"mcp",
|
|
40
|
-
"editor"
|
|
41
|
-
],
|
|
42
|
-
"scripts": {
|
|
43
|
-
"dev": "vite",
|
|
44
|
-
"build": "npm run typecheck && vite build",
|
|
45
|
-
"preview": "vite preview",
|
|
46
|
-
"test": "vitest run",
|
|
47
|
-
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.node.json",
|
|
48
|
-
"lint": "eslint .",
|
|
49
|
-
"lint:fix": "eslint . --fix",
|
|
50
|
-
"format": "prettier --write .",
|
|
51
|
-
"format:check": "prettier --check .",
|
|
52
|
-
"size": "node scripts/check-bundle-size.mjs",
|
|
53
|
-
"icons:azure": "node scripts/build-azure-icons.mjs",
|
|
54
|
-
"icons:index": "node scripts/build-icon-index.mjs",
|
|
55
|
-
"audit": "node scripts/audit-gate.mjs",
|
|
56
|
-
"sbom": "node scripts/sbom.mjs",
|
|
57
|
-
"notices:check": "node scripts/sbom.mjs && node scripts/check-notices.mjs",
|
|
58
|
-
"notices:update": "node scripts/sbom.mjs && node scripts/update-notices.mjs",
|
|
59
|
-
"mcp": "tsx mcp/server.ts",
|
|
60
|
-
"mcp:smoke": "tsx mcp/smoke.ts",
|
|
61
|
-
"test:e2e:export": "tsx tests/e2e-export.mts",
|
|
62
|
-
"test:e2e:i18n": "tsx tests/e2e-i18n-export.mts",
|
|
63
|
-
"test:e2e:a11y": "tsx tests/e2e-a11y.mts",
|
|
64
|
-
"test:e2e:rtl": "tsx tests/e2e-rtl.mts",
|
|
65
|
-
"test:e2e:csp": "tsx tests/e2e-csp.mts",
|
|
66
|
-
"test:e2e:drag": "tsx tests/e2e-drag.mts",
|
|
67
|
-
"test:e2e:waypoints": "tsx tests/e2e-waypoints.mts",
|
|
68
|
-
"test:e2e:
|
|
69
|
-
"test:e2e:
|
|
70
|
-
"test:e2e:
|
|
71
|
-
"test:e2e:
|
|
72
|
-
"test:e2e:
|
|
73
|
-
"
|
|
74
|
-
"
|
|
75
|
-
"
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
"@
|
|
82
|
-
"@iconify-json/
|
|
83
|
-
"@iconify-json/
|
|
84
|
-
"@iconify-json/
|
|
85
|
-
"@iconify/
|
|
86
|
-
"@
|
|
87
|
-
"@
|
|
88
|
-
"
|
|
89
|
-
"
|
|
90
|
-
"
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"
|
|
94
|
-
"
|
|
95
|
-
"
|
|
96
|
-
"
|
|
97
|
-
"
|
|
98
|
-
"
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
"@
|
|
104
|
-
"@
|
|
105
|
-
"@
|
|
106
|
-
"@types/
|
|
107
|
-
"@types/
|
|
108
|
-
"@
|
|
109
|
-
"
|
|
110
|
-
"
|
|
111
|
-
"
|
|
112
|
-
"
|
|
113
|
-
"
|
|
114
|
-
"eslint
|
|
115
|
-
"eslint-
|
|
116
|
-
"eslint-plugin-
|
|
117
|
-
"
|
|
118
|
-
"
|
|
119
|
-
"
|
|
120
|
-
"
|
|
121
|
-
"
|
|
122
|
-
"
|
|
123
|
-
"
|
|
124
|
-
"
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
"
|
|
129
|
-
|
|
130
|
-
"
|
|
131
|
-
"
|
|
132
|
-
|
|
133
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "archyne",
|
|
3
|
+
"version": "0.3.2-alpha.1",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"archyne": "bin/archyne.mjs"
|
|
8
|
+
},
|
|
9
|
+
"files": [
|
|
10
|
+
"bin",
|
|
11
|
+
"dist",
|
|
12
|
+
"LICENSE",
|
|
13
|
+
"NOTICE",
|
|
14
|
+
"README.md",
|
|
15
|
+
"THIRD-PARTY-NOTICES.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22"
|
|
19
|
+
},
|
|
20
|
+
"repository": {
|
|
21
|
+
"type": "git",
|
|
22
|
+
"url": "git+https://github.com/dariodd/archyne.git"
|
|
23
|
+
},
|
|
24
|
+
"bugs": {
|
|
25
|
+
"url": "https://github.com/dariodd/archyne/issues"
|
|
26
|
+
},
|
|
27
|
+
"homepage": "https://dariodd.github.io/archyne/",
|
|
28
|
+
"keywords": [
|
|
29
|
+
"mermaid",
|
|
30
|
+
"diagram",
|
|
31
|
+
"diagram-editor",
|
|
32
|
+
"flowchart",
|
|
33
|
+
"uml",
|
|
34
|
+
"erd",
|
|
35
|
+
"c4-model",
|
|
36
|
+
"sequence-diagram",
|
|
37
|
+
"architecture-diagram",
|
|
38
|
+
"local-first",
|
|
39
|
+
"mcp",
|
|
40
|
+
"editor"
|
|
41
|
+
],
|
|
42
|
+
"scripts": {
|
|
43
|
+
"dev": "vite",
|
|
44
|
+
"build": "npm run typecheck && vite build",
|
|
45
|
+
"preview": "vite preview",
|
|
46
|
+
"test": "vitest run",
|
|
47
|
+
"typecheck": "tsc -p tsconfig.json && tsc -p tsconfig.node.json",
|
|
48
|
+
"lint": "eslint .",
|
|
49
|
+
"lint:fix": "eslint . --fix",
|
|
50
|
+
"format": "prettier --write .",
|
|
51
|
+
"format:check": "prettier --check .",
|
|
52
|
+
"size": "node scripts/check-bundle-size.mjs",
|
|
53
|
+
"icons:azure": "node scripts/build-azure-icons.mjs",
|
|
54
|
+
"icons:index": "node scripts/build-icon-index.mjs",
|
|
55
|
+
"audit": "node scripts/audit-gate.mjs",
|
|
56
|
+
"sbom": "node scripts/sbom.mjs",
|
|
57
|
+
"notices:check": "node scripts/sbom.mjs && node scripts/check-notices.mjs",
|
|
58
|
+
"notices:update": "node scripts/sbom.mjs && node scripts/update-notices.mjs",
|
|
59
|
+
"mcp": "tsx mcp/server.ts",
|
|
60
|
+
"mcp:smoke": "tsx mcp/smoke.ts",
|
|
61
|
+
"test:e2e:export": "tsx tests/e2e-export.mts",
|
|
62
|
+
"test:e2e:i18n": "tsx tests/e2e-i18n-export.mts",
|
|
63
|
+
"test:e2e:a11y": "tsx tests/e2e-a11y.mts",
|
|
64
|
+
"test:e2e:rtl": "tsx tests/e2e-rtl.mts",
|
|
65
|
+
"test:e2e:csp": "tsx tests/e2e-csp.mts",
|
|
66
|
+
"test:e2e:drag": "tsx tests/e2e-drag.mts",
|
|
67
|
+
"test:e2e:waypoints": "tsx tests/e2e-waypoints.mts",
|
|
68
|
+
"test:e2e:sequence": "tsx tests/e2e-sequence.mts",
|
|
69
|
+
"test:e2e:architecture": "tsx tests/e2e-architecture.mts",
|
|
70
|
+
"test:e2e:resize": "tsx tests/e2e-resize.mts",
|
|
71
|
+
"test:e2e:watch": "tsx tests/e2e-watch.mts",
|
|
72
|
+
"test:e2e:panel": "tsx tests/e2e-panel.mts",
|
|
73
|
+
"test:e2e:icons": "tsx tests/e2e-icons.mts",
|
|
74
|
+
"test:e2e:import": "tsx tests/e2e-import.mts",
|
|
75
|
+
"start": "node bin/archyne.mjs",
|
|
76
|
+
"prepublishOnly": "npm run build",
|
|
77
|
+
"desktop": "electron desktop/main.cjs",
|
|
78
|
+
"desktop:build": "npm run build && electron-builder --win"
|
|
79
|
+
},
|
|
80
|
+
"dependencies": {
|
|
81
|
+
"@codemirror/theme-one-dark": "^6.1.3",
|
|
82
|
+
"@iconify-json/carbon": "^1.2.24",
|
|
83
|
+
"@iconify-json/devicon": "^1.2.62",
|
|
84
|
+
"@iconify-json/logos": "^1.2.11",
|
|
85
|
+
"@iconify-json/simple-icons": "^1.2.92",
|
|
86
|
+
"@iconify-json/tabler": "^1.2.38",
|
|
87
|
+
"@iconify/utils": "^3.1.4",
|
|
88
|
+
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
89
|
+
"@xyflow/react": "^12.8.0",
|
|
90
|
+
"codemirror": "^6.0.2",
|
|
91
|
+
"codemirror-lang-mermaid": "^0.5.0",
|
|
92
|
+
"elkjs": "^0.12.0",
|
|
93
|
+
"fflate": "^0.8.3",
|
|
94
|
+
"html-to-image": "^1.11.13",
|
|
95
|
+
"mermaid": "^11.9.0",
|
|
96
|
+
"react": "^19.1.0",
|
|
97
|
+
"react-dom": "^19.1.0",
|
|
98
|
+
"tsx": "^4.23.1",
|
|
99
|
+
"zod": "^4.4.3",
|
|
100
|
+
"zustand": "^5.0.0"
|
|
101
|
+
},
|
|
102
|
+
"devDependencies": {
|
|
103
|
+
"@eslint/js": "^9.39.5",
|
|
104
|
+
"@testing-library/react": "^16.3.2",
|
|
105
|
+
"@testing-library/user-event": "^14.6.1",
|
|
106
|
+
"@types/jsdom": "^28.0.3",
|
|
107
|
+
"@types/node": "^26.1.2",
|
|
108
|
+
"@types/react": "^19.1.0",
|
|
109
|
+
"@types/react-dom": "^19.1.0",
|
|
110
|
+
"@vitejs/plugin-react": "^4.5.0",
|
|
111
|
+
"axe-core": "^4.12.1",
|
|
112
|
+
"electron": "^43.2.0",
|
|
113
|
+
"electron-builder": "^26.15.3",
|
|
114
|
+
"eslint": "^9.39.5",
|
|
115
|
+
"eslint-config-prettier": "^10.1.8",
|
|
116
|
+
"eslint-plugin-jsx-a11y": "^6.10.2",
|
|
117
|
+
"eslint-plugin-react-hooks": "^7.1.1",
|
|
118
|
+
"eslint-plugin-react-refresh": "^0.5.3",
|
|
119
|
+
"globals": "^17.8.0",
|
|
120
|
+
"jsdom": "^30.0.1",
|
|
121
|
+
"playwright": "^1.62.1",
|
|
122
|
+
"prettier": "^3.9.6",
|
|
123
|
+
"typescript": "~5.8.0",
|
|
124
|
+
"typescript-eslint": "^8.65.0",
|
|
125
|
+
"vite": "^6.3.0",
|
|
126
|
+
"vitest": "^4.1.10"
|
|
127
|
+
},
|
|
128
|
+
"description": "A visual editor for Mermaid diagrams — draw, and get Mermaid code",
|
|
129
|
+
"author": {
|
|
130
|
+
"name": "dariodd",
|
|
131
|
+
"email": "57635667+dariodd@users.noreply.github.com",
|
|
132
|
+
"url": "https://github.com/dariodd"
|
|
133
|
+
}
|
|
134
|
+
}
|
package/desktop/main.cjs
DELETED
|
@@ -1,378 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Archyne desktop shell: a thin Electron window around the static build.
|
|
3
|
-
*
|
|
4
|
-
* Everything still runs locally in the renderer — no backend. The shell
|
|
5
|
-
* reaches the network in exactly one place, `archyne:fetch-icons`, and only
|
|
6
|
-
* because a link the user pasted asked it to; see the notes there.
|
|
7
|
-
*/
|
|
8
|
-
const { app, BrowserWindow, dialog, ipcMain, nativeTheme, shell } = require("electron");
|
|
9
|
-
const path = require("node:path");
|
|
10
|
-
const fs = require("node:fs");
|
|
11
|
-
const fsp = require("node:fs/promises");
|
|
12
|
-
const { unzipSync } = require("fflate");
|
|
13
|
-
|
|
14
|
-
/**
|
|
15
|
-
* .mmd file passed on the command line (double-click / "open with").
|
|
16
|
-
* @param {string[]} argv
|
|
17
|
-
* @returns {string | undefined}
|
|
18
|
-
*/
|
|
19
|
-
function fileArg(argv) {
|
|
20
|
-
// `.xml` is deliberately not here: the installer associates `.mmd`, and
|
|
21
|
-
// picking up any stray XML on the command line would be a surprise. A
|
|
22
|
-
// draw.io file named `.xml` can still be opened from the dialog.
|
|
23
|
-
const openable =
|
|
24
|
-
/\.(mmd|mermaid|drawio|vsdx|dot|gv|sql|ddl|excalidraw|puml|plantuml|iuml|wsd)$/i;
|
|
25
|
-
return argv.find((a) => openable.test(a) && fs.existsSync(a));
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* File the app was launched with, handed to the renderer over IPC once it
|
|
30
|
-
* asks. Passing it through the URL — as this used to — broke on large
|
|
31
|
-
* diagrams and lost the path, so saving could never write back to it.
|
|
32
|
-
* @type {string | undefined}
|
|
33
|
-
*/
|
|
34
|
-
let pendingFile;
|
|
35
|
-
|
|
36
|
-
const FILTERS = [
|
|
37
|
-
{ name: "Mermaid diagram", extensions: ["mmd", "mermaid"] },
|
|
38
|
-
{ name: "All files", extensions: ["*"] },
|
|
39
|
-
];
|
|
40
|
-
|
|
41
|
-
const IMPORTABLE = [
|
|
42
|
-
"drawio",
|
|
43
|
-
"xml",
|
|
44
|
-
"vsdx",
|
|
45
|
-
"dot",
|
|
46
|
-
"gv",
|
|
47
|
-
"sql",
|
|
48
|
-
"ddl",
|
|
49
|
-
"excalidraw",
|
|
50
|
-
"puml",
|
|
51
|
-
"plantuml",
|
|
52
|
-
"iuml",
|
|
53
|
-
"wsd",
|
|
54
|
-
];
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* What **Import** offers. Open shows `FILTERS` instead: opening a file means
|
|
58
|
-
* editing it and saving it back, and none of these is ever written back — the
|
|
59
|
-
* renderer converts it and unbinds it from its source, so Save always writes
|
|
60
|
-
* Mermaid.
|
|
61
|
-
*/
|
|
62
|
-
const IMPORT_FILTERS = [
|
|
63
|
-
{ name: "Any importable drawing", extensions: IMPORTABLE },
|
|
64
|
-
{ name: "draw.io diagram", extensions: ["drawio", "xml"] },
|
|
65
|
-
{ name: "Visio drawing", extensions: ["vsdx"] },
|
|
66
|
-
{ name: "Graphviz DOT", extensions: ["dot", "gv"] },
|
|
67
|
-
{ name: "SQL schema", extensions: ["sql", "ddl"] },
|
|
68
|
-
{ name: "PlantUML sequence", extensions: ["puml", "plantuml", "iuml", "wsd"] },
|
|
69
|
-
{ name: "Excalidraw scene", extensions: ["excalidraw"] },
|
|
70
|
-
{ name: "All files", extensions: ["*"] },
|
|
71
|
-
];
|
|
72
|
-
|
|
73
|
-
/** @param {string} [openFile] */
|
|
74
|
-
function createWindow(openFile) {
|
|
75
|
-
if (openFile) pendingFile = openFile;
|
|
76
|
-
|
|
77
|
-
const win = new BrowserWindow({
|
|
78
|
-
width: 1440,
|
|
79
|
-
height: 920,
|
|
80
|
-
// The layout now collapses the palette and side panel into drawers below
|
|
81
|
-
// 900px, so the window no longer has to stay that wide to be usable.
|
|
82
|
-
minWidth: 680,
|
|
83
|
-
minHeight: 520,
|
|
84
|
-
backgroundColor: "#12141a",
|
|
85
|
-
autoHideMenuBar: true,
|
|
86
|
-
icon: path.join(__dirname, "..", "build", "icon.png"),
|
|
87
|
-
webPreferences: {
|
|
88
|
-
contextIsolation: true,
|
|
89
|
-
nodeIntegration: false,
|
|
90
|
-
sandbox: true,
|
|
91
|
-
preload: path.join(__dirname, "preload.cjs"),
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
// External links open in the default browser, not in the app.
|
|
96
|
-
win.webContents.setWindowOpenHandler(({ url }) => {
|
|
97
|
-
void shell.openExternal(url);
|
|
98
|
-
return { action: "deny" };
|
|
99
|
-
});
|
|
100
|
-
|
|
101
|
-
void win.loadFile(path.join(__dirname, "..", "dist", "index.html"));
|
|
102
|
-
return win;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Read a file for the renderer; a failure surfaces as a rejected invoke.
|
|
107
|
-
* @param {string} filePath
|
|
108
|
-
*/
|
|
109
|
-
async function readFile(filePath) {
|
|
110
|
-
const buffer = await fsp.readFile(filePath);
|
|
111
|
-
// A Visio drawing is a zip, and decoding one as UTF-8 destroys it. Anything
|
|
112
|
-
// that opens with the zip signature crosses to the renderer as base64
|
|
113
|
-
// instead, and only the importers ever look at it.
|
|
114
|
-
const zip =
|
|
115
|
-
buffer.length > 3 &&
|
|
116
|
-
buffer[0] === 0x50 &&
|
|
117
|
-
buffer[1] === 0x4b &&
|
|
118
|
-
buffer[2] === 0x03 &&
|
|
119
|
-
buffer[3] === 0x04;
|
|
120
|
-
if (zip) return { path: filePath, content: "", base64: buffer.toString("base64") };
|
|
121
|
-
return { path: filePath, content: buffer.toString("utf8") };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
/**
|
|
125
|
-
* Downloading icons — the shell's one outward call, and the reason it exists
|
|
126
|
-
* here rather than in the page.
|
|
127
|
-
*
|
|
128
|
-
* A browser cannot fetch a vendor's icon pack: the file is a `.zip`, and the
|
|
129
|
-
* host does not permit cross-origin reads. The shell is under neither
|
|
130
|
-
* restriction, so this is where "paste the link to the Azure pack" actually
|
|
131
|
-
* works. That capability is worth fencing:
|
|
132
|
-
*
|
|
133
|
-
* - https only, and never at the machine or the network it is running on. A
|
|
134
|
-
* renderer bug that reached this handler must not be able to use the shell
|
|
135
|
-
* as a probe for whatever is on the user's LAN.
|
|
136
|
-
* - What comes back is bytes, not trust. The renderer sanitises every SVG
|
|
137
|
-
* before it is stored or drawn, exactly as it does for a file from disk.
|
|
138
|
-
* - Sizes are capped at every step, because a zip is an invitation to send
|
|
139
|
-
* far more than was asked for.
|
|
140
|
-
*/
|
|
141
|
-
const MAX_DOWNLOAD_BYTES = 64_000_000;
|
|
142
|
-
const MAX_ICON_BYTES = 512_000;
|
|
143
|
-
const MAX_ICONS = 800;
|
|
144
|
-
const MAX_LINKS = 200;
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Whether a hostname points at this machine or the network it sits on.
|
|
148
|
-
*
|
|
149
|
-
* Not a complete defence — a name that resolves to a private address passes
|
|
150
|
-
* this, and only the operating system knows for certain — but it refuses the
|
|
151
|
-
* forms anyone would actually reach for.
|
|
152
|
-
* @param {string} hostname
|
|
153
|
-
*/
|
|
154
|
-
function reachesLocalNetwork(hostname) {
|
|
155
|
-
const host = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
156
|
-
if (host.includes(":")) {
|
|
157
|
-
// IPv6: loopback, link-local, and the unique-local block.
|
|
158
|
-
return host === "::1" || host.startsWith("fe80:") || /^f[cd]/.test(host);
|
|
159
|
-
}
|
|
160
|
-
return (
|
|
161
|
-
host === "localhost" ||
|
|
162
|
-
host.endsWith(".localhost") ||
|
|
163
|
-
host.endsWith(".local") ||
|
|
164
|
-
host.endsWith(".internal") ||
|
|
165
|
-
host === "0.0.0.0" ||
|
|
166
|
-
/^127\./.test(host) ||
|
|
167
|
-
/^10\./.test(host) ||
|
|
168
|
-
/^192\.168\./.test(host) ||
|
|
169
|
-
/^169\.254\./.test(host) ||
|
|
170
|
-
/^172\.(1[6-9]|2\d|3[01])\./.test(host)
|
|
171
|
-
);
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Fetch a URL, refusing to hold more than the cap.
|
|
176
|
-
*
|
|
177
|
-
* Read in chunks rather than in one `arrayBuffer()`: a server that declares
|
|
178
|
-
* no length, or lies about it, would otherwise decide how much memory this
|
|
179
|
-
* process uses.
|
|
180
|
-
* @param {URL} url
|
|
181
|
-
* @returns {Promise<Buffer | null>}
|
|
182
|
-
*/
|
|
183
|
-
async function download(url) {
|
|
184
|
-
const res = await fetch(url, { redirect: "follow" });
|
|
185
|
-
if (!res.ok || !res.body) return null;
|
|
186
|
-
|
|
187
|
-
const declared = Number(res.headers.get("content-length"));
|
|
188
|
-
if (Number.isFinite(declared) && declared > MAX_DOWNLOAD_BYTES) return null;
|
|
189
|
-
|
|
190
|
-
const reader = res.body.getReader();
|
|
191
|
-
const chunks = [];
|
|
192
|
-
let total = 0;
|
|
193
|
-
for (;;) {
|
|
194
|
-
const { done, value } = await reader.read();
|
|
195
|
-
if (done) break;
|
|
196
|
-
total += value.length;
|
|
197
|
-
if (total > MAX_DOWNLOAD_BYTES) {
|
|
198
|
-
// Stop the transfer rather than draining it politely.
|
|
199
|
-
await reader.cancel();
|
|
200
|
-
return null;
|
|
201
|
-
}
|
|
202
|
-
chunks.push(value);
|
|
203
|
-
}
|
|
204
|
-
return Buffer.concat(chunks);
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
/**
|
|
208
|
-
* A zip begins `PK`; a vendor's pack is one, a single icon is not.
|
|
209
|
-
* @param {Buffer} buffer
|
|
210
|
-
*/
|
|
211
|
-
function looksZipped(buffer) {
|
|
212
|
-
return buffer.length > 4 && buffer[0] === 0x50 && buffer[1] === 0x4b;
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/**
|
|
216
|
-
* Every SVG in a zip, keeping the folders it arrived in.
|
|
217
|
-
*
|
|
218
|
-
* The path is not decoration: the renderer reads the vendor off it, so
|
|
219
|
-
* `Azure_Public_Service_Icons/Icons/networking/…` is filed under Azure and
|
|
220
|
-
* not into one undifferentiated heap. It reduces the path to a name itself.
|
|
221
|
-
* @param {Buffer} buffer
|
|
222
|
-
*/
|
|
223
|
-
function iconsFromZip(buffer) {
|
|
224
|
-
let taken = 0;
|
|
225
|
-
const files = unzipSync(buffer, {
|
|
226
|
-
// Decided before decompression, so an entry that claims to be enormous
|
|
227
|
-
// is never expanded.
|
|
228
|
-
filter: (file) => {
|
|
229
|
-
if (taken >= MAX_ICONS) return false;
|
|
230
|
-
if (!file.name.toLowerCase().endsWith(".svg")) return false;
|
|
231
|
-
if (file.originalSize > MAX_ICON_BYTES) return false;
|
|
232
|
-
taken++;
|
|
233
|
-
return true;
|
|
234
|
-
},
|
|
235
|
-
});
|
|
236
|
-
return Object.entries(files).map(([name, bytes]) => ({
|
|
237
|
-
name,
|
|
238
|
-
svg: Buffer.from(bytes).toString("utf8"),
|
|
239
|
-
}));
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
function registerIpc() {
|
|
243
|
-
// The renderer's theme is CSS, which reaches only what the page paints. The
|
|
244
|
-
// widgets Chromium draws itself — the option list a <select> pops up, the
|
|
245
|
-
// native dialogs, the scrollbars — follow the *app's* theme, and that
|
|
246
|
-
// defaults to whatever Windows is set to. A dark Archyne on a light Windows
|
|
247
|
-
// therefore opened a white option list. Told here, they match the app.
|
|
248
|
-
ipcMain.on("archyne:set-theme", (_event, theme) => {
|
|
249
|
-
nativeTheme.themeSource = theme === "light" ? "light" : "dark";
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
ipcMain.handle("archyne:opened-file", async () => {
|
|
253
|
-
if (!pendingFile) return null;
|
|
254
|
-
const filePath = pendingFile;
|
|
255
|
-
pendingFile = undefined; // hand it over exactly once
|
|
256
|
-
return readFile(filePath);
|
|
257
|
-
});
|
|
258
|
-
|
|
259
|
-
ipcMain.handle("archyne:show-open", async (event, arg) => {
|
|
260
|
-
// The sender's window can already be gone if the user closed it mid-call;
|
|
261
|
-
// fall back to an app-modal dialog rather than crashing.
|
|
262
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
263
|
-
// Import offers the foreign formats; Open offers only what Save writes.
|
|
264
|
-
const filters = arg && arg.mode === "import" ? IMPORT_FILTERS : FILTERS;
|
|
265
|
-
/** @type {import("electron").OpenDialogOptions} */
|
|
266
|
-
const options = { properties: ["openFile"], filters };
|
|
267
|
-
const { canceled, filePaths } = win
|
|
268
|
-
? await dialog.showOpenDialog(win, options)
|
|
269
|
-
: await dialog.showOpenDialog(options);
|
|
270
|
-
if (canceled || filePaths.length === 0) return null;
|
|
271
|
-
return readFile(filePaths[0]);
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
ipcMain.handle("archyne:show-save", async (event, { defaultPath, content }) => {
|
|
275
|
-
const win = BrowserWindow.fromWebContents(event.sender);
|
|
276
|
-
const options = { defaultPath, filters: FILTERS };
|
|
277
|
-
const { canceled, filePath } = win
|
|
278
|
-
? await dialog.showSaveDialog(win, options)
|
|
279
|
-
: await dialog.showSaveDialog(options);
|
|
280
|
-
if (canceled || !filePath) return null;
|
|
281
|
-
await fsp.writeFile(filePath, content, "utf8");
|
|
282
|
-
return filePath;
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
// Reading a file the renderer already holds a path for: no dialog, and no
|
|
286
|
-
// new capability — the path can only have come from an open or save the
|
|
287
|
-
// user went through.
|
|
288
|
-
ipcMain.handle("archyne:stat-file", async (_event, { path: filePath }) => {
|
|
289
|
-
try {
|
|
290
|
-
const stat = await fsp.stat(filePath);
|
|
291
|
-
return { mtimeMs: stat.mtimeMs };
|
|
292
|
-
} catch {
|
|
293
|
-
return null; // moved, deleted, or being written to
|
|
294
|
-
}
|
|
295
|
-
});
|
|
296
|
-
|
|
297
|
-
ipcMain.handle("archyne:read-file", async (_event, { path: filePath }) => {
|
|
298
|
-
try {
|
|
299
|
-
return await fsp.readFile(filePath, "utf8");
|
|
300
|
-
} catch {
|
|
301
|
-
return null;
|
|
302
|
-
}
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
ipcMain.handle("archyne:write-file", async (_event, { path: filePath, content }) => {
|
|
306
|
-
await fsp.writeFile(filePath, content, "utf8");
|
|
307
|
-
});
|
|
308
|
-
|
|
309
|
-
// Icons from pasted links: one `.svg`, or a vendor's whole `.zip`. See the
|
|
310
|
-
// notes above `MAX_DOWNLOAD_BYTES` for what this is allowed to reach.
|
|
311
|
-
ipcMain.handle("archyne:fetch-icons", async (_event, { urls }) => {
|
|
312
|
-
const icons = [];
|
|
313
|
-
const failed = [];
|
|
314
|
-
|
|
315
|
-
for (const link of (Array.isArray(urls) ? urls : []).slice(0, MAX_LINKS)) {
|
|
316
|
-
try {
|
|
317
|
-
const url = new URL(String(link));
|
|
318
|
-
if (url.protocol !== "https:" || reachesLocalNetwork(url.hostname)) {
|
|
319
|
-
failed.push(link);
|
|
320
|
-
continue;
|
|
321
|
-
}
|
|
322
|
-
|
|
323
|
-
const body = await download(url);
|
|
324
|
-
if (!body) {
|
|
325
|
-
failed.push(link);
|
|
326
|
-
continue;
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
const got = looksZipped(body)
|
|
330
|
-
? iconsFromZip(body)
|
|
331
|
-
: [{ name: decodeURIComponent(url.pathname), svg: body.toString("utf8") }];
|
|
332
|
-
if (got.length === 0) failed.push(link);
|
|
333
|
-
else icons.push(...got);
|
|
334
|
-
} catch {
|
|
335
|
-
// Unreachable, malformed, not a zip after all: the renderer only
|
|
336
|
-
// needs to know which links produced nothing.
|
|
337
|
-
failed.push(link);
|
|
338
|
-
}
|
|
339
|
-
if (icons.length >= MAX_ICONS) break;
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
return { icons: icons.slice(0, MAX_ICONS), failed };
|
|
343
|
-
});
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
const gotLock = app.requestSingleInstanceLock();
|
|
347
|
-
if (!gotLock) {
|
|
348
|
-
app.quit();
|
|
349
|
-
} else {
|
|
350
|
-
app.on("second-instance", (_e, argv) => {
|
|
351
|
-
const file = fileArg(argv.slice(1));
|
|
352
|
-
const [existing] = BrowserWindow.getAllWindows();
|
|
353
|
-
if (existing) {
|
|
354
|
-
// Reuse the running window rather than stacking another one up.
|
|
355
|
-
if (existing.isMinimized()) existing.restore();
|
|
356
|
-
existing.focus();
|
|
357
|
-
if (file) {
|
|
358
|
-
void readFile(file).then((payload) =>
|
|
359
|
-
existing.webContents.send("archyne:open-file", payload),
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
return;
|
|
363
|
-
}
|
|
364
|
-
createWindow(file);
|
|
365
|
-
});
|
|
366
|
-
|
|
367
|
-
void app.whenReady().then(() => {
|
|
368
|
-
registerIpc();
|
|
369
|
-
createWindow(fileArg(process.argv.slice(1)));
|
|
370
|
-
app.on("activate", () => {
|
|
371
|
-
if (BrowserWindow.getAllWindows().length === 0) createWindow();
|
|
372
|
-
});
|
|
373
|
-
});
|
|
374
|
-
|
|
375
|
-
app.on("window-all-closed", () => {
|
|
376
|
-
if (process.platform !== "darwin") app.quit();
|
|
377
|
-
});
|
|
378
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{U as a,D as n}from"./mermaid.core-cnu9Hu0H.js";const t=(r,o)=>a.lang.round(n.parse(r)[o]);export{t as c};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-wHUCmL_g.js";import{_ as i}from"./mermaid.core-cnu9Hu0H.js";import"./index-D2iswyef.js";import"./chunk-5VM5RSS4-Doshgyjn.js";import"./chunk-XXDRQBXY-DTNNhjpS.js";import"./chunk-KBJHAD2P-JqxcXows.js";import"./chunk-2GRJ4B5K-DrxYcIKi.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-wHUCmL_g.js";import{_ as i}from"./mermaid.core-cnu9Hu0H.js";import"./index-D2iswyef.js";import"./chunk-5VM5RSS4-Doshgyjn.js";import"./chunk-XXDRQBXY-DTNNhjpS.js";import"./chunk-KBJHAD2P-JqxcXows.js";import"./chunk-2GRJ4B5K-DrxYcIKi.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
|