diff --git a/.build/jsonSchema.ts b/.build/jsonSchema.ts
index 6fd8ca3f54..50b9ff097b 100644
--- a/.build/jsonSchema.ts
+++ b/.build/jsonSchema.ts
@@ -25,6 +25,7 @@ const MERMAID_CONFIG_DIAGRAM_KEYS = [
'sankey',
'block',
'packet',
+ 'architecture',
] as const;
/**
diff --git a/.changeset/famous-bananas-join.md b/.changeset/famous-bananas-join.md
new file mode 100644
index 0000000000..48c29a8ad6
--- /dev/null
+++ b/.changeset/famous-bananas-join.md
@@ -0,0 +1,6 @@
+---
+'mermaid': patch
+---
+
+Fix for self loops in cluster
+Supporting legacy defaultRenderer directive
diff --git a/.changeset/khaki-items-leave.md b/.changeset/khaki-items-leave.md
new file mode 100644
index 0000000000..d84776eb24
--- /dev/null
+++ b/.changeset/khaki-items-leave.md
@@ -0,0 +1,5 @@
+---
+'mermaid': minor
+---
+
+feat(er): allow multi-line relationship labels
diff --git a/.changeset/nice-flowers-yawn.md b/.changeset/nice-flowers-yawn.md
new file mode 100644
index 0000000000..b3c00cfb41
--- /dev/null
+++ b/.changeset/nice-flowers-yawn.md
@@ -0,0 +1,9 @@
+---
+'mermaid': minor
+'@mermaid-js/docs': patch
+'@mermaid-js/parser': minor
+---
+
+New Diagram: Architecture
+
+Adds architecture diagrams which allows users to show relations between services.
diff --git a/.changeset/pants-things-go.md b/.changeset/pants-things-go.md
new file mode 100644
index 0000000000..559e572d16
--- /dev/null
+++ b/.changeset/pants-things-go.md
@@ -0,0 +1,6 @@
+---
+'@mermaid-js/layout-elk': patch
+---
+
+fix: Updates to the default elk configuration
+feat: exposing cycleBreakingStrategy to the configuration so that it can be modified suing the configuration.
diff --git a/.changeset/silly-apples-glow.md b/.changeset/silly-apples-glow.md
new file mode 100644
index 0000000000..c06b1590dd
--- /dev/null
+++ b/.changeset/silly-apples-glow.md
@@ -0,0 +1,5 @@
+---
+'mermaid': patch
+---
+
+chore: Move icons to architecture, remove full icon sets to reduce bundle size
diff --git a/.cspell/code-terms.txt b/.cspell/code-terms.txt
index 6d6dad045b..8e4c02261a 100644
--- a/.cspell/code-terms.txt
+++ b/.cspell/code-terms.txt
@@ -55,6 +55,7 @@ GENERICTYPE
getBoundarys
grammr
graphtype
+halign
iife
interp
introdcued
@@ -66,6 +67,7 @@ Kaufmann
keyify
LABELPOS
LABELTYPE
+layoutstop
lcov
LEFTOF
Lexa
@@ -138,6 +140,7 @@ tsdoc
typeof
typestr
unshift
+urlsafe
verifymethod
VERIFYMTHD
WARN_DOCSDIR_DOESNT_MATCH
diff --git a/.cspell/libraries.txt b/.cspell/libraries.txt
index 3bfec1d5f4..ad0e3e7011 100644
--- a/.cspell/libraries.txt
+++ b/.cspell/libraries.txt
@@ -24,6 +24,7 @@ Doctave
DokuWiki
dompurify
elkjs
+fcose
fontawesome
Foswiki
Gitea
diff --git a/.cspell/mermaid-terms.txt b/.cspell/mermaid-terms.txt
index 46ad6dddb1..59a3d108fb 100644
--- a/.cspell/mermaid-terms.txt
+++ b/.cspell/mermaid-terms.txt
@@ -1,5 +1,6 @@
Adamiecki
arrowend
+Bendpoints
bmatrix
braintree
catmull
diff --git a/.cspell/misc-terms.txt b/.cspell/misc-terms.txt
index 3fc0943094..1820e3c863 100644
--- a/.cspell/misc-terms.txt
+++ b/.cspell/misc-terms.txt
@@ -4,3 +4,4 @@ handDrawn
KOEPF
neato
newbranch
+validify
diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml
index f26bf4ab89..6a43791ed3 100644
--- a/.github/workflows/autofix.yml
+++ b/.github/workflows/autofix.yml
@@ -7,17 +7,19 @@ on:
permissions:
contents: read
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
jobs:
autofix:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
# uses version from "packageManager" field in package.json
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -40,4 +42,4 @@ jobs:
working-directory: ./packages/mermaid
run: pnpm run docs:build
- - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c
+ - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c # main
diff --git a/.github/workflows/build-docs.yml b/.github/workflows/build-docs.yml
index 0ce7789573..eb0c4594a6 100644
--- a/.github/workflows/build-docs.yml
+++ b/.github/workflows/build-docs.yml
@@ -8,6 +8,8 @@ on:
pull_request:
merge_group:
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
permissions:
contents: read
@@ -16,12 +18,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
deleted file mode 100644
index c6e96912ef..0000000000
--- a/.github/workflows/build.yml
+++ /dev/null
@@ -1,49 +0,0 @@
-name: Build
-
-on:
- push: {}
- merge_group:
- pull_request:
- types:
- - opened
- - synchronize
- - ready_for_review
-
-permissions:
- contents: read
-
-jobs:
- build-mermaid:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
-
- - uses: pnpm/action-setup@v4
- # uses version from "packageManager" field in package.json
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- cache: pnpm
- node-version-file: '.node-version'
-
- - name: Install Packages
- run: |
- pnpm install --frozen-lockfile
- env:
- CYPRESS_CACHE_FOLDER: .cache/Cypress
-
- - name: Run Build
- run: pnpm run build
-
- - name: Upload Mermaid Build as Artifact
- uses: actions/upload-artifact@v4
- with:
- name: mermaid-build
- path: packages/mermaid/dist
-
- - name: Upload Mermaid Mindmap Build as Artifact
- uses: actions/upload-artifact@v4
- with:
- name: mermaid-mindmap-build
- path: packages/mermaid-mindmap/dist
diff --git a/.github/workflows/check-readme-in-sync.yml b/.github/workflows/check-readme-in-sync.yml
index ad6df66b50..5c940c0875 100644
--- a/.github/workflows/check-readme-in-sync.yml
+++ b/.github/workflows/check-readme-in-sync.yml
@@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Check for difference in README.md and docs/README.md
run: |
diff --git a/.github/workflows/checks.yml b/.github/workflows/checks.yml
deleted file mode 100644
index 012fbf19d5..0000000000
--- a/.github/workflows/checks.yml
+++ /dev/null
@@ -1,26 +0,0 @@
-on:
- push:
- merge_group:
- pull_request:
- types:
- - opened
- - synchronize
- - ready_for_review
-
-name: Static analysis on Test files
-
-jobs:
- check-tests:
- runs-on: ubuntu-latest
- name: check tests
- if: github.repository_owner == 'mermaid-js'
- steps:
- - uses: actions/checkout@v4
- with:
- fetch-depth: 0
- - uses: testomatio/check-tests@stable
- with:
- framework: cypress
- tests: './cypress/e2e/**/**.spec.js'
- token: ${{ secrets.GITHUB_TOKEN }}
- has-tests-label: true
diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml
index 764ec598cb..65962ce643 100644
--- a/.github/workflows/codeql.yml
+++ b/.github/workflows/codeql.yml
@@ -11,6 +11,9 @@ on:
- synchronize
- ready_for_review
+permissions: # added using https://github.com/step-security/secure-repo
+ contents: read
+
jobs:
analyze:
name: Analyze
@@ -29,11 +32,11 @@ jobs:
steps:
- name: Checkout repository
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
- uses: github/codeql-action/init@v3
+ uses: github/codeql-action/init@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
with:
config-file: ./.github/codeql/codeql-config.yml
languages: ${{ matrix.language }}
@@ -45,7 +48,7 @@ jobs:
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
# If this step fails, then you should remove it and run the build manually (see below)
- name: Autobuild
- uses: github/codeql-action/autobuild@v3
+ uses: github/codeql-action/autobuild@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
# ā¹ļø Command-line programs to run using the OS shell.
# š See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
@@ -59,4 +62,4 @@ jobs:
# make release
- name: Perform CodeQL Analysis
- uses: github/codeql-action/analyze@v3
+ uses: github/codeql-action/analyze@2c779ab0d087cd7fe7b826087247c2c81f27bfa6 # v3.26.5
diff --git a/.github/workflows/dependency-review.yml b/.github/workflows/dependency-review.yml
index 0d4a01360d..521735e6e5 100644
--- a/.github/workflows/dependency-review.yml
+++ b/.github/workflows/dependency-review.yml
@@ -15,6 +15,6 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: 'Checkout Repository'
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: 'Dependency Review'
- uses: actions/dependency-review-action@v4
+ uses: actions/dependency-review-action@5a2ce3f5b92ee19cbb1541a4984c76d921601d7c # v4.3.4
diff --git a/.github/workflows/e2e-applitools.yml b/.github/workflows/e2e-applitools.yml
index 5e5407a23b..6da65afe5c 100644
--- a/.github/workflows/e2e-applitools.yml
+++ b/.github/workflows/e2e-applitools.yml
@@ -11,6 +11,8 @@ on:
default: master
description: 'Parent branch to use for PRs'
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
permissions:
contents: read
@@ -30,13 +32,13 @@ jobs:
run: |
echo "::error,title=Not using Applitools::APPLITOOLS_API_KEY is empty, disabling Applitools for this run."
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
# uses version from "packageManager" field in package.json
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version-file: '.node-version'
@@ -52,7 +54,7 @@ jobs:
APPLITOOLS_SERVER_URL: 'https://eyesapi.applitools.com'
- name: Cypress run
- uses: cypress-io/github-action@v4
+ uses: cypress-io/github-action@d79d2d530a66e641eb4a5f227e13bc985c60b964 # v4.2.2
id: cypress
with:
start: pnpm run dev
diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml
index 2600b3fb84..2b91d078e5 100644
--- a/.github/workflows/e2e.yml
+++ b/.github/workflows/e2e.yml
@@ -2,11 +2,15 @@ name: E2E
on:
push:
- branches-ignore:
- - 'gh-readonly-queue/**'
+ branches:
+ - develop
+ - master
+ - release/**
pull_request:
merge_group:
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
permissions:
contents: read
@@ -32,15 +36,15 @@ jobs:
image: cypress/browsers:node-20.11.0-chrome-121.0.6167.85-1-ff-120.0-edge-121.0.2277.83-1
options: --user 1001
steps:
- - uses: actions/checkout@v4
- - uses: pnpm/action-setup@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version-file: '.node-version'
- name: Cache snapshots
id: cache-snapshot
- uses: actions/cache@v4
+ uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
save-always: true
path: ./cypress/snapshots
@@ -49,13 +53,13 @@ jobs:
# If a snapshot for a given Hash is not found, we checkout that commit, run the tests and cache the snapshots.
- name: Switch to base branch
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ env.targetHash }}
- name: Install dependencies
if: ${{ steps.cache-snapshot.outputs.cache-hit != 'true' }}
- uses: cypress-io/github-action@v6
+ uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2
with:
# just perform install
runTests: false
@@ -78,26 +82,26 @@ jobs:
matrix:
containers: [1, 2, 3, 4]
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
# uses version from "packageManager" field in package.json
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version-file: '.node-version'
# These cached snapshots are downloaded, providing the reference snapshots.
- name: Cache snapshots
id: cache-snapshot
- uses: actions/cache/restore@v4
+ uses: actions/cache/restore@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: ./cypress/snapshots
key: ${{ runner.os }}-snapshots-${{ env.targetHash }}
- name: Install dependencies
- uses: cypress-io/github-action@v6
+ uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2
with:
runTests: false
@@ -113,7 +117,7 @@ jobs:
# Install NPM dependencies, cache them correctly
# and run all Cypress tests
- name: Cypress run
- uses: cypress-io/github-action@v6
+ uses: cypress-io/github-action@df7484c5ba85def7eef30db301afa688187bc378 # v6.7.2
id: cypress
# If CYPRESS_RECORD_KEY is set, run in parallel on all containers
# Otherwise (e.g. if running from fork), we run on a single container only
@@ -137,7 +141,7 @@ jobs:
ARGOS_PARALLEL_INDEX: ${{ matrix.containers }}
- name: Upload Coverage to Codecov
- uses: codecov/codecov-action@v4
+ uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
# Run step only pushes to develop and pull_requests
if: ${{ steps.cypress.conclusion == 'success' && (github.event_name == 'pull_request' || github.ref == 'refs/heads/develop')}}
with:
diff --git a/.github/workflows/issue-triage.yml b/.github/workflows/issue-triage.yml
index 129bd62b67..87a6e958b2 100644
--- a/.github/workflows/issue-triage.yml
+++ b/.github/workflows/issue-triage.yml
@@ -4,11 +4,17 @@ on:
issues:
types: [opened]
+permissions: # added using https://github.com/step-security/secure-repo
+ contents: read
+
jobs:
triage:
+ permissions:
+ issues: write # for andymckay/labeler to label issues
+ pull-requests: write # for andymckay/labeler to label PRs
runs-on: ubuntu-latest
steps:
- - uses: andymckay/labeler@1.0.4
+ - uses: andymckay/labeler@e6c4322d0397f3240f0e7e30a33b5c5df2d39e90 # 1.0.4
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
add-labels: 'Status: Triage'
diff --git a/.github/workflows/link-checker.yml b/.github/workflows/link-checker.yml
index bf54d7df28..0a2b74dfe7 100644
--- a/.github/workflows/link-checker.yml
+++ b/.github/workflows/link-checker.yml
@@ -19,6 +19,9 @@ on:
# * is a special character in YAML so you have to quote this string
- cron: '30 8 * * *'
+permissions: # added using https://github.com/step-security/secure-repo
+ contents: read
+
jobs:
link-checker:
runs-on: ubuntu-latest
@@ -26,17 +29,17 @@ jobs:
# lychee only uses the GITHUB_TOKEN to avoid rate-limiting
contents: read
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Restore lychee cache
- uses: actions/cache@v4
+ uses: actions/cache@0c45773b623bea8c8e75f6c82b208c3cf94ea4f9 # v4.0.2
with:
path: .lycheecache
key: cache-lychee-${{ github.sha }}
restore-keys: cache-lychee-
- name: Link Checker
- uses: lycheeverse/lychee-action@v1.9.3
+ uses: lycheeverse/lychee-action@c053181aa0c3d17606addfe97a9075a32723548a # v1.9.3
with:
args: >-
--config .github/lychee.toml
diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml
index 632cd6ddc4..febd2f92de 100644
--- a/.github/workflows/lint.yml
+++ b/.github/workflows/lint.yml
@@ -4,26 +4,32 @@ on:
push:
merge_group:
pull_request:
- types:
- - opened
- - synchronize
- - ready_for_review
workflow_dispatch:
+concurrency: ${{ github.workflow }}-${{ github.ref }}
+
permissions:
contents: write
jobs:
+ docker-lint:
+ runs-on: ubuntu-latest
+ steps:
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+
+ - uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0
+ with:
+ verbose: true
lint:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
# uses version from "packageManager" field in package.json
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -82,3 +88,10 @@ jobs:
working-directory: ./packages/mermaid
continue-on-error: ${{ github.event_name == 'push' }}
run: pnpm run docs:verify
+
+ - uses: testomatio/check-tests@0ea638fcec1820cf2e7b9854fdbdd04128a55bd4 # stable
+ with:
+ framework: cypress
+ tests: './cypress/e2e/**/**.spec.js'
+ token: ${{ secrets.GITHUB_TOKEN }}
+ has-tests-label: true
diff --git a/.github/workflows/pr-labeler.yml b/.github/workflows/pr-labeler.yml
index 0965903467..c9faaa0620 100644
--- a/.github/workflows/pr-labeler.yml
+++ b/.github/workflows/pr-labeler.yml
@@ -22,7 +22,7 @@ jobs:
pull-requests: write # write permission is required to label PRs
steps:
- name: Label PR
- uses: release-drafter/release-drafter@v6
+ uses: release-drafter/release-drafter@3f0f87098bd6b5c5b9a36d49c41d998ea58f9348 # v6.0.0
with:
config-name: pr-labeler.yml
disable-autolabeler: false
diff --git a/.github/workflows/publish-docs.yml b/.github/workflows/publish-docs.yml
index 4ff5f41170..ecb411b5c6 100644
--- a/.github/workflows/publish-docs.yml
+++ b/.github/workflows/publish-docs.yml
@@ -23,12 +23,12 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout
- uses: actions/checkout@v4
+ uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -37,13 +37,13 @@ jobs:
run: pnpm install --frozen-lockfile
- name: Setup Pages
- uses: actions/configure-pages@v4
+ uses: actions/configure-pages@1f0c5cde4bc74cd7e1254d0cb4de8d49e9068c7d # v4.0.0
- name: Run Build
run: pnpm --filter mermaid run docs:build:vitepress
- name: Upload artifact
- uses: actions/upload-pages-artifact@v3
+ uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
with:
path: packages/mermaid/src/vitepress/.vitepress/dist
@@ -56,4 +56,4 @@ jobs:
steps:
- name: Deploy to GitHub Pages
id: deployment
- uses: actions/deploy-pages@v4
+ uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4.0.5
diff --git a/.github/workflows/release-preview-publish.yml b/.github/workflows/release-preview-publish.yml
index 91e3ac9813..96556aa262 100644
--- a/.github/workflows/release-preview-publish.yml
+++ b/.github/workflows/release-preview-publish.yml
@@ -9,14 +9,14 @@ jobs:
publish-preview:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
fetch-depth: 0
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -28,7 +28,7 @@ jobs:
CYPRESS_CACHE_FOLDER: .cache/Cypress
- name: Install Json
- run: npm i json --global
+ run: npm i json@11.0.0 --global
- name: Publish
working-directory: ./packages/mermaid
diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml
deleted file mode 100644
index 4dcf709c01..0000000000
--- a/.github/workflows/release-publish.yml
+++ /dev/null
@@ -1,47 +0,0 @@
-name: Publish release
-
-on:
- release:
- types: [published]
-
-jobs:
- publish:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: fregante/setup-git-user@v2
-
- - uses: pnpm/action-setup@v4
- # uses version from "packageManager" field in package.json
-
- - name: Setup Node.js
- uses: actions/setup-node@v4
- with:
- cache: pnpm
- node-version-file: '.node-version'
-
- - name: Install Packages
- run: |
- pnpm install --frozen-lockfile
- npm i json --global
- env:
- CYPRESS_CACHE_FOLDER: .cache/Cypress
-
- - name: Prepare release
- run: |
- VERSION=${GITHUB_REF:10}
- echo "Preparing release $VERSION"
- git checkout -t origin/release/$VERSION
- npm version --no-git-tag-version --allow-same-version $VERSION
- git add package.json
- git commit -nm "Bump version $VERSION"
- git checkout -t origin/master
- git merge -m "Release $VERSION" --no-ff release/$VERSION
- git push --no-verify
-
- - name: Publish
- run: |
- npm set //registry.npmjs.org/:_authToken $NPM_TOKEN
- npm publish
- env:
- NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
index 0b36a82b33..91153084e9 100644
--- a/.github/workflows/release.yml
+++ b/.github/workflows/release.yml
@@ -7,18 +7,24 @@ on:
concurrency: ${{ github.workflow }}-${{ github.ref }}
+permissions: # added using https://github.com/step-security/secure-repo
+ contents: read
+
jobs:
release:
+ permissions:
+ contents: write # for changesets/action to push to the repo
+ pull-requests: write # for changesets/action to create PRs
name: Release
runs-on: ubuntu-latest
steps:
- name: Checkout Repo
- uses: actions/checkout@v3
+ uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3.6.0
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -28,10 +34,11 @@ jobs:
- name: Create Release Pull Request or Publish to npm
id: changesets
- uses: changesets/action@v1
+ uses: changesets/action@aba318e9165b45b7948c60273e0b72fce0a64eb9 # v1.4.7
with:
version: pnpm changeset:version
publish: pnpm changeset:publish
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
+ NPM_CONFIG_PROVENANCE: true
diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml
new file mode 100644
index 0000000000..0dee2e666c
--- /dev/null
+++ b/.github/workflows/scorecard.yml
@@ -0,0 +1,37 @@
+name: Scorecard supply-chain security
+on:
+ branch_protection_rule:
+ push:
+ branches:
+ - develop
+ schedule:
+ - cron: 29 15 * * 0
+permissions: read-all
+jobs:
+ analysis:
+ name: Scorecard analysis
+ permissions:
+ id-token: write
+ security-events: write
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout code
+ uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
+ with:
+ persist-credentials: false
+ - name: Run analysis
+ uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1
+ with:
+ results_file: results.sarif
+ results_format: sarif
+ publish_results: true
+ - name: Upload artifact
+ uses: actions/upload-artifact@97a0fba1372883ab732affbe8f94b823f91727db # v3.pre.node20
+ with:
+ name: SARIF file
+ path: results.sarif
+ retention-days: 5
+ - name: Upload to code-scanning
+ uses: github/codeql-action/upload-sarif@f0f3afee809481da311ca3a6ff1ff51d81dbeb24 # v3.26.4
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
index a0b284a68f..375d5fada3 100644
--- a/.github/workflows/test.yml
+++ b/.github/workflows/test.yml
@@ -9,13 +9,13 @@ jobs:
unit-test:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- - uses: pnpm/action-setup@v4
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
# uses version from "packageManager" field in package.json
- name: Setup Node.js
- uses: actions/setup-node@v4
+ uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
cache: pnpm
node-version-file: '.node-version'
@@ -39,7 +39,7 @@ jobs:
pnpm exec vitest run ./packages/mermaid/src/diagrams/gantt/ganttDb.spec.ts --coverage
- name: Upload Coverage to Codecov
- uses: codecov/codecov-action@v4
+ uses: codecov/codecov-action@e28ff129e5465c2c0dcc6f003fc735cb6ae0c673 # v4.5.0
# Run step only pushes to develop and pull_requests
if: ${{ github.event_name == 'pull_request' || github.ref == 'refs/heads/develop' }}
with:
diff --git a/.github/workflows/unlock-reopened-issues.yml b/.github/workflows/unlock-reopened-issues.yml
index 4c53797297..b854eeb4bb 100644
--- a/.github/workflows/unlock-reopened-issues.yml
+++ b/.github/workflows/unlock-reopened-issues.yml
@@ -8,6 +8,6 @@ jobs:
triage:
runs-on: ubuntu-latest
steps:
- - uses: Dunning-Kruger/unlock-issues@v1
+ - uses: Dunning-Kruger/unlock-issues@b06b7f7e5c3f2eaa1c6d5d89f40930e4d6d9699e # v1
with:
repo-token: '${{ secrets.GITHUB_TOKEN }}'
diff --git a/.github/workflows/update-browserlist.yml b/.github/workflows/update-browserlist.yml
index f8f7696cde..1b26271f7c 100644
--- a/.github/workflows/update-browserlist.yml
+++ b/.github/workflows/update-browserlist.yml
@@ -8,18 +8,18 @@ jobs:
update-browser-list:
runs-on: ubuntu-latest
steps:
- - uses: actions/checkout@v4
- - uses: pnpm/action-setup@v4
+ - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
+ - uses: pnpm/action-setup@fe02b34f77f8bc703788d5817da081398fad5dd2 # v4.0.0
- run: npx update-browserslist-db@latest
- name: Commit changes
- uses: EndBug/add-and-commit@v9
+ uses: EndBug/add-and-commit@a94899bca583c204427a224a7af87c02f9b325d5 # v9.1.4
with:
author_name: ${{ github.actor }}
author_email: ${{ github.actor }}@users.noreply.github.com
message: 'chore: update browsers list'
push: false
- name: Create Pull Request
- uses: peter-evans/create-pull-request@v6
+ uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
branch: update-browserslist
title: Update Browserslist
diff --git a/.hadolint.yaml b/.hadolint.yaml
new file mode 100644
index 0000000000..280ff9592a
--- /dev/null
+++ b/.hadolint.yaml
@@ -0,0 +1,2 @@
+ignored:
+ - DL3002 # TODO: Last USER should not be root
diff --git a/.husky/pre-commit b/.husky/pre-commit
index ad85fc42c2..cc173f4a57 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -1,4 +1,2 @@
-#!/bin/sh
-. "$(dirname "$0")/_/husky.sh"
-
+#!/usr/bin/env sh
NODE_OPTIONS="--max_old_space_size=8192" pnpm run pre-commit
diff --git a/Dockerfile b/Dockerfile
index 7bec3bd4b7..fa933f999f 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,2 +1,10 @@
-FROM node:20.12.2-alpine3.19 AS base
-RUN wget -qO- https://get.pnpm.io/install.sh | ENV="$HOME/.shrc" SHELL="$(which sh)" sh -
+FROM node:20.12.2-alpine3.19@sha256:7a91aa397f2e2dfbfcdad2e2d72599f374e0b0172be1d86eeb73f1d33f36a4b2
+
+USER 0:0
+
+RUN corepack enable \
+ && corepack enable pnpm
+
+ENV NODE_OPTIONS="--max_old_space_size=8192"
+
+EXPOSE 9000 3333
diff --git a/README.md b/README.md
index 1788901ee5..456747132c 100644
--- a/README.md
+++ b/README.md
@@ -36,6 +36,7 @@ Try Live Editor previews of future releases:
diff --git a/cypress/integration/rendering/architecture.spec.ts b/cypress/integration/rendering/architecture.spec.ts
new file mode 100644
index 0000000000..9eefbe1e42
--- /dev/null
+++ b/cypress/integration/rendering/architecture.spec.ts
@@ -0,0 +1,174 @@
+import { imgSnapshotTest } from '../../helpers/util.ts';
+
+describe.skip('architecture diagram', () => {
+ it('should render a simple architecture diagram with groups', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ group api(cloud)[API]
+
+ service db(database)[Database] in api
+ service disk1(disk)[Storage] in api
+ service disk2(disk)[Storage] in api
+ service server(server)[Server] in api
+ service gateway(internet)[Gateway]
+
+ db L--R server
+ disk1 T--B server
+ disk2 T--B db
+ server T--B gateway
+ `
+ );
+ });
+ it('should render an architecture diagram with groups within groups', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ group api[API]
+ group public[Public API] in api
+ group private[Private API] in api
+
+ service serv1(server)[Server] in public
+
+ service serv2(server)[Server] in private
+ service db(database)[Database] in private
+
+ service gateway(internet)[Gateway] in api
+
+ serv1 B--T serv2
+ serv2 L--R db
+ serv1 L--R gateway
+ `
+ );
+ });
+ it('should render an architecture diagram with the fallback icon', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ service unknown(iconnamedoesntexist)[Unknown Icon]
+ `
+ );
+ });
+ it('should render an architecture diagram with split directioning', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ service db(database)[Database]
+ service s3(disk)[Storage]
+ service serv1(server)[Server 1]
+ service serv2(server)[Server 2]
+ service disk(disk)[Disk]
+
+ db L--R s3
+ serv1 L--T s3
+ serv2 L--B s3
+ serv1 T--B disk
+ `
+ );
+ });
+ it('should render an architecture diagram with directional arrows', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ service servC(server)[Server 1]
+ service servL(server)[Server 2]
+ service servR(server)[Server 3]
+ service servT(server)[Server 4]
+ service servB(server)[Server 5]
+
+ servC (L--R) servL
+ servC (R--L) servR
+ servC (T--B) servT
+ servC (B--T) servB
+
+ servL (T--L) servT
+ servL (B--L) servB
+ servR (T--R) servT
+ servR (B--R) servB
+ `
+ );
+ });
+ it('should render an architecture diagram with group edges', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ group left_group(cloud)[Left]
+ group right_group(cloud)[Right]
+ group top_group(cloud)[Top]
+ group bottom_group(cloud)[Bottom]
+ group center_group(cloud)[Center]
+
+ service left_disk(disk)[Disk] in left_group
+ service right_disk(disk)[Disk] in right_group
+ service top_disk(disk)[Disk] in top_group
+ service bottom_disk(disk)[Disk] in bottom_group
+ service center_disk(disk)[Disk] in center_group
+
+ left_disk{group} (R--L) center_disk{group}
+ right_disk{group} (L--R) center_disk{group}
+ top_disk{group} (B--T) center_disk{group}
+ bottom_disk{group} (T--B) center_disk{group}
+ `
+ );
+ });
+ it('should render an architecture diagram with edge labels', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ service servC(server)[Server 1]
+ service servL(server)[Server 2]
+ service servR(server)[Server 3]
+ service servT(server)[Server 4]
+ service servB(server)[Server 5]
+
+ servC L-[Label]-R servL
+ servC R-[Label]-L servR
+ servC T-[Label]-B servT
+ servC B-[Label]-T servB
+
+ servL T-[Label]-L servT
+ servL B-[Label]-L servB
+ servR T-[Label]-R servT
+ servR B-[Label]-R servB
+ `
+ );
+ });
+ it('should render an architecture diagram with simple junction edges', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ service left_disk(disk)[Disk]
+ service top_disk(disk)[Disk]
+ service bottom_disk(disk)[Disk]
+ service top_gateway(internet)[Gateway]
+ service bottom_gateway(internet)[Gateway]
+ junction juncC
+ junction juncR
+
+ left_disk R--L juncC
+ top_disk B--T juncC
+ bottom_disk T--B juncC
+ juncC R--L juncR
+ top_gateway B--T juncR
+ bottom_gateway T--B juncR
+ `
+ );
+ });
+ it('should render an architecture diagram with complex junction edges', () => {
+ imgSnapshotTest(
+ `architecture-beta
+ group left
+ group right
+ service left_disk(disk)[Disk] in left
+ service top_disk(disk)[Disk] in left
+ service bottom_disk(disk)[Disk] in left
+ service top_gateway(internet)[Gateway] in right
+ service bottom_gateway(internet)[Gateway] in right
+ junction juncC in left
+ junction juncR in right
+
+ left_disk R--L juncC
+ top_disk B--T juncC
+ bottom_disk T--B juncC
+
+
+ top_gateway (B--T juncR
+ bottom_gateway (T--B juncR
+
+ juncC{group} R--L) juncR{group}
+ `
+ );
+ });
+});
diff --git a/cypress/integration/rendering/erDiagram.spec.js b/cypress/integration/rendering/erDiagram.spec.js
index 1a2340906a..aad9b1cf7f 100644
--- a/cypress/integration/rendering/erDiagram.spec.js
+++ b/cypress/integration/rendering/erDiagram.spec.js
@@ -321,4 +321,37 @@ ORDER ||--|{ LINE-ITEM : contains
{ logLevel: 1 }
);
});
+
+ it('should render relationship labels with line breaks', () => {
+ imgSnapshotTest(
+ `
+ erDiagram
+ p[Person] {
+ string firstName
+ string lastName
+ }
+ a["Customer Account"] {
+ string email
+ }
+
+ b["Customer Account Secondary"] {
+ string email
+ }
+
+ c["Customer Account Tertiary"] {
+ string email
+ }
+
+ d["Customer Account Nth"] {
+ string email
+ }
+
+ p ||--o| a : "has
one"
+ p ||--o| b : "has
one
two"
+ p ||--o| c : "has
one
two
three"
+ p ||--o| d : "has
one
two
three
...
Nth"
+ `,
+ { logLevel: 1 }
+ );
+ });
});
diff --git a/cypress/platform/knsv2.html b/cypress/platform/knsv2.html
index 8808a3c9d5..a3cbf60bfc 100644
--- a/cypress/platform/knsv2.html
+++ b/cypress/platform/knsv2.html
@@ -73,7 +73,9 @@
font-family: monospace;
font-size: 72px;
}
-
+ pre {
+ width: 100%;
+ }
/* tspan {
font-size: 6px !important;
} */
@@ -88,17 +90,202 @@
config:
look: handDrawn
layout: elk
+ elk:
+
+
+---
+stateDiagram-v2
+ direction LR
+ accTitle: An idealized Open Source supply-chain graph
+
+ %%
+ state "š¦ Importer" as author_importer
+ state "š„ Supplier, Owner" as author_owner
+ state "šØš„ Maintainer, Author\nšØ Custodian" as author
+ state "š© Distributor" as repository_distributor
+ state "š¦ Importer" as language_importer
+ state "š¦šØ Packager" as language_packager
+ state "š¦šØ OSS Steward" as language_steward
+ state "šØ Curator" as language_curator
+ state "š© Distributor" as language_distributor
+ state "š¦ Contributor" as contributor
+ state "š¦ Importer" as package_importer
+ state "šØ Patcher" as package_patcher
+ state "šØš¦ Builder\nšØš¦ Packager\nšØš¦ Containerizer" as package_packager
+ state "šØ Curator" as package_curator
+ state "š© Distributor" as package_distributor
+ state "š¦ Importer" as integrator_importer
+ state "š„ Supplier, Manufacturer, Owner" as integrator_owner
+ state "š¦šØš„ Integrator, Developer" as integrator_developer
+ state "š©šØ SBOM Redactor\nš© Publisher" as integrator_publisher
+ state "š¦šØ Builder" as integrator_builder
+ state "šØ Deployer" as deployer
+ state "š¦ Vuln. Checker" as integrator_checker
+ state "š©šØ SBOM Redactor" as redactor
+ state "š¦ Consumer\nš¦ User" as consumer
+ state "š¦ Auditor" as auditor_internal
+ state "š¦ Auditor" as auditor_external
+
+ %%
+ classDef createsSBOM stroke:red,stroke-width:3px;
+ classDef updatesSBOM stroke:yellow,stroke-width:3px;
+ classDef assemblesSBOM stroke:yellow,stroke-width:3px;
+ classDef distributesSBOM stroke:green,stroke-width:3px;
+ classDef verifiesSBOM stroke:#07f,stroke-width:3px;
+
+ %%
+ class author_importer verifiesSBOM
+ class author_owner createsSBOM
+ class manufacturer_owner createsSBOM
+ class author assemblesSBOM
+ class package_importer verifiesSBOM
+ class package_patcher updatesSBOM
+ class package_packager assemblesSBOM
+ class package_curator distributesSBOM
+ class package_distributor distributesSBOM
+ class language_importer verifiesSBOM
+ class language_packager assemblesSBOM
+ class language_steward updatesSBOM
+ class language_curator distributesSBOM
+ class language_distributor distributesSBOM
+ class repository_distributor distributesSBOM
+ class integrator_importer verifiesSBOM
+ class integrator_owner createsSBOM
+ class integrator_developer assemblesSBOM
+ class integrator_publisher distributesSBOM
+ class integrator_builder assemblesSBOM
+ class integrator_checker verifiesSBOM
+ class deployer assemblesSBOM
+ class redactor distributesSBOM
+ class auditor_internal verifiesSBOM
+ class auditor_external verifiesSBOM
+
+ state "Maintainer Environment" as environment_maintainer {
+ [*] --> author_importer
+ [*] --> author
+ author_importer --> author
+ author_owner --> author
+ author --> language_packager
+ }
+
+ [*] --> environment_maintainer
+
+ state "Language Ecosystem" as ecosystem_lang {
+ [*] --> language_importer
+ [*] --> language_steward
+ [*] --> language_curator
+ [*] --> language_distributor
+ language_importer --> language_distributor
+ language_importer --> language_curator
+ language_steward --> language_curator
+ language_curator --> language_distributor
+ }
+
+ language_packager --> ecosystem_lang
+ ecosystem_lang --> ecosystem_lang
+
+ state "Public Collaboration Ecosystem" as ecosystem_repo {
+ [*] --> repository_distributor
+ }
+
+ author --> ecosystem_repo
+ ecosystem_repo --> author
+
+ repository_distributor --> contributor
+ contributor --> repository_distributor
+
+ state "Package Ecosystem" as ecosystem_package {
+ [*] --> package_importer
+ [*] --> package_packager
+ [*] --> package_patcher
+ package_importer --> package_patcher
+ package_importer --> package_packager
+ package_patcher --> package_packager
+ package_packager --> package_curator
+ package_packager --> package_distributor
+ package_curator --> package_distributor
+ }
+
+ repository_distributor --> ecosystem_package
+ language_distributor --> ecosystem_package
+ ecosystem_package --> ecosystem_package
+
+ state "Integrator Environment" as environment_integrator {
+ [*] --> integrator_developer
+ [*] --> integrator_importer
+ integrator_importer --> integrator_developer
+ integrator_owner --> integrator_developer
+ integrator_builder --> integrator_publisher
+ integrator_developer --> integrator_checker
+ integrator_checker --> integrator_developer
+ auditor_internal --> integrator_developer
+ integrator_developer --> integrator_builder
+ integrator_developer --> auditor_internal
+ }
+
+ repository_distributor --> environment_integrator
+ language_distributor --> environment_integrator
+ package_distributor --> environment_integrator
+
+ state "Production Environment" as environment_prod {
+ [*] --> deployer
+ deployer --> redactor
+ }
+
+ integrator_publisher --> [*]
+ integrator_developer --> environment_prod
+ integrator_builder --> environment_prod
+ integrator_publisher --> environment_prod
+
+ deployer --> auditor_external
+ deployer --> consumer
+ redactor --> consumer
+
+
+
+
+
+--- + title: hello2 + config: + look: handDrawn + layout: dagre elk: nodePlacementStrategy: BRANDES_KOEPF --- -flowchart LR - A[Start] --Some text--> B(Continue) - B --> C{Evaluate} - C -- One --> D[Option 1] - C -- Two --> E[Option 2] - C -- Three --> F[fa:fa-car Option 3] +stateDiagram-v2 + A --> A + state A { + B --> D + state B { + C + } + state D { + E + } + } ++
+--- + title: hello2 + config: + look: handDrawn + layout: dagre + elk: + nodePlacementStrategy: BRANDES_KOEPF +--- +flowchart + A --> A + subgraph A + B --> B + subgraph B + C + end + end +@@ -195,7 +382,7 @@ messageFontFamily: 'courier', }, fontSize: 12, - logLevel: 0, + logLevel: 3, securityLevel: 'loose', }); function callback() { diff --git a/demos/architecture.html b/demos/architecture.html new file mode 100644 index 0000000000..137b3fbf01 --- /dev/null +++ b/demos/architecture.html @@ -0,0 +1,252 @@ + + + + + +
+ architecture-beta + group api(cloud)[API] + + service db(database)[Database] in api + service disk1(disk)[Storage] in api + service disk2(disk)[Storage] in api + service server(server)[Server] in api + service gateway(internet)[Gateway] + + db:L -- R:server + disk1:T -- B:server + disk2:T -- B:db + server:T -- B:gateway ++
+ architecture-beta + group api[API] + group public[Public API] in api + group private[Private API] in api + + + service serv1(server)[Server] in public + + + service serv2(server)[Server] in private + service db(database)[Database] in private + + service gateway(internet)[Gateway] in api + + serv1:B -- T:serv2 + + serv2:L -- R:db + + serv1:L -- R:gateway ++
+ architecture-beta + service unknown(iconnamedoesntexist)[Unknown Icon] ++
+ architecture-beta + service db(database)[Database] + service s3(disk)[Storage] + service serv1(server)[Server 1] + service serv2(server)[Server 2] + service disk(disk)[Disk] + + db:L -- R:s3 + serv1:L -- T:s3 + serv2:L -- B:s3 + serv1:T -- B:disk ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L <--> R:servL + servC:R <--> L:servR + servC:T <--> B:servT + servC:B <--> T:servB + + servL:T <--> L:servT + servL:B <--> L:servB + servR:T <--> R:servT + servR:B <--> R:servB ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L <--> R:servL + servC:R <--> L:servR + servC:T <--> B:servT + servC:B <--> T:servB + + servT:L <--> T:servL + servB:L <--> B:servL + servT:R <--> T:servR + servB:R <--> B:servR ++
+ architecture-beta + group left_group(cloud)[Left] + group right_group(cloud)[Right] + group top_group(cloud)[Top] + group bottom_group(cloud)[Bottom] + group center_group(cloud)[Center] + + service left_disk(disk)[Disk] in left_group + service right_disk(disk)[Disk] in right_group + service top_disk(disk)[Disk] in top_group + service bottom_disk(disk)[Disk] in bottom_group + service center_disk(disk)[Disk] in center_group + + left_disk{group}:R <--> L:center_disk{group} + right_disk{group}:L <--> R:center_disk{group} + top_disk{group}:B <--> T:center_disk{group} + bottom_disk{group}:T <--> B:center_disk{group} ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L -[Label]- R:servL + servC:R -[Label]- L:servR + servC:T -[Label]- B:servT + servC:B -[Label]- T:servB + + servL:T -[Label]- L:servT + servL:B -[Label]- L:servB + servR:T -[Label]- R:servT + servR:B -[Label]- R:servB ++
+ architecture-beta + service servC(server)[Server 1] + service servL(server)[Server 2] + service servR(server)[Server 3] + service servT(server)[Server 4] + service servB(server)[Server 5] + + servC:L -[Label that is Long]- R:servL + servC:R -[Label that is Long]- L:servR + servC:T -[Label that is Long]- B:servT + servC:B -[Label that is Long]- T:servB + + servL:T -[Label that is Long]- L:servT + servL:B -[Label that is Long]- L:servB + servR:T -[Label that is Long]- R:servT + servR:B -[Label that is Long]- R:servB ++ +
+ architecture-beta + service left_disk(disk)[Disk] + service top_disk(disk)[Disk] + service bottom_disk(disk)[Disk] + service top_gateway(internet)[Gateway] + service bottom_gateway(internet)[Gateway] + junction juncC + junction juncR + + left_disk:R -- L:juncC + top_disk:B -- T:juncC + bottom_disk:T -- B:juncC + juncC:R -- L:juncR + top_gateway:B -- T:juncR + bottom_gateway:T -- B:juncR ++
+ architecture-beta + group left + group right + service left_disk(disk)[Disk] in left + service top_disk(disk)[Disk] in left + service bottom_disk(disk)[Disk] in left + service top_gateway(internet)[Gateway] in right + service bottom_gateway(internet)[Gateway] in right + junction juncC in left + junction juncR in right + + left_disk:R -- L:juncC + top_disk:B -- T:juncC + bottom_disk:T -- B:juncC + + + top_gateway:B <-- T:juncR + bottom_gateway:T <-- B:juncR + + juncC{group}:R --> L:juncR{group} ++
+ erDiagram + p[Person] { + string firstName + string lastName + } + a["Customer Account"] { + string email + } + + b["Customer Account Secondary"] { + string email + } + + c["Customer Account Tertiary"] { + string email + } + + d["Customer Account Nth"] { + string email + } + + p ||--o| a : "has+
one" + p ||--o| b : "has
one
two" + p ||--o| c : "has
one
two
three" + p ||--o| d : "has
one
two
three
...
Nth" +
erDiagram _customer_order { diff --git a/demos/index.html b/demos/index.html index 61a86a2aa0..07b51a3136 100644 --- a/demos/index.html +++ b/demos/index.html @@ -88,6 +88,9 @@Packet