@mdsnai/sdk 0.2.2 → 0.3.3

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 (255) hide show
  1. package/README.md +40 -76
  2. package/dist/core/errors.d.ts +14 -0
  3. package/dist/core/errors.d.ts.map +1 -0
  4. package/dist/core/errors.js +13 -0
  5. package/dist/core/errors.js.map +1 -0
  6. package/dist/core/index.d.ts +16 -4
  7. package/dist/core/index.d.ts.map +1 -0
  8. package/dist/core/index.js +69 -13
  9. package/dist/core/index.js.map +1 -0
  10. package/dist/core/markdown-body.d.ts +3 -0
  11. package/dist/core/markdown-body.d.ts.map +1 -0
  12. package/dist/core/markdown-body.js +65 -0
  13. package/dist/core/markdown-body.js.map +1 -0
  14. package/dist/core/markdown-renderer.d.ts +5 -0
  15. package/dist/core/markdown-renderer.d.ts.map +1 -0
  16. package/dist/core/markdown-renderer.js +75 -0
  17. package/dist/core/markdown-renderer.js.map +1 -0
  18. package/dist/core/negotiate.d.ts +3 -0
  19. package/dist/core/negotiate.d.ts.map +1 -0
  20. package/dist/core/negotiate.js +63 -0
  21. package/dist/core/negotiate.js.map +1 -0
  22. package/dist/core/parse/anchors.d.ts +2 -0
  23. package/dist/core/parse/anchors.d.ts.map +1 -0
  24. package/dist/core/parse/anchors.js +26 -0
  25. package/dist/core/parse/anchors.js.map +1 -0
  26. package/dist/core/parse/block-parser.d.ts +3 -0
  27. package/dist/core/parse/block-parser.d.ts.map +1 -0
  28. package/dist/core/parse/block-parser.js +116 -0
  29. package/dist/core/parse/block-parser.js.map +1 -0
  30. package/dist/core/parse/executable-block.d.ts +6 -0
  31. package/dist/core/parse/executable-block.d.ts.map +1 -0
  32. package/dist/core/parse/executable-block.js +48 -0
  33. package/dist/core/parse/executable-block.js.map +1 -0
  34. package/dist/core/parse/frontmatter.d.ts +7 -0
  35. package/dist/core/parse/frontmatter.d.ts.map +1 -0
  36. package/dist/core/parse/frontmatter.js +45 -0
  37. package/dist/core/parse/frontmatter.js.map +1 -0
  38. package/dist/core/serialize.d.ts +4 -0
  39. package/dist/core/serialize.d.ts.map +1 -0
  40. package/dist/core/serialize.js +123 -0
  41. package/dist/core/serialize.js.map +1 -0
  42. package/dist/core/types.d.ts +66 -0
  43. package/dist/core/types.d.ts.map +1 -0
  44. package/dist/core/types.js +2 -0
  45. package/dist/core/types.js.map +1 -0
  46. package/dist/core/validate.d.ts +3 -0
  47. package/dist/core/validate.d.ts.map +1 -0
  48. package/dist/core/validate.js +91 -0
  49. package/dist/core/validate.js.map +1 -0
  50. package/dist/elements/components/mdsn-action.d.ts +6 -0
  51. package/dist/elements/components/mdsn-action.d.ts.map +1 -0
  52. package/dist/elements/components/mdsn-action.js +34 -0
  53. package/dist/elements/components/mdsn-action.js.map +1 -0
  54. package/dist/elements/components/mdsn-block.d.ts +9 -0
  55. package/dist/elements/components/mdsn-block.d.ts.map +1 -0
  56. package/dist/elements/components/mdsn-block.js +36 -0
  57. package/dist/elements/components/mdsn-block.js.map +1 -0
  58. package/dist/elements/components/mdsn-error.d.ts +9 -0
  59. package/dist/elements/components/mdsn-error.d.ts.map +1 -0
  60. package/dist/elements/components/mdsn-error.js +36 -0
  61. package/dist/elements/components/mdsn-error.js.map +1 -0
  62. package/dist/elements/components/mdsn-field.d.ts +6 -0
  63. package/dist/elements/components/mdsn-field.d.ts.map +1 -0
  64. package/dist/elements/components/mdsn-field.js +35 -0
  65. package/dist/elements/components/mdsn-field.js.map +1 -0
  66. package/dist/elements/components/mdsn-form.d.ts +6 -0
  67. package/dist/elements/components/mdsn-form.d.ts.map +1 -0
  68. package/dist/elements/components/mdsn-form.js +22 -0
  69. package/dist/elements/components/mdsn-form.js.map +1 -0
  70. package/dist/elements/components/mdsn-page.d.ts +9 -0
  71. package/dist/elements/components/mdsn-page.d.ts.map +1 -0
  72. package/dist/elements/components/mdsn-page.js +46 -0
  73. package/dist/elements/components/mdsn-page.js.map +1 -0
  74. package/dist/elements/index.d.ts +3 -0
  75. package/dist/elements/index.d.ts.map +1 -0
  76. package/dist/elements/index.js +3 -0
  77. package/dist/elements/index.js.map +1 -0
  78. package/dist/elements/mount.d.ts +11 -0
  79. package/dist/elements/mount.d.ts.map +1 -0
  80. package/dist/elements/mount.js +245 -0
  81. package/dist/elements/mount.js.map +1 -0
  82. package/dist/elements/register.d.ts +2 -0
  83. package/dist/elements/register.d.ts.map +1 -0
  84. package/dist/elements/register.js +27 -0
  85. package/dist/elements/register.js.map +1 -0
  86. package/dist/elements/theme.d.ts +2 -0
  87. package/dist/elements/theme.d.ts.map +1 -0
  88. package/dist/elements/theme.js +13 -0
  89. package/dist/elements/theme.js.map +1 -0
  90. package/dist/index.d.ts +4 -8
  91. package/dist/index.d.ts.map +1 -0
  92. package/dist/index.js +5 -35
  93. package/dist/index.js.map +1 -0
  94. package/dist/server/hosted-app.d.ts +35 -0
  95. package/dist/server/hosted-app.d.ts.map +1 -0
  96. package/dist/server/hosted-app.js +105 -0
  97. package/dist/server/hosted-app.js.map +1 -0
  98. package/dist/server/html-render.d.ts +13 -0
  99. package/dist/server/html-render.d.ts.map +1 -0
  100. package/dist/server/html-render.js +316 -0
  101. package/dist/server/html-render.js.map +1 -0
  102. package/dist/server/index.d.ts +8 -15
  103. package/dist/server/index.d.ts.map +1 -0
  104. package/dist/server/index.js +6 -32
  105. package/dist/server/index.js.map +1 -0
  106. package/dist/server/node.d.ts +23 -0
  107. package/dist/server/node.d.ts.map +1 -0
  108. package/dist/server/node.js +200 -0
  109. package/dist/server/node.js.map +1 -0
  110. package/dist/server/result.d.ts +15 -0
  111. package/dist/server/result.d.ts.map +1 -0
  112. package/dist/server/result.js +64 -0
  113. package/dist/server/result.js.map +1 -0
  114. package/dist/server/router.d.ts +12 -0
  115. package/dist/server/router.d.ts.map +1 -0
  116. package/dist/server/router.js +24 -0
  117. package/dist/server/router.js.map +1 -0
  118. package/dist/server/runtime.d.ts +15 -0
  119. package/dist/server/runtime.d.ts.map +1 -0
  120. package/dist/server/runtime.js +245 -0
  121. package/dist/server/runtime.js.map +1 -0
  122. package/dist/server/session.d.ts +5 -40
  123. package/dist/server/session.d.ts.map +1 -0
  124. package/dist/server/session.js +11 -213
  125. package/dist/server/session.js.map +1 -0
  126. package/dist/server/types.d.ts +62 -0
  127. package/dist/server/types.d.ts.map +1 -0
  128. package/dist/server/types.js +2 -0
  129. package/dist/server/types.js.map +1 -0
  130. package/dist/web/headless.d.ts +22 -92
  131. package/dist/web/headless.d.ts.map +1 -0
  132. package/dist/web/headless.js +311 -337
  133. package/dist/web/headless.js.map +1 -0
  134. package/dist/web/index.d.ts +2 -11
  135. package/dist/web/index.d.ts.map +1 -0
  136. package/dist/web/index.js +2 -23
  137. package/dist/web/index.js.map +1 -0
  138. package/package.json +19 -43
  139. package/LICENSE +0 -21
  140. package/dist/cli/args.d.ts +0 -8
  141. package/dist/cli/args.js +0 -63
  142. package/dist/cli/commands/build.d.ts +0 -5
  143. package/dist/cli/commands/build.js +0 -19
  144. package/dist/cli/commands/create.d.ts +0 -2
  145. package/dist/cli/commands/create.js +0 -39
  146. package/dist/cli/commands/dev.d.ts +0 -10
  147. package/dist/cli/commands/dev.js +0 -13
  148. package/dist/cli/commands/start.d.ts +0 -9
  149. package/dist/cli/commands/start.js +0 -13
  150. package/dist/cli/entry.d.ts +0 -2
  151. package/dist/cli/entry.js +0 -8
  152. package/dist/cli/index.d.ts +0 -9
  153. package/dist/cli/index.js +0 -58
  154. package/dist/core/document/frontmatter.d.ts +0 -5
  155. package/dist/core/document/frontmatter.js +0 -41
  156. package/dist/core/document/markdown.d.ts +0 -5
  157. package/dist/core/document/markdown.js +0 -81
  158. package/dist/core/document/page-definition.d.ts +0 -2
  159. package/dist/core/document/page-definition.js +0 -23
  160. package/dist/core/model/block.d.ts +0 -26
  161. package/dist/core/model/block.js +0 -8
  162. package/dist/core/model/document.d.ts +0 -11
  163. package/dist/core/model/document.js +0 -2
  164. package/dist/core/model/fragment.d.ts +0 -4
  165. package/dist/core/model/fragment.js +0 -2
  166. package/dist/core/model/index.d.ts +0 -4
  167. package/dist/core/model/index.js +0 -2
  168. package/dist/core/model/input.d.ts +0 -10
  169. package/dist/core/model/input.js +0 -2
  170. package/dist/core/protocol/mdsn.d.ts +0 -4
  171. package/dist/core/protocol/mdsn.js +0 -66
  172. package/dist/core/protocol/statements.d.ts +0 -7
  173. package/dist/core/protocol/statements.js +0 -115
  174. package/dist/core/protocol/validation.d.ts +0 -3
  175. package/dist/core/protocol/validation.js +0 -70
  176. package/dist/core/utils/html.d.ts +0 -6
  177. package/dist/core/utils/html.js +0 -28
  178. package/dist/core/utils/index.d.ts +0 -2
  179. package/dist/core/utils/index.js +0 -12
  180. package/dist/core/utils/logger.d.ts +0 -12
  181. package/dist/core/utils/logger.js +0 -45
  182. package/dist/framework/create-framework-app.d.ts +0 -13
  183. package/dist/framework/create-framework-app.js +0 -12
  184. package/dist/framework/hosted-app.d.ts +0 -34
  185. package/dist/framework/hosted-app.js +0 -223
  186. package/dist/framework/index.d.ts +0 -6
  187. package/dist/framework/index.js +0 -9
  188. package/dist/framework/site-app.d.ts +0 -13
  189. package/dist/framework/site-app.js +0 -147
  190. package/dist/server/action-context.d.ts +0 -11
  191. package/dist/server/action-context.js +0 -26
  192. package/dist/server/action-host.d.ts +0 -2
  193. package/dist/server/action-host.js +0 -10
  194. package/dist/server/action-inputs.d.ts +0 -3
  195. package/dist/server/action-inputs.js +0 -178
  196. package/dist/server/action-runtime.d.ts +0 -8
  197. package/dist/server/action-runtime.js +0 -62
  198. package/dist/server/action.d.ts +0 -33
  199. package/dist/server/action.js +0 -101
  200. package/dist/server/build.d.ts +0 -10
  201. package/dist/server/build.js +0 -170
  202. package/dist/server/config.d.ts +0 -56
  203. package/dist/server/config.js +0 -42
  204. package/dist/server/dev.d.ts +0 -48
  205. package/dist/server/dev.js +0 -90
  206. package/dist/server/error-fragments.d.ts +0 -46
  207. package/dist/server/error-fragments.js +0 -77
  208. package/dist/server/init.d.ts +0 -1
  209. package/dist/server/init.js +0 -176
  210. package/dist/server/layout.d.ts +0 -17
  211. package/dist/server/layout.js +0 -40
  212. package/dist/server/markdown.d.ts +0 -49
  213. package/dist/server/markdown.js +0 -77
  214. package/dist/server/module-loader.d.ts +0 -4
  215. package/dist/server/module-loader.js +0 -71
  216. package/dist/server/negotiate.d.ts +0 -3
  217. package/dist/server/negotiate.js +0 -61
  218. package/dist/server/page-host.d.ts +0 -21
  219. package/dist/server/page-host.js +0 -66
  220. package/dist/server/page-links.d.ts +0 -10
  221. package/dist/server/page-links.js +0 -80
  222. package/dist/server/route-matcher.d.ts +0 -6
  223. package/dist/server/route-matcher.js +0 -73
  224. package/dist/server/routes.d.ts +0 -6
  225. package/dist/server/routes.js +0 -73
  226. package/dist/server/server.d.ts +0 -28
  227. package/dist/server/server.js +0 -161
  228. package/dist/server/site.d.ts +0 -11
  229. package/dist/server/site.js +0 -59
  230. package/dist/server/targets.d.ts +0 -7
  231. package/dist/server/targets.js +0 -21
  232. package/dist/web/block-runtime.d.ts +0 -2
  233. package/dist/web/block-runtime.js +0 -25
  234. package/dist/web/fragment-render.d.ts +0 -8
  235. package/dist/web/fragment-render.js +0 -58
  236. package/dist/web/i18n.d.ts +0 -29
  237. package/dist/web/i18n.js +0 -65
  238. package/dist/web/navigation.d.ts +0 -3
  239. package/dist/web/navigation.js +0 -32
  240. package/dist/web/page-bootstrap.d.ts +0 -6
  241. package/dist/web/page-bootstrap.js +0 -28
  242. package/dist/web/page-client-runtime.d.ts +0 -4
  243. package/dist/web/page-client-runtime.js +0 -7
  244. package/dist/web/page-client-script.d.ts +0 -1
  245. package/dist/web/page-client-script.js +0 -579
  246. package/dist/web/page-html.d.ts +0 -8
  247. package/dist/web/page-html.js +0 -42
  248. package/dist/web/page-render.d.ts +0 -20
  249. package/dist/web/page-render.js +0 -84
  250. package/dist/web/public-client-runtime.d.ts +0 -1
  251. package/dist/web/public-client-runtime.js +0 -5
  252. package/dist/web/public-render.d.ts +0 -12
  253. package/dist/web/public-render.js +0 -18
  254. package/dist/web/target-path.d.ts +0 -1
  255. package/dist/web/target-path.js +0 -35
@@ -1,579 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.getPageClientRuntimeScript = getPageClientRuntimeScript;
4
- function serializeForInlineScript(value) {
5
- return JSON.stringify(value)
6
- .replace(/</g, "\\u003C")
7
- .replace(/>/g, "\\u003E")
8
- .replace(/&/g, "\\u0026");
9
- }
10
- function getPageClientRuntimeScript() {
11
- return `
12
- (() => {
13
- function escapeHtml(value) {
14
- return String(value)
15
- .replace(/&/g, "&amp;")
16
- .replace(/</g, "&lt;")
17
- .replace(/>/g, "&gt;")
18
- .replace(/"/g, "&quot;")
19
- .replace(/'/g, "&#39;");
20
- }
21
-
22
- function createRegionMarker(kind, blockName) {
23
- return "<!--mdsn:block-region:" + kind + ":" + escapeHtml(blockName) + "-->";
24
- }
25
-
26
- function createBlockRegionMarkup(blockName, innerHtml) {
27
- return createRegionMarker("start", blockName) + '<section class="mdsn-block-region" data-mdsn-block-region="' + escapeHtml(blockName) + '">' + innerHtml + "</section>" + createRegionMarker("end", blockName);
28
- }
29
-
30
- function normalizeRoutePath(routePath) {
31
- if (!routePath || routePath === "/") {
32
- return "/";
33
- }
34
- if (String(routePath).startsWith("/")) {
35
- return String(routePath).replace(/\\/+$|$/u, "") || "/";
36
- }
37
- return ("/" + String(routePath)).replace(/\\/+$|$/u, "") || "/";
38
- }
39
-
40
- function markdownPathToRoutePath(pathname) {
41
- if (!pathname || !String(pathname).toLowerCase().endsWith(".md")) {
42
- return null;
43
- }
44
-
45
- const normalized = normalizeRoutePath(pathname);
46
- if (normalized === "/index.md") {
47
- return "/";
48
- }
49
-
50
- const stripped = normalized.slice(0, -3);
51
- if (stripped.endsWith("/index")) {
52
- return stripped.slice(0, -6) || "/";
53
- }
54
-
55
- return stripped.length > 0 ? stripped : "/";
56
- }
57
-
58
- function mapTargetToHttpPath(target) {
59
- if (/^https?:\\/\\//i.test(String(target))) {
60
- return String(target);
61
- }
62
-
63
- const markdownRoutePath = markdownPathToRoutePath(target);
64
- if (markdownRoutePath) {
65
- return markdownRoutePath;
66
- }
67
- return String(target);
68
- }
69
-
70
- function replaceBlockRegionMarkup(html, blockName, replacementInnerHtml) {
71
- const escapedName = escapeHtml(blockName).replace(/[.*+?^$()|[\\]\\\\]/g, "\\\\$&");
72
- const pattern = new RegExp("<!--mdsn:block-region:start:" + escapedName + "-->[\\\\s\\\\S]*?<!--mdsn:block-region:end:" + escapedName + "-->", "g");
73
- return html.replace(pattern, createBlockRegionMarkup(blockName, replacementInnerHtml));
74
- }
75
-
76
- function trimTrailingBlankLines(value) {
77
- return String(value).replace(/\\n+$/u, "\\n");
78
- }
79
-
80
- function extractExecutableMdsnBlocks(markdown) {
81
- const lines = String(markdown).split(/\\r?\\n/);
82
- const keptLines = [];
83
- const blocks = [];
84
- const fence = String.fromCharCode(96) + String.fromCharCode(96) + String.fromCharCode(96);
85
- let index = 0;
86
-
87
- while (index < lines.length) {
88
- const line = lines[index];
89
- const trimmed = line.trim();
90
-
91
- if (trimmed === fence + "mdsn") {
92
- index += 1;
93
- const blockLines = [];
94
- while (index < lines.length && lines[index].trim() !== fence) {
95
- blockLines.push(lines[index]);
96
- index += 1;
97
- }
98
- if (index >= lines.length) {
99
- throw new Error("Unterminated mdsn code block");
100
- }
101
- blocks.push(blockLines.join("\\n"));
102
- index += 1;
103
- continue;
104
- }
105
-
106
- keptLines.push(line);
107
- index += 1;
108
- }
109
-
110
- return {
111
- markdownWithoutMdsn: trimTrailingBlankLines(keptLines.join("\\n")),
112
- blocks,
113
- };
114
- }
115
-
116
- function isIdentifier(value) {
117
- return /^[a-zA-Z_][\\w-]*$/.test(value);
118
- }
119
-
120
- function parseIdentifierList(raw) {
121
- const trimmed = String(raw || "").trim();
122
- if (!trimmed) return [];
123
- const items = trimmed.split(",").map((part) => part.trim()).filter(Boolean);
124
- for (const item of items) {
125
- if (!isIdentifier(item)) {
126
- throw new Error("Invalid identifier in argument list: " + item);
127
- }
128
- }
129
- return items;
130
- }
131
-
132
- function parseStringArrayLiteral(raw) {
133
- const parsed = JSON.parse(raw);
134
- if (!Array.isArray(parsed) || !parsed.every((item) => typeof item === "string")) {
135
- throw new Error("Invalid array literal: " + raw);
136
- }
137
- return parsed;
138
- }
139
-
140
- function parseBlockHeaderLine(line) {
141
- const match = String(line).trim().match(/^block\\s+([a-zA-Z_][\\w-]*)\\s*\\{$/);
142
- if (!match) {
143
- throw new Error("Invalid block declaration: " + line);
144
- }
145
- return match[1];
146
- }
147
-
148
- function parseInputLine(line, blockName) {
149
- const match = String(line)
150
- .trim()
151
- .match(/^INPUT\\s+(text|number|boolean|choice|asset)(?:\\s+(.*?))?\\s*->\\s*([a-zA-Z_][\\w-]*)$/);
152
- if (!match) {
153
- throw new Error("Invalid input declaration: " + line);
154
- }
155
-
156
- const type = match[1];
157
- const trailing = String(match[2] || "").trim();
158
- const name = match[3];
159
- const required = /\\brequired\\b/u.test(trailing);
160
- const secret = /\\bsecret\\b/u.test(trailing);
161
- const optionsLiteral = (trailing.match(/(\\[.*\\])/u) || [])[1];
162
- const normalizedTrailing = trailing
163
- .replace(/\\brequired\\b/gu, "")
164
- .replace(/\\bsecret\\b/gu, "")
165
- .replace(/(\\[.*\\])/u, "")
166
- .trim();
167
- if (normalizedTrailing) {
168
- throw new Error("Invalid input declaration: " + line);
169
- }
170
- const input = {
171
- id: blockName + "::input::" + name,
172
- block: blockName,
173
- name,
174
- type,
175
- required,
176
- secret,
177
- };
178
-
179
- if (optionsLiteral) {
180
- input.options = parseStringArrayLiteral(optionsLiteral);
181
- }
182
-
183
- if (input.type === "choice" && (!input.options || input.options.length === 0)) {
184
- throw new Error("Choice input " + name + " in block " + blockName + " must define options");
185
- }
186
-
187
- if (input.type !== "choice" && input.options) {
188
- throw new Error("Only choice input " + name + " in block " + blockName + " can define options");
189
- }
190
-
191
- return input;
192
- }
193
-
194
- function parseReadOrWriteLine(line, kind, blockName, index) {
195
- if (kind === "read") {
196
- const match = String(line)
197
- .trim()
198
- .match(/^GET\\s+"([^"]+)"(?:\\s*\\(([^)]*)\\))?(?:\\s+accept:"([^"]+)")?(?:\\s*->\\s*([a-zA-Z_][\\w-]*))?$/);
199
- if (!match) {
200
- throw new Error("Invalid " + kind + " declaration: " + line);
201
- }
202
-
203
- const target = match[1];
204
- const rawInputs = match[2];
205
- const accept = match[3];
206
- const name = match[4];
207
- const isStream = String(accept || "").toLowerCase() === "text/event-stream";
208
-
209
- if ((!name && !isStream) || (isStream && name)) {
210
- throw new Error("Invalid " + kind + " declaration: " + line);
211
- }
212
-
213
- return {
214
- id: blockName + "::" + kind + "::" + index,
215
- block: blockName,
216
- name,
217
- target,
218
- inputs: parseIdentifierList(rawInputs || ""),
219
- accept,
220
- order: index,
221
- };
222
- }
223
-
224
- const match = String(line).trim().match(/^POST\\s+"([^"]+)"\\s*\\(([^)]*)\\)\\s*->\\s*([a-zA-Z_][\\w-]*)$/);
225
- if (!match) {
226
- throw new Error("Invalid " + kind + " declaration: " + line);
227
- }
228
-
229
- const target = match[1];
230
- const rawInputs = match[2];
231
- const name = match[3];
232
-
233
- return {
234
- id: blockName + "::" + kind + "::" + index,
235
- block: blockName,
236
- name,
237
- target,
238
- inputs: parseIdentifierList(rawInputs || ""),
239
- order: index,
240
- };
241
- }
242
-
243
- function getNextOperationOrder(block) {
244
- return block.reads.length + block.writes.length;
245
- }
246
-
247
- function parseMdsnBlocks(blocks) {
248
- const documentBlocks = [];
249
- let currentBlock = null;
250
-
251
- for (const blockText of blocks) {
252
- const lines = String(blockText).split(/\\r?\\n/);
253
- let index = 0;
254
-
255
- while (index < lines.length) {
256
- const line = String(lines[index]).trim();
257
- if (!line) {
258
- index += 1;
259
- continue;
260
- }
261
-
262
- if (!currentBlock) {
263
- if (line.startsWith("block ")) {
264
- currentBlock = {
265
- name: parseBlockHeaderLine(line),
266
- inputs: [],
267
- reads: [],
268
- writes: [],
269
- };
270
- documentBlocks.push(currentBlock);
271
- index += 1;
272
- continue;
273
- }
274
-
275
- if (line === "}") {
276
- throw new Error("Unexpected block terminator: " + line);
277
- }
278
-
279
- throw new Error("Unsupported MDSN statement: " + line);
280
- }
281
-
282
- if (line === "}") {
283
- currentBlock = null;
284
- index += 1;
285
- continue;
286
- }
287
-
288
- if (line.startsWith("INPUT ")) {
289
- currentBlock.inputs.push(parseInputLine(line, currentBlock.name));
290
- index += 1;
291
- continue;
292
- }
293
-
294
- if (line.startsWith("GET ")) {
295
- currentBlock.reads.push(parseReadOrWriteLine(line, "read", currentBlock.name, getNextOperationOrder(currentBlock)));
296
- index += 1;
297
- continue;
298
- }
299
-
300
- if (line.startsWith("POST ")) {
301
- currentBlock.writes.push(parseReadOrWriteLine(line, "write", currentBlock.name, getNextOperationOrder(currentBlock)));
302
- index += 1;
303
- continue;
304
- }
305
-
306
- throw new Error("Unsupported MDSN statement: " + line);
307
- }
308
- }
309
-
310
- if (currentBlock) {
311
- throw new Error("Unterminated block declaration: " + currentBlock.name);
312
- }
313
-
314
- return {
315
- blocks: documentBlocks,
316
- };
317
- }
318
-
319
- function parseBlockFragment(raw) {
320
- const extracted = extractExecutableMdsnBlocks(raw);
321
- if (extracted.blocks.length > 1) {
322
- throw new Error("A block fragment may contain at most one mdsn code block");
323
- }
324
- if (extracted.blocks.length === 0) {
325
- return {
326
- markdown: extracted.markdownWithoutMdsn,
327
- blocks: [],
328
- };
329
- }
330
- const parsed = parseMdsnBlocks(extracted.blocks);
331
- return {
332
- markdown: extracted.markdownWithoutMdsn,
333
- blocks: parsed.blocks,
334
- };
335
- }
336
-
337
- const bootstrapElement = document.getElementById("mdsn-bootstrap");
338
- if (!bootstrapElement || !bootstrapElement.textContent) return;
339
-
340
- const bootstrap = JSON.parse(bootstrapElement.textContent);
341
- if (!bootstrap || bootstrap.version !== "vNext") return;
342
-
343
- const root = document.querySelector("[data-mdsn-root]");
344
- if (!(root instanceof HTMLElement)) return;
345
-
346
- const statusElement = document.querySelector("[data-mdsn-status]");
347
- const inputDefinitionsById = new Map();
348
- const operationsById = new Map();
349
-
350
- function registerBlock(block) {
351
- for (const input of block.inputs || []) {
352
- inputDefinitionsById.set(input.id, input);
353
- }
354
- for (const read of block.reads || []) {
355
- operationsById.set(read.id, { ...read, kind: "read" });
356
- }
357
- for (const write of block.writes || []) {
358
- operationsById.set(write.id, { ...write, kind: "write" });
359
- }
360
- }
361
-
362
- function clearBlock(blockName) {
363
- for (const key of Array.from(inputDefinitionsById.keys())) {
364
- if (String(key).startsWith(blockName + "::input::")) {
365
- inputDefinitionsById.delete(key);
366
- }
367
- }
368
- for (const [key, value] of Array.from(operationsById.entries())) {
369
- if (value && value.block === blockName) {
370
- operationsById.delete(key);
371
- }
372
- }
373
- }
374
-
375
- function parseOperationOrder(operationId, kind) {
376
- const pattern = new RegExp("::" + kind + "::(\\\\d+)$");
377
- const match = String(operationId || "").match(pattern);
378
- return match ? Number(match[1]) : 0;
379
- }
380
-
381
- function registerBlockFromDom(blockName) {
382
- clearBlock(blockName);
383
- for (const element of document.querySelectorAll("[data-mdsn-input]")) {
384
- const inputId = element.getAttribute("data-mdsn-input");
385
- const name = element.getAttribute("data-input-name");
386
- const type = element.getAttribute("data-input-type");
387
- if (!inputId || !inputId.startsWith(blockName + "::input::") || !name || !type) {
388
- continue;
389
- }
390
-
391
- inputDefinitionsById.set(inputId, {
392
- id: inputId,
393
- block: blockName,
394
- name,
395
- type,
396
- required: element.getAttribute("data-required") === "true",
397
- secret: element.getAttribute("data-secret") === "true",
398
- });
399
- }
400
-
401
- for (const element of document.querySelectorAll("[data-mdsn-read]")) {
402
- const operationId = element.getAttribute("data-mdsn-read");
403
- const target = element.getAttribute("data-target");
404
- if (!operationId || !operationId.startsWith(blockName + "::read::") || !target) {
405
- continue;
406
- }
407
-
408
- operationsById.set(operationId, {
409
- id: operationId,
410
- block: blockName,
411
- kind: "read",
412
- name: element.getAttribute("data-op-name") || element.textContent || "read",
413
- target,
414
- inputs: parseIdentifierList(element.getAttribute("data-inputs") || ""),
415
- order: parseOperationOrder(operationId, "read"),
416
- });
417
- }
418
-
419
- for (const element of document.querySelectorAll("[data-mdsn-write]")) {
420
- const operationId = element.getAttribute("data-mdsn-write");
421
- const target = element.getAttribute("data-target");
422
- if (!operationId || !operationId.startsWith(blockName + "::write::") || !target) {
423
- continue;
424
- }
425
-
426
- operationsById.set(operationId, {
427
- id: operationId,
428
- block: blockName,
429
- kind: "write",
430
- name: element.getAttribute("data-op-name") || element.textContent || "write",
431
- target,
432
- inputs: parseIdentifierList(element.getAttribute("data-inputs") || ""),
433
- order: parseOperationOrder(operationId, "write"),
434
- });
435
- }
436
-
437
- }
438
-
439
- for (const block of bootstrap.blocks || []) {
440
- registerBlock(block);
441
- }
442
-
443
- function updateStatus(message, state) {
444
- if (!(statusElement instanceof HTMLElement)) return;
445
- statusElement.textContent = message;
446
- if (typeof state === "string") {
447
- statusElement.dataset.state = state;
448
- }
449
- statusElement.hidden = !message;
450
- }
451
-
452
- function findInputElement(inputId) {
453
- const elements = document.querySelectorAll("[data-mdsn-input]");
454
- for (const element of elements) {
455
- if (element instanceof HTMLElement && element.getAttribute("data-mdsn-input") === inputId) {
456
- return element;
457
- }
458
- }
459
- return null;
460
- }
461
-
462
- function getInputValue(definition) {
463
- const element = findInputElement(definition.id);
464
- if (!element) {
465
- return bootstrap.inputState ? bootstrap.inputState[definition.id] : "";
466
- }
467
-
468
- if (element instanceof HTMLInputElement && element.type === "checkbox") {
469
- return Boolean(element.checked);
470
- }
471
-
472
- if (element instanceof HTMLInputElement && element.type === "number") {
473
- return element.value === "" ? "" : Number(element.value);
474
- }
475
-
476
- return element.value;
477
- }
478
-
479
- function serializeInputsAsMarkdown(inputs) {
480
- return Object.entries(inputs)
481
- .filter((entry) => entry[1] !== undefined)
482
- .map((entry) => entry[0] + ": " + JSON.stringify(entry[1]))
483
- .join(", ");
484
- }
485
-
486
- function applyQueryParams(target, inputs) {
487
- const source = String(target || "");
488
- if (!inputs || Object.keys(inputs).length === 0) {
489
- return source;
490
- }
491
- const parts = source.split("?");
492
- const basePath = parts[0] || "";
493
- const existingQuery = parts[1] ? new URLSearchParams(parts[1]) : new URLSearchParams();
494
- for (const entry of Object.entries(inputs)) {
495
- const name = entry[0];
496
- const value = entry[1];
497
- if (value === undefined || value === null || value === "") {
498
- continue;
499
- }
500
- existingQuery.set(name, String(value));
501
- }
502
- const queryString = existingQuery.toString();
503
- return queryString ? basePath + "?" + queryString : basePath;
504
- }
505
-
506
- async function runOperation(operationId, button) {
507
- const operation = operationsById.get(operationId);
508
- if (!operation) return;
509
-
510
- if (button instanceof HTMLButtonElement) {
511
- button.disabled = true;
512
- }
513
-
514
- updateStatus("Loading...", "loading");
515
-
516
- try {
517
- const inputs = {};
518
- for (const inputName of operation.inputs || []) {
519
- const inputId = operation.block + "::input::" + inputName;
520
- const definition = inputDefinitionsById.get(inputId);
521
- if (!definition) continue;
522
- inputs[inputName] = getInputValue(definition);
523
- }
524
-
525
- const method = operation.kind === "read" ? "GET" : "POST";
526
- const mappedTarget = mapTargetToHttpPath(operation.target);
527
- const requestTarget = method === "GET" ? applyQueryParams(mappedTarget, inputs) : mappedTarget;
528
- const requestInit = method === "GET"
529
- ? {
530
- method,
531
- headers: { Accept: "text/html" },
532
- }
533
- : {
534
- method,
535
- headers: {
536
- "content-type": "text/markdown",
537
- Accept: "text/html",
538
- },
539
- body: serializeInputsAsMarkdown(inputs),
540
- };
541
- const response = await fetch(requestTarget, requestInit);
542
- const contentType = response.headers.get("content-type") || "";
543
- const payload = await response.text();
544
- if (contentType && !contentType.includes("text/html")) {
545
- throw new Error("Invalid action response: expected text/html fragment");
546
- }
547
-
548
- root.innerHTML = replaceBlockRegionMarkup(root.innerHTML, operation.block, payload);
549
- registerBlockFromDom(operation.block);
550
- bindActions("[data-mdsn-read]", "data-mdsn-read");
551
- bindActions("[data-mdsn-write]", "data-mdsn-write");
552
- updateStatus(response.ok ? "Updated." : "Failed: action returned an error fragment.", response.ok ? "success" : "error");
553
- } catch (error) {
554
- updateStatus("Failed: " + (error instanceof Error ? error.message : String(error)), "error");
555
- } finally {
556
- if (button instanceof HTMLButtonElement) {
557
- button.disabled = false;
558
- }
559
- }
560
- }
561
-
562
- function bindActions(selector, attributeName) {
563
- for (const element of document.querySelectorAll(selector)) {
564
- if (!(element instanceof HTMLButtonElement)) continue;
565
- if (element.dataset.bound === "true") continue;
566
- const operationId = element.getAttribute(attributeName);
567
- if (!operationId) continue;
568
- element.addEventListener("click", () => {
569
- void runOperation(operationId, element);
570
- });
571
- element.dataset.bound = "true";
572
- }
573
- }
574
-
575
- bindActions("[data-mdsn-read]", "data-mdsn-read");
576
- bindActions("[data-mdsn-write]", "data-mdsn-write");
577
- })();
578
- `;
579
- }
@@ -1,8 +0,0 @@
1
- import type { PageRenderModel } from "./page-render";
2
- export interface PageHtmlOptions {
3
- title?: string;
4
- lang?: string;
5
- clientScriptPath?: string;
6
- }
7
- export declare function renderPageHtmlContent(model: PageRenderModel, options?: Pick<PageHtmlOptions, "clientScriptPath">): string;
8
- export declare function renderPageHtmlDocument(model: PageRenderModel, options?: PageHtmlOptions): string;
@@ -1,42 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.renderPageHtmlContent = renderPageHtmlContent;
4
- exports.renderPageHtmlDocument = renderPageHtmlDocument;
5
- const core_1 = require("../core");
6
- function serializeInlineJson(value) {
7
- return JSON.stringify(value)
8
- .replace(/</g, "\\u003C")
9
- .replace(/>/g, "\\u003E")
10
- .replace(/&/g, "\\u0026");
11
- }
12
- function renderPageHtmlContent(model, options) {
13
- const clientScriptPath = options?.clientScriptPath ?? "/__mdsn/client.js";
14
- return `<main>
15
- <article class="mdsn-content" data-mdsn-root>${model.markdownHtml}</article>
16
- <div data-mdsn-status hidden></div>
17
- </main>
18
- <script id="mdsn-bootstrap" type="application/json">${serializeInlineJson(model.bootstrap)}</script>
19
- <script src="${(0, core_1.escapeHtml)(clientScriptPath)}" defer></script>`;
20
- }
21
- function renderPageHtmlDocument(model, options) {
22
- const title = typeof options?.title === "string" && options.title.trim().length > 0
23
- ? options.title
24
- : typeof model.document.frontmatter.title === "string" && model.document.frontmatter.title.trim().length > 0
25
- ? model.document.frontmatter.title
26
- : "MDSN Page";
27
- const lang = typeof options?.lang === "string" && options.lang.trim().length > 0
28
- ? options.lang
29
- : "en";
30
- const clientScriptPath = options?.clientScriptPath ?? "/__mdsn/client.js";
31
- return `<!doctype html>
32
- <html lang="${(0, core_1.escapeHtml)(lang)}">
33
- <head>
34
- <meta charset="utf-8" />
35
- <meta name="viewport" content="width=device-width, initial-scale=1" />
36
- <title>${(0, core_1.escapeHtml)(title)}</title>
37
- </head>
38
- <body>
39
- ${renderPageHtmlContent(model, { clientScriptPath })}
40
- </body>
41
- </html>`;
42
- }
@@ -1,20 +0,0 @@
1
- import { type BlockDefinition } from "../core/model/block";
2
- import type { DocumentDefinition } from "../core/model/document";
3
- import { type PageBootstrap } from "./page-bootstrap";
4
- import { type ParsedPage } from "./headless";
5
- export interface PageRenderModel {
6
- markdownHtml: string;
7
- bootstrap: PageBootstrap;
8
- document: DocumentDefinition;
9
- page: ParsedPage;
10
- }
11
- export interface RenderMarkdownOptions {
12
- linkify?: boolean;
13
- typographer?: boolean;
14
- }
15
- export interface CreatePageRenderOptions {
16
- mapActionTarget?: (target: string) => string;
17
- markdown?: RenderMarkdownOptions;
18
- }
19
- export declare function renderBlockPanelHtml(block: BlockDefinition, options?: CreatePageRenderOptions, mode?: "region" | "plain"): string;
20
- export declare function createPageRenderModel(document: DocumentDefinition, options?: CreatePageRenderOptions): PageRenderModel;