@ampless/plugin-mermaid 0.1.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.ja.md +91 -0
- package/README.md +91 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +117 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 ampless contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.ja.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
> English: [README.md](./README.md)
|
|
2
|
+
|
|
3
|
+
# @ampless/plugin-mermaid
|
|
4
|
+
|
|
5
|
+
[ampless](https://github.com/heavymoons/ampless) 向け Mermaid ダイアグラムプラグイン。`mermaid` 言語を指定したコードブロックを、CDN から遅延ロードした [mermaid.js](https://mermaid.js.org/) で公開サイト上の図として描画します。
|
|
6
|
+
|
|
7
|
+
> **プレリリース / ベータ版。** v1.0 まではマイナーバージョンでも破壊的変更が入る可能性があります。
|
|
8
|
+
|
|
9
|
+
`publicHead` capability 経由でインラインスクリプトを 1 本だけ `<head>` に注入します。公開ページ側でスクリプトが `<pre><code class="language-mermaid">` ブロックを走査し、**1 つでも存在する場合のみ** jsDelivr から mermaid.js を動的 import して各ブロックを SVG ダイアグラムに描画します。Mermaid ブロックの無いページではライブラリを一切ダウンロードしません。
|
|
10
|
+
|
|
11
|
+
AWS のデータ権限は不要です。ディスクリプタの生成は公開 Next.js プロセスのリクエスト時に行われ、描画はブラウザ上で行われます。`trust_level` は `untrusted`。
|
|
12
|
+
|
|
13
|
+
## インストール
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @ampless/plugin-mermaid@beta
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 設定
|
|
20
|
+
|
|
21
|
+
`cms.config.ts` に記述します:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { defineConfig } from 'ampless'
|
|
25
|
+
import mermaidPlugin from '@ampless/plugin-mermaid'
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
// ...
|
|
29
|
+
plugins: [mermaidPlugin()],
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## オプション
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
mermaidPlugin({
|
|
37
|
+
version: '11.15.0', // 既定値(固定 x.y.z)
|
|
38
|
+
theme: 'default', // default | dark | forest | neutral | base
|
|
39
|
+
securityLevel: 'strict', // strict | loose | antiscript | sandbox
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| オプション | デフォルト | 備考 |
|
|
44
|
+
| --------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| `version` | `'11.15.0'` | jsDelivr から読み込む mermaid のバージョン。`x` / `x.y` / `x.y.z` に一致する必要あり。不正値は `console.warn` してデフォルトにフォールバック。 |
|
|
46
|
+
| `theme` | `'default'` | `default` / `dark` / `forest` / `neutral` / `base` のいずれか。それ以外は `default` にフォールバック。 |
|
|
47
|
+
| `securityLevel` | `'strict'` | `strict` / `loose` / `antiscript` / `sandbox` のいずれか。それ以外は `strict` にフォールバック。[セキュリティ](#セキュリティ--cdn-に関する注意)参照。 |
|
|
48
|
+
|
|
49
|
+
## コードブロックの検出方法
|
|
50
|
+
|
|
51
|
+
描画後の投稿 HTML から `<pre><code class="language-mermaid">` を探します。ampless のツールバーにあるコードブロック単位の **言語エディタ**が `language-*` クラスを付与し、どの本文フォーマットでも同じ形に着地します:
|
|
52
|
+
|
|
53
|
+
| `post.format` | クラスの付き方 |
|
|
54
|
+
| ------------- | ------------------------------------------------------------------------------ |
|
|
55
|
+
| `tiptap` | コードブロックノードの `language` 属性 → 描画時に `class="language-mermaid"`。 |
|
|
56
|
+
| `markdown` | フェンスドブロック ` ```mermaid ` → `class="language-mermaid"`。 |
|
|
57
|
+
| `html` | 記述された `<pre><code class="language-mermaid">` はそのまま保持。 |
|
|
58
|
+
|
|
59
|
+
`mermaid` コードブロックの中に図のソースを書きます:
|
|
60
|
+
|
|
61
|
+
````markdown
|
|
62
|
+
```mermaid
|
|
63
|
+
graph TD
|
|
64
|
+
A[Start] --> B{Choice}
|
|
65
|
+
B -->|yes| C[OK]
|
|
66
|
+
B -->|no| D[Stop]
|
|
67
|
+
```
|
|
68
|
+
````
|
|
69
|
+
|
|
70
|
+
描画後はプラグインが `<pre>` 全体を `<div class="ampless-mermaid">…svg…</div>` に置換するため、テーマ CSS から `.ampless-mermaid` を対象にスタイリングできます。
|
|
71
|
+
|
|
72
|
+
## @ampless/plugin-highlight との共存
|
|
73
|
+
|
|
74
|
+
両プラグインは順序非依存で同時に動作するよう設計されています。`@ampless/plugin-highlight` は `code.language-mermaid` を明示的に除外し、本プラグインは `<pre>` ごと置換するため、Mermaid ブロックがシンタックスハイライトされることも、ハイライト済みブロックが図として扱われることもありません。
|
|
75
|
+
|
|
76
|
+
## クライアント側の堅牢性
|
|
77
|
+
|
|
78
|
+
- **冪等な再スキャン** — 処理済みブロックは `data-ampless-done` でマークするため、二重描画しません。
|
|
79
|
+
- **SPA / App Router 遷移** — head スクリプトは一度だけ実行されますが、`document.body` に張ったデバウンス付き `MutationObserver` が、クライアント遷移で後から挿入された投稿コンテンツを再スキャンします。
|
|
80
|
+
- **失敗時の復旧** — 動的 import が失敗した場合はキャッシュした import Promise を破棄し、ブロックのマークも外すため次回スキャンで再試行されます。失敗は握り潰さず `console.warn` で報告します。個別の図の描画失敗時は元のコードブロックを残します。
|
|
81
|
+
|
|
82
|
+
## セキュリティ / CDN に関する注意
|
|
83
|
+
|
|
84
|
+
- 図のソースは(半信頼の)投稿本文由来なので **既定は `securityLevel: 'strict'`** です。`'loose'` にするとインタラクティブ機能(クリックハンドラ、リンク)が有効になりますが、図に書かれた `javascript:` href による XSS も成立します。本文を編集できる全員を完全に信頼できる場合のみ `'loose'` を使ってください。
|
|
85
|
+
- **既定バージョンは固定。** 供給網の攻撃面を最小化するため `version` の既定値は厳密な `x.y.z` です。floating な major/minor タグ(例: `'11'`)も指定できますが、その供給網リスクは利用者の責任です。
|
|
86
|
+
- **動的 `import()` には SRI(Subresource Integrity)が効きません。** ライブラリは実行時に jsDelivr から取得され、integrity 固定はできません。ライブラリの自前ホスティングは将来のオプションとして検討します。
|
|
87
|
+
|
|
88
|
+
## v1 で対応しないこと
|
|
89
|
+
|
|
90
|
+
- mermaid 自身の `securityLevel` を超える **SVG の後処理 / DOMPurify 通し**は行いません。描画後 SVG の強化は将来の拡張候補です。
|
|
91
|
+
- **ビルド時 / サーバサイドレンダリングは非対応** — 図はブラウザで描画されるため、JS 無効クライアントや初回描画時には図のソースがそのまま見えます。
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
> 日本語版: [README.ja.md](./README.ja.md)
|
|
2
|
+
|
|
3
|
+
# @ampless/plugin-mermaid
|
|
4
|
+
|
|
5
|
+
Mermaid diagram plugin for [ampless](https://github.com/heavymoons/ampless). Renders fenced code blocks tagged with the `mermaid` language as diagrams on the public site, using [mermaid.js](https://mermaid.js.org/) loaded lazily from a CDN.
|
|
6
|
+
|
|
7
|
+
> **Pre-release / beta.** Breaking changes possible in any minor version until v1.0.
|
|
8
|
+
|
|
9
|
+
The plugin injects a single inline script into `<head>` via the `publicHead` capability. On the public page the script scans for `<pre><code class="language-mermaid">` blocks and, **only if at least one exists**, dynamically imports mermaid.js from jsDelivr and renders each block to an SVG diagram. Pages without a Mermaid block never download the library.
|
|
10
|
+
|
|
11
|
+
No AWS data permissions are required — the descriptor is produced at request time in the public Next.js process and the rendering happens in the browser. The plugin's `trust_level` is `untrusted`.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
pnpm add @ampless/plugin-mermaid@beta
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Configure
|
|
20
|
+
|
|
21
|
+
In `cms.config.ts`:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
import { defineConfig } from 'ampless'
|
|
25
|
+
import mermaidPlugin from '@ampless/plugin-mermaid'
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
// ...
|
|
29
|
+
plugins: [mermaidPlugin()],
|
|
30
|
+
})
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## Options
|
|
34
|
+
|
|
35
|
+
```ts
|
|
36
|
+
mermaidPlugin({
|
|
37
|
+
version: '11.15.0', // pinned default
|
|
38
|
+
theme: 'default', // default | dark | forest | neutral | base
|
|
39
|
+
securityLevel: 'strict', // strict | loose | antiscript | sandbox
|
|
40
|
+
})
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
| Option | Default | Notes |
|
|
44
|
+
| --------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------- |
|
|
45
|
+
| `version` | `'11.15.0'` | mermaid version loaded from jsDelivr. Must match `x` / `x.y` / `x.y.z`. Invalid values fall back to the default with a `console.warn`. |
|
|
46
|
+
| `theme` | `'default'` | One of `default` / `dark` / `forest` / `neutral` / `base`. Anything else falls back to `default`. |
|
|
47
|
+
| `securityLevel` | `'strict'` | One of `strict` / `loose` / `antiscript` / `sandbox`. Anything else falls back to `strict`. See [Security](#security--cdn-notes). |
|
|
48
|
+
|
|
49
|
+
## How code blocks are detected
|
|
50
|
+
|
|
51
|
+
The plugin looks for `<pre><code class="language-mermaid">` in the rendered post HTML. The ampless toolbar's per-code-block **language editor** writes the `language-*` class, and all body formats land on the same shape:
|
|
52
|
+
|
|
53
|
+
| `post.format` | How the class appears |
|
|
54
|
+
| ------------- | ------------------------------------------------------------------------------------------ |
|
|
55
|
+
| `tiptap` | The code-block node carries a `language` attribute → `class="language-mermaid"` on render. |
|
|
56
|
+
| `markdown` | A fenced block ` ```mermaid ` → `class="language-mermaid"`. |
|
|
57
|
+
| `html` | Authored `<pre><code class="language-mermaid">` is preserved literally. |
|
|
58
|
+
|
|
59
|
+
Write your diagram source inside a `mermaid` code block:
|
|
60
|
+
|
|
61
|
+
````markdown
|
|
62
|
+
```mermaid
|
|
63
|
+
graph TD
|
|
64
|
+
A[Start] --> B{Choice}
|
|
65
|
+
B -->|yes| C[OK]
|
|
66
|
+
B -->|no| D[Stop]
|
|
67
|
+
```
|
|
68
|
+
````
|
|
69
|
+
|
|
70
|
+
The plugin replaces the whole `<pre>` with `<div class="ampless-mermaid">…svg…</div>` once rendered, so you can target `.ampless-mermaid` from your theme CSS.
|
|
71
|
+
|
|
72
|
+
## Coexistence with @ampless/plugin-highlight
|
|
73
|
+
|
|
74
|
+
The two plugins are designed to run together in any order. `@ampless/plugin-highlight` explicitly skips `code.language-mermaid`, and this plugin replaces the `<pre>` outright, so a Mermaid block is never syntax-highlighted and a highlighted block is never treated as a diagram.
|
|
75
|
+
|
|
76
|
+
## Client-side robustness
|
|
77
|
+
|
|
78
|
+
- **Idempotent re-scan** — processed blocks are marked with `data-ampless-done`, so the scan never double-renders.
|
|
79
|
+
- **SPA / App Router navigation** — the head script runs once, but a debounced `MutationObserver` on `document.body` re-scans when client navigation injects new post content.
|
|
80
|
+
- **Failure recovery** — if the dynamic import fails, the cached import promise is cleared and the block marks are removed so a later scan retries; failures are reported via `console.warn` rather than swallowed. A per-diagram render failure leaves the original code block visible.
|
|
81
|
+
|
|
82
|
+
## Security / CDN notes
|
|
83
|
+
|
|
84
|
+
- **`securityLevel: 'strict'` is the default** because the diagram source comes from the (semi-trusted) post body. Switching to `'loose'` enables interactive features (click handlers, links) but also allows `javascript:` href XSS authored into a diagram. Only use `'loose'` if you fully trust everyone who can edit post bodies.
|
|
85
|
+
- **Pinned default version.** The default `version` is an exact `x.y.z` to minimize supply-chain surface. You may pass a floating major/minor tag (e.g. `'11'`), but the supply-chain risk of a floating tag is your responsibility.
|
|
86
|
+
- **Dynamic `import()` cannot use Subresource Integrity (SRI).** The library is fetched from jsDelivr at runtime; there is no integrity pin. Self-hosting the library is a possible future option.
|
|
87
|
+
|
|
88
|
+
## What it does not do (v1)
|
|
89
|
+
|
|
90
|
+
- **No SVG post-processing / DOMPurify pass** beyond mermaid's own `securityLevel`. Hardening the rendered SVG is a possible future enhancement.
|
|
91
|
+
- **No build-time / server-side rendering** — diagrams render in the browser, so a no-JS client or the first paint shows the raw diagram source.
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { AmplessPlugin } from 'ampless';
|
|
2
|
+
|
|
3
|
+
declare const THEMES: readonly ["default", "dark", "forest", "neutral", "base"];
|
|
4
|
+
declare const SECURITY_LEVELS: readonly ["strict", "loose", "antiscript", "sandbox"];
|
|
5
|
+
type MermaidTheme = (typeof THEMES)[number];
|
|
6
|
+
type MermaidSecurityLevel = (typeof SECURITY_LEVELS)[number];
|
|
7
|
+
interface MermaidPluginOptions {
|
|
8
|
+
/**
|
|
9
|
+
* mermaid version to load from jsDelivr. Must be an exact or partial
|
|
10
|
+
* `x` / `x.y` / `x.y.z` version string. Invalid values fall back to the
|
|
11
|
+
* pinned default with a `console.warn`. Floating major/minor tags are
|
|
12
|
+
* accepted but their supply-chain risk is the site author's
|
|
13
|
+
* responsibility.
|
|
14
|
+
*/
|
|
15
|
+
version?: string;
|
|
16
|
+
/** mermaid theme. One of default / dark / forest / neutral / base. */
|
|
17
|
+
theme?: MermaidTheme;
|
|
18
|
+
/**
|
|
19
|
+
* mermaid `securityLevel`. Default `'strict'`. `'loose'` enables
|
|
20
|
+
* interactivity (click handlers, links) but allows `javascript:` href
|
|
21
|
+
* XSS from the (semi-trusted) diagram source — see README.
|
|
22
|
+
*/
|
|
23
|
+
securityLevel?: MermaidSecurityLevel;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Factory for the Mermaid diagram plugin. Usage in `cms.config.ts`:
|
|
27
|
+
*
|
|
28
|
+
* ```ts
|
|
29
|
+
* import { defineConfig } from 'ampless'
|
|
30
|
+
* import mermaidPlugin from '@ampless/plugin-mermaid'
|
|
31
|
+
*
|
|
32
|
+
* export default defineConfig({
|
|
33
|
+
* plugins: [mermaidPlugin()],
|
|
34
|
+
* })
|
|
35
|
+
* ```
|
|
36
|
+
*/
|
|
37
|
+
declare function mermaidPlugin(opts?: MermaidPluginOptions): AmplessPlugin;
|
|
38
|
+
|
|
39
|
+
export { type MermaidPluginOptions, type MermaidSecurityLevel, type MermaidTheme, mermaidPlugin as default };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
// src/index.ts
|
|
2
|
+
import { definePlugin } from "ampless";
|
|
3
|
+
var DEFAULT_VERSION = "11.15.0";
|
|
4
|
+
var DEFAULT_THEME = "default";
|
|
5
|
+
var DEFAULT_SECURITY_LEVEL = "strict";
|
|
6
|
+
var VERSION_RE = /^[0-9]+(\.[0-9]+){0,2}$/;
|
|
7
|
+
var THEMES = ["default", "dark", "forest", "neutral", "base"];
|
|
8
|
+
var SECURITY_LEVELS = ["strict", "loose", "antiscript", "sandbox"];
|
|
9
|
+
function pickAllowed(value, allowed, fallback, label) {
|
|
10
|
+
if (value === void 0) return fallback;
|
|
11
|
+
if (allowed.includes(value)) return value;
|
|
12
|
+
console.warn(
|
|
13
|
+
`[ampless-mermaid] ignoring invalid ${label} "${value}"; falling back to "${fallback}".`
|
|
14
|
+
);
|
|
15
|
+
return fallback;
|
|
16
|
+
}
|
|
17
|
+
function pickVersion(value) {
|
|
18
|
+
if (value === void 0) return DEFAULT_VERSION;
|
|
19
|
+
if (VERSION_RE.test(value)) return value;
|
|
20
|
+
console.warn(
|
|
21
|
+
`[ampless-mermaid] ignoring invalid version "${value}"; falling back to "${DEFAULT_VERSION}".`
|
|
22
|
+
);
|
|
23
|
+
return DEFAULT_VERSION;
|
|
24
|
+
}
|
|
25
|
+
function buildBody(version, theme, securityLevel) {
|
|
26
|
+
const SEC = JSON.stringify(securityLevel);
|
|
27
|
+
const THEME = JSON.stringify(theme);
|
|
28
|
+
const SRC = JSON.stringify(
|
|
29
|
+
`https://cdn.jsdelivr.net/npm/mermaid@${version}/dist/mermaid.esm.min.mjs`
|
|
30
|
+
);
|
|
31
|
+
return `(function () {
|
|
32
|
+
var modPromise;
|
|
33
|
+
var counter = 0;
|
|
34
|
+
function scan() {
|
|
35
|
+
var blocks = Array.prototype.slice.call(
|
|
36
|
+
document.querySelectorAll('pre > code.language-mermaid:not([data-ampless-done])')
|
|
37
|
+
);
|
|
38
|
+
if (!blocks.length) return;
|
|
39
|
+
// Mark first so a re-entrant scan (MutationObserver firing while the
|
|
40
|
+
// import resolves) does not double-process the same block.
|
|
41
|
+
blocks.forEach(function (b) { b.setAttribute('data-ampless-done', '1'); });
|
|
42
|
+
if (!modPromise) modPromise = import(${SRC});
|
|
43
|
+
modPromise.then(function (mod) {
|
|
44
|
+
var mermaid = mod.default;
|
|
45
|
+
mermaid.initialize({ startOnLoad: false, securityLevel: ${SEC}, theme: ${THEME} });
|
|
46
|
+
blocks.forEach(function (code) {
|
|
47
|
+
var pre = code.closest('pre');
|
|
48
|
+
var uuid = globalThis.crypto && globalThis.crypto.randomUUID
|
|
49
|
+
? globalThis.crypto.randomUUID() : undefined;
|
|
50
|
+
var id = uuid ? 'm' + uuid : 'ampless-mmd-' + (counter++);
|
|
51
|
+
Promise.resolve()
|
|
52
|
+
.then(function () { return mermaid.render(id, code.textContent || ''); })
|
|
53
|
+
.then(function (res) {
|
|
54
|
+
var wrap = document.createElement('div');
|
|
55
|
+
wrap.className = 'ampless-mermaid';
|
|
56
|
+
wrap.innerHTML = res.svg;
|
|
57
|
+
(pre || code).replaceWith(wrap);
|
|
58
|
+
})
|
|
59
|
+
.catch(function (e) {
|
|
60
|
+
// Keep the original code visible and allow a later scan to retry.
|
|
61
|
+
code.removeAttribute('data-ampless-done');
|
|
62
|
+
console.warn('[ampless-mermaid] render failed', e);
|
|
63
|
+
});
|
|
64
|
+
});
|
|
65
|
+
}).catch(function (e) {
|
|
66
|
+
// Drop the cached import so a later scan re-attempts the load, and
|
|
67
|
+
// unmark the blocks so they are picked up again.
|
|
68
|
+
modPromise = undefined;
|
|
69
|
+
blocks.forEach(function (b) { b.removeAttribute('data-ampless-done'); });
|
|
70
|
+
console.warn('[ampless-mermaid] load failed', e);
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
function init() {
|
|
74
|
+
scan();
|
|
75
|
+
// SPA / App Router client navigation: the head script runs once but new
|
|
76
|
+
// post content arrives later. Re-scan (debounced) when the body mutates.
|
|
77
|
+
if (typeof MutationObserver === 'function') {
|
|
78
|
+
var t;
|
|
79
|
+
var obs = new MutationObserver(function () {
|
|
80
|
+
clearTimeout(t);
|
|
81
|
+
t = setTimeout(scan, 100);
|
|
82
|
+
});
|
|
83
|
+
obs.observe(document.body, { childList: true, subtree: true });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
if (document.readyState === 'loading') {
|
|
87
|
+
document.addEventListener('DOMContentLoaded', init);
|
|
88
|
+
} else {
|
|
89
|
+
init();
|
|
90
|
+
}
|
|
91
|
+
})();`;
|
|
92
|
+
}
|
|
93
|
+
function mermaidPlugin(opts = {}) {
|
|
94
|
+
const version = pickVersion(opts.version);
|
|
95
|
+
const theme = pickAllowed(opts.theme, THEMES, DEFAULT_THEME, "theme");
|
|
96
|
+
const securityLevel = pickAllowed(
|
|
97
|
+
opts.securityLevel,
|
|
98
|
+
SECURITY_LEVELS,
|
|
99
|
+
DEFAULT_SECURITY_LEVEL,
|
|
100
|
+
"securityLevel"
|
|
101
|
+
);
|
|
102
|
+
const body = buildBody(version, theme, securityLevel);
|
|
103
|
+
return definePlugin({
|
|
104
|
+
name: "mermaid",
|
|
105
|
+
apiVersion: 1,
|
|
106
|
+
packageName: "@ampless/plugin-mermaid",
|
|
107
|
+
trust_level: "untrusted",
|
|
108
|
+
capabilities: ["publicHead"],
|
|
109
|
+
displayName: { en: "Mermaid diagrams", ja: "Mermaid \u30C0\u30A4\u30A2\u30B0\u30E9\u30E0" },
|
|
110
|
+
publicHead() {
|
|
111
|
+
return [{ type: "inlineScript", id: "ampless-mermaid", body }];
|
|
112
|
+
}
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
export {
|
|
116
|
+
mermaidPlugin as default
|
|
117
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@ampless/plugin-mermaid",
|
|
3
|
+
"version": "0.1.0-beta.0",
|
|
4
|
+
"description": "Mermaid diagram plugin for ampless — renders `code.language-mermaid` blocks on the public site as diagrams via a lazily CDN-loaded mermaid.js",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": "./dist/index.js",
|
|
10
|
+
"types": "./dist/index.d.ts"
|
|
11
|
+
},
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist",
|
|
16
|
+
"README.md"
|
|
17
|
+
],
|
|
18
|
+
"publishConfig": {
|
|
19
|
+
"access": "public"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/heavymoons/ampless.git",
|
|
24
|
+
"directory": "packages/plugin-mermaid"
|
|
25
|
+
},
|
|
26
|
+
"homepage": "https://github.com/heavymoons/ampless/tree/main/packages/plugin-mermaid#readme",
|
|
27
|
+
"bugs": "https://github.com/heavymoons/ampless/issues",
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"ampless": "1.0.0-beta.52"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"ampless",
|
|
33
|
+
"plugin",
|
|
34
|
+
"ampless-plugin",
|
|
35
|
+
"mermaid",
|
|
36
|
+
"diagram",
|
|
37
|
+
"flowchart",
|
|
38
|
+
"cms"
|
|
39
|
+
],
|
|
40
|
+
"amplessPlugin": {
|
|
41
|
+
"apiVersion": 1,
|
|
42
|
+
"name": "mermaid",
|
|
43
|
+
"trustLevel": "untrusted",
|
|
44
|
+
"capabilities": [
|
|
45
|
+
"publicHead"
|
|
46
|
+
],
|
|
47
|
+
"displayName": {
|
|
48
|
+
"en": "Mermaid diagrams",
|
|
49
|
+
"ja": "Mermaid ダイアグラム"
|
|
50
|
+
}
|
|
51
|
+
},
|
|
52
|
+
"scripts": {
|
|
53
|
+
"build": "tsup",
|
|
54
|
+
"dev": "tsup --watch",
|
|
55
|
+
"lint": "tsc --noEmit",
|
|
56
|
+
"test": "vitest run --passWithNoTests"
|
|
57
|
+
}
|
|
58
|
+
}
|