@mdanai/sdk 0.5.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.
Files changed (151) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +126 -0
  3. package/dist/core/errors.d.ts +14 -0
  4. package/dist/core/errors.d.ts.map +1 -0
  5. package/dist/core/errors.js +13 -0
  6. package/dist/core/errors.js.map +1 -0
  7. package/dist/core/index.d.ts +16 -0
  8. package/dist/core/index.d.ts.map +1 -0
  9. package/dist/core/index.js +69 -0
  10. package/dist/core/index.js.map +1 -0
  11. package/dist/core/markdown-body.d.ts +3 -0
  12. package/dist/core/markdown-body.d.ts.map +1 -0
  13. package/dist/core/markdown-body.js +65 -0
  14. package/dist/core/markdown-body.js.map +1 -0
  15. package/dist/core/markdown-renderer.d.ts +5 -0
  16. package/dist/core/markdown-renderer.d.ts.map +1 -0
  17. package/dist/core/markdown-renderer.js +75 -0
  18. package/dist/core/markdown-renderer.js.map +1 -0
  19. package/dist/core/negotiate.d.ts +3 -0
  20. package/dist/core/negotiate.d.ts.map +1 -0
  21. package/dist/core/negotiate.js +63 -0
  22. package/dist/core/negotiate.js.map +1 -0
  23. package/dist/core/parse/anchors.d.ts +2 -0
  24. package/dist/core/parse/anchors.d.ts.map +1 -0
  25. package/dist/core/parse/anchors.js +26 -0
  26. package/dist/core/parse/anchors.js.map +1 -0
  27. package/dist/core/parse/block-parser.d.ts +3 -0
  28. package/dist/core/parse/block-parser.d.ts.map +1 -0
  29. package/dist/core/parse/block-parser.js +117 -0
  30. package/dist/core/parse/block-parser.js.map +1 -0
  31. package/dist/core/parse/executable-block.d.ts +6 -0
  32. package/dist/core/parse/executable-block.d.ts.map +1 -0
  33. package/dist/core/parse/executable-block.js +48 -0
  34. package/dist/core/parse/executable-block.js.map +1 -0
  35. package/dist/core/parse/frontmatter.d.ts +7 -0
  36. package/dist/core/parse/frontmatter.d.ts.map +1 -0
  37. package/dist/core/parse/frontmatter.js +45 -0
  38. package/dist/core/parse/frontmatter.js.map +1 -0
  39. package/dist/core/serialize.d.ts +4 -0
  40. package/dist/core/serialize.d.ts.map +1 -0
  41. package/dist/core/serialize.js +126 -0
  42. package/dist/core/serialize.js.map +1 -0
  43. package/dist/core/types.d.ts +67 -0
  44. package/dist/core/types.d.ts.map +1 -0
  45. package/dist/core/types.js +2 -0
  46. package/dist/core/types.js.map +1 -0
  47. package/dist/core/validate.d.ts +3 -0
  48. package/dist/core/validate.d.ts.map +1 -0
  49. package/dist/core/validate.js +107 -0
  50. package/dist/core/validate.js.map +1 -0
  51. package/dist/elements/components/mdan-action.d.ts +6 -0
  52. package/dist/elements/components/mdan-action.d.ts.map +1 -0
  53. package/dist/elements/components/mdan-action.js +34 -0
  54. package/dist/elements/components/mdan-action.js.map +1 -0
  55. package/dist/elements/components/mdan-block.d.ts +9 -0
  56. package/dist/elements/components/mdan-block.d.ts.map +1 -0
  57. package/dist/elements/components/mdan-block.js +36 -0
  58. package/dist/elements/components/mdan-block.js.map +1 -0
  59. package/dist/elements/components/mdan-error.d.ts +9 -0
  60. package/dist/elements/components/mdan-error.d.ts.map +1 -0
  61. package/dist/elements/components/mdan-error.js +36 -0
  62. package/dist/elements/components/mdan-error.js.map +1 -0
  63. package/dist/elements/components/mdan-field.d.ts +6 -0
  64. package/dist/elements/components/mdan-field.d.ts.map +1 -0
  65. package/dist/elements/components/mdan-field.js +35 -0
  66. package/dist/elements/components/mdan-field.js.map +1 -0
  67. package/dist/elements/components/mdan-form.d.ts +6 -0
  68. package/dist/elements/components/mdan-form.d.ts.map +1 -0
  69. package/dist/elements/components/mdan-form.js +22 -0
  70. package/dist/elements/components/mdan-form.js.map +1 -0
  71. package/dist/elements/components/mdan-page.d.ts +9 -0
  72. package/dist/elements/components/mdan-page.d.ts.map +1 -0
  73. package/dist/elements/components/mdan-page.js +46 -0
  74. package/dist/elements/components/mdan-page.js.map +1 -0
  75. package/dist/elements/index.d.ts +3 -0
  76. package/dist/elements/index.d.ts.map +1 -0
  77. package/dist/elements/index.js +3 -0
  78. package/dist/elements/index.js.map +1 -0
  79. package/dist/elements/mount.d.ts +11 -0
  80. package/dist/elements/mount.d.ts.map +1 -0
  81. package/dist/elements/mount.js +436 -0
  82. package/dist/elements/mount.js.map +1 -0
  83. package/dist/elements/register.d.ts +2 -0
  84. package/dist/elements/register.d.ts.map +1 -0
  85. package/dist/elements/register.js +27 -0
  86. package/dist/elements/register.js.map +1 -0
  87. package/dist/elements/theme.d.ts +2 -0
  88. package/dist/elements/theme.d.ts.map +1 -0
  89. package/dist/elements/theme.js +13 -0
  90. package/dist/elements/theme.js.map +1 -0
  91. package/dist/index.d.ts +4 -0
  92. package/dist/index.d.ts.map +1 -0
  93. package/dist/index.js +5 -0
  94. package/dist/index.js.map +1 -0
  95. package/dist/server/bun.d.ts +19 -0
  96. package/dist/server/bun.d.ts.map +1 -0
  97. package/dist/server/bun.js +214 -0
  98. package/dist/server/bun.js.map +1 -0
  99. package/dist/server/content-type.d.ts +3 -0
  100. package/dist/server/content-type.d.ts.map +1 -0
  101. package/dist/server/content-type.js +5 -0
  102. package/dist/server/content-type.js.map +1 -0
  103. package/dist/server/hosted-app.d.ts +35 -0
  104. package/dist/server/hosted-app.d.ts.map +1 -0
  105. package/dist/server/hosted-app.js +113 -0
  106. package/dist/server/hosted-app.js.map +1 -0
  107. package/dist/server/html-render.d.ts +21 -0
  108. package/dist/server/html-render.d.ts.map +1 -0
  109. package/dist/server/html-render.js +360 -0
  110. package/dist/server/html-render.js.map +1 -0
  111. package/dist/server/index.d.ts +8 -0
  112. package/dist/server/index.d.ts.map +1 -0
  113. package/dist/server/index.js +6 -0
  114. package/dist/server/index.js.map +1 -0
  115. package/dist/server/node-runtime.d.ts +2 -0
  116. package/dist/server/node-runtime.d.ts.map +1 -0
  117. package/dist/server/node-runtime.js +2 -0
  118. package/dist/server/node-runtime.js.map +1 -0
  119. package/dist/server/node.d.ts +23 -0
  120. package/dist/server/node.d.ts.map +1 -0
  121. package/dist/server/node.js +210 -0
  122. package/dist/server/node.js.map +1 -0
  123. package/dist/server/result.d.ts +7 -0
  124. package/dist/server/result.d.ts.map +1 -0
  125. package/dist/server/result.js +26 -0
  126. package/dist/server/result.js.map +1 -0
  127. package/dist/server/router.d.ts +12 -0
  128. package/dist/server/router.d.ts.map +1 -0
  129. package/dist/server/router.js +24 -0
  130. package/dist/server/router.js.map +1 -0
  131. package/dist/server/runtime.d.ts +16 -0
  132. package/dist/server/runtime.d.ts.map +1 -0
  133. package/dist/server/runtime.js +532 -0
  134. package/dist/server/runtime.js.map +1 -0
  135. package/dist/server/session.d.ts +5 -0
  136. package/dist/server/session.d.ts.map +1 -0
  137. package/dist/server/session.js +18 -0
  138. package/dist/server/session.js.map +1 -0
  139. package/dist/server/types.d.ts +72 -0
  140. package/dist/server/types.d.ts.map +1 -0
  141. package/dist/server/types.js +2 -0
  142. package/dist/server/types.js.map +1 -0
  143. package/dist/web/headless.d.ts +32 -0
  144. package/dist/web/headless.d.ts.map +1 -0
  145. package/dist/web/headless.js +391 -0
  146. package/dist/web/headless.js.map +1 -0
  147. package/dist/web/index.d.ts +2 -0
  148. package/dist/web/index.d.ts.map +1 -0
  149. package/dist/web/index.js +2 -0
  150. package/dist/web/index.js.map +1 -0
  151. package/package.json +81 -0
@@ -0,0 +1,360 @@
1
+ import { basicMarkdownRenderer } from "../core/index.js";
2
+ const blockAnchorPattern = /^<!--\s*mdan:block\s+([a-zA-Z_][\w-]*)\s*-->$/;
3
+ function escapeHtml(value) {
4
+ return value
5
+ .replaceAll("&", "&amp;")
6
+ .replaceAll("<", "&lt;")
7
+ .replaceAll(">", "&gt;")
8
+ .replaceAll('"', "&quot;");
9
+ }
10
+ function humanizeLabel(value) {
11
+ return value
12
+ .replace(/[_-]+/g, " ")
13
+ .replace(/\s+/g, " ")
14
+ .trim();
15
+ }
16
+ function resolveActionVariant(operation) {
17
+ const signature = `${operation.name ?? ""} ${operation.label ?? ""} ${operation.target}`.toLowerCase();
18
+ if (signature.includes("logout") || signature.includes("log out")) {
19
+ return "quiet";
20
+ }
21
+ if (operation.method === "GET") {
22
+ return "secondary";
23
+ }
24
+ return "primary";
25
+ }
26
+ function renderInput(input) {
27
+ const required = input.required ? ' required aria-required="true" data-required="true"' : "";
28
+ const placeholder = input.name === "message" ? ` placeholder="Write something worth keeping"` : "";
29
+ const name = escapeHtml(input.name);
30
+ const labelText = humanizeLabel(name);
31
+ const label = input.required
32
+ ? `<span class="mdan-label-text">${escapeHtml(labelText)} <span class="mdan-required" aria-hidden="true">*</span></span>`
33
+ : `<span class="mdan-label-text">${escapeHtml(labelText)}</span>`;
34
+ if (input.type === "choice") {
35
+ const options = (input.options ?? [])
36
+ .map((option) => `<option value="${escapeHtml(option)}">${escapeHtml(option)}</option>`)
37
+ .join("");
38
+ return `<mdan-field><label>${label}<select name="${name}"${required}>${options}</select></label></mdan-field>`;
39
+ }
40
+ if (input.type === "boolean") {
41
+ return `<mdan-field><label>${label}<input name="${name}" type="checkbox"${required}></label></mdan-field>`;
42
+ }
43
+ if (input.type === "asset") {
44
+ return `<mdan-field><label>${label}<input name="${name}" type="file"${required}></label></mdan-field>`;
45
+ }
46
+ const type = input.secret ? "password" : input.type === "number" ? "number" : "text";
47
+ return `<mdan-field><label>${label}<input name="${name}" type="${type}"${required}${placeholder}></label></mdan-field>`;
48
+ }
49
+ function renderOperation(operation, inputs) {
50
+ const variant = resolveActionVariant(operation);
51
+ const actionAttrs = `data-mdan-action-variant="${variant}"`;
52
+ if (operation.method === "GET") {
53
+ if (operation.accept === "text/event-stream") {
54
+ return `<mdan-stream data-mdan-stream-target="${escapeHtml(operation.target)}"></mdan-stream>`;
55
+ }
56
+ const fields = inputs
57
+ .filter((input) => operation.inputs.includes(input.name))
58
+ .map(renderInput)
59
+ .join("");
60
+ return `<mdan-form><form method="GET" action="${escapeHtml(operation.target)}" data-mdan-method="GET" data-mdan-target="${escapeHtml(operation.target)}" ${actionAttrs}>${fields}<mdan-action><button type="submit" ${actionAttrs}>${escapeHtml(operation.label ?? operation.name ?? operation.target)}</button></mdan-action></form></mdan-form>`;
61
+ }
62
+ const fields = inputs
63
+ .filter((input) => operation.inputs.includes(input.name))
64
+ .map(renderInput)
65
+ .join("");
66
+ return `<mdan-form><form method="POST" action="${escapeHtml(operation.target)}" data-mdan-method="POST" data-mdan-target="${escapeHtml(operation.target)}" ${actionAttrs}>${fields}<mdan-action><button type="submit" ${actionAttrs}>${escapeHtml(operation.label ?? operation.name)}</button></mdan-action></form></mdan-form>`;
67
+ }
68
+ function renderBlock(block, innerHtml = "") {
69
+ const operations = block.operations.map((operation) => renderOperation(operation, block.inputs)).join("");
70
+ return `<mdan-block data-mdan-block="${escapeHtml(block.name)}">${innerHtml}${operations}</mdan-block>`;
71
+ }
72
+ function escapeScriptJson(value) {
73
+ return value.replaceAll("</script>", "<\\/script>");
74
+ }
75
+ function resolveBlockMarkdown(fragment, blockName, hasAnchors, isSingleBlockResponse) {
76
+ if (hasAnchors) {
77
+ return fragment.blockContent?.[blockName]?.trim() ?? "";
78
+ }
79
+ if (isSingleBlockResponse && fragment.blocks[0]?.name === blockName) {
80
+ return fragment.markdown.trim();
81
+ }
82
+ return "";
83
+ }
84
+ function createHeadlessBlockSnapshot(block, markdown) {
85
+ return {
86
+ name: block.name,
87
+ markdown,
88
+ inputs: block.inputs,
89
+ operations: block.operations
90
+ };
91
+ }
92
+ function createHeadlessBootstrap(fragment, options, hasAnchors, isSingleBlockResponse) {
93
+ if (options.kind === "page") {
94
+ return {
95
+ kind: "page",
96
+ ...(options.route ? { route: options.route } : {}),
97
+ markdown: fragment.markdown,
98
+ blocks: fragment.blocks.map((block) => createHeadlessBlockSnapshot(block, resolveBlockMarkdown(fragment, block.name, hasAnchors, isSingleBlockResponse)))
99
+ };
100
+ }
101
+ if (fragment.blocks.length !== 1) {
102
+ return null;
103
+ }
104
+ const block = fragment.blocks[0];
105
+ if (!block) {
106
+ return null;
107
+ }
108
+ const bootstrap = {
109
+ kind: "fragment",
110
+ block: createHeadlessBlockSnapshot(block, resolveBlockMarkdown(fragment, block.name, hasAnchors, isSingleBlockResponse))
111
+ };
112
+ return bootstrap;
113
+ }
114
+ function resolveProtocolDiscovery(options) {
115
+ return {
116
+ ...(options.protocol?.discovery?.markdownHref
117
+ ? { markdownHref: options.protocol.discovery.markdownHref }
118
+ : options.alternateMarkdownHref
119
+ ? { markdownHref: options.alternateMarkdownHref }
120
+ : {}),
121
+ ...(options.protocol?.discovery?.llmsTxtHref
122
+ ? { llmsTxtHref: options.protocol.discovery.llmsTxtHref }
123
+ : options.llmsTxtHref
124
+ ? { llmsTxtHref: options.llmsTxtHref }
125
+ : {})
126
+ };
127
+ }
128
+ export function renderProtocolHeadLinks(discovery) {
129
+ return [
130
+ discovery.markdownHref
131
+ ? `<link rel="alternate" type="text/markdown" href="${escapeHtml(discovery.markdownHref)}">`
132
+ : "",
133
+ discovery.llmsTxtHref ? `<link rel="llms-txt" href="${escapeHtml(discovery.llmsTxtHref)}">` : ""
134
+ ]
135
+ .filter(Boolean)
136
+ .join("\n ");
137
+ }
138
+ export function renderHtmlDiscoveryLinks(options) {
139
+ return renderProtocolHeadLinks(resolveProtocolDiscovery(options));
140
+ }
141
+ export function injectHtmlDiscoveryLinks(html, options) {
142
+ const discovery = resolveProtocolDiscovery(options);
143
+ const links = {
144
+ ...(discovery.markdownHref && !html.includes('rel="alternate" type="text/markdown"')
145
+ ? { markdownHref: discovery.markdownHref }
146
+ : {}),
147
+ ...(discovery.llmsTxtHref && !html.includes('rel="llms-txt"') ? { llmsTxtHref: discovery.llmsTxtHref } : {})
148
+ };
149
+ const tags = renderProtocolHeadLinks(links);
150
+ if (!tags || !html.includes("</head>")) {
151
+ return html;
152
+ }
153
+ return html.replace("</head>", ` ${tags}\n </head>`);
154
+ }
155
+ function renderMarkdownWithAnchors(markdown, blocks, blockContent, markdownRenderer) {
156
+ const rendered = [];
157
+ const buffer = [];
158
+ const blockMap = new Map(blocks.map((block) => [block.name, block]));
159
+ function flushBuffer() {
160
+ const text = buffer.join("\n").trim();
161
+ if (text) {
162
+ rendered.push(markdownRenderer.render(text));
163
+ }
164
+ buffer.length = 0;
165
+ }
166
+ for (const line of markdown.split("\n")) {
167
+ const trimmed = line.trim();
168
+ const anchorMatch = trimmed.match(blockAnchorPattern);
169
+ if (anchorMatch) {
170
+ flushBuffer();
171
+ const block = blockMap.get(anchorMatch[1] ?? "");
172
+ if (block) {
173
+ const innerMarkdown = blockContent?.[anchorMatch[1] ?? ""]?.trim() ?? "";
174
+ rendered.push(renderBlock(block, markdownRenderer.render(innerMarkdown)));
175
+ }
176
+ continue;
177
+ }
178
+ buffer.push(line);
179
+ }
180
+ flushBuffer();
181
+ return rendered.join("\n");
182
+ }
183
+ export function renderHtmlDocument(fragment, options = {}) {
184
+ const markdownRenderer = options.markdownRenderer ?? basicMarkdownRenderer;
185
+ const hasAnchors = fragment.markdown.includes("<!-- mdan:block");
186
+ const isSingleBlockResponse = !hasAnchors && fragment.blocks.length === 1 && fragment.markdown.trim().length > 0;
187
+ const markdown = hasAnchors
188
+ ? renderMarkdownWithAnchors(fragment.markdown, fragment.blocks, fragment.blockContent, markdownRenderer)
189
+ : isSingleBlockResponse
190
+ ? ""
191
+ : markdownRenderer.render(fragment.markdown);
192
+ const blocks = hasAnchors
193
+ ? ""
194
+ : isSingleBlockResponse
195
+ ? renderBlock(fragment.blocks[0], markdownRenderer.render(fragment.markdown))
196
+ : fragment.blocks.map((block) => renderBlock(block)).join("\n");
197
+ const bootstrap = createHeadlessBootstrap(fragment, options, hasAnchors, isSingleBlockResponse);
198
+ const bootstrapScript = bootstrap
199
+ ? `\n <script id="mdan-bootstrap" type="application/json">${escapeScriptJson(JSON.stringify(bootstrap))}</script>`
200
+ : "";
201
+ const discoveryLinks = renderHtmlDiscoveryLinks(options);
202
+ const discoveryHead = discoveryLinks ? `\n ${discoveryLinks}` : "";
203
+ return `<!doctype html>
204
+ <html lang="en">
205
+ <head>
206
+ <meta charset="utf-8">
207
+ <meta name="viewport" content="width=device-width, initial-scale=1">
208
+ ${discoveryHead}
209
+ <style>
210
+ :root {
211
+ font-family: ui-sans-serif, system-ui, sans-serif;
212
+ color: #1f2937;
213
+ background: #f4f7fb;
214
+ }
215
+ body {
216
+ margin: 0;
217
+ padding: 32px 16px;
218
+ }
219
+ main[data-mdan-root] {
220
+ max-width: 760px;
221
+ margin: 0 auto;
222
+ background: rgba(255, 255, 255, 0.85);
223
+ border: 1px solid #dbe3ef;
224
+ border-radius: 24px;
225
+ box-shadow: 0 24px 64px rgba(15, 23, 42, 0.08);
226
+ padding: 28px;
227
+ }
228
+ h1 {
229
+ margin: 0 0 8px;
230
+ font-size: clamp(2.4rem, 5vw, 3.8rem);
231
+ line-height: 0.95;
232
+ letter-spacing: -0.05em;
233
+ }
234
+ h2 {
235
+ margin: 24px 0 10px;
236
+ font-size: 0.95rem;
237
+ letter-spacing: 0.12em;
238
+ text-transform: uppercase;
239
+ color: #0f766e;
240
+ }
241
+ mdan-block, mdan-form, mdan-field, mdan-action {
242
+ display: block;
243
+ }
244
+ mdan-block {
245
+ margin-top: 20px;
246
+ padding: 20px;
247
+ border-radius: 22px;
248
+ background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
249
+ border: 1px solid rgba(148, 163, 184, 0.22);
250
+ box-shadow: 0 20px 44px rgba(15, 23, 42, 0.06);
251
+ }
252
+ form {
253
+ display: grid;
254
+ gap: 14px;
255
+ margin: 10px 0 0;
256
+ }
257
+ label {
258
+ display: grid;
259
+ gap: 8px;
260
+ font-size: 0.82rem;
261
+ letter-spacing: 0.08em;
262
+ text-transform: uppercase;
263
+ color: #475569;
264
+ font-weight: 700;
265
+ }
266
+ .mdan-label-text {
267
+ display: inline-flex;
268
+ align-items: center;
269
+ gap: 6px;
270
+ }
271
+ .mdan-required {
272
+ color: #dc2626;
273
+ font-size: 1rem;
274
+ line-height: 1;
275
+ }
276
+ input {
277
+ width: 100%;
278
+ box-sizing: border-box;
279
+ border: 1px solid rgba(148, 163, 184, 0.32);
280
+ border-radius: 14px;
281
+ padding: 12px 14px;
282
+ font: inherit;
283
+ background: rgba(255, 255, 255, 0.94);
284
+ }
285
+ input:invalid, select:invalid, textarea:invalid {
286
+ border-color: rgba(220, 38, 38, 0.58);
287
+ box-shadow: 0 0 0 4px rgba(220, 38, 38, 0.08);
288
+ }
289
+ mdan-action {
290
+ display: flex;
291
+ align-items: center;
292
+ gap: 10px;
293
+ }
294
+ button {
295
+ border: 0;
296
+ border-radius: 999px;
297
+ padding: 11px 18px;
298
+ font: inherit;
299
+ font-weight: 700;
300
+ color: white;
301
+ background: linear-gradient(180deg, #14b8a6 0%, #0f766e 100%);
302
+ box-shadow: 0 12px 24px rgba(15, 118, 110, 0.22);
303
+ cursor: pointer;
304
+ }
305
+ button[data-mdan-action-variant="secondary"] {
306
+ color: #0f766e;
307
+ background: rgba(240, 253, 250, 0.92);
308
+ border: 1px solid rgba(15, 118, 110, 0.18);
309
+ box-shadow: none;
310
+ }
311
+ button[data-mdan-action-variant="quiet"] {
312
+ color: #334155;
313
+ background: rgba(241, 245, 249, 0.92);
314
+ border: 1px solid rgba(148, 163, 184, 0.22);
315
+ box-shadow: none;
316
+ }
317
+ p {
318
+ line-height: 1.6;
319
+ color: #334155;
320
+ }
321
+ ul {
322
+ list-style: none;
323
+ padding: 0;
324
+ margin: 20px 0;
325
+ display: grid;
326
+ gap: 12px;
327
+ }
328
+ li {
329
+ position: relative;
330
+ padding: 16px 18px 16px 48px;
331
+ border-radius: 18px;
332
+ background: linear-gradient(180deg, #ffffff 0%, #f8fafc 100%);
333
+ border: 1px solid #dbe3ef;
334
+ box-shadow: 0 12px 30px rgba(15, 23, 42, 0.05);
335
+ }
336
+ li::before {
337
+ content: "";
338
+ position: absolute;
339
+ left: 18px;
340
+ top: 18px;
341
+ width: 14px;
342
+ height: 14px;
343
+ border-radius: 999px;
344
+ background: linear-gradient(180deg, #14b8a6 0%, #0f766e 100%);
345
+ box-shadow: 0 0 0 6px rgba(20, 184, 166, 0.12);
346
+ }
347
+ </style>
348
+ </head>
349
+ <body>
350
+ <mdan-page>
351
+ <main data-mdan-root>
352
+ ${markdown}
353
+ ${blocks}
354
+ </main>
355
+ </mdan-page>
356
+ ${bootstrapScript}
357
+ </body>
358
+ </html>`;
359
+ }
360
+ //# sourceMappingURL=html-render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html-render.js","sourceRoot":"","sources":["../../src/server/html-render.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ export { createHostedApp } from "./hosted-app.js";
2
+ export { renderProtocolHeadLinks } from "./html-render.js";
3
+ export { block, fail, ok, stream } from "./result.js";
4
+ export { createMdanServer, type CreateMdanServerOptions } from "./runtime.js";
5
+ export { refreshSession, signIn, signOut } from "./session.js";
6
+ export type { CreateHostedAppOptions, HostedAction, HostedActionDefinition, HostedActionContext, HostedPageFactory } from "./hosted-app.js";
7
+ export type { MdanActionResult, MdanHandler, MdanHandlerContext, MdanHandlerResult, MdanHtmlDiscoveryContext, MdanHtmlDiscoveryLinks, MdanHtmlDiscoveryResolver, MdanProtocolDiscovery, MdanPageHandler, MdanPageHandlerContext, MdanRequest, MdanResponse, MdanSessionMutation, MdanSessionProvider, MdanSessionSnapshot, MdanStreamChunk, MdanStreamResult } from "./types.js";
8
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,KAAK,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAC/D,YAAY,EACV,sBAAsB,EACtB,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,iBAAiB,EAClB,MAAM,iBAAiB,CAAC;AACzB,YAAY,EACV,gBAAgB,EAChB,WAAW,EACX,kBAAkB,EAClB,iBAAiB,EACjB,wBAAwB,EACxB,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,eAAe,EACf,sBAAsB,EACtB,WAAW,EACX,YAAY,EACZ,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,eAAe,EACf,gBAAgB,EACjB,MAAM,YAAY,CAAC"}
@@ -0,0 +1,6 @@
1
+ export { createHostedApp } from "./hosted-app.js";
2
+ export { renderProtocolHeadLinks } from "./html-render.js";
3
+ export { block, fail, ok, stream } from "./result.js";
4
+ export { createMdanServer } from "./runtime.js";
5
+ export { refreshSession, signIn, signOut } from "./session.js";
6
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAE,uBAAuB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAgC,MAAM,cAAc,CAAC;AAC9E,OAAO,EAAE,cAAc,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createNodeHost as createHost, createNodeHost, createNodeRequestListener, type CreateNodeHostOptions, type CreateNodeRequestListenerOptions, type NodeStaticMount } from "./node.js";
2
+ //# sourceMappingURL=node-runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-runtime.d.ts","sourceRoot":"","sources":["../../src/server/node-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,IAAI,UAAU,EAC5B,cAAc,EACd,yBAAyB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,gCAAgC,EACrC,KAAK,eAAe,EACrB,MAAM,WAAW,CAAC"}
@@ -0,0 +1,2 @@
1
+ export { createNodeHost as createHost, createNodeHost, createNodeRequestListener } from "./node.js";
2
+ //# sourceMappingURL=node-runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node-runtime.js","sourceRoot":"","sources":["../../src/server/node-runtime.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,IAAI,UAAU,EAC5B,cAAc,EACd,yBAAyB,EAI1B,MAAM,WAAW,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { RequestListener } from "node:http";
2
+ import type { MdanRequest, MdanResponse } from "./types.js";
3
+ interface MdanRequestHandler {
4
+ handle(request: MdanRequest): Promise<MdanResponse>;
5
+ }
6
+ export interface CreateNodeRequestListenerOptions {
7
+ transformHtml?: (html: string) => string;
8
+ maxBodyBytes?: number;
9
+ }
10
+ export interface NodeStaticMount {
11
+ urlPrefix: string;
12
+ directory: string;
13
+ }
14
+ export interface CreateNodeHostOptions extends CreateNodeRequestListenerOptions {
15
+ rootRedirect?: string;
16
+ ignoreFavicon?: boolean;
17
+ staticFiles?: Record<string, string>;
18
+ staticMounts?: NodeStaticMount[];
19
+ }
20
+ export declare function createNodeRequestListener(handler: MdanRequestHandler, options?: CreateNodeRequestListenerOptions): RequestListener;
21
+ export declare function createNodeHost(handler: MdanRequestHandler, options?: CreateNodeHostOptions): RequestListener;
22
+ export {};
23
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAmB,eAAe,EAAkB,MAAM,WAAW,CAAC;AASlF,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE5D,UAAU,kBAAkB;IAC1B,MAAM,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CACrD;AAED,MAAM,WAAW,gCAAgC;IAC/C,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,qBAAsB,SAAQ,gCAAgC;IAC7E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,YAAY,CAAC,EAAE,eAAe,EAAE,CAAC;CAClC;AAmLD,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,kBAAkB,EAC3B,OAAO,GAAE,gCAAqC,GAC7C,eAAe,CAmBjB;AAED,wBAAgB,cAAc,CAAC,OAAO,EAAE,kBAAkB,EAAE,OAAO,GAAE,qBAA0B,GAAG,eAAe,CAiChH"}
@@ -0,0 +1,210 @@
1
+ import { createReadStream } from "node:fs";
2
+ import { stat } from "node:fs/promises";
3
+ import { extname, resolve } from "node:path";
4
+ import { pipeline } from "node:stream/promises";
5
+ import { serializeMarkdownBody } from "../core/index.js";
6
+ import { toMarkdownContentType } from "./content-type.js";
7
+ const DEFAULT_MAX_BODY_BYTES = 1024 * 1024;
8
+ class PayloadTooLargeError extends Error {
9
+ constructor() {
10
+ super("Payload Too Large");
11
+ }
12
+ }
13
+ async function readBody(request, maxBodyBytes) {
14
+ let body = "";
15
+ let totalBytes = 0;
16
+ for await (const chunk of request) {
17
+ const textChunk = typeof chunk === "string" ? chunk : chunk.toString("utf8");
18
+ const chunkBytes = typeof chunk === "string" ? Buffer.byteLength(chunk) : chunk.byteLength;
19
+ totalBytes += chunkBytes;
20
+ if (totalBytes > maxBodyBytes) {
21
+ throw new PayloadTooLargeError();
22
+ }
23
+ body += textChunk;
24
+ }
25
+ return body || undefined;
26
+ }
27
+ function normalizeHeaderValue(value) {
28
+ if (Array.isArray(value)) {
29
+ return value.join(", ");
30
+ }
31
+ return value;
32
+ }
33
+ function parseCookies(header) {
34
+ if (!header?.trim()) {
35
+ return {};
36
+ }
37
+ const cookies = {};
38
+ for (const pair of header.split(";")) {
39
+ const [rawName, ...rawValue] = pair.split("=");
40
+ const name = rawName?.trim();
41
+ if (!name) {
42
+ continue;
43
+ }
44
+ const serializedValue = rawValue.join("=").trim();
45
+ try {
46
+ cookies[name] = decodeURIComponent(serializedValue);
47
+ }
48
+ catch {
49
+ cookies[name] = serializedValue;
50
+ }
51
+ }
52
+ return cookies;
53
+ }
54
+ function normalizeBody(body, contentType) {
55
+ if (!body) {
56
+ return undefined;
57
+ }
58
+ if (!contentType.includes("application/x-www-form-urlencoded")) {
59
+ return body;
60
+ }
61
+ const params = new URLSearchParams(body);
62
+ return serializeMarkdownBody(Object.fromEntries(params.entries()));
63
+ }
64
+ function getContentType(filePath) {
65
+ const extension = extname(filePath);
66
+ return extension === ".js"
67
+ ? "text/javascript"
68
+ : extension === ".css"
69
+ ? "text/css"
70
+ : extension === ".map" || extension === ".json"
71
+ ? "application/json"
72
+ : extension === ".html"
73
+ ? "text/html"
74
+ : extension === ".svg"
75
+ ? "image/svg+xml"
76
+ : extension === ".mjs"
77
+ ? "text/javascript"
78
+ : extension === ".txt"
79
+ ? "text/plain"
80
+ : "application/octet-stream";
81
+ }
82
+ function toEtag(size, mtimeMs) {
83
+ return `W/"${size.toString(16)}-${Math.floor(mtimeMs).toString(16)}"`;
84
+ }
85
+ async function tryServeStaticFile(request, response, filePath) {
86
+ try {
87
+ const fileStat = await stat(filePath);
88
+ if (!fileStat.isFile()) {
89
+ return false;
90
+ }
91
+ const contentType = getContentType(filePath);
92
+ const etag = toEtag(fileStat.size, fileStat.mtimeMs);
93
+ response.setHeader("content-type", contentType);
94
+ response.setHeader("cache-control", "public, max-age=0, must-revalidate");
95
+ response.setHeader("etag", etag);
96
+ if (request.headers["if-none-match"] === etag) {
97
+ response.statusCode = 304;
98
+ response.end();
99
+ return true;
100
+ }
101
+ response.statusCode = 200;
102
+ await pipeline(createReadStream(filePath), response);
103
+ return true;
104
+ }
105
+ catch {
106
+ return false;
107
+ }
108
+ }
109
+ function resolveMountedFile(directory, urlPrefix, pathname) {
110
+ const normalizedPrefix = urlPrefix.length > 1 && urlPrefix.endsWith("/") ? urlPrefix.slice(0, -1) : urlPrefix;
111
+ if (normalizedPrefix === "/") {
112
+ const baseDirectory = resolve(directory);
113
+ const target = resolve(baseDirectory, pathname.replace(/^\/+/, ""));
114
+ if (target !== baseDirectory && !target.startsWith(`${baseDirectory}/`)) {
115
+ return null;
116
+ }
117
+ return target;
118
+ }
119
+ if (pathname !== normalizedPrefix && !pathname.startsWith(`${normalizedPrefix}/`)) {
120
+ return null;
121
+ }
122
+ const relativePath = pathname.slice(normalizedPrefix.length).replace(/^\/+/, "");
123
+ const baseDirectory = resolve(directory);
124
+ const target = resolve(baseDirectory, relativePath);
125
+ if (target !== baseDirectory && !target.startsWith(`${baseDirectory}/`)) {
126
+ return null;
127
+ }
128
+ return target;
129
+ }
130
+ function toMdanRequest(request, body) {
131
+ const method = request.method === "POST" ? "POST" : "GET";
132
+ const host = request.headers.host ?? "127.0.0.1";
133
+ const headers = Object.fromEntries(Object.entries(request.headers).map(([key, value]) => [key, normalizeHeaderValue(value)]));
134
+ headers.accept ??= "text/html";
135
+ if (body && headers["content-type"]?.includes("application/x-www-form-urlencoded")) {
136
+ headers["content-type"] = "text/markdown";
137
+ }
138
+ return {
139
+ method,
140
+ url: new URL(request.url ?? "/", `http://${host}`).toString(),
141
+ headers,
142
+ ...(body ? { body } : {}),
143
+ cookies: parseCookies(headers.cookie)
144
+ };
145
+ }
146
+ async function writeResponse(response, result, transformHtml) {
147
+ response.statusCode = result.status;
148
+ for (const [key, value] of Object.entries(result.headers)) {
149
+ response.setHeader(key, value);
150
+ }
151
+ const contentType = String(result.headers["content-type"] ?? "");
152
+ if (typeof result.body === "string") {
153
+ response.end(contentType.includes("text/html") && transformHtml ? transformHtml(result.body) : result.body);
154
+ return;
155
+ }
156
+ for await (const chunk of result.body) {
157
+ response.write(chunk);
158
+ }
159
+ response.end();
160
+ }
161
+ export function createNodeRequestListener(handler, options = {}) {
162
+ return async (request, response) => {
163
+ const contentType = request.headers["content-type"] ?? "";
164
+ const maxBodyBytes = options.maxBodyBytes ?? DEFAULT_MAX_BODY_BYTES;
165
+ let normalizedBody;
166
+ try {
167
+ normalizedBody = normalizeBody(await readBody(request, maxBodyBytes), contentType);
168
+ }
169
+ catch (error) {
170
+ if (error instanceof PayloadTooLargeError) {
171
+ response.statusCode = 413;
172
+ response.setHeader("content-type", toMarkdownContentType());
173
+ response.end("## Payload Too Large\n\nRequest body exceeded maxBodyBytes.");
174
+ return;
175
+ }
176
+ throw error;
177
+ }
178
+ const result = await handler.handle(toMdanRequest(request, normalizedBody));
179
+ await writeResponse(response, result, options.transformHtml);
180
+ };
181
+ }
182
+ export function createNodeHost(handler, options = {}) {
183
+ const requestListener = createNodeRequestListener(handler, options);
184
+ return async (request, response) => {
185
+ const url = new URL(request.url ?? "/", `http://${request.headers.host ?? "127.0.0.1"}`);
186
+ if (options.rootRedirect && url.pathname === "/") {
187
+ response.statusCode = 302;
188
+ response.setHeader("location", options.rootRedirect);
189
+ response.end();
190
+ return;
191
+ }
192
+ if (options.ignoreFavicon !== false && url.pathname === "/favicon.ico") {
193
+ response.statusCode = 204;
194
+ response.end();
195
+ return;
196
+ }
197
+ const staticFile = options.staticFiles?.[url.pathname];
198
+ if (staticFile && (await tryServeStaticFile(request, response, staticFile))) {
199
+ return;
200
+ }
201
+ for (const mount of options.staticMounts ?? []) {
202
+ const target = resolveMountedFile(mount.directory, mount.urlPrefix, url.pathname);
203
+ if (target && (await tryServeStaticFile(request, response, target))) {
204
+ return;
205
+ }
206
+ }
207
+ await requestListener(request, response);
208
+ };
209
+ }
210
+ //# sourceMappingURL=node.js.map