tailprint 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +160 -2
- package/dist/config/env.d.ts +77 -0
- package/dist/config/env.js +38 -0
- package/dist/config/env.js.map +1 -0
- package/dist/config/plans.d.ts +15 -0
- package/dist/config/plans.js +104 -0
- package/dist/config/plans.js.map +1 -0
- package/dist/config/templates.d.ts +10 -0
- package/dist/config/templates.js +746 -0
- package/dist/config/templates.js.map +1 -0
- package/dist/mcp/server.d.ts +10 -0
- package/dist/mcp/server.js +897 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/stdio.d.ts +2 -0
- package/dist/mcp/stdio.js +27 -0
- package/dist/mcp/stdio.js.map +1 -0
- package/dist/routes/dashboard.d.ts +2 -0
- package/dist/routes/dashboard.js +454 -0
- package/dist/routes/dashboard.js.map +1 -0
- package/dist/routes/mcp.d.ts +2 -0
- package/dist/routes/mcp.js +329 -0
- package/dist/routes/mcp.js.map +1 -0
- package/dist/routes/render.d.ts +2 -0
- package/dist/routes/render.js +444 -0
- package/dist/routes/render.js.map +1 -0
- package/dist/routes/scrape.d.ts +2 -0
- package/dist/routes/scrape.js +132 -0
- package/dist/routes/scrape.js.map +1 -0
- package/dist/routes/templates.d.ts +2 -0
- package/dist/routes/templates.js +2449 -0
- package/dist/routes/templates.js.map +1 -0
- package/dist/routes/usage.d.ts +31 -0
- package/dist/routes/usage.js +73 -0
- package/dist/routes/usage.js.map +1 -0
- package/dist/routes/webhooks.d.ts +2 -0
- package/dist/routes/webhooks.js +227 -0
- package/dist/routes/webhooks.js.map +1 -0
- package/dist/schemas/render.d.ts +422 -0
- package/dist/schemas/render.js +91 -0
- package/dist/schemas/render.js.map +1 -0
- package/dist/schemas/scrape.d.ts +65 -0
- package/dist/schemas/scrape.js +24 -0
- package/dist/schemas/scrape.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.js +206 -0
- package/dist/server.js.map +1 -0
- package/dist/services/browser.d.ts +21 -0
- package/dist/services/browser.js +299 -0
- package/dist/services/browser.js.map +1 -0
- package/dist/services/carousel.d.ts +43 -0
- package/dist/services/carousel.js +300 -0
- package/dist/services/carousel.js.map +1 -0
- package/dist/services/chart.d.ts +29 -0
- package/dist/services/chart.js +129 -0
- package/dist/services/chart.js.map +1 -0
- package/dist/services/eInvoice.d.ts +62 -0
- package/dist/services/eInvoice.js +413 -0
- package/dist/services/eInvoice.js.map +1 -0
- package/dist/services/email.d.ts +24 -0
- package/dist/services/email.js +177 -0
- package/dist/services/email.js.map +1 -0
- package/dist/services/mockup.d.ts +14 -0
- package/dist/services/mockup.js +130 -0
- package/dist/services/mockup.js.map +1 -0
- package/dist/services/pdfStamper.d.ts +16 -0
- package/dist/services/pdfStamper.js +47 -0
- package/dist/services/pdfStamper.js.map +1 -0
- package/dist/services/qr.d.ts +20 -0
- package/dist/services/qr.js +44 -0
- package/dist/services/qr.js.map +1 -0
- package/dist/services/redis.d.ts +65 -0
- package/dist/services/redis.js +318 -0
- package/dist/services/redis.js.map +1 -0
- package/dist/services/scraper.d.ts +16 -0
- package/dist/services/scraper.js +138 -0
- package/dist/services/scraper.js.map +1 -0
- package/dist/services/storage.d.ts +38 -0
- package/dist/services/storage.js +123 -0
- package/dist/services/storage.js.map +1 -0
- package/dist/services/stripe.d.ts +32 -0
- package/dist/services/stripe.js +229 -0
- package/dist/services/stripe.js.map +1 -0
- package/dist/services/visualDiff.d.ts +33 -0
- package/dist/services/visualDiff.js +218 -0
- package/dist/services/visualDiff.js.map +1 -0
- package/package.json +74 -4
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export interface CompareSnapshotsParams {
|
|
2
|
+
beforeUrl?: string;
|
|
3
|
+
beforeHtml?: string;
|
|
4
|
+
afterUrl?: string;
|
|
5
|
+
afterHtml?: string;
|
|
6
|
+
beforeImageBase64?: string;
|
|
7
|
+
afterImageBase64?: string;
|
|
8
|
+
width?: number;
|
|
9
|
+
height?: number;
|
|
10
|
+
threshold?: number;
|
|
11
|
+
generateComposite?: boolean;
|
|
12
|
+
delayMs?: number;
|
|
13
|
+
}
|
|
14
|
+
export interface CompareSnapshotsResult {
|
|
15
|
+
differentPixels: number;
|
|
16
|
+
totalPixels: number;
|
|
17
|
+
diffPercentage: number;
|
|
18
|
+
isIdentical: boolean;
|
|
19
|
+
diffImageBuffer: Buffer;
|
|
20
|
+
compositeImageBuffer: Buffer;
|
|
21
|
+
}
|
|
22
|
+
export declare class VisualDiffService {
|
|
23
|
+
private static instance;
|
|
24
|
+
private constructor();
|
|
25
|
+
static getInstance(): VisualDiffService;
|
|
26
|
+
private normalizePng;
|
|
27
|
+
/**
|
|
28
|
+
* Captures or decodes two snapshots, computes a pixel-by-pixel diff,
|
|
29
|
+
* and creates a studio 3-column visual regression inspection canvas.
|
|
30
|
+
*/
|
|
31
|
+
compareSnapshots(params: CompareSnapshotsParams): Promise<CompareSnapshotsResult>;
|
|
32
|
+
}
|
|
33
|
+
export declare const visualDiffService: VisualDiffService;
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { PNG } from 'pngjs';
|
|
2
|
+
import pixelmatch from 'pixelmatch';
|
|
3
|
+
import { browserService } from './browser.js';
|
|
4
|
+
export class VisualDiffService {
|
|
5
|
+
static instance = null;
|
|
6
|
+
constructor() { }
|
|
7
|
+
static getInstance() {
|
|
8
|
+
if (!VisualDiffService.instance) {
|
|
9
|
+
VisualDiffService.instance = new VisualDiffService();
|
|
10
|
+
}
|
|
11
|
+
return VisualDiffService.instance;
|
|
12
|
+
}
|
|
13
|
+
normalizePng(src, targetWidth, targetHeight) {
|
|
14
|
+
if (src.width === targetWidth && src.height === targetHeight) {
|
|
15
|
+
return src;
|
|
16
|
+
}
|
|
17
|
+
const out = new PNG({ width: targetWidth, height: targetHeight });
|
|
18
|
+
out.data.fill(0); // Initialize transparent buffer
|
|
19
|
+
for (let y = 0; y < src.height && y < targetHeight; y++) {
|
|
20
|
+
for (let x = 0; x < src.width && x < targetWidth; x++) {
|
|
21
|
+
const srcIdx = (y * src.width + x) * 4;
|
|
22
|
+
const outIdx = (y * targetWidth + x) * 4;
|
|
23
|
+
out.data[outIdx] = src.data[srcIdx];
|
|
24
|
+
out.data[outIdx + 1] = src.data[srcIdx + 1];
|
|
25
|
+
out.data[outIdx + 2] = src.data[srcIdx + 2];
|
|
26
|
+
out.data[outIdx + 3] = src.data[srcIdx + 3];
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
return out;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Captures or decodes two snapshots, computes a pixel-by-pixel diff,
|
|
33
|
+
* and creates a studio 3-column visual regression inspection canvas.
|
|
34
|
+
*/
|
|
35
|
+
async compareSnapshots(params) {
|
|
36
|
+
const width = Math.min(Math.max(params.width || 1200, 320), 2560);
|
|
37
|
+
const height = Math.min(Math.max(params.height || 800, 240), 2560);
|
|
38
|
+
const delayMs = params.delayMs !== undefined ? params.delayMs : 300;
|
|
39
|
+
const threshold = params.threshold !== undefined ? params.threshold : 0.1;
|
|
40
|
+
// 1. Resolve Before Snapshot Buffer
|
|
41
|
+
let beforeBuffer;
|
|
42
|
+
if (params.beforeImageBase64) {
|
|
43
|
+
const clean = params.beforeImageBase64.replace(/^data:image\/[a-z]+;base64,/, '').trim();
|
|
44
|
+
beforeBuffer = Buffer.from(clean, 'base64');
|
|
45
|
+
}
|
|
46
|
+
else if (params.beforeUrl || params.beforeHtml) {
|
|
47
|
+
beforeBuffer = await browserService.renderImage({
|
|
48
|
+
url: params.beforeUrl,
|
|
49
|
+
html: params.beforeHtml,
|
|
50
|
+
width,
|
|
51
|
+
height,
|
|
52
|
+
type: 'png',
|
|
53
|
+
delay_ms: delayMs,
|
|
54
|
+
});
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
throw new Error('Must provide beforeUrl, beforeHtml, or beforeImageBase64');
|
|
58
|
+
}
|
|
59
|
+
// 2. Resolve After Snapshot Buffer
|
|
60
|
+
let afterBuffer;
|
|
61
|
+
if (params.afterImageBase64) {
|
|
62
|
+
const clean = params.afterImageBase64.replace(/^data:image\/[a-z]+;base64,/, '').trim();
|
|
63
|
+
afterBuffer = Buffer.from(clean, 'base64');
|
|
64
|
+
}
|
|
65
|
+
else if (params.afterUrl || params.afterHtml) {
|
|
66
|
+
afterBuffer = await browserService.renderImage({
|
|
67
|
+
url: params.afterUrl,
|
|
68
|
+
html: params.afterHtml,
|
|
69
|
+
width,
|
|
70
|
+
height,
|
|
71
|
+
type: 'png',
|
|
72
|
+
delay_ms: delayMs,
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
throw new Error('Must provide afterUrl, afterHtml, or afterImageBase64');
|
|
77
|
+
}
|
|
78
|
+
// 3. Parse PNGs
|
|
79
|
+
let png1 = PNG.sync.read(beforeBuffer);
|
|
80
|
+
let png2 = PNG.sync.read(afterBuffer);
|
|
81
|
+
const targetWidth = Math.max(png1.width, png2.width);
|
|
82
|
+
const targetHeight = Math.max(png1.height, png2.height);
|
|
83
|
+
png1 = this.normalizePng(png1, targetWidth, targetHeight);
|
|
84
|
+
png2 = this.normalizePng(png2, targetWidth, targetHeight);
|
|
85
|
+
// 4. Compute pixel diff
|
|
86
|
+
const diffPng = new PNG({ width: targetWidth, height: targetHeight });
|
|
87
|
+
const differentPixels = pixelmatch(png1.data, png2.data, diffPng.data, targetWidth, targetHeight, {
|
|
88
|
+
threshold,
|
|
89
|
+
diffColor: [244, 63, 94], // Neon rose/pink #f43f5e for changed pixels
|
|
90
|
+
diffColorAlt: [56, 189, 248], // Sky blue #38bdf8
|
|
91
|
+
alpha: 0.25,
|
|
92
|
+
});
|
|
93
|
+
const totalPixels = targetWidth * targetHeight;
|
|
94
|
+
const diffPercentage = Number(((differentPixels / totalPixels) * 100).toFixed(2));
|
|
95
|
+
const isIdentical = differentPixels === 0;
|
|
96
|
+
const diffImageBuffer = PNG.sync.write(diffPng);
|
|
97
|
+
// 5. Generate 3-Panel Side-by-Side Visual Regression Studio Canvas
|
|
98
|
+
const beforeBase64 = PNG.sync.write(png1).toString('base64');
|
|
99
|
+
const afterBase64 = PNG.sync.write(png2).toString('base64');
|
|
100
|
+
const diffBase64 = diffImageBuffer.toString('base64');
|
|
101
|
+
const badgeColor = isIdentical
|
|
102
|
+
? 'bg-emerald-500/20 text-emerald-400 border-emerald-500/40'
|
|
103
|
+
: diffPercentage < 1.0
|
|
104
|
+
? 'bg-amber-500/20 text-amber-400 border-amber-500/40'
|
|
105
|
+
: 'bg-rose-500/20 text-rose-400 border-rose-500/40';
|
|
106
|
+
const badgeText = isIdentical
|
|
107
|
+
? '✓ IDENTICAL (0% DIFF)'
|
|
108
|
+
: `⚠ ${diffPercentage}% DIFF (${differentPixels.toLocaleString()} PIXELS)`;
|
|
109
|
+
const compositeHtml = `<!DOCTYPE html>
|
|
110
|
+
<html>
|
|
111
|
+
<head>
|
|
112
|
+
<meta charset="utf-8" />
|
|
113
|
+
<script src="https://cdn.tailwindcss.com"></script>
|
|
114
|
+
</head>
|
|
115
|
+
<body class="bg-[#090d16] text-slate-100 p-8 font-sans antialiased m-0">
|
|
116
|
+
<div class="max-w-[1700px] mx-auto">
|
|
117
|
+
|
|
118
|
+
<!-- Top Header -->
|
|
119
|
+
<div class="flex items-center justify-between pb-6 border-b border-slate-800 mb-6">
|
|
120
|
+
<div class="flex items-center space-x-3">
|
|
121
|
+
<span class="text-2xl">🔍</span>
|
|
122
|
+
<div>
|
|
123
|
+
<h1 class="text-xl font-black tracking-tight text-white flex items-center space-x-2">
|
|
124
|
+
<span>Visual Regression Heatmap</span>
|
|
125
|
+
<span class="text-xs font-mono font-normal text-slate-400">(${targetWidth}×${targetHeight}px)</span>
|
|
126
|
+
</h1>
|
|
127
|
+
<p class="text-xs text-slate-400 mt-0.5">Pixelmatch comparison with highlighted layout and color shifts</p>
|
|
128
|
+
</div>
|
|
129
|
+
</div>
|
|
130
|
+
<div class="flex items-center space-x-4">
|
|
131
|
+
<div class="text-right">
|
|
132
|
+
<span class="text-[10px] uppercase font-bold tracking-wider text-slate-400 block">Status</span>
|
|
133
|
+
<span class="inline-block px-3 py-1 rounded-full text-xs font-black border ${badgeColor}">
|
|
134
|
+
${badgeText}
|
|
135
|
+
</span>
|
|
136
|
+
</div>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
|
|
140
|
+
<!-- 3-Column Panels -->
|
|
141
|
+
<div class="grid grid-cols-3 gap-6">
|
|
142
|
+
|
|
143
|
+
<!-- Panel 1: Baseline / Before -->
|
|
144
|
+
<div class="rounded-2xl bg-slate-900/90 border border-slate-800 overflow-hidden shadow-xl">
|
|
145
|
+
<div class="px-4 py-2.5 bg-slate-950/80 border-b border-slate-800 flex items-center justify-between text-xs">
|
|
146
|
+
<span class="font-bold text-slate-300 flex items-center space-x-1.5">
|
|
147
|
+
<span class="w-2 h-2 rounded-full bg-slate-400"></span>
|
|
148
|
+
<span>1. Baseline (Before)</span>
|
|
149
|
+
</span>
|
|
150
|
+
<span class="text-[10px] font-mono text-slate-400">Original</span>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="p-3 bg-slate-950/40">
|
|
153
|
+
<img src="data:image/png;base64,${beforeBase64}" class="w-full h-auto rounded-lg shadow-inner object-contain max-h-[700px]" />
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
|
|
157
|
+
<!-- Panel 2: Diff Heatmap -->
|
|
158
|
+
<div class="rounded-2xl bg-slate-900/90 border border-rose-500/40 overflow-hidden shadow-2xl relative ring-1 ring-rose-500/30">
|
|
159
|
+
<div class="px-4 py-2.5 bg-rose-950/40 border-b border-rose-900/40 flex items-center justify-between text-xs">
|
|
160
|
+
<span class="font-bold text-rose-300 flex items-center space-x-1.5">
|
|
161
|
+
<span class="w-2 h-2 rounded-full bg-rose-500 animate-pulse"></span>
|
|
162
|
+
<span>2. Heatmap Diff Overlay</span>
|
|
163
|
+
</span>
|
|
164
|
+
<span class="text-[10px] font-mono text-rose-300 font-bold">${diffPercentage}% Changed</span>
|
|
165
|
+
</div>
|
|
166
|
+
<div class="p-3 bg-slate-950/40">
|
|
167
|
+
<img src="data:image/png;base64,${diffBase64}" class="w-full h-auto rounded-lg shadow-inner object-contain max-h-[700px]" />
|
|
168
|
+
</div>
|
|
169
|
+
</div>
|
|
170
|
+
|
|
171
|
+
<!-- Panel 3: Current / After -->
|
|
172
|
+
<div class="rounded-2xl bg-slate-900/90 border border-slate-800 overflow-hidden shadow-xl">
|
|
173
|
+
<div class="px-4 py-2.5 bg-slate-950/80 border-b border-slate-800 flex items-center justify-between text-xs">
|
|
174
|
+
<span class="font-bold text-indigo-300 flex items-center space-x-1.5">
|
|
175
|
+
<span class="w-2 h-2 rounded-full bg-indigo-400"></span>
|
|
176
|
+
<span>3. Current (After)</span>
|
|
177
|
+
</span>
|
|
178
|
+
<span class="text-[10px] font-mono text-slate-400">Modified</span>
|
|
179
|
+
</div>
|
|
180
|
+
<div class="p-3 bg-slate-950/40">
|
|
181
|
+
<img src="data:image/png;base64,${afterBase64}" class="w-full h-auto rounded-lg shadow-inner object-contain max-h-[700px]" />
|
|
182
|
+
</div>
|
|
183
|
+
</div>
|
|
184
|
+
|
|
185
|
+
</div>
|
|
186
|
+
|
|
187
|
+
<!-- Footer Stats Strip -->
|
|
188
|
+
<div class="mt-6 p-4 rounded-xl bg-slate-950 border border-slate-800/80 flex items-center justify-between text-xs font-mono text-slate-400">
|
|
189
|
+
<div class="flex items-center space-x-6">
|
|
190
|
+
<span>Total Pixels: <strong class="text-white">${totalPixels.toLocaleString()}</strong></span>
|
|
191
|
+
<span>Different Pixels: <strong class="${isIdentical ? 'text-emerald-400' : 'text-rose-400'}">${differentPixels.toLocaleString()}</strong></span>
|
|
192
|
+
<span>Matching Threshold: <strong class="text-white">${threshold}</strong></span>
|
|
193
|
+
</div>
|
|
194
|
+
<div class="text-[11px] text-slate-400">Generated by Tailprint Visual Inspector</div>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
</div>
|
|
198
|
+
</body>
|
|
199
|
+
</html>`;
|
|
200
|
+
const compositeImageBuffer = await browserService.renderImage({
|
|
201
|
+
html: compositeHtml,
|
|
202
|
+
width: 1700,
|
|
203
|
+
height: 980,
|
|
204
|
+
type: 'png',
|
|
205
|
+
delay_ms: 150,
|
|
206
|
+
});
|
|
207
|
+
return {
|
|
208
|
+
differentPixels,
|
|
209
|
+
totalPixels,
|
|
210
|
+
diffPercentage,
|
|
211
|
+
isIdentical,
|
|
212
|
+
diffImageBuffer,
|
|
213
|
+
compositeImageBuffer,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
export const visualDiffService = VisualDiffService.getInstance();
|
|
218
|
+
//# sourceMappingURL=visualDiff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"visualDiff.js","sourceRoot":"","sources":["../../src/services/visualDiff.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,76 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "tailprint",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Tailwind-Native Render & PDF Engine + AI Web Scraper (tailprint.com)",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/server.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"tailprint": "dist/mcp/stdio.js",
|
|
9
|
+
"tailprint-mcp": "dist/mcp/stdio.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE"
|
|
15
|
+
],
|
|
16
|
+
"repository": {
|
|
17
|
+
"type": "git",
|
|
18
|
+
"url": "git+https://github.com/coheroseb/tailprint.git"
|
|
19
|
+
},
|
|
20
|
+
"homepage": "https://tailprint.com",
|
|
21
|
+
"bugs": {
|
|
22
|
+
"url": "https://github.com/coheroseb/tailprint/issues"
|
|
23
|
+
},
|
|
24
|
+
"scripts": {
|
|
25
|
+
"build": "tsc",
|
|
26
|
+
"start": "node dist/server.js",
|
|
27
|
+
"dev": "tsx watch src/server.ts",
|
|
28
|
+
"mcp": "tsx src/mcp/stdio.ts",
|
|
29
|
+
"test": "vitest run"
|
|
30
|
+
},
|
|
31
|
+
"keywords": [
|
|
32
|
+
"fastify",
|
|
33
|
+
"tailwind",
|
|
34
|
+
"pdf",
|
|
35
|
+
"screenshot",
|
|
36
|
+
"eaas",
|
|
37
|
+
"playwright"
|
|
38
|
+
],
|
|
39
|
+
"author": "",
|
|
40
|
+
"license": "MIT",
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@fastify/swagger": "^9.4.2",
|
|
43
|
+
"@modelcontextprotocol/sdk": "^1.32.2",
|
|
44
|
+
"@mozilla/readability": "^0.6.0",
|
|
45
|
+
"@scalar/fastify-api-reference": "^1.25.105",
|
|
46
|
+
"@types/pixelmatch": "^5.2.6",
|
|
47
|
+
"@types/pngjs": "^6.0.5",
|
|
48
|
+
"@upstash/redis": "^1.34.4",
|
|
49
|
+
"cryptpdf": "^0.1.1",
|
|
50
|
+
"dotenv": "^16.4.7",
|
|
51
|
+
"fastify": "^5.2.1",
|
|
52
|
+
"fastify-raw-body": "^5.0.0",
|
|
53
|
+
"fastify-type-provider-zod": "^4.0.2",
|
|
54
|
+
"jsdom": "^29.1.1",
|
|
55
|
+
"nodemailer": "^10.5.0",
|
|
56
|
+
"p-limit": "^6.2.0",
|
|
57
|
+
"pdf-lib": "^1.17.1",
|
|
58
|
+
"pixelmatch": "^8.0.0",
|
|
59
|
+
"playwright": "^1.50.1",
|
|
60
|
+
"qrcode": "^1.5.4",
|
|
61
|
+
"stripe": "^17.7.0",
|
|
62
|
+
"turndown": "^7.2.5",
|
|
63
|
+
"turndown-plugin-gfm": "^1.0.2",
|
|
64
|
+
"zod": "^3.24.2"
|
|
65
|
+
},
|
|
66
|
+
"devDependencies": {
|
|
67
|
+
"@types/jsdom": "^30.0.0",
|
|
68
|
+
"@types/node": "^22.13.5",
|
|
69
|
+
"@types/nodemailer": "^8.0.2",
|
|
70
|
+
"@types/qrcode": "^1.5.6",
|
|
71
|
+
"@types/turndown": "^5.0.6",
|
|
72
|
+
"tsx": "^4.19.3",
|
|
73
|
+
"typescript": "^5.7.3",
|
|
74
|
+
"vitest": "^3.0.6"
|
|
75
|
+
}
|
|
76
|
+
}
|