@mise-en-scene/server 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +221 -0
- package/dist/export/index.d.ts +10 -0
- package/dist/export/index.d.ts.map +1 -0
- package/dist/export/index.js +53 -0
- package/dist/export/index.js.map +1 -0
- package/dist/export/pdf-export.d.ts +8 -0
- package/dist/export/pdf-export.d.ts.map +1 -0
- package/dist/export/pdf-export.js +17 -0
- package/dist/export/pdf-export.js.map +1 -0
- package/dist/export/presets.d.ts +4 -0
- package/dist/export/presets.d.ts.map +1 -0
- package/dist/export/presets.js +22 -0
- package/dist/export/presets.js.map +1 -0
- package/dist/export/puppeteer-manager.d.ts +8 -0
- package/dist/export/puppeteer-manager.d.ts.map +1 -0
- package/dist/export/puppeteer-manager.js +23 -0
- package/dist/export/puppeteer-manager.js.map +1 -0
- package/dist/export/raster-export.d.ts +11 -0
- package/dist/export/raster-export.d.ts.map +1 -0
- package/dist/export/raster-export.js +22 -0
- package/dist/export/raster-export.js.map +1 -0
- package/dist/export/svg-export.d.ts +2 -0
- package/dist/export/svg-export.d.ts.map +1 -0
- package/dist/export/svg-export.js +24 -0
- package/dist/export/svg-export.js.map +1 -0
- package/dist/feedback.d.ts +4 -0
- package/dist/feedback.d.ts.map +1 -0
- package/dist/feedback.js +23 -0
- package/dist/feedback.js.map +1 -0
- package/dist/http-server.d.ts +15 -0
- package/dist/http-server.d.ts.map +1 -0
- package/dist/http-server.js +113 -0
- package/dist/http-server.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +30 -0
- package/dist/index.js.map +1 -0
- package/dist/mcp-server.d.ts +435 -0
- package/dist/mcp-server.d.ts.map +1 -0
- package/dist/mcp-server.js +220 -0
- package/dist/mcp-server.js.map +1 -0
- package/dist/preview.d.ts +2 -0
- package/dist/preview.d.ts.map +1 -0
- package/dist/preview.js +12 -0
- package/dist/preview.js.map +1 -0
- package/dist/screenshot.d.ts +7 -0
- package/dist/screenshot.d.ts.map +1 -0
- package/dist/screenshot.js +20 -0
- package/dist/screenshot.js.map +1 -0
- package/dist/types.d.ts +84 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/typography/analyze-url.d.ts +10 -0
- package/dist/typography/analyze-url.d.ts.map +1 -0
- package/dist/typography/analyze-url.js +28 -0
- package/dist/typography/analyze-url.js.map +1 -0
- package/dist/typography/classify.d.ts +9 -0
- package/dist/typography/classify.d.ts.map +1 -0
- package/dist/typography/classify.js +15 -0
- package/dist/typography/classify.js.map +1 -0
- package/dist/typography/embed.d.ts +5 -0
- package/dist/typography/embed.d.ts.map +1 -0
- package/dist/typography/embed.js +33 -0
- package/dist/typography/embed.js.map +1 -0
- package/dist/typography/mood-match.d.ts +3 -0
- package/dist/typography/mood-match.d.ts.map +1 -0
- package/dist/typography/mood-match.js +21 -0
- package/dist/typography/mood-match.js.map +1 -0
- package/dist/typography/registry.d.ts +23 -0
- package/dist/typography/registry.d.ts.map +1 -0
- package/dist/typography/registry.js +103 -0
- package/dist/typography/registry.js.map +1 -0
- package/dist/typography/scale.d.ts +3 -0
- package/dist/typography/scale.d.ts.map +1 -0
- package/dist/typography/scale.js +45 -0
- package/dist/typography/scale.js.map +1 -0
- package/dist/typography/suggest.d.ts +9 -0
- package/dist/typography/suggest.d.ts.map +1 -0
- package/dist/typography/suggest.js +21 -0
- package/dist/typography/suggest.js.map +1 -0
- package/dist/versioning/gallery.d.ts +3 -0
- package/dist/versioning/gallery.d.ts.map +1 -0
- package/dist/versioning/gallery.js +57 -0
- package/dist/versioning/gallery.js.map +1 -0
- package/dist/versioning/versions.d.ts +19 -0
- package/dist/versioning/versions.d.ts.map +1 -0
- package/dist/versioning/versions.js +91 -0
- package/dist/versioning/versions.js.map +1 -0
- package/dist/watcher.d.ts +6 -0
- package/dist/watcher.d.ts.map +1 -0
- package/dist/watcher.js +15 -0
- package/dist/watcher.js.map +1 -0
- package/dist/websocket.d.ts +13 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +30 -0
- package/dist/websocket.js.map +1 -0
- package/package.json +50 -0
package/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# @mise-en-scene/server
|
|
2
|
+
|
|
3
|
+
Design studio MCP + HTTP server. Serves HTML designs in the browser with hot-reload, exports to SVG/PNG/JPG/PDF, manages design versions with branching, and provides typography intelligence.
|
|
4
|
+
|
|
5
|
+
## MCP Tools
|
|
6
|
+
|
|
7
|
+
### Core
|
|
8
|
+
|
|
9
|
+
| Tool | Input | Description |
|
|
10
|
+
|------|-------|-------------|
|
|
11
|
+
| `studio_preview` | `html`, `filename?` | Write HTML+CSS+SVG to preview server, triggers hot-reload |
|
|
12
|
+
| `studio_feedback` | — | Read user interaction feedback (click selections) |
|
|
13
|
+
| `studio_screenshot` | `selector?` | Capture screenshot for self-critique (returns image) |
|
|
14
|
+
| `studio_export` | `format`, `width?`, `height?`, `preset?`, `quality?` | Export to SVG, PNG, JPG, or PDF |
|
|
15
|
+
|
|
16
|
+
### Versioning
|
|
17
|
+
|
|
18
|
+
| Tool | Input | Description |
|
|
19
|
+
|------|-------|-------------|
|
|
20
|
+
| `studio_branch` | `name`, `from_branch?`, `from_version?` | Create a design branch |
|
|
21
|
+
| `studio_checkout` | `branch`, `version?` | Switch to a branch or version |
|
|
22
|
+
| `studio_gallery` | — | Open the version gallery in browser |
|
|
23
|
+
|
|
24
|
+
### Typography
|
|
25
|
+
|
|
26
|
+
| Tool | Input | Description |
|
|
27
|
+
|------|-------|-------------|
|
|
28
|
+
| `studio_font_suggest` | `mood`, `context?` | Get curated font pairing suggestions |
|
|
29
|
+
| `studio_font_analyze_url` | `url` | Extract font stack from any website |
|
|
30
|
+
| `studio_font_scale` | `base_size?`, `ratio?` | Generate a modular type scale |
|
|
31
|
+
| `studio_font_embed` | `fonts[]` | Generate @font-face CSS with base64 woff2 |
|
|
32
|
+
|
|
33
|
+
## Usage
|
|
34
|
+
|
|
35
|
+
### As an MCP Server
|
|
36
|
+
|
|
37
|
+
```json
|
|
38
|
+
{
|
|
39
|
+
"mcpServers": {
|
|
40
|
+
"mise-en-scene-server": {
|
|
41
|
+
"command": "npx",
|
|
42
|
+
"args": ["@mise-en-scene/server"]
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Environment Variables
|
|
49
|
+
|
|
50
|
+
| Variable | Default | Description |
|
|
51
|
+
|----------|---------|-------------|
|
|
52
|
+
| `MISE_PORT` | `3333` | HTTP server port |
|
|
53
|
+
| `MISE_DESIGN_DIR` | `mise-en-scene/main` | Directory for design files |
|
|
54
|
+
|
|
55
|
+
## Components
|
|
56
|
+
|
|
57
|
+
### HTTP Server
|
|
58
|
+
|
|
59
|
+
Zero-dependency HTTP server (no Express). Serves the newest `.html` file from the design directory with runtime injection — a `<script>` tag and `<link>` to the client-side runtime are added automatically.
|
|
60
|
+
|
|
61
|
+
Routes:
|
|
62
|
+
|
|
63
|
+
| Route | Description |
|
|
64
|
+
|-------|-------------|
|
|
65
|
+
| `GET /` | Serve newest HTML design with runtime injection |
|
|
66
|
+
| `GET /gallery` | Version gallery with thumbnail grid |
|
|
67
|
+
| `GET /mise-en-scene.js` | Client-side runtime |
|
|
68
|
+
| `GET /styles.css` | Selection highlight styles |
|
|
69
|
+
|
|
70
|
+
### WebSocket Server
|
|
71
|
+
|
|
72
|
+
Real-time communication between the browser and the MCP server:
|
|
73
|
+
|
|
74
|
+
- **Server → Browser**: `reload` (trigger page refresh), `highlight` (visual feedback)
|
|
75
|
+
- **Browser → Server**: `select` (user clicked an element — captured as feedback)
|
|
76
|
+
|
|
77
|
+
### File Watcher
|
|
78
|
+
|
|
79
|
+
Uses chokidar to watch the design directory for `.html` file changes. Triggers WebSocket `reload` broadcast on new or modified files.
|
|
80
|
+
|
|
81
|
+
### Export Pipeline
|
|
82
|
+
|
|
83
|
+
Lazy-loads Puppeteer on first use. Supports four export formats:
|
|
84
|
+
|
|
85
|
+
| Format | Engine | Notes |
|
|
86
|
+
|--------|--------|-------|
|
|
87
|
+
| SVG | SVGO | Extracts inline SVGs, optimizes with multipass |
|
|
88
|
+
| PNG | Puppeteer | Full-page or selector-based capture |
|
|
89
|
+
| JPG | Puppeteer | Configurable quality (1-100) |
|
|
90
|
+
| PDF | Puppeteer | Configurable dimensions, print media |
|
|
91
|
+
|
|
92
|
+
#### Dimension Presets
|
|
93
|
+
|
|
94
|
+
13 built-in presets across three categories:
|
|
95
|
+
|
|
96
|
+
**Social:**
|
|
97
|
+
`instagram-post` (1080x1080), `instagram-story` (1080x1920), `twitter-post` (1200x675), `twitter-header` (1500x500), `facebook-post` (1200x630), `linkedin-post` (1200x627), `og-image` (1200x630)
|
|
98
|
+
|
|
99
|
+
**Web:**
|
|
100
|
+
`desktop-hd` (1920x1080), `desktop` (1440x900), `tablet` (768x1024), `mobile` (375x812)
|
|
101
|
+
|
|
102
|
+
**Print:**
|
|
103
|
+
`a4` (2480x3508 @ 300dpi), `letter` (2550x3300 @ 300dpi)
|
|
104
|
+
|
|
105
|
+
### Screenshot
|
|
106
|
+
|
|
107
|
+
Captures the current design state as a PNG image. Used by the agent for self-critique — screenshot the design, analyze it against the taste profile, fix issues before presenting to the user.
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
studio_screenshot() → full page capture
|
|
111
|
+
studio_screenshot("h1") → capture specific element
|
|
112
|
+
studio_screenshot(".header") → capture by CSS selector
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Returns image data as base64 in the MCP response (not written to disk).
|
|
116
|
+
|
|
117
|
+
### Version Manager
|
|
118
|
+
|
|
119
|
+
Git-inspired branching for design iterations:
|
|
120
|
+
|
|
121
|
+
```
|
|
122
|
+
studio_preview(html) → saves as next version on current branch
|
|
123
|
+
studio_branch("dark-theme") → fork from current version
|
|
124
|
+
studio_checkout("main", 2) → switch to main/v2
|
|
125
|
+
studio_gallery() → view all branches and versions
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
Versions are stored as flat HTML files (`v1.html`, `v2.html`, ...) organized by branch. Metadata is persisted in `meta.json`:
|
|
129
|
+
|
|
130
|
+
```json
|
|
131
|
+
{
|
|
132
|
+
"branches": {
|
|
133
|
+
"main": { "versions": [1, 2, 3] },
|
|
134
|
+
"dark-theme": { "forkedFrom": { "branch": "main", "version": 2 }, "versions": [1] }
|
|
135
|
+
},
|
|
136
|
+
"stars": [{ "branch": "main", "version": 2 }],
|
|
137
|
+
"current": { "branch": "main", "version": 3 }
|
|
138
|
+
}
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
### Typography Intelligence
|
|
142
|
+
|
|
143
|
+
#### Font Registry
|
|
144
|
+
|
|
145
|
+
35+ fonts classified by category and subtype:
|
|
146
|
+
|
|
147
|
+
| Category | Subtypes |
|
|
148
|
+
|----------|----------|
|
|
149
|
+
| Serif | old-style, transitional, modern, slab |
|
|
150
|
+
| Sans-serif | grotesque, neo-grotesque, geometric, humanist |
|
|
151
|
+
| Display | creative, bold, futuristic |
|
|
152
|
+
| Monospace | technical, terminal |
|
|
153
|
+
|
|
154
|
+
Each font entry includes `category`, `subtype`, `era`, and `mood` descriptors.
|
|
155
|
+
|
|
156
|
+
#### Curated Pairings
|
|
157
|
+
|
|
158
|
+
8 aesthetic presets with display + body font pairings, Google Fonts import URLs, and mood descriptions:
|
|
159
|
+
|
|
160
|
+
| Aesthetic | Display | Body | Mood |
|
|
161
|
+
|-----------|---------|------|------|
|
|
162
|
+
| dark-premium | Fraunces | Outfit | Elegant, editorial |
|
|
163
|
+
| clean-minimal | Satoshi | Satoshi | Confident, modern |
|
|
164
|
+
| neobrutalism | Space Grotesk | Space Mono | Technical, raw |
|
|
165
|
+
| editorial | Instrument Serif | Instrument Sans | Refined, readable |
|
|
166
|
+
| y2k-cyber | Orbitron | JetBrains Mono | Sci-fi, technical |
|
|
167
|
+
| warm-scandinavian | DM Serif Display | DM Sans | Approachable, refined |
|
|
168
|
+
| creative-playful | Bricolage Grotesque | Bricolage Grotesque | Expressive, bold |
|
|
169
|
+
| luxury | Playfair Display | Source Sans 3 | Classic, timeless |
|
|
170
|
+
|
|
171
|
+
#### Font Suggestion Engine
|
|
172
|
+
|
|
173
|
+
`studio_font_suggest(mood)` scores pairings against the mood query using token-based text similarity, filters out avoided fonts, and returns the top 3 matches.
|
|
174
|
+
|
|
175
|
+
#### Type Scale Generator
|
|
176
|
+
|
|
177
|
+
`studio_font_scale(base_size, ratio)` generates CSS custom properties for a modular type scale:
|
|
178
|
+
|
|
179
|
+
| Ratio | Name | Use Case |
|
|
180
|
+
|-------|------|----------|
|
|
181
|
+
| 1.2 | Minor Third | Body-heavy, readability |
|
|
182
|
+
| 1.25 | Major Third | General purpose |
|
|
183
|
+
| 1.333 | Perfect Fourth | Balanced drama |
|
|
184
|
+
| 1.618 | Golden Ratio | Posters, maximum drama |
|
|
185
|
+
|
|
186
|
+
Produces 11 named steps (xs through 7xl) with size, line-height, and letter-spacing. Headlines get tighter line-height and tracking automatically.
|
|
187
|
+
|
|
188
|
+
#### URL Font Analyzer
|
|
189
|
+
|
|
190
|
+
`studio_font_analyze_url(url)` launches Puppeteer, navigates to the URL, and extracts computed font families, weights, and styles from common HTML elements.
|
|
191
|
+
|
|
192
|
+
#### Font Embedder
|
|
193
|
+
|
|
194
|
+
`studio_font_embed(fonts)` fetches woff2 files from URLs and returns `@font-face` CSS with base64-inlined font data — for self-contained SVG exports.
|
|
195
|
+
|
|
196
|
+
## Feedback System
|
|
197
|
+
|
|
198
|
+
User interactions in the browser are captured as JSON Lines in a `.feedback` file:
|
|
199
|
+
|
|
200
|
+
```jsonl
|
|
201
|
+
{"type":"select","element":{"tag":"h1","classes":["title"],"text":"Hello"},"timestamp":1710...}
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
The agent reads feedback via `studio_feedback`, interprets selections, and records design decisions in taste memory.
|
|
205
|
+
|
|
206
|
+
## Client Runtime
|
|
207
|
+
|
|
208
|
+
The browser runtime (`mise-en-scene.js`) provides:
|
|
209
|
+
|
|
210
|
+
- **WebSocket connection** with auto-reconnect (2s backoff)
|
|
211
|
+
- **Live reload** on design file changes
|
|
212
|
+
- **Click-to-select** — clicking any element sends a `select` event to the server
|
|
213
|
+
- **Visual feedback** — selected elements get a `.mise-selected` outline
|
|
214
|
+
|
|
215
|
+
## Development
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
npm test # Run tests (42 unit + 3 integration + 6 Puppeteer)
|
|
219
|
+
npm run build # Compile TypeScript
|
|
220
|
+
npm run test:watch # Watch mode
|
|
221
|
+
```
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { PuppeteerManager } from './puppeteer-manager.js';
|
|
2
|
+
import type { ExportOptions } from '../types.js';
|
|
3
|
+
export declare class ExportPipeline {
|
|
4
|
+
private puppeteer;
|
|
5
|
+
export(html: string, outputDir: string, opts: ExportOptions): Promise<string>;
|
|
6
|
+
screenshot(url: string, selector?: string): Promise<Buffer>;
|
|
7
|
+
getPuppeteerManager(): PuppeteerManager;
|
|
8
|
+
shutdown(): Promise<void>;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/export/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAK1D,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAIjD,qBAAa,cAAc;IACzB,OAAO,CAAC,SAAS,CAA0B;IAErC,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC;IAkC7E,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAKjE,mBAAmB,IAAI,gBAAgB;IAEjC,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAChC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { PuppeteerManager } from './puppeteer-manager.js';
|
|
2
|
+
import { extractAndOptimizeSvg } from './svg-export.js';
|
|
3
|
+
import { exportRaster } from './raster-export.js';
|
|
4
|
+
import { exportPdf } from './pdf-export.js';
|
|
5
|
+
import { getPreset } from './presets.js';
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
export class ExportPipeline {
|
|
9
|
+
puppeteer = new PuppeteerManager();
|
|
10
|
+
async export(html, outputDir, opts) {
|
|
11
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
12
|
+
let width = opts.width;
|
|
13
|
+
let height = opts.height;
|
|
14
|
+
if (opts.preset) {
|
|
15
|
+
const preset = getPreset(opts.preset);
|
|
16
|
+
if (preset) {
|
|
17
|
+
width = width ?? preset.width;
|
|
18
|
+
height = height ?? preset.height;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
const timestamp = Date.now();
|
|
22
|
+
switch (opts.format) {
|
|
23
|
+
case 'svg': {
|
|
24
|
+
const svg = await extractAndOptimizeSvg(html);
|
|
25
|
+
const outPath = path.join(outputDir, `export-${timestamp}.svg`);
|
|
26
|
+
fs.writeFileSync(outPath, svg);
|
|
27
|
+
return outPath;
|
|
28
|
+
}
|
|
29
|
+
case 'png':
|
|
30
|
+
case 'jpg': {
|
|
31
|
+
const buffer = await exportRaster(this.puppeteer, html, { format: opts.format, width, height, quality: opts.quality, dpi: opts.dpi });
|
|
32
|
+
const ext = opts.format === 'jpg' ? 'jpg' : 'png';
|
|
33
|
+
const outPath = path.join(outputDir, `export-${timestamp}.${ext}`);
|
|
34
|
+
fs.writeFileSync(outPath, buffer);
|
|
35
|
+
return outPath;
|
|
36
|
+
}
|
|
37
|
+
case 'pdf': {
|
|
38
|
+
const buffer = await exportPdf(this.puppeteer, html, { width, height });
|
|
39
|
+
const outPath = path.join(outputDir, `export-${timestamp}.pdf`);
|
|
40
|
+
fs.writeFileSync(outPath, buffer);
|
|
41
|
+
return outPath;
|
|
42
|
+
}
|
|
43
|
+
default: throw new Error(`Unsupported format: ${opts.format}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
async screenshot(url, selector) {
|
|
47
|
+
const { takeScreenshot } = await import('../screenshot.js');
|
|
48
|
+
return takeScreenshot(this.puppeteer, url, { selector });
|
|
49
|
+
}
|
|
50
|
+
getPuppeteerManager() { return this.puppeteer; }
|
|
51
|
+
async shutdown() { await this.puppeteer.shutdown(); }
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/export/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAe,MAAM,cAAc,CAAC;AAEtD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAExB,MAAM,OAAO,cAAc;IACjB,SAAS,GAAG,IAAI,gBAAgB,EAAE,CAAC;IAE3C,KAAK,CAAC,MAAM,CAAC,IAAY,EAAE,SAAiB,EAAE,IAAmB;QAC/D,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7C,IAAI,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QACvB,IAAI,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QACzB,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YACtC,IAAI,MAAM,EAAE,CAAC;gBAAC,KAAK,GAAG,KAAK,IAAI,MAAM,CAAC,KAAK,CAAC;gBAAC,MAAM,GAAG,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC;YAAC,CAAC;QAClF,CAAC;QACD,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,QAAQ,IAAI,CAAC,MAAM,EAAE,CAAC;YACpB,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,GAAG,GAAG,MAAM,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBAC9C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,SAAS,MAAM,CAAC,CAAC;gBAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;gBAC/B,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,KAAK,KAAK,CAAC;YACX,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;gBACtI,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC;gBAClD,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,SAAS,IAAI,GAAG,EAAE,CAAC,CAAC;gBACnE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClC,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBACxE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,UAAU,SAAS,MAAM,CAAC,CAAC;gBAChE,EAAE,CAAC,aAAa,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;gBAClC,OAAO,OAAO,CAAC;YACjB,CAAC;YACD,OAAO,CAAC,CAAC,MAAM,IAAI,KAAK,CAAC,uBAAuB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QACjE,CAAC;IACH,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW,EAAE,QAAiB;QAC7C,MAAM,EAAE,cAAc,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;QAC5D,OAAO,cAAc,CAAC,IAAI,CAAC,SAAS,EAAE,GAAG,EAAE,EAAE,QAAQ,EAAE,CAAC,CAAC;IAC3D,CAAC;IAED,mBAAmB,KAAuB,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC;IAElE,KAAK,CAAC,QAAQ,KAAoB,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC;CACrE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { PuppeteerManager } from './puppeteer-manager.js';
|
|
2
|
+
interface PdfOptions {
|
|
3
|
+
width?: number;
|
|
4
|
+
height?: number;
|
|
5
|
+
}
|
|
6
|
+
export declare function exportPdf(manager: PuppeteerManager, html: string, opts?: PdfOptions): Promise<Buffer>;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=pdf-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-export.d.ts","sourceRoot":"","sources":["../../src/export/pdf-export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,UAAU,UAAU;IAAG,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAAE;AAEzD,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAc3G"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export async function exportPdf(manager, html, opts) {
|
|
2
|
+
const page = await manager.getPage();
|
|
3
|
+
try {
|
|
4
|
+
await page.setContent(html, { waitUntil: 'networkidle0', timeout: 10000 });
|
|
5
|
+
const buffer = await page.pdf({
|
|
6
|
+
width: opts?.width ? `${opts.width}px` : undefined,
|
|
7
|
+
height: opts?.height ? `${opts.height}px` : undefined,
|
|
8
|
+
printBackground: true,
|
|
9
|
+
margin: { top: 0, right: 0, bottom: 0, left: 0 },
|
|
10
|
+
});
|
|
11
|
+
return Buffer.from(buffer);
|
|
12
|
+
}
|
|
13
|
+
finally {
|
|
14
|
+
await page.close();
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=pdf-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pdf-export.js","sourceRoot":"","sources":["../../src/export/pdf-export.ts"],"names":[],"mappings":"AAIA,MAAM,CAAC,KAAK,UAAU,SAAS,CAAC,OAAyB,EAAE,IAAY,EAAE,IAAiB;IACxF,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,GAAG,CAAC;YAC5B,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,SAAS;YAClD,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,SAAS;YACrD,eAAe,EAAE,IAAI;YACrB,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE;SACjD,CAAC,CAAC;QACH,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../src/export/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAkBnD,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,GAAG,IAAI,CAE9D;AAED,wBAAgB,WAAW,IAAI,eAAe,EAAE,CAE/C"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const PRESETS = {
|
|
2
|
+
'instagram-post': { name: 'Instagram Post', width: 1080, height: 1080, category: 'social' },
|
|
3
|
+
'instagram-story': { name: 'Instagram Story', width: 1080, height: 1920, category: 'social' },
|
|
4
|
+
'twitter-header': { name: 'Twitter Header', width: 1500, height: 500, category: 'social' },
|
|
5
|
+
'twitter-post': { name: 'Twitter Post', width: 1200, height: 675, category: 'social' },
|
|
6
|
+
'facebook-cover': { name: 'Facebook Cover', width: 1640, height: 624, category: 'social' },
|
|
7
|
+
'linkedin-banner': { name: 'LinkedIn Banner', width: 1584, height: 396, category: 'social' },
|
|
8
|
+
'og-image': { name: 'OG Image', width: 1200, height: 630, category: 'web' },
|
|
9
|
+
'favicon': { name: 'Favicon', width: 512, height: 512, category: 'web' },
|
|
10
|
+
'hd': { name: 'HD 1080p', width: 1920, height: 1080, category: 'web' },
|
|
11
|
+
'a4': { name: 'A4 (300dpi)', width: 2480, height: 3508, category: 'print' },
|
|
12
|
+
'letter': { name: 'US Letter (300dpi)', width: 2550, height: 3300, category: 'print' },
|
|
13
|
+
'poster-18x24': { name: 'Poster 18×24 (150dpi)', width: 2700, height: 3600, category: 'print' },
|
|
14
|
+
'business-card': { name: 'Business Card (300dpi)', width: 1050, height: 600, category: 'print' },
|
|
15
|
+
};
|
|
16
|
+
export function getPreset(name) {
|
|
17
|
+
return PRESETS[name] ?? null;
|
|
18
|
+
}
|
|
19
|
+
export function listPresets() {
|
|
20
|
+
return Object.values(PRESETS);
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=presets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"presets.js","sourceRoot":"","sources":["../../src/export/presets.ts"],"names":[],"mappings":"AAEA,MAAM,OAAO,GAAoC;IAC/C,gBAAgB,EAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC9F,iBAAiB,EAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC/F,gBAAgB,EAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC7F,cAAc,EAAO,EAAE,IAAI,EAAE,cAAc,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC3F,gBAAgB,EAAK,EAAE,IAAI,EAAE,gBAAgB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC7F,iBAAiB,EAAI,EAAE,IAAI,EAAE,iBAAiB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE;IAC9F,UAAU,EAAW,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE;IACpF,SAAS,EAAY,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,KAAK,EAAE;IAClF,IAAI,EAAiB,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE;IACrF,IAAI,EAAiB,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE;IAC1F,QAAQ,EAAa,EAAE,IAAI,EAAE,oBAAoB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE;IACjG,cAAc,EAAO,EAAE,IAAI,EAAE,uBAAuB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE;IACpG,eAAe,EAAM,EAAE,IAAI,EAAE,wBAAwB,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE;CACrG,CAAC;AAEF,MAAM,UAAU,SAAS,CAAC,IAAY;IACpC,OAAO,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,WAAW;IACzB,OAAO,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-manager.d.ts","sourceRoot":"","sources":["../../src/export/puppeteer-manager.ts"],"names":[],"mappings":"AAAA,OAAkB,EAAgB,KAAK,IAAI,EAAE,MAAM,WAAW,CAAC;AAE/D,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,OAAO,CAAwB;IAEvC,SAAS,IAAI,OAAO;IAId,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAUxB,QAAQ,IAAI,OAAO,CAAC,IAAI,CAAC;CAMhC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import puppeteer from 'puppeteer';
|
|
2
|
+
export class PuppeteerManager {
|
|
3
|
+
browser = null;
|
|
4
|
+
isRunning() {
|
|
5
|
+
return this.browser !== null && this.browser.connected;
|
|
6
|
+
}
|
|
7
|
+
async getPage() {
|
|
8
|
+
if (!this.browser || !this.browser.connected) {
|
|
9
|
+
this.browser = await puppeteer.launch({
|
|
10
|
+
headless: true,
|
|
11
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
|
|
12
|
+
});
|
|
13
|
+
}
|
|
14
|
+
return this.browser.newPage();
|
|
15
|
+
}
|
|
16
|
+
async shutdown() {
|
|
17
|
+
if (this.browser) {
|
|
18
|
+
await this.browser.close();
|
|
19
|
+
this.browser = null;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=puppeteer-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"puppeteer-manager.js","sourceRoot":"","sources":["../../src/export/puppeteer-manager.ts"],"names":[],"mappings":"AAAA,OAAO,SAAsC,MAAM,WAAW,CAAC;AAE/D,MAAM,OAAO,gBAAgB;IACnB,OAAO,GAAmB,IAAI,CAAC;IAEvC,SAAS;QACP,OAAO,IAAI,CAAC,OAAO,KAAK,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC;IACzD,CAAC;IAED,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;YAC7C,IAAI,CAAC,OAAO,GAAG,MAAM,SAAS,CAAC,MAAM,CAAC;gBACpC,QAAQ,EAAE,IAAI;gBACd,IAAI,EAAE,CAAC,cAAc,EAAE,0BAA0B,CAAC;aACnD,CAAC,CAAC;QACL,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC;IAChC,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,MAAM,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YAC3B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;CACF"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PuppeteerManager } from './puppeteer-manager.js';
|
|
2
|
+
interface RasterOptions {
|
|
3
|
+
format: 'png' | 'jpg';
|
|
4
|
+
width?: number;
|
|
5
|
+
height?: number;
|
|
6
|
+
quality?: number;
|
|
7
|
+
dpi?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function exportRaster(manager: PuppeteerManager, html: string, opts: RasterOptions): Promise<Buffer>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=raster-export.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster-export.d.ts","sourceRoot":"","sources":["../../src/export/raster-export.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAE/D,UAAU,aAAa;IACrB,MAAM,EAAE,KAAK,GAAG,KAAK,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,MAAM,CAAC,CAkBhH"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export async function exportRaster(manager, html, opts) {
|
|
2
|
+
const page = await manager.getPage();
|
|
3
|
+
try {
|
|
4
|
+
const width = opts.width ?? 1200;
|
|
5
|
+
const height = opts.height ?? 800;
|
|
6
|
+
await page.setViewport({ width, height, deviceScaleFactor: opts.dpi ?? 1 });
|
|
7
|
+
await page.setContent(html, { waitUntil: 'networkidle0', timeout: 10000 });
|
|
8
|
+
const screenshotOpts = {
|
|
9
|
+
type: opts.format === 'jpg' ? 'jpeg' : 'png',
|
|
10
|
+
fullPage: false,
|
|
11
|
+
clip: { x: 0, y: 0, width, height },
|
|
12
|
+
};
|
|
13
|
+
if (opts.format === 'jpg' && opts.quality)
|
|
14
|
+
screenshotOpts.quality = opts.quality;
|
|
15
|
+
const buffer = await page.screenshot(screenshotOpts);
|
|
16
|
+
return Buffer.from(buffer);
|
|
17
|
+
}
|
|
18
|
+
finally {
|
|
19
|
+
await page.close();
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=raster-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raster-export.js","sourceRoot":"","sources":["../../src/export/raster-export.ts"],"names":[],"mappings":"AAUA,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAyB,EAAE,IAAY,EAAE,IAAmB;IAC7F,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,OAAO,EAAE,CAAC;IACrC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC;QACjC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC;QAClC,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,iBAAiB,EAAE,IAAI,CAAC,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC;QAC5E,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,cAAc,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;QAC3E,MAAM,cAAc,GAAQ;YAC1B,IAAI,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;YAC5C,QAAQ,EAAE,KAAK;YACf,IAAI,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE;SACpC,CAAC;QACF,IAAI,IAAI,CAAC,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,OAAO;YAAE,cAAc,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;QACjF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,CAAC;QACrD,OAAO,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAC7B,CAAC;YAAS,CAAC;QACT,MAAM,IAAI,CAAC,KAAK,EAAE,CAAC;IACrB,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-export.d.ts","sourceRoot":"","sources":["../../src/export/svg-export.ts"],"names":[],"mappings":"AAEA,wBAAsB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAoBzE"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { optimize } from 'svgo';
|
|
2
|
+
export async function extractAndOptimizeSvg(html) {
|
|
3
|
+
const svgMatch = html.match(/<svg[\s\S]*?<\/svg>/i);
|
|
4
|
+
if (!svgMatch)
|
|
5
|
+
throw new Error('No SVG element found in the provided HTML');
|
|
6
|
+
const rawSvg = svgMatch[0];
|
|
7
|
+
const result = optimize(rawSvg, {
|
|
8
|
+
multipass: true,
|
|
9
|
+
plugins: [
|
|
10
|
+
'removeDoctype', 'removeXMLProcInst', 'removeComments', 'removeMetadata',
|
|
11
|
+
'removeEditorsNSData', 'cleanupAttrs', 'mergeStyles', 'inlineStyles',
|
|
12
|
+
'minifyStyles', 'cleanupIds', 'removeUselessDefs', 'cleanupNumericValues',
|
|
13
|
+
'convertColors', 'removeUnknownsAndDefaults', 'removeNonInheritableGroupAttrs',
|
|
14
|
+
'removeUselessStrokeAndFill', 'cleanupEnableBackground', 'removeHiddenElems',
|
|
15
|
+
'removeEmptyText', 'convertShapeToPath', 'convertEllipseToCircle',
|
|
16
|
+
'moveElemsAttrsToGroup', 'moveGroupAttrsToElems', 'collapseGroups',
|
|
17
|
+
'convertPathData', 'convertTransform', 'removeEmptyAttrs',
|
|
18
|
+
'removeEmptyContainers', 'removeDimensions', 'removeStyleElement',
|
|
19
|
+
'removeScriptElement', 'sortAttrs', 'sortDefsChildren',
|
|
20
|
+
],
|
|
21
|
+
});
|
|
22
|
+
return result.data;
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=svg-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"svg-export.js","sourceRoot":"","sources":["../../src/export/svg-export.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAEhC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,IAAY;IACtD,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,CAAC;IACpD,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC5E,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC3B,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,EAAE;QAC9B,SAAS,EAAE,IAAI;QACf,OAAO,EAAE;YACP,eAAe,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,gBAAgB;YACxE,qBAAqB,EAAE,cAAc,EAAE,aAAa,EAAE,cAAc;YACpE,cAAc,EAAE,YAAY,EAAE,mBAAmB,EAAE,sBAAsB;YACzE,eAAe,EAAE,2BAA2B,EAAE,gCAAgC;YAC9E,4BAA4B,EAAE,yBAAyB,EAAE,mBAAmB;YAC5E,iBAAiB,EAAE,oBAAoB,EAAE,wBAAwB;YACjE,uBAAuB,EAAE,uBAAuB,EAAE,gBAAgB;YAClE,iBAAiB,EAAE,kBAAkB,EAAE,kBAAkB;YACzD,uBAAuB,EAAE,kBAAkB,EAAE,oBAAoB;YACjE,qBAAqB,EAAE,WAAW,EAAE,kBAAkB;SACvD;KACF,CAAC,CAAC;IACH,OAAO,MAAM,CAAC,IAAI,CAAC;AACrB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.d.ts","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAEhD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,GAAG,aAAa,EAAE,CAQ/D;AAED,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAGtF"}
|
package/dist/feedback.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
export function readFeedback(designDir) {
|
|
4
|
+
const feedbackPath = path.join(designDir, '.feedback');
|
|
5
|
+
if (!fs.existsSync(feedbackPath))
|
|
6
|
+
return [];
|
|
7
|
+
const content = fs.readFileSync(feedbackPath, 'utf-8').trim();
|
|
8
|
+
if (!content)
|
|
9
|
+
return [];
|
|
10
|
+
return content.split('\n').filter((line) => line.trim()).map((line) => {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(line);
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return null;
|
|
16
|
+
}
|
|
17
|
+
}).filter(Boolean);
|
|
18
|
+
}
|
|
19
|
+
export function appendFeedback(designDir, event) {
|
|
20
|
+
fs.mkdirSync(designDir, { recursive: true });
|
|
21
|
+
fs.appendFileSync(path.join(designDir, '.feedback'), JSON.stringify(event) + '\n');
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=feedback.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"feedback.js","sourceRoot":"","sources":["../src/feedback.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,IAAI,MAAM,MAAM,CAAC;AAGxB,MAAM,UAAU,YAAY,CAAC,SAAiB;IAC5C,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;IACvD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC;QAAE,OAAO,EAAE,CAAC;IAC5C,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC,IAAI,EAAE,CAAC;IAC9D,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,CAAC;IACxB,OAAO,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QACpE,IAAI,CAAC;YAAC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAAC,CAAC;QAAC,MAAM,CAAC;YAAC,OAAO,IAAI,CAAC;QAAC,CAAC;IACzD,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAoB,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,KAA8B;IAC9E,EAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC7C,EAAE,CAAC,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,IAAI,CAAC,CAAC;AACrF,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import http from 'http';
|
|
2
|
+
interface ServerOptions {
|
|
3
|
+
port: number;
|
|
4
|
+
designDir: string;
|
|
5
|
+
host?: string;
|
|
6
|
+
}
|
|
7
|
+
interface ServerInstance {
|
|
8
|
+
port: number;
|
|
9
|
+
server: http.Server;
|
|
10
|
+
close: () => Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function getNewestHtmlFile(dir: string): string | null;
|
|
13
|
+
export declare function createHttpServer(opts: ServerOptions): Promise<ServerInstance>;
|
|
14
|
+
export {};
|
|
15
|
+
//# sourceMappingURL=http-server.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"http-server.d.ts","sourceRoot":"","sources":["../src/http-server.ts"],"names":[],"mappings":"AAAA,OAAO,IAAI,MAAM,MAAM,CAAC;AAMxB,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,UAAU,cAAc;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAW5D;AA4BD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,cAAc,CAAC,CAwEnF"}
|