@draftably/markdown 0.0.0-stage → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -2
- package/dist/LICENSE +21 -0
- package/dist/chunks/core-D4HpamVq.js +323 -0
- package/dist/chunks/mermaid-facade-BoLWBerE.js +289 -0
- package/dist/chunks/mermaid-importer-IVovOQE9.js +3753 -0
- package/dist/chunks/metadata-Dx6T_2Zy.js +53 -0
- package/dist/client.js +153 -0
- package/dist/files.js +103 -0
- package/dist/index.js +8 -0
- package/dist/markdown-it.js +156 -0
- package/dist/mermaid.js +93 -0
- package/dist/remark.js +86 -0
- package/dist/types/packages/markdown/src/client-validation.d.ts +5 -0
- package/dist/types/packages/markdown/src/client.d.ts +12 -0
- package/dist/types/packages/markdown/src/core.d.ts +110 -0
- package/dist/types/packages/markdown/src/files.d.ts +12 -0
- package/dist/types/packages/markdown/src/index.d.ts +3 -0
- package/dist/types/packages/markdown/src/markdown-it-helpers.d.ts +9 -0
- package/dist/types/packages/markdown/src/markdown-it.d.ts +30 -0
- package/dist/types/packages/markdown/src/mermaid.d.ts +8 -0
- package/dist/types/packages/markdown/src/metadata.d.ts +9 -0
- package/dist/types/packages/markdown/src/remark.d.ts +21 -0
- package/dist/types/packages/markdown/src/source.d.ts +4 -0
- package/dist/types/src/dsl/cells.d.ts +91 -0
- package/dist/types/src/dsl/channels.d.ts +53 -0
- package/dist/types/src/dsl/compile.d.ts +162 -0
- package/dist/types/src/dsl/frame.d.ts +38 -0
- package/dist/types/src/dsl/lanes.d.ts +23 -0
- package/dist/types/src/dsl/legend-notes.d.ts +3 -0
- package/dist/types/src/dsl/project.d.ts +39 -0
- package/dist/types/src/dsl/syntax.d.ts +317 -0
- package/dist/types/src/import/import-core.d.ts +105 -0
- package/dist/types/src/import/mermaid-facade.d.ts +120 -0
- package/dist/types/src/import/mermaid-importer.d.ts +4 -0
- package/dist/types/src/import/mermaid-sequence.d.ts +8 -0
- package/dist/types/src/model/appearance.d.ts +209 -0
- package/dist/types/src/model/bounds.d.ts +19 -0
- package/dist/types/src/model/document.d.ts +24 -0
- package/dist/types/src/model/font-faces.d.ts +24 -0
- package/dist/types/src/model/fonts.d.ts +47 -0
- package/dist/types/src/model/footnote.d.ts +34 -0
- package/dist/types/src/model/geometry.d.ts +29 -0
- package/dist/types/src/model/graph.d.ts +53 -0
- package/dist/types/src/model/heading.d.ts +38 -0
- package/dist/types/src/model/icons.d.ts +2 -0
- package/dist/types/src/model/labels.d.ts +88 -0
- package/dist/types/src/model/link.d.ts +63 -0
- package/dist/types/src/model/markers.d.ts +47 -0
- package/dist/types/src/model/note.d.ts +75 -0
- package/dist/types/src/model/rich-text.d.ts +24 -0
- package/dist/types/src/model/routes.d.ts +170 -0
- package/dist/types/src/model/status.d.ts +84 -0
- package/dist/types/src/model/styles.d.ts +13 -0
- package/dist/types/src/model/types.d.ts +277 -0
- package/package.json +53 -3
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
function w(a) {
|
|
2
|
+
const n = a.charCodeAt(0);
|
|
3
|
+
return n < 32 || n === 127;
|
|
4
|
+
}
|
|
5
|
+
function f(a) {
|
|
6
|
+
const n = /^draft(?:\s+\{([\s\S]*)\})?$/.exec(a.trim());
|
|
7
|
+
if (!n)
|
|
8
|
+
throw new Error('Expected the canonical draft fence, optionally followed by {key="value"}.');
|
|
9
|
+
const r = n[1];
|
|
10
|
+
if (r === void 0) return {};
|
|
11
|
+
const t = {};
|
|
12
|
+
let e = 0;
|
|
13
|
+
const i = () => {
|
|
14
|
+
for (; /\s/.test(r[e] ?? "") && e < r.length; ) e++;
|
|
15
|
+
};
|
|
16
|
+
for (; e < r.length && (i(), e !== r.length); ) {
|
|
17
|
+
const o = /^[A-Za-z][A-Za-z0-9_-]*/.exec(r.slice(e))?.[0];
|
|
18
|
+
if (!o) throw new Error(`Invalid metadata near "${r.slice(e)}".`);
|
|
19
|
+
if (e += o.length, i(), r[e++] !== "=") throw new Error(`Expected '=' after ${o}.`);
|
|
20
|
+
if (i(), r[e++] !== '"') throw new Error(`${o} must use a quoted value.`);
|
|
21
|
+
let c = "", d = !1;
|
|
22
|
+
for (; e < r.length; ) {
|
|
23
|
+
const s = r[e++];
|
|
24
|
+
if (s === '"') {
|
|
25
|
+
d = !0;
|
|
26
|
+
break;
|
|
27
|
+
}
|
|
28
|
+
if (s === "\\") {
|
|
29
|
+
const l = r[e++];
|
|
30
|
+
if (l !== '"' && l !== "\\") throw new Error(`Invalid escape in ${o}.`);
|
|
31
|
+
c += l;
|
|
32
|
+
} else {
|
|
33
|
+
if (w(s)) throw new Error(`${o} cannot contain control characters.`);
|
|
34
|
+
c += s;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
if (!d) throw new Error(`Unclosed value for ${o}.`);
|
|
38
|
+
if (!["id", "alt", "caption", "src", "mode", "state"].includes(o))
|
|
39
|
+
throw new Error(`Unknown draft option "${o}".`);
|
|
40
|
+
if (Object.hasOwn(t, o)) throw new Error(`Duplicate draft option "${o}".`);
|
|
41
|
+
t[o] = c, i();
|
|
42
|
+
}
|
|
43
|
+
if (t.id !== void 0 && !/^[A-Za-z0-9_-]+$/.test(t.id))
|
|
44
|
+
throw new Error("id must be a non-empty ASCII token.");
|
|
45
|
+
if (t.mode !== void 0 && t.mode !== "static" && t.mode !== "interactive")
|
|
46
|
+
throw new Error('mode must be "static" or "interactive".');
|
|
47
|
+
if (t.src !== void 0 && (!t.src.endsWith(".draft") || t.src.trim() !== t.src || t.src.includes("\0") || t.src.startsWith("/") || t.src.startsWith("\\") || /^[A-Za-z][A-Za-z\d+.-]*:/.test(t.src) || /^[A-Za-z]:/.test(t.src)))
|
|
48
|
+
throw new Error("src must name a relative local .draft file.");
|
|
49
|
+
return t;
|
|
50
|
+
}
|
|
51
|
+
export {
|
|
52
|
+
f as p
|
|
53
|
+
};
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { mountViewer as k } from "@draftably/runtime/viewer";
|
|
2
|
+
const m = 1e6, v = 1e6;
|
|
3
|
+
function T(e) {
|
|
4
|
+
for (const a of e) {
|
|
5
|
+
const n = a.charCodeAt(0);
|
|
6
|
+
if (n < 32 || n === 127) return !0;
|
|
7
|
+
}
|
|
8
|
+
return !1;
|
|
9
|
+
}
|
|
10
|
+
function p(e, a, n) {
|
|
11
|
+
if (!e || T(e)) throw new Error("Invalid initialization URL.");
|
|
12
|
+
const i = new URL(e, n);
|
|
13
|
+
if (!["http:", "https:"].includes(i.protocol) || i.origin !== a || i.username || i.password)
|
|
14
|
+
throw new Error("Initialization URL must be same-origin.");
|
|
15
|
+
return i;
|
|
16
|
+
}
|
|
17
|
+
function A(e, a, n) {
|
|
18
|
+
if (new TextEncoder().encode(e).byteLength > m) throw new Error("Initialization data exceeds the size limit.");
|
|
19
|
+
let o;
|
|
20
|
+
try {
|
|
21
|
+
o = JSON.parse(e);
|
|
22
|
+
} catch {
|
|
23
|
+
throw new Error("Initialization data is not valid JSON.");
|
|
24
|
+
}
|
|
25
|
+
if (!o || typeof o != "object" || Array.isArray(o))
|
|
26
|
+
throw new Error("Initialization data has an invalid shape.");
|
|
27
|
+
const t = o;
|
|
28
|
+
if (Object.keys(t).sort().join(",") !== "key,label,policyId,source,state,version")
|
|
29
|
+
throw new Error("Initialization data has unknown or missing fields.");
|
|
30
|
+
if (t.version !== 1 || t.key !== a || !/^draft-[0-9a-f]{24}$/.test(a))
|
|
31
|
+
throw new Error("Initialization identity is invalid.");
|
|
32
|
+
if (t.policyId !== n || typeof t.policyId != "string")
|
|
33
|
+
throw new Error("Initialization policy does not match.");
|
|
34
|
+
if (typeof t.source != "string" || new TextEncoder().encode(t.source).byteLength > v)
|
|
35
|
+
throw new Error("Diagram source is invalid or too large.");
|
|
36
|
+
if (typeof t.label != "string" || t.label.length > 2e3)
|
|
37
|
+
throw new Error("Diagram label is invalid.");
|
|
38
|
+
if (t.state !== null && typeof t.state != "string")
|
|
39
|
+
throw new Error("Diagram state is invalid.");
|
|
40
|
+
return t;
|
|
41
|
+
}
|
|
42
|
+
const u = /* @__PURE__ */ new WeakSet();
|
|
43
|
+
async function S(e) {
|
|
44
|
+
if (!e.ok) throw new Error(`Initialization request failed with HTTP ${e.status}.`);
|
|
45
|
+
const a = Number(e.headers.get("content-length"));
|
|
46
|
+
if (Number.isFinite(a) && a > m)
|
|
47
|
+
throw new Error("Initialization response exceeds the size limit.");
|
|
48
|
+
if (!e.body) throw new Error("Initialization response has no body.");
|
|
49
|
+
const n = e.body.getReader(), i = [];
|
|
50
|
+
let o = 0;
|
|
51
|
+
try {
|
|
52
|
+
for (; ; ) {
|
|
53
|
+
const { done: s, value: f } = await n.read();
|
|
54
|
+
if (s) break;
|
|
55
|
+
if (o += f.byteLength, o > m)
|
|
56
|
+
throw await n.cancel(), new Error("Initialization response exceeds the size limit.");
|
|
57
|
+
i.push(f);
|
|
58
|
+
}
|
|
59
|
+
} finally {
|
|
60
|
+
n.releaseLock();
|
|
61
|
+
}
|
|
62
|
+
const t = new Uint8Array(o);
|
|
63
|
+
let l = 0;
|
|
64
|
+
for (const s of i)
|
|
65
|
+
t.set(s, l), l += s.byteLength;
|
|
66
|
+
return new TextDecoder("utf-8", { fatal: !0 }).decode(t);
|
|
67
|
+
}
|
|
68
|
+
function D(e) {
|
|
69
|
+
return { code: "DRAFT_ENHANCE", severity: "warning", message: e, itemIds: [] };
|
|
70
|
+
}
|
|
71
|
+
function U(e, a) {
|
|
72
|
+
if (u.has(e))
|
|
73
|
+
throw new Error("This Markdown root already has an active Draftably enhancement.");
|
|
74
|
+
u.add(e);
|
|
75
|
+
const n = e.ownerDocument, i = n.defaultView;
|
|
76
|
+
if (!i)
|
|
77
|
+
throw u.delete(e), new Error("The Markdown root has no browser window.");
|
|
78
|
+
let o = !1;
|
|
79
|
+
const t = /* @__PURE__ */ new Set(), l = /* @__PURE__ */ new Set(), s = [], f = (r) => {
|
|
80
|
+
try {
|
|
81
|
+
a.onDiagnostic?.(D(r));
|
|
82
|
+
} catch {
|
|
83
|
+
}
|
|
84
|
+
}, I = Array.from(
|
|
85
|
+
e.querySelectorAll("[data-draftably-region][data-draftably-init]")
|
|
86
|
+
);
|
|
87
|
+
for (const r of I) {
|
|
88
|
+
const w = r.closest("figure")?.querySelector("img");
|
|
89
|
+
if (w) {
|
|
90
|
+
const h = w.hidden;
|
|
91
|
+
s.push(() => {
|
|
92
|
+
w.hidden = h;
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
const c = new i.AbortController();
|
|
96
|
+
t.add(c), (async () => {
|
|
97
|
+
let h;
|
|
98
|
+
try {
|
|
99
|
+
const y = p(
|
|
100
|
+
r.dataset.draftablyInit ?? "",
|
|
101
|
+
i.location.origin,
|
|
102
|
+
n.baseURI
|
|
103
|
+
), g = await i.fetch(y, {
|
|
104
|
+
signal: c.signal,
|
|
105
|
+
credentials: "same-origin",
|
|
106
|
+
redirect: "error"
|
|
107
|
+
});
|
|
108
|
+
g.url && p(g.url, i.location.origin, n.baseURI);
|
|
109
|
+
const z = await S(g);
|
|
110
|
+
if (o || c.signal.aborted) return;
|
|
111
|
+
const d = A(
|
|
112
|
+
z,
|
|
113
|
+
r.dataset.draftablyKey ?? "",
|
|
114
|
+
r.dataset.draftablyPolicy ?? ""
|
|
115
|
+
), b = a.policies.get(d.policyId);
|
|
116
|
+
if (!b) throw new Error("No viewer policy is configured for this diagram.");
|
|
117
|
+
if (r.dataset.draftablyKey !== d.key || r.dataset.draftablyPolicy !== d.policyId)
|
|
118
|
+
throw new Error("Figure markers do not match initialization data.");
|
|
119
|
+
if (r.childNodes.length) throw new Error("Viewer region is not empty.");
|
|
120
|
+
h = k(r, { ...b, label: b.label ?? d.label }), l.add(h);
|
|
121
|
+
const E = await h.update(d.source, {
|
|
122
|
+
state: d.state,
|
|
123
|
+
camera: "fit",
|
|
124
|
+
signal: c.signal
|
|
125
|
+
});
|
|
126
|
+
if (o || c.signal.aborted) return;
|
|
127
|
+
E.status === "committed" && w ? w.hidden = !0 : E.status === "error" && f("The interactive diagram could not load. The static image is still available.");
|
|
128
|
+
} catch (y) {
|
|
129
|
+
!o && !c.signal.aborted && f(
|
|
130
|
+
y instanceof Error ? y.message : "The interactive diagram could not load."
|
|
131
|
+
);
|
|
132
|
+
} finally {
|
|
133
|
+
t.delete(c);
|
|
134
|
+
}
|
|
135
|
+
})();
|
|
136
|
+
}
|
|
137
|
+
return {
|
|
138
|
+
destroy() {
|
|
139
|
+
if (!o) {
|
|
140
|
+
o = !0;
|
|
141
|
+
for (const r of t) r.abort();
|
|
142
|
+
t.clear();
|
|
143
|
+
for (const r of l) r.destroy();
|
|
144
|
+
l.clear();
|
|
145
|
+
for (const r of s) r();
|
|
146
|
+
s.length = 0, u.delete(e);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
}
|
|
151
|
+
export {
|
|
152
|
+
U as enhanceDrafts
|
|
153
|
+
};
|
package/dist/files.js
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { randomUUID as v, createHash as $ } from "node:crypto";
|
|
2
|
+
import { mkdir as m, readdir as x, readFile as p, writeFile as b, link as N, rm as U } from "node:fs/promises";
|
|
3
|
+
import { resolve as h, join as l } from "node:path";
|
|
4
|
+
function A(t) {
|
|
5
|
+
return $("sha256").update(t).digest("hex");
|
|
6
|
+
}
|
|
7
|
+
function g(t, r) {
|
|
8
|
+
return `draft-${A(t)}.${r}`;
|
|
9
|
+
}
|
|
10
|
+
function j(t) {
|
|
11
|
+
for (const r of t) {
|
|
12
|
+
const o = r.charCodeAt(0);
|
|
13
|
+
if (o < 32 || o === 127) return !0;
|
|
14
|
+
}
|
|
15
|
+
return !1;
|
|
16
|
+
}
|
|
17
|
+
function S(t) {
|
|
18
|
+
if (typeof t != "string" || !t || /[\s\\?#]/.test(t) || j(t))
|
|
19
|
+
throw new TypeError(
|
|
20
|
+
"publicPath must be a URL path without query, hash, backslash, or controls."
|
|
21
|
+
);
|
|
22
|
+
let r;
|
|
23
|
+
if (t.startsWith("/")) {
|
|
24
|
+
if (t.startsWith("//"))
|
|
25
|
+
throw new TypeError("publicPath must not be protocol-relative.");
|
|
26
|
+
r = t;
|
|
27
|
+
} else {
|
|
28
|
+
let o;
|
|
29
|
+
try {
|
|
30
|
+
o = new URL(t);
|
|
31
|
+
} catch {
|
|
32
|
+
throw new TypeError("publicPath must be root-relative or an absolute HTTP(S) URL.");
|
|
33
|
+
}
|
|
34
|
+
if (!["http:", "https:"].includes(o.protocol) || o.username || o.password)
|
|
35
|
+
throw new TypeError("publicPath must be root-relative or an absolute HTTP(S) URL.");
|
|
36
|
+
r = `${o.origin}${o.pathname}`;
|
|
37
|
+
}
|
|
38
|
+
return r.replace(/\/+$/, "");
|
|
39
|
+
}
|
|
40
|
+
async function d(t, r, o) {
|
|
41
|
+
await m(t, { recursive: !0 });
|
|
42
|
+
const s = l(t, r), c = l(t, `.${r}.${v()}.tmp`);
|
|
43
|
+
try {
|
|
44
|
+
await b(c, o, { flag: "wx" });
|
|
45
|
+
try {
|
|
46
|
+
await N(c, s);
|
|
47
|
+
} catch (f) {
|
|
48
|
+
if (f.code !== "EEXIST") throw f;
|
|
49
|
+
if (!(await p(s)).equals(o)) throw new Error(`Asset collision: ${r}`, { cause: f });
|
|
50
|
+
}
|
|
51
|
+
} finally {
|
|
52
|
+
await U(c, { force: !0 });
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
function y(t, r) {
|
|
56
|
+
const o = t.endsWith(".svg") ? "svg" : t.endsWith(".json") ? "json" : void 0;
|
|
57
|
+
return !!o && t === g(r, o);
|
|
58
|
+
}
|
|
59
|
+
function R(t) {
|
|
60
|
+
if (!t || typeof t.directory != "string" || !t.directory)
|
|
61
|
+
throw new TypeError("directory must be a non-empty path.");
|
|
62
|
+
const r = h(t.directory), o = S(t.publicPath), s = /* @__PURE__ */ new Map();
|
|
63
|
+
async function c(e, i) {
|
|
64
|
+
if (!y(e, i))
|
|
65
|
+
throw new TypeError(`Invalid content-addressed asset name: ${e}`);
|
|
66
|
+
let n = s.get(e);
|
|
67
|
+
n || (n = d(r, e, i), s.set(e, n));
|
|
68
|
+
try {
|
|
69
|
+
await n;
|
|
70
|
+
} finally {
|
|
71
|
+
s.get(e) === n && s.delete(e);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
const f = (e) => `${o}/${e}`, u = async (e) => {
|
|
75
|
+
if (e.mediaType !== "image/svg+xml" || !e.fileName.endsWith(".svg"))
|
|
76
|
+
throw new TypeError("Expected a content-addressed Draftably SVG.");
|
|
77
|
+
return await c(e.fileName, e.bytes), { url: f(e.fileName) };
|
|
78
|
+
}, T = async (e) => {
|
|
79
|
+
const i = new TextEncoder().encode(JSON.stringify(e)), n = g(i, "json");
|
|
80
|
+
return await c(n, i), { fileName: n, url: f(n) };
|
|
81
|
+
};
|
|
82
|
+
async function E(e) {
|
|
83
|
+
const i = h(e);
|
|
84
|
+
await m(i, { recursive: !0 });
|
|
85
|
+
let n;
|
|
86
|
+
try {
|
|
87
|
+
n = await x(r);
|
|
88
|
+
} catch (a) {
|
|
89
|
+
if (a.code === "ENOENT") return;
|
|
90
|
+
throw a;
|
|
91
|
+
}
|
|
92
|
+
for (const a of n) {
|
|
93
|
+
if (!/^draft-[0-9a-f]{64}\.(?:svg|json)$/.test(a)) continue;
|
|
94
|
+
const w = await p(l(r, a));
|
|
95
|
+
if (!y(a, w)) throw new Error(`Asset content hash mismatch: ${a}`);
|
|
96
|
+
await d(i, a, w);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return { directory: r, emitAsset: u, emitInit: T, copyTo: E };
|
|
100
|
+
}
|
|
101
|
+
export {
|
|
102
|
+
R as createFileAssets
|
|
103
|
+
};
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
import { m as I, a as T, p as F, i as j, b as x, h as H } from "./chunks/core-D4HpamVq.js";
|
|
2
|
+
import { p as O } from "./chunks/metadata-Dx6T_2Zy.js";
|
|
3
|
+
function R(t) {
|
|
4
|
+
return /^draft(?:\s|$)/.test(t.trim());
|
|
5
|
+
}
|
|
6
|
+
function M(t) {
|
|
7
|
+
return t.replace(
|
|
8
|
+
/[&<>"']/g,
|
|
9
|
+
(e) => ({
|
|
10
|
+
"&": "&",
|
|
11
|
+
"<": "<",
|
|
12
|
+
">": ">",
|
|
13
|
+
'"': """,
|
|
14
|
+
"'": "'"
|
|
15
|
+
})[e]
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
function _(t) {
|
|
19
|
+
const e = `${t.width === void 0 ? "" : ` width="${t.width}"`}${t.height === void 0 ? "" : ` height="${t.height}"`}`;
|
|
20
|
+
return `<img src="${M(t.url)}" alt="${M(t.alt)}"${e}>`;
|
|
21
|
+
}
|
|
22
|
+
function A(t, e) {
|
|
23
|
+
const c = t.type;
|
|
24
|
+
if (c === "paragraph") {
|
|
25
|
+
const r = t.data?.hProperties ?? {}, f = typeof r.id == "string" ? ` id="${e(r.id)}"` : "", o = t.children.map((s) => A(s, e)).join("");
|
|
26
|
+
return `<p${f}>${o}</p>
|
|
27
|
+
`;
|
|
28
|
+
}
|
|
29
|
+
if (c === "figure") {
|
|
30
|
+
const f = t.data?.hProperties?.id, h = typeof f == "string" ? ` id="${e(f)}"` : "", o = t.children;
|
|
31
|
+
return `<figure${h}>${o.map((s) => A(s, e)).join("")}</figure>
|
|
32
|
+
`;
|
|
33
|
+
}
|
|
34
|
+
if (c === "image") {
|
|
35
|
+
const r = t.data?.hProperties ?? {};
|
|
36
|
+
return _({
|
|
37
|
+
url: String(t.url ?? ""),
|
|
38
|
+
alt: String(t.alt ?? ""),
|
|
39
|
+
...typeof r.width == "number" ? { width: r.width } : {},
|
|
40
|
+
...typeof r.height == "number" ? { height: r.height } : {}
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
if (c === "figcaption")
|
|
44
|
+
return `<figcaption>${t.children.map((f) => A(f, e)).join("")}</figcaption>`;
|
|
45
|
+
if (c === "div") {
|
|
46
|
+
const r = t.data?.hProperties ?? {};
|
|
47
|
+
if (!(r["data-draftably-region"] === "") || typeof r["data-draftably-init"] != "string" || typeof r["data-draftably-policy"] != "string" || typeof r["data-draftably-key"] != "string")
|
|
48
|
+
throw new Error("Invalid generated viewer region.");
|
|
49
|
+
const h = typeof r["aria-label"] == "string" ? r["aria-label"] : "Diagram viewer";
|
|
50
|
+
return `<div class="draftably-viewer-region" data-draftably-region="" data-draftably-init="${e(String(r["data-draftably-init"]))}" data-draftably-policy="${e(String(r["data-draftably-policy"]))}" data-draftably-key="${e(String(r["data-draftably-key"]))}" role="region" aria-label="${e(h)}"></div>`;
|
|
51
|
+
}
|
|
52
|
+
if (c === "text") return e(String(t.value ?? ""));
|
|
53
|
+
throw new Error(`Unsupported generated AST node: ${String(c)}.`);
|
|
54
|
+
}
|
|
55
|
+
function B(t) {
|
|
56
|
+
if (!t || typeof t.emitAsset != "function")
|
|
57
|
+
throw new TypeError("createMarkdownItDraft requires an emitAsset function.");
|
|
58
|
+
const e = /* @__PURE__ */ new WeakMap(), c = (o) => o.type === "fence" && R(o.info ?? "");
|
|
59
|
+
function r(o) {
|
|
60
|
+
const s = o, l = s.renderer.rules.fence;
|
|
61
|
+
s.renderer.rules.fence = function(d, p, y, g, b) {
|
|
62
|
+
const $ = d[p];
|
|
63
|
+
if (!c($) && !e.has($))
|
|
64
|
+
return l ? l(d, p, y, g, b) : b.renderToken(d, p, y);
|
|
65
|
+
const v = e.get($);
|
|
66
|
+
if (!v)
|
|
67
|
+
throw new Error(
|
|
68
|
+
"Draft fence rendered before prepare(). Prepare and render the same token tree."
|
|
69
|
+
);
|
|
70
|
+
return A(v.node, (k) => s.utils.escapeHtml(k));
|
|
71
|
+
};
|
|
72
|
+
}
|
|
73
|
+
async function f(o, s, l = {}) {
|
|
74
|
+
const d = o.parse(s, l), p = await h(d, l);
|
|
75
|
+
return { html: o.renderer.render(d, o.options, l), manifest: p };
|
|
76
|
+
}
|
|
77
|
+
async function h(o, s = {}) {
|
|
78
|
+
const l = { path: s.draftably?.documentPath }, d = [], p = /* @__PURE__ */ new Set(), y = /* @__PURE__ */ new Set(), g = [], b = /* @__PURE__ */ new Set(), $ = t.sources && {
|
|
79
|
+
...t.sources,
|
|
80
|
+
onDependency: (m) => {
|
|
81
|
+
p.add(m.dependencyPath);
|
|
82
|
+
try {
|
|
83
|
+
t.sources?.onDependency?.(m);
|
|
84
|
+
} catch (a) {
|
|
85
|
+
throw H(a, "Markdown dependency callback failed.");
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
let v = 0;
|
|
90
|
+
const k = async (m) => {
|
|
91
|
+
for (const a of m) {
|
|
92
|
+
const D = { sourceId: l.path, line: (a.map?.[0] ?? 0) + 1 }, w = a.type === "fence" && /^mermaid(?:\s|$)/.test((a.info ?? "").trim()) ? await I(a.content ?? "", D, t) : void 0;
|
|
93
|
+
if (g.push(...w?.diagnostics ?? []), w && e.delete(a), c(a) || w?.source) {
|
|
94
|
+
const P = v++;
|
|
95
|
+
e.delete(a);
|
|
96
|
+
try {
|
|
97
|
+
let n;
|
|
98
|
+
try {
|
|
99
|
+
n = w ? { alt: w.alt } : O(a.info ?? "");
|
|
100
|
+
} catch (u) {
|
|
101
|
+
const E = u instanceof Error ? u.message : "Invalid draft fence metadata.";
|
|
102
|
+
throw Object.assign(new Error(E), {
|
|
103
|
+
diagnostic: T("DRAFT_METADATA", E, D)
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
if (n.id && b.has(n.id)) {
|
|
107
|
+
const u = `Duplicate draft id "${n.id}" in this document.`;
|
|
108
|
+
throw Object.assign(new Error(u), {
|
|
109
|
+
diagnostic: T("DRAFT_METADATA", u, D)
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
n.id && b.add(n.id);
|
|
113
|
+
const S = w?.source ?? a.content ?? "", i = await F(S, n, D, l, P, {
|
|
114
|
+
...t,
|
|
115
|
+
sources: $
|
|
116
|
+
});
|
|
117
|
+
e.set(a, { node: i.node, diagnostics: i.diagnostics }), i.asset && d.push(i.asset), d.push(...i.extraAssets ?? []), i.dependency && p.add(i.dependency), i.clientModule && y.add(i.clientModule), g.push(...i.diagnostics);
|
|
118
|
+
} catch (n) {
|
|
119
|
+
if (j(n)) throw n.cause ?? n;
|
|
120
|
+
if (x(n)) throw n;
|
|
121
|
+
const S = n.diagnostic, i = n.diagnostics, u = S ?? i?.[0] ?? T(
|
|
122
|
+
"DRAFT_BUILD",
|
|
123
|
+
n instanceof Error ? n.message : "Could not prepare diagram.",
|
|
124
|
+
D
|
|
125
|
+
);
|
|
126
|
+
if (g.push(...i ?? [u]), (t.errors ?? "fail") === "fail")
|
|
127
|
+
throw Object.assign(new Error("Draftably Markdown preparation failed."), {
|
|
128
|
+
diagnostics: i ?? [u]
|
|
129
|
+
});
|
|
130
|
+
e.set(a, {
|
|
131
|
+
node: {
|
|
132
|
+
type: "paragraph",
|
|
133
|
+
children: [{ type: "text", value: "Diagram unavailable." }]
|
|
134
|
+
},
|
|
135
|
+
diagnostics: i ?? [u]
|
|
136
|
+
});
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
a.children?.length && await k(a.children);
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
await k(o);
|
|
143
|
+
for (const m of g) t.onDiagnostic?.(m);
|
|
144
|
+
return {
|
|
145
|
+
version: 1,
|
|
146
|
+
assets: d,
|
|
147
|
+
clientModules: [...y],
|
|
148
|
+
dependencies: [...p],
|
|
149
|
+
diagnostics: g
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return { plugin: r, prepare: h, render: f };
|
|
153
|
+
}
|
|
154
|
+
export {
|
|
155
|
+
B as createMarkdownItDraft
|
|
156
|
+
};
|
package/dist/mermaid.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { isMainThread as y, workerData as b, parentPort as g, Worker as v } from "node:worker_threads";
|
|
2
|
+
const k = /^(?:flowchart|graph|sequenceDiagram)\b/;
|
|
3
|
+
function D(i) {
|
|
4
|
+
const s = i.replace(/^\uFEFF/, "").split(`
|
|
5
|
+
`);
|
|
6
|
+
let e = 0;
|
|
7
|
+
if (s[0]?.trim() === "---" && (e = s.findIndex((t, r) => r > 0 && t.trim() === "---") + 1, e === 0))
|
|
8
|
+
return !1;
|
|
9
|
+
for (; e < s.length; e++) {
|
|
10
|
+
const t = s[e].trim();
|
|
11
|
+
if (!(!t || t.startsWith("%%")))
|
|
12
|
+
return k.test(t);
|
|
13
|
+
}
|
|
14
|
+
return !1;
|
|
15
|
+
}
|
|
16
|
+
let f, F = 0;
|
|
17
|
+
const n = /* @__PURE__ */ new Map();
|
|
18
|
+
function T() {
|
|
19
|
+
const i = new v(new URL(import.meta.url), {
|
|
20
|
+
workerData: { kind: "draftably-mermaid" },
|
|
21
|
+
resourceLimits: { maxOldGenerationSizeMb: 512, stackSizeMb: 4 }
|
|
22
|
+
});
|
|
23
|
+
i.unref();
|
|
24
|
+
const s = (e) => {
|
|
25
|
+
f = void 0;
|
|
26
|
+
for (const [t, r] of n) r({ id: t, messages: [e] });
|
|
27
|
+
n.clear();
|
|
28
|
+
};
|
|
29
|
+
return i.on("message", (e) => {
|
|
30
|
+
n.get(e.id)?.(e), n.delete(e.id);
|
|
31
|
+
}), i.on("error", (e) => s(`Mermaid parser failed: ${e.message}`)), i.on("exit", (e) => s(`Mermaid parser stopped with status ${e}.`)), i;
|
|
32
|
+
}
|
|
33
|
+
async function I(i, s) {
|
|
34
|
+
if (!D(i)) return { source: null, diagnostics: [] };
|
|
35
|
+
f ??= T();
|
|
36
|
+
const e = F++, t = f, r = await new Promise((o) => {
|
|
37
|
+
const d = setTimeout(() => {
|
|
38
|
+
n.delete(e), t.terminate(), o({ id: e, messages: ["Mermaid parsing timed out."] });
|
|
39
|
+
}, 3e4);
|
|
40
|
+
n.set(e, (c) => {
|
|
41
|
+
clearTimeout(d), o(c);
|
|
42
|
+
}), t.ref(), t.postMessage({ id: e, text: i });
|
|
43
|
+
}).finally(() => {
|
|
44
|
+
n.size || t.unref();
|
|
45
|
+
});
|
|
46
|
+
return {
|
|
47
|
+
source: r.source ?? null,
|
|
48
|
+
alt: r.alt,
|
|
49
|
+
diagnostics: r.source ? [] : [
|
|
50
|
+
{
|
|
51
|
+
code: "DRAFT_MERMAID",
|
|
52
|
+
severity: "warning",
|
|
53
|
+
message: `Left this Mermaid fence to Mermaid: ${r.messages.join(" ") || "it could not be converted."}`,
|
|
54
|
+
location: s,
|
|
55
|
+
itemIds: []
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async function S() {
|
|
61
|
+
globalThis.fetch = async () => {
|
|
62
|
+
throw Error("Mermaid resource loading is disabled.");
|
|
63
|
+
};
|
|
64
|
+
const { JSDOM: i } = await import("jsdom"), { createMermaidFlowParser: s, makePlainLabel: e } = await import("./chunks/mermaid-facade-BoLWBerE.js"), { importMermaidFlow: t } = await import("./chunks/mermaid-importer-IVovOQE9.js"), r = new i("<!doctype html><html><body></body></html>", {
|
|
65
|
+
url: "https://import.invalid/"
|
|
66
|
+
});
|
|
67
|
+
Object.assign(globalThis, {
|
|
68
|
+
window: r.window,
|
|
69
|
+
document: r.window.document,
|
|
70
|
+
Option: r.window.Option
|
|
71
|
+
});
|
|
72
|
+
const o = s(async () => (await import("mermaid")).default), d = e(r.window.document);
|
|
73
|
+
g.on("message", async ({ id: c, text: h }) => {
|
|
74
|
+
let m;
|
|
75
|
+
try {
|
|
76
|
+
const a = await o(h), l = a.ok ? a.snapshot : void 0, p = l?.family === "sequence" ? l.title ?? "" : "", M = p || (l?.family === "sequence" ? "Sequence diagram" : "Flowchart"), w = t(a, d, p);
|
|
77
|
+
m = {
|
|
78
|
+
id: c,
|
|
79
|
+
source: w.nativeSource,
|
|
80
|
+
alt: M,
|
|
81
|
+
messages: w.diagnostics.filter((u) => u.severity === "error").map((u) => u.message)
|
|
82
|
+
};
|
|
83
|
+
} catch (a) {
|
|
84
|
+
m = { id: c, messages: [a instanceof Error ? a.message : String(a)] };
|
|
85
|
+
}
|
|
86
|
+
g.postMessage(m);
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
!y && b?.kind === "draftably-mermaid" && S();
|
|
90
|
+
export {
|
|
91
|
+
I as convertMermaid,
|
|
92
|
+
D as isMermaidCandidate
|
|
93
|
+
};
|
package/dist/remark.js
ADDED
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import { m as T, a as g, p as k, i as F, b as x, h as O } from "./chunks/core-D4HpamVq.js";
|
|
2
|
+
import { p as I } from "./chunks/metadata-Dx6T_2Zy.js";
|
|
3
|
+
function R(s) {
|
|
4
|
+
if (!s || typeof s.emitAsset != "function")
|
|
5
|
+
throw new TypeError("remarkDraft requires an emitAsset function.");
|
|
6
|
+
return async (A, f) => {
|
|
7
|
+
const b = { path: f.path }, m = [], w = /* @__PURE__ */ new Set(), p = /* @__PURE__ */ new Set(), v = s.sources && {
|
|
8
|
+
...s.sources,
|
|
9
|
+
onDependency: (i) => {
|
|
10
|
+
p.add(i.dependencyPath);
|
|
11
|
+
try {
|
|
12
|
+
s.sources?.onDependency?.(i);
|
|
13
|
+
} catch (r) {
|
|
14
|
+
throw O(r, "Markdown dependency callback failed.");
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}, o = [], y = /* @__PURE__ */ new Set();
|
|
18
|
+
let E = 0;
|
|
19
|
+
async function D(i) {
|
|
20
|
+
const r = i.children;
|
|
21
|
+
if (r)
|
|
22
|
+
for (let c = 0; c < r.length; c++) {
|
|
23
|
+
const t = r[c], d = {
|
|
24
|
+
sourceId: f.path,
|
|
25
|
+
line: t.position?.start?.line ?? 1,
|
|
26
|
+
column: t.position?.start?.column
|
|
27
|
+
}, l = t.type === "code" && t.lang === "mermaid" ? await T(t.value ?? "", d, s) : void 0;
|
|
28
|
+
if (o.push(...l?.diagnostics ?? []), t.type === "code" && t.lang === "draft" || l?.source) {
|
|
29
|
+
const M = E++;
|
|
30
|
+
try {
|
|
31
|
+
let e;
|
|
32
|
+
try {
|
|
33
|
+
e = l ? { alt: l.alt } : I(t.meta ? `draft ${t.meta}` : "draft");
|
|
34
|
+
} catch (n) {
|
|
35
|
+
const u = n instanceof Error ? n.message : "Invalid draft fence metadata.";
|
|
36
|
+
throw Object.assign(new Error(u), {
|
|
37
|
+
diagnostic: g("DRAFT_METADATA", u, d)
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
if (e.id && y.has(e.id)) {
|
|
41
|
+
const n = `Duplicate draft id "${e.id}" in this document.`;
|
|
42
|
+
throw Object.assign(new Error(n), {
|
|
43
|
+
diagnostic: g("DRAFT_METADATA", n, d)
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
e.id && y.add(e.id);
|
|
47
|
+
const h = l?.source ?? t.value ?? "", a = await k(h, e, d, b, M, {
|
|
48
|
+
...s,
|
|
49
|
+
sources: v
|
|
50
|
+
});
|
|
51
|
+
r.splice(c, 1, a.node), a.asset && m.push(a.asset), m.push(...a.extraAssets ?? []), a.clientModule && w.add(a.clientModule), a.dependency && p.add(a.dependency), o.push(...a.diagnostics);
|
|
52
|
+
} catch (e) {
|
|
53
|
+
if (F(e)) throw e.cause ?? e;
|
|
54
|
+
if (x(e)) throw e;
|
|
55
|
+
const h = e.diagnostic, a = e.diagnostics, n = h ?? a?.[0] ?? g(
|
|
56
|
+
"DRAFT_BUILD",
|
|
57
|
+
e instanceof Error ? e.message : "Could not prepare diagram.",
|
|
58
|
+
d
|
|
59
|
+
);
|
|
60
|
+
if (o.push(...a ?? [n]), (s.errors ?? "fail") === "fail") {
|
|
61
|
+
const u = new Error("Draftably Markdown transform failed.");
|
|
62
|
+
throw Object.assign(u, { diagnostics: a ?? [n] }), u;
|
|
63
|
+
}
|
|
64
|
+
r.splice(c, 1, {
|
|
65
|
+
type: "paragraph",
|
|
66
|
+
children: [{ type: "text", value: "Diagram unavailable." }]
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
} else
|
|
70
|
+
await D(t);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
await D(A);
|
|
74
|
+
for (const i of o) s.onDiagnostic?.(i);
|
|
75
|
+
f.data ??= {}, f.data.draftably = {
|
|
76
|
+
version: 1,
|
|
77
|
+
assets: m,
|
|
78
|
+
clientModules: [...w],
|
|
79
|
+
dependencies: [...p],
|
|
80
|
+
diagnostics: o
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
}
|
|
84
|
+
export {
|
|
85
|
+
R as default
|
|
86
|
+
};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { DraftViewerInitV1 } from './core.js';
|
|
2
|
+
export declare const MAX_INIT_BYTES = 1000000;
|
|
3
|
+
export declare const MAX_SOURCE_BYTES = 1000000;
|
|
4
|
+
export declare function sameOriginInitUrl(value: string, origin: string, baseUrl: string): URL;
|
|
5
|
+
export declare function parseInitJson(text: string, expectedKey: string, expectedPolicy: string): DraftViewerInitV1;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { mountViewer } from '@draftably/runtime/viewer';
|
|
2
|
+
import type { Diagnostic } from '@draftably/runtime';
|
|
3
|
+
type ViewerOptions = Parameters<typeof mountViewer>[1];
|
|
4
|
+
export interface EnhanceDraftsOptions {
|
|
5
|
+
policies: ReadonlyMap<string, ViewerOptions>;
|
|
6
|
+
onDiagnostic?: (diagnostic: Diagnostic) => void;
|
|
7
|
+
}
|
|
8
|
+
/** Load generated init assets and progressively enhance static diagram figures under root. */
|
|
9
|
+
export declare function enhanceDrafts(root: HTMLElement, options: EnhanceDraftsOptions): {
|
|
10
|
+
destroy(): void;
|
|
11
|
+
};
|
|
12
|
+
export {};
|