diff --git a/.dockerignore b/.dockerignore index b477f4cc..a16bb106 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,13 @@ **/.git **/.svelte-kit **/dist -**/docs \ No newline at end of file +**/docs + +**/.github +**/.husky +**/.vscode + +Dockerfile +.dockerignore +docker-compose.yml +README.md \ No newline at end of file diff --git a/.env b/.env new file mode 100644 index 00000000..5d946ab4 --- /dev/null +++ b/.env @@ -0,0 +1,2 @@ + MERMAID_DOMAIN="mermaid.live" + MERMAID_ANALYTICS_URL="https://p.mermaid.live" diff --git a/.eslintrc.cjs b/.eslintrc.cjs index af91af2d..65ff1269 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -7,17 +7,11 @@ module.exports = { // 'plugin:@typescript-eslint/recommended-requiring-type-checking', 'plugin:@typescript-eslint/strict', 'plugin:unicorn/recommended', + 'plugin:svelte/recommended', + 'plugin:svelte/prettier', 'prettier' ], - plugins: [ - 'svelte3', - 'tailwindcss', - '@typescript-eslint', - 'es', - 'vitest', - 'no-only-tests', - 'unicorn' - ], + plugins: ['tailwindcss', '@typescript-eslint', 'es', 'vitest', 'no-only-tests', 'unicorn'], ignorePatterns: [ 'docs/*', '*.cjs', @@ -30,7 +24,13 @@ module.exports = { 'tsconfig.json' ], overrides: [ - { files: ['*.svelte'], processor: 'svelte3/svelte3' }, + { + files: ['*.svelte'], + parser: 'svelte-eslint-parser', + parserOptions: { + parser: '@typescript-eslint/parser' + } + }, { files: ['*.ts'], extends: [ @@ -42,16 +42,12 @@ module.exports = { ] } ], - settings: { - 'svelte3/typescript': () => require('typescript') - }, parserOptions: { sourceType: 'module', ecmaVersion: 2020, tsconfigRootDir: __dirname, - project: ['./tsconfig.json'], - extraFileExtensions: ['.svelte'], - allowAutomaticSingleRunInference: true + project: './tsconfig.json', + extraFileExtensions: ['.svelte'] }, env: { browser: true, @@ -76,6 +72,7 @@ module.exports = { case: 'camelCase' } ], + 'unicorn/filename-case': 'off', 'unicorn/prevent-abbreviations': [ 'error', { diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 4aa47fd7..fc10710d 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -12,6 +12,6 @@ Describe the way your implementation works or what design decisions you made if Make sure you -- [ ] :book: have read the [contribution guidelines](https://github.com/mermaid-js/mermaid/blob/master/CONTRIBUTING.md) +- [ ] :book: have read the [contribution guidelines](https://mermaid.js.org/community/contributing.html) - [ ] :computer: have added unit/e2e tests (if appropriate) - [ ] :bookmark: targeted `develop` branch diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index fcdc4c04..87b64abc 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -20,6 +20,9 @@ jobs: cache: yarn - name: Build & Deploy + env: + MERMAID_DOMAIN: 'mermaid.live' + MERMAID_ANALYTICS_URL: 'https://p.mermaid.live' run: | export DEPLOY=true [ "$GITHUB_EVENT_NAME" != "pull_request" ] && rm -rf docs/_app/ diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index d57fc48a..ebc0b917 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -2,13 +2,11 @@ name: Docker on: push: - # Publish `master` as Docker `latest` image. branches: + # Publish `master` as Docker `latest` image. - master - - # Publish `v1.2.3` tags as releases. - tags: - - v* + # Publish `develop` as Docker `nightly` image. + - develop # Run tests for all PRs to master and develop. pull_request: @@ -16,54 +14,35 @@ on: - master - develop -env: - IMAGE_NAME: mermaid-live-editor - jobs: - test: + docker: runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - - name: Run tests + - uses: actions/checkout@v4 + - uses: docker/setup-qemu-action@v3 + - uses: docker/setup-buildx-action@v3 + - name: Login to GitHub Container Registry + if: github.event_name != 'pull_request' + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.repository_owner }} + password: ${{ secrets.GITHUB_TOKEN }} + - name: Get release version run: | - docker build . --file Dockerfile - - push: - # Ensure test job passes before pushing image. - needs: test - - runs-on: ubuntu-latest - if: github.event_name == 'push' - - steps: - - uses: actions/checkout@v3 - - - name: Build image - run: docker build . --file Dockerfile --tag $IMAGE_NAME - - - name: Log into registry - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u ${{ github.actor }} --password-stdin - - - name: Push image - run: | - IMAGE_ID=ghcr.io/${{ github.repository_owner }}/$IMAGE_NAME - - # Change all uppercase to lowercase - IMAGE_ID=$(echo $IMAGE_ID | tr '[A-Z]' '[a-z]') - - # Strip git ref prefix from version - VERSION=$(echo "${{ github.ref }}" | sed -e 's,.*/\(.*\),\1,') - - # Strip "v" prefix from tag name - [[ "${{ github.ref }}" == "refs/tags/"* ]] && VERSION=$(echo $VERSION | sed -e 's/^v//') - - # Use Docker `latest` tag convention - [ "$VERSION" == "master" ] && VERSION=latest - - echo IMAGE_ID=$IMAGE_ID - echo VERSION=$VERSION - - docker tag $IMAGE_NAME $IMAGE_ID:$VERSION - docker push $IMAGE_ID:$VERSION + RELEASE_VERSION=$([ "${{ github.ref_name }}" = "master" ] && echo "latest" || echo "nightly") + echo "RELEASE_VERSION=${RELEASE_VERSION}" >> "${GITHUB_ENV}" + - uses: docker/metadata-action@v5 + id: meta + with: + images: ghcr.io/${{ github.repository }} + tags: | + type=raw,value=${{ env.RELEASE_VERSION }} + - uses: docker/build-push-action@v5 + with: + context: . + target: mermaid + push: ${{ github.event_name == 'push' }} + pull: true + tags: ${{ steps.meta.outputs.tags }} + labels: ${{ steps.meta.outputs.labels }} diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index ae9e0e4e..00000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,20 +0,0 @@ -name: Mark stale issues and pull requests - -on: - schedule: - - cron: '0 0 * * 4' - -jobs: - stale: - runs-on: ubuntu-latest - steps: - - uses: actions/stale@v8 - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - exempt-issue-labels: 'retained' - exempt-pr-labels: 'retained' - stale-issue-message: 'This issue is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days' - stale-pr-message: 'This pr is stale because it has been open 90 days with no activity. Remove stale label or comment or this will be closed in 30 days' - days-before-stale: 90 - days-before-close: 30 - days-before-pr-close: -1 diff --git a/.node-version b/.node-version new file mode 100644 index 00000000..48b14e6b --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20.14.0 diff --git a/.prettierrc b/.prettierrc index ab65daf2..e0366fc9 100644 --- a/.prettierrc +++ b/.prettierrc @@ -3,5 +3,7 @@ "svelteSortOrder": "options-scripts-markup-styles", "bracketSameLine": true, "trailingComma": "none", - "printWidth": 100 + "printWidth": 100, + "tailwindConfig": "./tailwind.config.cjs", + "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"] } diff --git a/.vscode/settings.json b/.vscode/settings.json index 71acc20d..b02e495c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -9,11 +9,17 @@ "cssnano", "daisyui", "esserializer", + "gantt", + "gitgraph", "KROKI", "localstorage", "mermaidchart", "mindmap", + "Pageview", "pako", + "panzoom", + "pzoom", + "roughjs", "Serde", "serdes", "tailwindcss", diff --git a/Dockerfile b/Dockerfile index fc7e87c6..b400b6a7 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,17 +1,33 @@ -# Two-stage docker container for mermaid-js/mermaid-live-editor -# Build : docker build -t mermaid-js/mermaid-live-editor . -# Run : docker run --name mermaid-live-editor --publish 8080:8080 mermaid-js/mermaid-live-editor -# Start : docker start mermaid-live-editor -# Use webbrowser : http://localhost:8080 -# Stop : press ctrl + c -# or -# docker stop mermaid-live-editor -FROM node:18.17.1 as mermaid-live-editor-builder -COPY --chown=node:node . /home -WORKDIR /home +FROM docker.io/library/node:20-alpine3.18 AS mermaid-live-editor-dependencies + +RUN apk --no-cache add build-base git python3 && \ + rm -rf /var/cache/apk/* + +RUN yarn global add node-gyp + +WORKDIR /app + +COPY ./package.json . +COPY ./yarn.lock . + RUN yarn install + +FROM mermaid-live-editor-dependencies AS mermaid-live-editor-builder + +ARG MERMAID_RENDERER_URL +ARG MERMAID_KROKI_RENDERER_URL +ARG MERMAID_ANALYTICS_URL +ARG MERMAID_DOMAIN + +COPY . ./ + RUN yarn build -FROM nginxinc/nginx-unprivileged:alpine as mermaid-live-editor-runner +FROM mermaid-live-editor-builder AS mermaid-dev + +ENTRYPOINT ["yarn", "dev"] + +FROM nginx:1.25-alpine3.18 AS mermaid + COPY ./nginx.conf /etc/nginx/conf.d/default.conf -COPY --from=mermaid-live-editor-builder --chown=nginx:nginx /home/docs /usr/share/nginx/html +COPY --from=mermaid-live-editor-builder /app/docs /usr/share/nginx/html diff --git a/Dockerfile.dev b/Dockerfile.dev deleted file mode 100644 index bb0bd2c9..00000000 --- a/Dockerfile.dev +++ /dev/null @@ -1,8 +0,0 @@ -FROM node:18.17.1 -WORKDIR /app -COPY package.json . -COPY yarn.lock . -RUN npm install -COPY . . -RUN ls -CMD ["yarn", "dev"] diff --git a/README.md b/README.md index cf042bd3..74685558 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE)[![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys) +[![Mermaid Live Editor](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/detailed/2ckppp/master&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/2ckppp/runs) [![Join our Slack!](https://img.shields.io/static/v1?message=join%20chat&color=9cf&logo=slack&label=slack)](https://join.slack.com/t/mermaid-talk/shared_invite/enQtNzc4NDIyNzk4OTAyLWVhYjQxOTI2OTg4YmE1ZmJkY2Y4MTU3ODliYmIwOTY3NDJlYjA0YjIyZTdkMDMyZTUwOGI0NjEzYmEwODcwOTE) [![Netlify Status](https://api.netlify.com/api/v1/badges/27fa023d-7c73-4a3f-9791-b3b657a47100/deploy-status)](https://app.netlify.com/sites/mermaidjs/deploys) # Contributors are welcome! @@ -29,14 +29,20 @@ docker run --platform linux/amd64 --publish 8000:8080 ghcr.io/mermaid-js/mermaid ### To configure renderer URL -When building, Set the Environment variable MERMAID_RENDERER_URL to the rendering service. +When building set the MERMAID_RENDERER_URL build argument to the rendering service. Default is `https://mermaid.ink` ### To configure Kroki Instance URL -When building, Set the Environment variable MERMAID_KROKI_RENDERER_URL to your Kroki instance. +When building set the MERMAID_KROKI_RENDERER_URL build argument to your Kroki instance. Default is `https://kroki.io` +### To configure Analytics + +When building set the MERMAID_ANALYTICS_URL build argument to your plausible instance, and MERMAID_DOMAIN to your domain. + +Default is empty, disabling analytics. + ### Development ```bash @@ -45,6 +51,28 @@ docker compose up --build Then open http://localhost:3000 +### Building and running images locally + +#### Build + +```bash +docker build -t mermaid-js/mermaid-live-editor . +``` + +#### Run + +```bash +docker run --detach --name mermaid-live-editor --publish 8080:8080 mermaid-js/mermaid-live-editor +``` + +Visit: + +#### Stop + +```bash +docker stop mermaid-live-editor +``` + ## Setup Below link will help you making a copy of the repository in your local system. diff --git a/cypress.config.js b/cypress.config.js index 7ebe9ef4..8b8edd92 100644 --- a/cypress.config.js +++ b/cypress.config.js @@ -1,6 +1,6 @@ import { defineConfig } from 'cypress'; import fs from 'fs'; -import { isFileExist, findFiles } from 'cy-verify-downloads'; +import path from 'path'; export default defineConfig({ projectId: '2ckppp', viewportWidth: 1440, @@ -15,17 +15,19 @@ export default defineConfig({ e2e: { setupNodeEvents(on, config) { on('task', { - isFileExist, - findFiles, - deleteFile(path) { - fs.rmSync(path); - return null; - }, - readFileMaybe(filename) { - if (fs.existsSync(filename)) { - return fs.readFileSync(filename, 'utf8'); + readAndDeleteFile({ fileNamePattern, folder, mode }) { + const fileNameRegex = new RegExp(fileNamePattern); + const files = fs.readdirSync(folder); + const filename = files.find((file) => file.match(fileNameRegex)); + const filePath = path.join(folder, filename); + try { + if (mode === 'size') { + return fs.statSync(filePath).size; + } + return fs.readFileSync(filePath, 'utf8'); + } finally { + fs.rmSync(filePath); } - return null; } }); }, diff --git a/cypress/e2e/actions.spec.ts b/cypress/e2e/actions.spec.ts index 4206f022..24d8d1b1 100644 --- a/cypress/e2e/actions.spec.ts +++ b/cypress/e2e/actions.spec.ts @@ -26,8 +26,6 @@ describe('Check actions', () => { }); it('should download png and svg', () => { - cy.clock(new Date(2022, 0, 1).getTime()); - cy.get(`#downloadPNG`).click(); verifyFileSizeGreaterThan('diagram', 'png', 34_000); @@ -43,7 +41,5 @@ describe('Check actions', () => { cy.get(`#downloadSVG`).click(); verifyFileSizeGreaterThan('diagram', 'svg', 11_000); - - cy.clock().invoke('restore'); }); }); diff --git a/cypress/e2e/diagramUpdate.spec.ts b/cypress/e2e/diagramUpdate.spec.ts index d2ca433c..377b365f 100644 --- a/cypress/e2e/diagramUpdate.spec.ts +++ b/cypress/e2e/diagramUpdate.spec.ts @@ -50,8 +50,26 @@ describe('Auto sync tests', () => { cy.getLocalStorage('codeStore').snapshot(); }); + it('should automatically defer rendering when complex diagrams are edited', () => { + cy.get('#view').should('not.have.class', 'outOfSync'); + typeInEditor(` +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i +A & B & C & D & E --> F & G & K & Z & i`); + cy.get('#view').should('have.class', 'outOfSync'); + cy.get('#errorContainer').should('contain.text', 'It will be updated automatically.'); + // The class should be removed automatically after 1 second. + cy.get('#view').should('not.have.class', 'outOfSync'); + }); + it('supports commenting code out/in', () => { - cy.get('#editor').contains('Car').click(); + cy.get('#editor').contains('Car').click({ force: true }); cy.get('#editor').get('textarea').type(`${cmd}/`, { force: true }); cy.get('#view').contains('Car').should('not.exist'); diff --git a/cypress/e2e/docMap.spec.ts b/cypress/e2e/docMap.spec.ts index 5c7e8201..0a43ee18 100755 --- a/cypress/e2e/docMap.spec.ts +++ b/cypress/e2e/docMap.spec.ts @@ -9,28 +9,28 @@ describe('Editor docs tests', () => { }); it('Test default loading', () => { - cy.get(`[data-cy=docs][href^="https://mermaid-js.github.io/mermaid"]`).should('exist'); + cy.get(`[data-cy=docs][href^="https://mermaid.js.org/"]`).should('exist'); }); it('Test to see if the correct URL loads when changing from one diagram to other', () => { cy.contains('Flow').click(); - cy.get(`[data-cy=docs][href$="/#/flowchart"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/flowchart.html"]`).should('exist'); cy.contains('Config').click(); - cy.get(`[data-cy=docs][href$="/#/flowchart?id=configuration"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/flowchart.html#configuration"]`).should('exist'); cy.contains('Sequence').click(); - cy.get(`[data-cy=docs][href$="/#/sequenceDiagram?id=configuration"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/sequenceDiagram.html#configuration"]`).should('exist'); cy.contains('Code').click(); - cy.get(`[data-cy=docs][href$="/#/sequenceDiagram"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/sequenceDiagram.html"]`).should('exist'); }); it("Test to check URLs for a case where config URL doesn't exist", () => { cy.contains('State').click(); - cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/stateDiagram.html"]`).should('exist'); cy.contains('Config').click(); - cy.get(`[data-cy=docs][href$="/#/stateDiagram"]`).should('exist'); + cy.get(`[data-cy=docs][href$="/syntax/stateDiagram.html"]`).should('exist'); }); }); diff --git a/cypress/e2e/util.ts b/cypress/e2e/util.ts index 57a9f54b..2f76f625 100644 --- a/cypress/e2e/util.ts +++ b/cypress/e2e/util.ts @@ -11,7 +11,7 @@ export const typeInEditor = ( ) => { cy.window().should('have.property', 'editorLoaded', true); cy.get('#editor').click(); - cy.get('#editor').within(($editor) => { + cy.get('#editor').within(() => { if (bottom) { cy.get('textarea').type('{pageDown}', { force: true }); } @@ -29,17 +29,15 @@ export const verifyFileSizeGreaterThan = ( extension: string, size: number ) => { - const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`; - const filePath = `${downloadsFolder}/${fileName}`; - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - cy.verifyDownload(fileName); - cy.readFile(filePath, null, { - log: false - }).then((buffer: ArrayBuffer) => { - expect(buffer.byteLength).to.be.gt(size); - expect(buffer.byteLength).to.be.lt(size * 1.3); + cy.get('#view').should('not.have.class', 'outOfSync'); + cy.task('readAndDeleteFile', { + folder: downloadsFolder, + fileNamePattern: `^mermaid-${fileType}-.*.${extension}$`, + mode: 'size' + }).then((fileSize: number) => { + expect(fileSize).to.be.gt(size); + expect(fileSize).to.be.lt(size * 1.3); }); - cy.task('deleteFile', filePath); }; export const verifyFileSnapshot = ( @@ -47,14 +45,11 @@ export const verifyFileSnapshot = ( extension: string, content: string ) => { - const fileName = `mermaid-${fileType}-2022-01-01-000000.${extension}`; - const filePath = `${downloadsFolder}/${fileName}`; - // eslint-disable-next-line @typescript-eslint/no-unsafe-call - cy.verifyDownload(fileName); - cy.readFile(filePath, null, { - log: false - }).then((buffer: ArrayBuffer) => - expect(new TextDecoder('utf8').decode(buffer)).to.contain(content) - ); - cy.task('deleteFile', filePath); + cy.task('readAndDeleteFile', { + folder: downloadsFolder, + fileNamePattern: `^mermaid-${fileType}-.*.${extension}$`, + mode: 'content' + }).then((fileContent: number) => { + expect(fileContent).to.contain(content); + }); }; diff --git a/cypress/support/e2e.js b/cypress/support/e2e.js index d9401131..4ef4ffaa 100644 --- a/cypress/support/e2e.js +++ b/cypress/support/e2e.js @@ -15,7 +15,6 @@ // Import commands.js using ES2015 syntax: import './commands'; -require('cy-verify-downloads').addCustomCommand(); // Alternatively you can use CommonJS syntax: // require('./commands') diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index edd14f8b..e9f59358 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,7 +1,7 @@ { "compilerOptions": { "allowJs": true, - "types": ["cypress", "cypress-localstorage-commands", "cy-verify-downloads", "node"] + "types": ["cypress", "cypress-localstorage-commands", "node"] }, "include": ["**/*.ts"] } diff --git a/docker-compose.yml b/docker-compose.yml index 68a47332..c4649256 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -3,7 +3,7 @@ services: mermaid: build: context: . - dockerfile: Dockerfile.dev + target: mermaid-dev volumes: - ./src:/app/src ports: diff --git a/netlify.toml b/netlify.toml new file mode 100644 index 00000000..4b646fa7 --- /dev/null +++ b/netlify.toml @@ -0,0 +1,3 @@ +[build.environment] + MERMAID_ANALYTICS_URL = 'https://p.mermaid.live' + MERMAID_DOMAIN = 'mermaid.live' diff --git a/package.json b/package.json index 6c10e0cc..7d090ef4 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,9 @@ "dev:test": "yarn dev", "build": "vite build", "preview": "vite preview", - "lint": "prettier --check --cache --plugin-search-dir=. .;eslint --ignore-path .gitignore .", - "lint:fix": "prettier --write --cache --plugin-search-dir=. .;eslint --fix --ignore-path .gitignore .", - "format": "prettier --write --cache --plugin-search-dir=. .", + "lint": "prettier --check --cache . && eslint --ignore-path .gitignore .", + "lint:fix": "prettier --write --cache . && eslint --fix --ignore-path .gitignore .", + "format": "prettier --write --cache .", "pre-commit": "lint-staged", "postinstall": "husky install && svelte-kit sync && (git config blame.ignoreRevsFile .git-blame-ignore-revs || true)", "test:unit": "vitest", @@ -23,61 +23,65 @@ }, "devDependencies": { "@cypress/snapshot": "2.1.7", - "@sveltejs/adapter-static": "2.0.3", - "@sveltejs/kit": "1.25.0", - "@testing-library/jest-dom": "5.17.0", - "@testing-library/svelte": "3.2.2", - "@types/pako": "2.0.0", - "@types/uuid": "9.0.4", - "@typescript-eslint/eslint-plugin": "5.62.0", - "@typescript-eslint/parser": "5.62.0", - "@vitest/ui": "^0.34.0", + "@fortawesome/fontawesome-free": "^6.5.1", + "@sveltejs/adapter-static": "3.0.2", + "@sveltejs/kit": "2.5.16", + "@sveltejs/vite-plugin-svelte": "^3.0.1", + "@testing-library/svelte": "4.2.3", + "@types/lodash-es": "^4.17.12", + "@types/pako": "2.0.3", + "@types/uuid": "9.0.8", + "@typescript-eslint/eslint-plugin": "6.21.0", + "@typescript-eslint/parser": "6.21.0", + "@vitest/ui": "^1.1.3", "autoprefixer": "^10.4.14", "c8": "7.14.0", "chai": "^4.3.7", "cssnano": "^6.0.0", - "cy-verify-downloads": "0.2.0", "cypress": "12.17.4", - "cypress-localstorage-commands": "2.2.4", - "eslint": "8.49.0", - "eslint-config-prettier": "8.10.0", - "eslint-plugin-cypress": "2.14.0", - "eslint-plugin-es": "4.1.0", + "cypress-localstorage-commands": "2.2.6", + "eslint": "8.57.0", + "eslint-config-prettier": "9.1.0", + "eslint-plugin-cypress": "2.15.2", + "eslint-plugin-es": "^4.1.0", "eslint-plugin-no-only-tests": "^3.1.0", - "eslint-plugin-postcss-modules": "2.0.0", - "eslint-plugin-svelte3": "4.0.0", - "eslint-plugin-tailwindcss": "3.13.0", - "eslint-plugin-unicorn": "^46.0.0", - "eslint-plugin-vitest": "^0.3.0", - "esserializer": "1.3.11", - "font-awesome": "^4.7.0", + "eslint-plugin-postcss-modules": "^2.0.0", + "eslint-plugin-svelte": "^2.35.1", + "eslint-plugin-tailwindcss": "^3.13.1", + "eslint-plugin-unicorn": "^50.0.1", + "eslint-plugin-vitest": "^0.5.0", + "esserializer": "^1.3.11", "husky": "^8.0.3", - "jsdom": "21.1.2", - "lint-staged": "13.3.0", + "jsdom": "^21.1.2", + "lint-staged": "^15.2.0", "node-html-parser": "^6.1.5", - "postcss": "^8.4.21", - "postcss-load-config": "4.0.1", - "prettier": "2.8.8", - "prettier-plugin-svelte": "^2.10.0", - "svelte": "3.59.2", - "svelte-preprocess": "5.0.4", - "tailwindcss": "^3.3.1", - "tslib": "^2.5.0", - "typescript": "5.2.2", - "vite": "^4.3.9", - "vitest": "^0.34.0" + "postcss": "^8.4.33", + "postcss-load-config": "5.1.0", + "prettier": "^3.1.0", + "prettier-plugin-svelte": "^3.1.2", + "prettier-plugin-tailwindcss": "^0.6.0", + "svelte": "^4.2.8", + "svelte-preprocess": "^5.1.3", + "tailwindcss": "^3.4.1", + "tslib": "^2.6.2", + "typescript": "^5.3.3", + "vite": "^5.0.11", + "vitest": "^1.1.3", + "vitest-dom": "^0.1.1" }, "dependencies": { - "analytics": "0.8.9", - "analytics-plugin-plausible": "0.0.6", + "@mermaid-js/mermaid-zenuml": "^0.2.0", "daisyui": "2.52.0", "dayjs": "^1.11.7", - "js-base64": "3.7.5", - "mermaid": "10.3.1", - "monaco-editor": "0.43.0", + "js-base64": "3.7.7", + "lodash-es": "^4.17.21", + "mermaid": "10.9.1", + "monaco-editor": "0.49.0", "pako": "2.1.0", + "plausible-tracker": "^0.3.8", "random-word-slugs": "0.1.7", "svg-pan-zoom": "3.6.1", + "svg2roughjs": "^3.2.0", "uuid": "9.0.1" }, "lint-staged": { @@ -87,8 +91,8 @@ ] }, "volta": { - "node": "18.17.1", - "yarn": "1.22.19" + "node": "18.20.3", + "yarn": "1.22.22" }, "engines": { "node": ">=16.7" diff --git a/src/app.html b/src/app.html index ae3fdb02..827bd6bc 100644 --- a/src/app.html +++ b/src/app.html @@ -1,4 +1,4 @@ - + @@ -15,15 +15,9 @@ - %sveltekit.head% - +
%sveltekit.body%
diff --git a/src/app.postcss b/src/app.postcss index 888c737e..528b5111 100644 --- a/src/app.postcss +++ b/src/app.postcss @@ -1,10 +1,17 @@ +@import '@fortawesome/fontawesome-free/css/all.min.css'; + @tailwind base; @tailwind components; @tailwind utilities; .input { - @apply flex-1 border-primary border-solid border-2 rounded; + @apply flex-1 rounded border-2 border-solid border-primary; } .action-btn { @apply btn btn-primary; } +#graph-div sub, +#graph-div sup { + position: initial; + vertical-align: revert; +} diff --git a/src/env.d.ts b/src/env.d.ts index 8188f7aa..ec4a2ff4 100644 --- a/src/env.d.ts +++ b/src/env.d.ts @@ -3,9 +3,8 @@ interface ImportMetaEnv { readonly MERMAID_RENDERER_URL?: string; readonly MERMAID_KROKI_RENDERER_URL?: string; - readonly MERMAID_CDN_URL?: string; - readonly MERMAID_BASE_URL?: string; - readonly MERMAID_LOCAL?: boolean; + readonly MERMAID_ANALYTICS_URL?: string; + readonly MERMAID_DOMAIN?: string; // more env variables... } diff --git a/src/global.d.ts b/src/global.d.ts index 95ecd6a0..63908c66 100644 --- a/src/global.d.ts +++ b/src/global.d.ts @@ -1,16 +1 @@ -/* eslint-disable @typescript-eslint/no-empty-interface */ -/* eslint-disable @typescript-eslint/ban-types */ -/* eslint-disable @typescript-eslint/no-unused-vars */ - /// -import type { TestingLibraryMatchers } from '@testing-library/jest-dom/matchers'; - -declare global { - namespace jest { - interface Matchers - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-expect-error - // eslint-disable-next-line no-undef - extends TestingLibraryMatchers {} - } -} diff --git a/src/lib/components/Actions.svelte b/src/lib/components/Actions.svelte index a038712e..9c0bd1c4 100644 --- a/src/lib/components/Actions.svelte +++ b/src/lib/components/Actions.svelte @@ -1,34 +1,49 @@ -
+
{#if isClipboardAvailable()} -
+
PNG size
-
+
-
+
{#if isNetlify} -
- + diff --git a/src/lib/components/Card/Card.svelte b/src/lib/components/Card/Card.svelte index 38098eb6..3e107487 100644 --- a/src/lib/components/Card/Card.svelte +++ b/src/lib/components/Card/Card.svelte @@ -11,20 +11,22 @@ $: isTabsShown = isOpen && tabs.length > 0; -
+