mulmocast 2.6.16 → 2.6.17
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/lib/actions/viewer.js +1 -1
- package/lib/cli/bin.js +0 -0
- package/lib/mcp/server.js +0 -0
- package/lib/types/schema.d.ts +457 -457
- package/lib/types/schema.js +2 -2
- package/lib/utils/context.d.ts +728 -728
- package/lib/utils/image_plugins/slide.d.ts +1 -1
- package/lib/utils/image_plugins/slide.js +1 -1
- package/package.json +7 -6
- package/lib/data/styles.d.ts +0 -255
- package/lib/data/styles.js +0 -284
- package/lib/slide/blocks.d.ts +0 -13
- package/lib/slide/blocks.js +0 -251
- package/lib/slide/index.d.ts +0 -6
- package/lib/slide/index.js +0 -7
- package/lib/slide/layouts/big_quote.d.ts +0 -2
- package/lib/slide/layouts/big_quote.js +0 -19
- package/lib/slide/layouts/columns.d.ts +0 -2
- package/lib/slide/layouts/columns.js +0 -53
- package/lib/slide/layouts/comparison.d.ts +0 -2
- package/lib/slide/layouts/comparison.js +0 -25
- package/lib/slide/layouts/funnel.d.ts +0 -2
- package/lib/slide/layouts/funnel.js +0 -25
- package/lib/slide/layouts/grid.d.ts +0 -2
- package/lib/slide/layouts/grid.js +0 -38
- package/lib/slide/layouts/index.d.ts +0 -3
- package/lib/slide/layouts/index.js +0 -46
- package/lib/slide/layouts/matrix.d.ts +0 -2
- package/lib/slide/layouts/matrix.js +0 -53
- package/lib/slide/layouts/split.d.ts +0 -2
- package/lib/slide/layouts/split.js +0 -51
- package/lib/slide/layouts/stats.d.ts +0 -2
- package/lib/slide/layouts/stats.js +0 -23
- package/lib/slide/layouts/table.d.ts +0 -2
- package/lib/slide/layouts/table.js +0 -10
- package/lib/slide/layouts/timeline.d.ts +0 -2
- package/lib/slide/layouts/timeline.js +0 -27
- package/lib/slide/layouts/title.d.ts +0 -2
- package/lib/slide/layouts/title.js +0 -19
- package/lib/slide/layouts/waterfall.d.ts +0 -2
- package/lib/slide/layouts/waterfall.js +0 -63
- package/lib/slide/render.d.ts +0 -17
- package/lib/slide/render.js +0 -101
- package/lib/slide/schema.d.ts +0 -9309
- package/lib/slide/schema.js +0 -434
- package/lib/slide/utils.d.ts +0 -76
- package/lib/slide/utils.js +0 -243
- package/lib/types/slide.d.ts +0 -9309
- package/lib/types/slide.js +0 -434
- package/lib/utils/browser_pool.d.ts +0 -5
- package/lib/utils/browser_pool.js +0 -39
- package/lib/utils/markdown.d.ts +0 -3
- package/lib/utils/markdown.js +0 -49
package/lib/types/slide.js
DELETED
|
@@ -1,434 +0,0 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
// ═══════════════════════════════════════════════════════════
|
|
3
|
-
// Foundation: Colors & Typography
|
|
4
|
-
// ═══════════════════════════════════════════════════════════
|
|
5
|
-
/** 6-digit hex without '#' prefix, e.g. "3B82F6" */
|
|
6
|
-
const hexColorSchema = z.string().regex(/^[0-9A-Fa-f]{6}$/);
|
|
7
|
-
/** Semantic accent colors usable on cards, badges, borders, etc. */
|
|
8
|
-
export const accentColorKeySchema = z.enum(["primary", "accent", "success", "warning", "danger", "info", "highlight"]);
|
|
9
|
-
export const slideThemeColorsSchema = z.object({
|
|
10
|
-
bg: hexColorSchema,
|
|
11
|
-
bgCard: hexColorSchema,
|
|
12
|
-
bgCardAlt: hexColorSchema,
|
|
13
|
-
text: hexColorSchema,
|
|
14
|
-
textMuted: hexColorSchema,
|
|
15
|
-
textDim: hexColorSchema,
|
|
16
|
-
primary: hexColorSchema,
|
|
17
|
-
accent: hexColorSchema,
|
|
18
|
-
success: hexColorSchema,
|
|
19
|
-
warning: hexColorSchema,
|
|
20
|
-
danger: hexColorSchema,
|
|
21
|
-
info: hexColorSchema,
|
|
22
|
-
highlight: hexColorSchema,
|
|
23
|
-
});
|
|
24
|
-
export const slideThemeFontsSchema = z.object({
|
|
25
|
-
title: z.string(),
|
|
26
|
-
body: z.string(),
|
|
27
|
-
mono: z.string(),
|
|
28
|
-
});
|
|
29
|
-
export const slideThemeSchema = z.object({
|
|
30
|
-
colors: slideThemeColorsSchema,
|
|
31
|
-
fonts: slideThemeFontsSchema,
|
|
32
|
-
});
|
|
33
|
-
// ═══════════════════════════════════════════════════════════
|
|
34
|
-
// Content Blocks — the atoms of slide content
|
|
35
|
-
// ═══════════════════════════════════════════════════════════
|
|
36
|
-
export const textBlockSchema = z.object({
|
|
37
|
-
type: z.literal("text"),
|
|
38
|
-
value: z.string(),
|
|
39
|
-
align: z.enum(["left", "center", "right"]).optional(),
|
|
40
|
-
bold: z.boolean().optional(),
|
|
41
|
-
dim: z.boolean().optional(),
|
|
42
|
-
fontSize: z.number().optional(),
|
|
43
|
-
color: accentColorKeySchema.optional(),
|
|
44
|
-
});
|
|
45
|
-
/** Sub-bullet item: plain string or object with text */
|
|
46
|
-
const subBulletItemSchema = z.union([z.string(), z.object({ text: z.string() })]);
|
|
47
|
-
/** Bullet item: plain string or object with text and optional sub-items (2 levels max) */
|
|
48
|
-
export const bulletItemSchema = z.union([
|
|
49
|
-
z.string(),
|
|
50
|
-
z.object({
|
|
51
|
-
text: z.string(),
|
|
52
|
-
items: z.array(subBulletItemSchema).optional(),
|
|
53
|
-
}),
|
|
54
|
-
]);
|
|
55
|
-
export const bulletsBlockSchema = z.object({
|
|
56
|
-
type: z.literal("bullets"),
|
|
57
|
-
items: z.array(bulletItemSchema),
|
|
58
|
-
ordered: z.boolean().optional(),
|
|
59
|
-
icon: z.string().optional(),
|
|
60
|
-
});
|
|
61
|
-
export const codeBlockSchema = z.object({
|
|
62
|
-
type: z.literal("code"),
|
|
63
|
-
code: z.string(),
|
|
64
|
-
language: z.string().optional(),
|
|
65
|
-
});
|
|
66
|
-
export const calloutBlockSchema = z.object({
|
|
67
|
-
type: z.literal("callout"),
|
|
68
|
-
text: z.string(),
|
|
69
|
-
label: z.string().optional(),
|
|
70
|
-
color: accentColorKeySchema.optional(),
|
|
71
|
-
style: z.enum(["quote", "info", "warning"]).optional(),
|
|
72
|
-
});
|
|
73
|
-
export const metricBlockSchema = z.object({
|
|
74
|
-
type: z.literal("metric"),
|
|
75
|
-
value: z.string(),
|
|
76
|
-
label: z.string(),
|
|
77
|
-
color: accentColorKeySchema.optional(),
|
|
78
|
-
change: z.string().optional(),
|
|
79
|
-
});
|
|
80
|
-
export const dividerBlockSchema = z.object({
|
|
81
|
-
type: z.literal("divider"),
|
|
82
|
-
color: accentColorKeySchema.optional(),
|
|
83
|
-
});
|
|
84
|
-
export const imageBlockSchema = z.object({
|
|
85
|
-
type: z.literal("image"),
|
|
86
|
-
src: z.string(),
|
|
87
|
-
alt: z.string().optional(),
|
|
88
|
-
fit: z.enum(["contain", "cover"]).optional(),
|
|
89
|
-
});
|
|
90
|
-
export const imageRefBlockSchema = z.object({
|
|
91
|
-
type: z.literal("imageRef"),
|
|
92
|
-
ref: z.string(),
|
|
93
|
-
alt: z.string().optional(),
|
|
94
|
-
fit: z.enum(["contain", "cover"]).optional(),
|
|
95
|
-
});
|
|
96
|
-
export const chartBlockSchema = z.object({
|
|
97
|
-
type: z.literal("chart"),
|
|
98
|
-
chartData: z.record(z.string(), z.unknown()),
|
|
99
|
-
title: z.string().optional(),
|
|
100
|
-
});
|
|
101
|
-
export const mermaidBlockSchema = z.object({
|
|
102
|
-
type: z.literal("mermaid"),
|
|
103
|
-
code: z.string(),
|
|
104
|
-
title: z.string().optional(),
|
|
105
|
-
});
|
|
106
|
-
export const tableCellValueSchema = z.union([
|
|
107
|
-
z.string(),
|
|
108
|
-
z.object({
|
|
109
|
-
text: z.string(),
|
|
110
|
-
color: accentColorKeySchema.optional(),
|
|
111
|
-
bold: z.boolean().optional(),
|
|
112
|
-
badge: z.boolean().optional(),
|
|
113
|
-
}),
|
|
114
|
-
]);
|
|
115
|
-
export const tableBlockSchema = z.object({
|
|
116
|
-
type: z.literal("table"),
|
|
117
|
-
title: z.string().optional(),
|
|
118
|
-
headers: z.array(z.string()).optional(),
|
|
119
|
-
rows: z.array(z.array(tableCellValueSchema)),
|
|
120
|
-
rowHeaders: z.boolean().optional(),
|
|
121
|
-
striped: z.boolean().optional(),
|
|
122
|
-
});
|
|
123
|
-
/** Block schemas shared between contentBlockSchema and nonSectionContentBlockSchema */
|
|
124
|
-
const baseBlockSchemas = [
|
|
125
|
-
textBlockSchema,
|
|
126
|
-
bulletsBlockSchema,
|
|
127
|
-
codeBlockSchema,
|
|
128
|
-
calloutBlockSchema,
|
|
129
|
-
metricBlockSchema,
|
|
130
|
-
dividerBlockSchema,
|
|
131
|
-
imageBlockSchema,
|
|
132
|
-
imageRefBlockSchema,
|
|
133
|
-
chartBlockSchema,
|
|
134
|
-
mermaidBlockSchema,
|
|
135
|
-
tableBlockSchema,
|
|
136
|
-
];
|
|
137
|
-
/** All content block types except section (used inside section to prevent recursion) */
|
|
138
|
-
const nonSectionContentBlockSchema = z.discriminatedUnion("type", [...baseBlockSchemas]);
|
|
139
|
-
export const sectionBlockSchema = z.object({
|
|
140
|
-
type: z.literal("section"),
|
|
141
|
-
label: z.string(),
|
|
142
|
-
color: accentColorKeySchema.optional(),
|
|
143
|
-
content: z.array(nonSectionContentBlockSchema).optional(),
|
|
144
|
-
text: z.string().optional(),
|
|
145
|
-
sidebar: z.boolean().optional(),
|
|
146
|
-
});
|
|
147
|
-
export const contentBlockSchema = z.discriminatedUnion("type", [...baseBlockSchemas, sectionBlockSchema]);
|
|
148
|
-
// ═══════════════════════════════════════════════════════════
|
|
149
|
-
// Shared Components
|
|
150
|
-
// ═══════════════════════════════════════════════════════════
|
|
151
|
-
/** Bottom-of-slide callout bar */
|
|
152
|
-
export const calloutBarSchema = z.object({
|
|
153
|
-
text: z.string(),
|
|
154
|
-
label: z.string().optional(),
|
|
155
|
-
color: accentColorKeySchema.optional(),
|
|
156
|
-
align: z.enum(["left", "center"]).optional(),
|
|
157
|
-
leftBar: z.boolean().optional(),
|
|
158
|
-
});
|
|
159
|
-
/** Reusable card definition — used by columns, grid */
|
|
160
|
-
export const cardSchema = z.object({
|
|
161
|
-
title: z.string(),
|
|
162
|
-
accentColor: accentColorKeySchema.optional(),
|
|
163
|
-
content: z.array(contentBlockSchema).optional(),
|
|
164
|
-
footer: z.string().optional(),
|
|
165
|
-
label: z.string().optional(),
|
|
166
|
-
num: z.number().optional(),
|
|
167
|
-
icon: z.string().optional(),
|
|
168
|
-
});
|
|
169
|
-
// ═══════════════════════════════════════════════════════════
|
|
170
|
-
// Slide-level styling — orthogonal to layout
|
|
171
|
-
// ═══════════════════════════════════════════════════════════
|
|
172
|
-
export const slideStyleSchema = z.object({
|
|
173
|
-
bgColor: z.string().optional(),
|
|
174
|
-
decorations: z.boolean().optional(),
|
|
175
|
-
bgOpacity: z.number().optional(),
|
|
176
|
-
footer: z.string().optional(),
|
|
177
|
-
});
|
|
178
|
-
/** Common slide properties shared across all layouts */
|
|
179
|
-
const slideBaseFields = {
|
|
180
|
-
accentColor: accentColorKeySchema.optional(),
|
|
181
|
-
style: slideStyleSchema.optional(),
|
|
182
|
-
};
|
|
183
|
-
// ═══════════════════════════════════════════════════════════
|
|
184
|
-
// Layouts
|
|
185
|
-
// ═══════════════════════════════════════════════════════════
|
|
186
|
-
// ─── title ───
|
|
187
|
-
export const titleSlideSchema = z.object({
|
|
188
|
-
layout: z.literal("title"),
|
|
189
|
-
...slideBaseFields,
|
|
190
|
-
title: z.string(),
|
|
191
|
-
subtitle: z.string().optional(),
|
|
192
|
-
author: z.string().optional(),
|
|
193
|
-
note: z.string().optional(),
|
|
194
|
-
});
|
|
195
|
-
// ─── columns ───
|
|
196
|
-
export const columnsSlideSchema = z.object({
|
|
197
|
-
layout: z.literal("columns"),
|
|
198
|
-
...slideBaseFields,
|
|
199
|
-
title: z.string(),
|
|
200
|
-
stepLabel: z.string().optional(),
|
|
201
|
-
subtitle: z.string().optional(),
|
|
202
|
-
columns: z.array(cardSchema),
|
|
203
|
-
showArrows: z.boolean().optional(),
|
|
204
|
-
callout: calloutBarSchema.optional(),
|
|
205
|
-
bottomText: z.string().optional(),
|
|
206
|
-
});
|
|
207
|
-
// ─── comparison ───
|
|
208
|
-
export const comparisonPanelSchema = z.object({
|
|
209
|
-
title: z.string(),
|
|
210
|
-
accentColor: accentColorKeySchema.optional(),
|
|
211
|
-
content: z.array(contentBlockSchema).optional(),
|
|
212
|
-
footer: z.string().optional(),
|
|
213
|
-
});
|
|
214
|
-
export const comparisonSlideSchema = z.object({
|
|
215
|
-
layout: z.literal("comparison"),
|
|
216
|
-
...slideBaseFields,
|
|
217
|
-
title: z.string(),
|
|
218
|
-
stepLabel: z.string().optional(),
|
|
219
|
-
subtitle: z.string().optional(),
|
|
220
|
-
left: comparisonPanelSchema,
|
|
221
|
-
right: comparisonPanelSchema,
|
|
222
|
-
callout: calloutBarSchema.optional(),
|
|
223
|
-
});
|
|
224
|
-
// ─── grid ───
|
|
225
|
-
export const gridItemSchema = z.object({
|
|
226
|
-
title: z.string(),
|
|
227
|
-
description: z.string().optional(),
|
|
228
|
-
accentColor: accentColorKeySchema.optional(),
|
|
229
|
-
num: z.number().optional(),
|
|
230
|
-
icon: z.string().optional(),
|
|
231
|
-
content: z.array(contentBlockSchema).optional(),
|
|
232
|
-
});
|
|
233
|
-
export const gridSlideSchema = z.object({
|
|
234
|
-
layout: z.literal("grid"),
|
|
235
|
-
...slideBaseFields,
|
|
236
|
-
title: z.string(),
|
|
237
|
-
subtitle: z.string().optional(),
|
|
238
|
-
gridColumns: z.number().optional(),
|
|
239
|
-
items: z.array(gridItemSchema),
|
|
240
|
-
footer: z.string().optional(),
|
|
241
|
-
});
|
|
242
|
-
// ─── bigQuote ───
|
|
243
|
-
export const bigQuoteSlideSchema = z.object({
|
|
244
|
-
layout: z.literal("bigQuote"),
|
|
245
|
-
...slideBaseFields,
|
|
246
|
-
quote: z.string(),
|
|
247
|
-
author: z.string().optional(),
|
|
248
|
-
role: z.string().optional(),
|
|
249
|
-
});
|
|
250
|
-
// ─── stats ───
|
|
251
|
-
export const statItemSchema = z.object({
|
|
252
|
-
value: z.string(),
|
|
253
|
-
label: z.string(),
|
|
254
|
-
color: accentColorKeySchema.optional(),
|
|
255
|
-
change: z.string().optional(),
|
|
256
|
-
});
|
|
257
|
-
export const statsSlideSchema = z.object({
|
|
258
|
-
layout: z.literal("stats"),
|
|
259
|
-
...slideBaseFields,
|
|
260
|
-
title: z.string(),
|
|
261
|
-
stepLabel: z.string().optional(),
|
|
262
|
-
subtitle: z.string().optional(),
|
|
263
|
-
stats: z.array(statItemSchema),
|
|
264
|
-
callout: calloutBarSchema.optional(),
|
|
265
|
-
});
|
|
266
|
-
// ─── timeline ───
|
|
267
|
-
export const timelineItemSchema = z.object({
|
|
268
|
-
date: z.string(),
|
|
269
|
-
title: z.string(),
|
|
270
|
-
description: z.string().optional(),
|
|
271
|
-
color: accentColorKeySchema.optional(),
|
|
272
|
-
done: z.boolean().optional(),
|
|
273
|
-
});
|
|
274
|
-
export const timelineSlideSchema = z.object({
|
|
275
|
-
layout: z.literal("timeline"),
|
|
276
|
-
...slideBaseFields,
|
|
277
|
-
title: z.string(),
|
|
278
|
-
stepLabel: z.string().optional(),
|
|
279
|
-
subtitle: z.string().optional(),
|
|
280
|
-
items: z.array(timelineItemSchema),
|
|
281
|
-
});
|
|
282
|
-
// ─── split ───
|
|
283
|
-
export const splitPanelSchema = z.object({
|
|
284
|
-
title: z.string().optional(),
|
|
285
|
-
subtitle: z.string().optional(),
|
|
286
|
-
label: z.string().optional(),
|
|
287
|
-
labelBadge: z.boolean().optional(),
|
|
288
|
-
accentColor: accentColorKeySchema.optional(),
|
|
289
|
-
content: z.array(contentBlockSchema).optional(),
|
|
290
|
-
dark: z.boolean().optional(),
|
|
291
|
-
ratio: z.number().optional(),
|
|
292
|
-
valign: z.enum(["top", "center", "bottom"]).optional(),
|
|
293
|
-
});
|
|
294
|
-
export const splitSlideSchema = z.object({
|
|
295
|
-
layout: z.literal("split"),
|
|
296
|
-
...slideBaseFields,
|
|
297
|
-
left: splitPanelSchema.optional(),
|
|
298
|
-
right: splitPanelSchema.optional(),
|
|
299
|
-
});
|
|
300
|
-
// ─── matrix ───
|
|
301
|
-
export const matrixCellSchema = z.object({
|
|
302
|
-
label: z.string(),
|
|
303
|
-
items: z.array(z.string()).optional(),
|
|
304
|
-
content: z.array(contentBlockSchema).optional(),
|
|
305
|
-
accentColor: accentColorKeySchema.optional(),
|
|
306
|
-
});
|
|
307
|
-
export const matrixSlideSchema = z.object({
|
|
308
|
-
layout: z.literal("matrix"),
|
|
309
|
-
...slideBaseFields,
|
|
310
|
-
title: z.string(),
|
|
311
|
-
stepLabel: z.string().optional(),
|
|
312
|
-
subtitle: z.string().optional(),
|
|
313
|
-
rows: z.number().optional(),
|
|
314
|
-
cols: z.number().optional(),
|
|
315
|
-
xAxis: z
|
|
316
|
-
.object({
|
|
317
|
-
low: z.string().optional(),
|
|
318
|
-
high: z.string().optional(),
|
|
319
|
-
label: z.string().optional(),
|
|
320
|
-
})
|
|
321
|
-
.optional(),
|
|
322
|
-
yAxis: z
|
|
323
|
-
.object({
|
|
324
|
-
low: z.string().optional(),
|
|
325
|
-
high: z.string().optional(),
|
|
326
|
-
label: z.string().optional(),
|
|
327
|
-
})
|
|
328
|
-
.optional(),
|
|
329
|
-
cells: z.array(matrixCellSchema),
|
|
330
|
-
});
|
|
331
|
-
// ─── table ───
|
|
332
|
-
export const tableSlideSchema = z.object({
|
|
333
|
-
layout: z.literal("table"),
|
|
334
|
-
...slideBaseFields,
|
|
335
|
-
title: z.string(),
|
|
336
|
-
stepLabel: z.string().optional(),
|
|
337
|
-
subtitle: z.string().optional(),
|
|
338
|
-
headers: z.array(z.string()),
|
|
339
|
-
rows: z.array(z.array(tableCellValueSchema)),
|
|
340
|
-
rowHeaders: z.boolean().optional(),
|
|
341
|
-
striped: z.boolean().optional(),
|
|
342
|
-
callout: calloutBarSchema.optional(),
|
|
343
|
-
});
|
|
344
|
-
// ─── waterfall ───
|
|
345
|
-
export const waterfallItemSchema = z.object({
|
|
346
|
-
label: z.string(),
|
|
347
|
-
value: z.number(),
|
|
348
|
-
isTotal: z.boolean().optional(),
|
|
349
|
-
color: accentColorKeySchema.optional(),
|
|
350
|
-
});
|
|
351
|
-
export const waterfallSlideSchema = z.object({
|
|
352
|
-
layout: z.literal("waterfall"),
|
|
353
|
-
...slideBaseFields,
|
|
354
|
-
title: z.string(),
|
|
355
|
-
stepLabel: z.string().optional(),
|
|
356
|
-
subtitle: z.string().optional(),
|
|
357
|
-
items: z.array(waterfallItemSchema),
|
|
358
|
-
unit: z.string().optional(),
|
|
359
|
-
callout: calloutBarSchema.optional(),
|
|
360
|
-
});
|
|
361
|
-
// ─── funnel ───
|
|
362
|
-
export const funnelStageSchema = z.object({
|
|
363
|
-
label: z.string(),
|
|
364
|
-
value: z.string().optional(),
|
|
365
|
-
description: z.string().optional(),
|
|
366
|
-
color: accentColorKeySchema.optional(),
|
|
367
|
-
});
|
|
368
|
-
export const funnelSlideSchema = z.object({
|
|
369
|
-
layout: z.literal("funnel"),
|
|
370
|
-
...slideBaseFields,
|
|
371
|
-
title: z.string(),
|
|
372
|
-
stepLabel: z.string().optional(),
|
|
373
|
-
subtitle: z.string().optional(),
|
|
374
|
-
stages: z.array(funnelStageSchema),
|
|
375
|
-
callout: calloutBarSchema.optional(),
|
|
376
|
-
});
|
|
377
|
-
// ═══════════════════════════════════════════════════════════
|
|
378
|
-
// Branding — logo & background image overlay
|
|
379
|
-
// ═══════════════════════════════════════════════════════════
|
|
380
|
-
/**
|
|
381
|
-
* Media source for branding assets (self-contained definition to avoid
|
|
382
|
-
* circular dependency with src/types/schema.ts).
|
|
383
|
-
*/
|
|
384
|
-
const slideMediaSourceSchema = z.discriminatedUnion("kind", [
|
|
385
|
-
z.object({ kind: z.literal("url"), url: z.url() }).strict(),
|
|
386
|
-
z.object({ kind: z.literal("base64"), data: z.string().min(1) }).strict(),
|
|
387
|
-
z.object({ kind: z.literal("path"), path: z.string().min(1) }).strict(),
|
|
388
|
-
]);
|
|
389
|
-
const slideBackgroundImageSourceSchema = z.object({
|
|
390
|
-
source: slideMediaSourceSchema,
|
|
391
|
-
size: z.enum(["cover", "contain", "fill", "auto"]).optional(),
|
|
392
|
-
opacity: z.number().min(0).max(1).optional(),
|
|
393
|
-
bgOpacity: z.number().min(0).max(1).optional(),
|
|
394
|
-
});
|
|
395
|
-
export const slideBrandingLogoSchema = z
|
|
396
|
-
.object({
|
|
397
|
-
source: slideMediaSourceSchema,
|
|
398
|
-
position: z.enum(["top-left", "top-right", "bottom-left", "bottom-right"]).default("top-right"),
|
|
399
|
-
width: z.number().positive().default(120),
|
|
400
|
-
})
|
|
401
|
-
.strict();
|
|
402
|
-
export const slideBrandingSchema = z
|
|
403
|
-
.object({
|
|
404
|
-
logo: slideBrandingLogoSchema.optional(),
|
|
405
|
-
backgroundImage: slideBackgroundImageSourceSchema.optional(),
|
|
406
|
-
})
|
|
407
|
-
.strict();
|
|
408
|
-
// ═══════════════════════════════════════════════════════════
|
|
409
|
-
// Slide Union & Media Schema
|
|
410
|
-
// ═══════════════════════════════════════════════════════════
|
|
411
|
-
export const slideLayoutSchema = z.discriminatedUnion("layout", [
|
|
412
|
-
titleSlideSchema,
|
|
413
|
-
columnsSlideSchema,
|
|
414
|
-
comparisonSlideSchema,
|
|
415
|
-
gridSlideSchema,
|
|
416
|
-
bigQuoteSlideSchema,
|
|
417
|
-
statsSlideSchema,
|
|
418
|
-
timelineSlideSchema,
|
|
419
|
-
splitSlideSchema,
|
|
420
|
-
matrixSlideSchema,
|
|
421
|
-
tableSlideSchema,
|
|
422
|
-
funnelSlideSchema,
|
|
423
|
-
waterfallSlideSchema,
|
|
424
|
-
]);
|
|
425
|
-
/** Media schema registered in mulmoImageAssetSchema */
|
|
426
|
-
export const mulmoSlideMediaSchema = z
|
|
427
|
-
.object({
|
|
428
|
-
type: z.literal("slide"),
|
|
429
|
-
theme: slideThemeSchema.optional(),
|
|
430
|
-
slide: slideLayoutSchema,
|
|
431
|
-
reference: z.string().optional(),
|
|
432
|
-
branding: slideBrandingSchema.nullable().optional(),
|
|
433
|
-
})
|
|
434
|
-
.strict();
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
import puppeteer from "puppeteer";
|
|
2
|
-
/** Get a shared browser instance. Launches one if none exists. */
|
|
3
|
-
export declare const getBrowser: () => Promise<puppeteer.Browser>;
|
|
4
|
-
/** Close the shared browser instance. Call at the end of processing. */
|
|
5
|
-
export declare const closeBrowser: () => Promise<void>;
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import puppeteer from "puppeteer";
|
|
2
|
-
const isCI = process.env.CI === "true";
|
|
3
|
-
const launchArgs = isCI ? ["--no-sandbox", "--allow-file-access-from-files"] : ["--allow-file-access-from-files"];
|
|
4
|
-
let browserInstance = null;
|
|
5
|
-
let launchPromise = null;
|
|
6
|
-
const launchBrowser = async () => {
|
|
7
|
-
const browser = await puppeteer.launch({ args: launchArgs });
|
|
8
|
-
browser.on("disconnected", () => {
|
|
9
|
-
browserInstance = null;
|
|
10
|
-
launchPromise = null;
|
|
11
|
-
});
|
|
12
|
-
return browser;
|
|
13
|
-
};
|
|
14
|
-
/** Get a shared browser instance. Launches one if none exists. */
|
|
15
|
-
export const getBrowser = async () => {
|
|
16
|
-
if (browserInstance?.connected) {
|
|
17
|
-
return browserInstance;
|
|
18
|
-
}
|
|
19
|
-
// Prevent multiple concurrent launches
|
|
20
|
-
if (!launchPromise) {
|
|
21
|
-
launchPromise = launchBrowser().then((browser) => {
|
|
22
|
-
browserInstance = browser;
|
|
23
|
-
launchPromise = null;
|
|
24
|
-
return browser;
|
|
25
|
-
});
|
|
26
|
-
}
|
|
27
|
-
return launchPromise;
|
|
28
|
-
};
|
|
29
|
-
/** Close the shared browser instance. Call at the end of processing. */
|
|
30
|
-
export const closeBrowser = async () => {
|
|
31
|
-
if (launchPromise) {
|
|
32
|
-
await launchPromise;
|
|
33
|
-
}
|
|
34
|
-
if (browserInstance?.connected) {
|
|
35
|
-
await browserInstance.close();
|
|
36
|
-
}
|
|
37
|
-
browserInstance = null;
|
|
38
|
-
launchPromise = null;
|
|
39
|
-
};
|
package/lib/utils/markdown.d.ts
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare const renderHTMLToImage: (html: string, outputPath: string, width: number, height: number, isMermaid?: boolean, omitBackground?: boolean) => Promise<void>;
|
|
2
|
-
export declare const renderMarkdownToImage: (markdown: string, style: string, outputPath: string, width: number, height: number) => Promise<void>;
|
|
3
|
-
export declare const interpolate: (template: string, data: Record<string, string>) => string;
|
package/lib/utils/markdown.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { marked } from "marked";
|
|
2
|
-
import puppeteer from "puppeteer";
|
|
3
|
-
const isCI = process.env.CI === "true";
|
|
4
|
-
export const renderHTMLToImage = async (html, outputPath, width, height, isMermaid = false, omitBackground = false) => {
|
|
5
|
-
// Use Puppeteer to render HTML to an image
|
|
6
|
-
const browser = await puppeteer.launch({
|
|
7
|
-
args: isCI ? ["--no-sandbox"] : [],
|
|
8
|
-
});
|
|
9
|
-
const page = await browser.newPage();
|
|
10
|
-
// Set the page content to the HTML generated from the Markdown
|
|
11
|
-
await page.setContent(html);
|
|
12
|
-
// Adjust page settings if needed (like width, height, etc.)
|
|
13
|
-
await page.setViewport({ width, height });
|
|
14
|
-
await page.addStyleTag({ content: "html,body{margin:0;padding:0;overflow:hidden}" });
|
|
15
|
-
if (isMermaid) {
|
|
16
|
-
await page.waitForFunction(() => {
|
|
17
|
-
const el = document.querySelector(".mermaid");
|
|
18
|
-
return el && el.dataset.ready === "true";
|
|
19
|
-
}, { timeout: 20000 });
|
|
20
|
-
}
|
|
21
|
-
// Wait for Chart.js to finish rendering if this is a chart
|
|
22
|
-
if (html.includes("data-chart-ready")) {
|
|
23
|
-
await page.waitForFunction(() => {
|
|
24
|
-
const canvas = document.querySelector("canvas[data-chart-ready='true']");
|
|
25
|
-
return !!canvas;
|
|
26
|
-
}, { timeout: 20000 });
|
|
27
|
-
}
|
|
28
|
-
// Measure the size of the page and scale the page to the width and height
|
|
29
|
-
await page.evaluate(({ vw, vh }) => {
|
|
30
|
-
const de = document.documentElement;
|
|
31
|
-
const sw = Math.max(de.scrollWidth, document.body.scrollWidth || 0);
|
|
32
|
-
const sh = Math.max(de.scrollHeight, document.body.scrollHeight || 0);
|
|
33
|
-
const scale = Math.min(vw / (sw || vw), vh / (sh || vh), 1); // <=1 で縮小のみ
|
|
34
|
-
de.style.overflow = "hidden";
|
|
35
|
-
document.body.style.zoom = String(scale);
|
|
36
|
-
}, { vw: width, vh: height });
|
|
37
|
-
// Step 3: Capture screenshot of the page (which contains the Markdown-rendered HTML)
|
|
38
|
-
await page.screenshot({ path: outputPath, omitBackground });
|
|
39
|
-
await browser.close();
|
|
40
|
-
};
|
|
41
|
-
export const renderMarkdownToImage = async (markdown, style, outputPath, width, height) => {
|
|
42
|
-
const header = `<head><style>${style}</style></head>`;
|
|
43
|
-
const body = await marked(markdown);
|
|
44
|
-
const html = `<html>${header}<body>${body}</body></html>`;
|
|
45
|
-
await renderHTMLToImage(html, outputPath, width, height);
|
|
46
|
-
};
|
|
47
|
-
export const interpolate = (template, data) => {
|
|
48
|
-
return template.replace(/\$\{(.*?)\}/g, (_, key) => data[key.trim()] ?? "");
|
|
49
|
-
};
|