@open-assets/open-assets 0.4.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +141 -25
- package/bin/open-assets.mjs +2 -3
- package/lib/init.mjs +1 -1
- package/lib/lockfile.mjs +6 -3
- package/lib/manifest.mjs +5 -17
- package/lib/render.mjs +301 -176
- package/lib/renderer.mjs +214 -88
- package/lib/server.mjs +20 -12
- package/package.json +3 -3
- package/public/img/banner/1280.png +0 -0
- package/public/img/examples/tax-days-icon.png +0 -0
- package/public/img/examples/tax-days.png +0 -0
- package/public/img/examples/thoughtful-icon.png +0 -0
- package/public/img/examples/thoughtful.png +0 -0
- package/skills/open-assets/SKILL.md +46 -36
- package/public/img/banner/1280/banner.png +0 -0
package/README.md
CHANGED
|
@@ -1,20 +1,40 @@
|
|
|
1
1
|
<p align="center">
|
|
2
|
-
<img src="public/img/banner/1280
|
|
2
|
+
<img src="public/img/banner/1280.png" alt="Open Assets" width="100%" />
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
# Open Assets
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
[](https://www.npmjs.com/package/@open-assets/open-assets)
|
|
8
|
+
[](LICENSE)
|
|
9
|
+
[](#2-design-with-claude-code)
|
|
8
10
|
|
|
9
|
-
|
|
11
|
+
**Screenshots, icons, and marketing assets, made a breeze in your git repo.**
|
|
10
12
|
|
|
11
|
-
Design
|
|
13
|
+
Design App Store screenshots, app icons, logos, OG images, and favicons as HTML/CSS/SVG templates. Preview them live in the browser. Render every size your stores need from a single template with one command, then export the results anywhere: your exports folder, your web app's public directory, or straight into an Xcode asset catalog.
|
|
14
|
+
|
|
15
|
+
Like Storybook, but for marketing assets. Free, local, MIT licensed, and built for AI coding agents.
|
|
16
|
+
|
|
17
|
+
## Why Open Assets
|
|
18
|
+
|
|
19
|
+
- **One template, every size.** Author a screenshot once at its source size and render it for iPhone 6.9", 6.7", iPad, Play Store, Product Hunt, and any custom dimension. No per-device rework.
|
|
20
|
+
- **Export to multiple locations.** Each export size can write to its own destination with `outFile`: drop `favicon.png` into `public/`, send the OG image to your web app, and write the app icon directly into your Xcode `.appiconset`.
|
|
21
|
+
- **Localization built in.** One template renders in every language. Mustache-style `{{placeholders}}`, locale-aware number formatting, and automatic RTL layout for Arabic, Hebrew, and friends. See [Localization](#localization).
|
|
22
|
+
- **Live preview dev server.** A Storybook-style UI with hot reload, zoom/pan, and one-click exports while you iterate on templates.
|
|
23
|
+
- **Incremental renders.** `assets.lock` checksums every source file, so you, your teammates, and CI only re-render what changed.
|
|
24
|
+
- **Versioned in git, rendered in CI.** No SaaS, no per-seat design tool. Review screenshot changes in a PR with `git diff`, re-render on every push with GitHub Actions.
|
|
25
|
+
- **Agent native.** Ships a Claude Code skill (`npx open-assets skills`), so your agent can design, localize, and render the entire asset set for you.
|
|
12
26
|
|
|
13
27
|
## Examples
|
|
14
28
|
|
|
15
|
-
<p><img src="public/img/examples/
|
|
29
|
+
<p><img src="public/img/examples/tax-days-icon.png" width="14" height="14" /> <a href="https://apps.apple.com/us/app/tax-days-residency-tracker/id6761441335"><strong>Tax Days</strong></a> (<a href="examples/tax-days">examples</a>)</p>
|
|
30
|
+
<img src="public/img/examples/tax-days.png" alt="Tax Days screenshots" width="100%" />
|
|
31
|
+
|
|
32
|
+
<p><img src="public/img/examples/only-recipes-icon.png" width="14" height="14" /> <a href="https://apps.apple.com/us/app/only-recipes-recipe-keeper/id1553858589"><strong>Only Recipes</strong></a> (<a href="examples/only-recipes">examples</a>)</p>
|
|
16
33
|
<img src="public/img/examples/only-recipes.png" alt="Only Recipes screenshots" width="100%" />
|
|
17
34
|
|
|
35
|
+
<p><img src="public/img/examples/thoughtful-icon.png" width="14" height="14" /> <a href="https://apps.apple.com/us/app/thoughtful-grow-relationships/id6762098726"><strong>Thoughtful</strong></a> (<a href="examples/thoughtful">examples</a>)</p>
|
|
36
|
+
<img src="public/img/examples/thoughtful.png" alt="Thoughtful screenshots" width="100%" />
|
|
37
|
+
|
|
18
38
|
<p><img src="public/img/examples/cat-iq-test-icon.png" width="14" height="14" /> <a href="https://apps.apple.com/us/app/cat-iq-test/id6759520249"><strong>Cat IQ Test</strong></a> (<a href="examples/cat-iq-test">examples</a>)</p>
|
|
19
39
|
<img src="public/img/examples/cat-iq-test.png" alt="Cat IQ Test screenshots" width="100%" />
|
|
20
40
|
|
|
@@ -59,7 +79,7 @@ Then use `oa` anywhere:
|
|
|
59
79
|
|
|
60
80
|
```bash
|
|
61
81
|
oa dev
|
|
62
|
-
oa render
|
|
82
|
+
oa render
|
|
63
83
|
oa init
|
|
64
84
|
```
|
|
65
85
|
|
|
@@ -75,6 +95,26 @@ open-assets uses a simple, unified data model. Every asset type follows the same
|
|
|
75
95
|
| **Source Size** | The dimensions the HTML template is authored at. Puppeteer scales from source → export size. |
|
|
76
96
|
| **Output** | An optional post-render action (e.g., write to Xcode `.appiconset`, copy SVG source). |
|
|
77
97
|
|
|
98
|
+
### One template, many sizes, many destinations
|
|
99
|
+
|
|
100
|
+
Every entry in a collection's `export` array is either a size or an output action. A single template renders to all of them in one pass:
|
|
101
|
+
|
|
102
|
+
```json
|
|
103
|
+
"export": [
|
|
104
|
+
{ "name": "iphone-6.9", "label": "iPhone 6.9\"", "size": { "width": 1320, "height": 2868 } },
|
|
105
|
+
{ "name": "iphone-6.7", "label": "iPhone 6.7\"", "size": { "width": 1290, "height": 2796 } },
|
|
106
|
+
{ "name": "favicon", "size": { "width": 32, "height": 32 }, "outFile": "public/favicon.png" },
|
|
107
|
+
{ "type": "xcode", "path": "../MyApp/Assets.xcassets/AppIcon.appiconset" }
|
|
108
|
+
]
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
- Sized entries land in `exports/{collection}/{size}/{template}.png`
|
|
112
|
+
- `outFile` sends a rendered size anywhere in your repo (`.png` or `.jpg`), like your web app's `public/` directory
|
|
113
|
+
- `xcode` fills an Xcode `.appiconset` directly
|
|
114
|
+
- `copy-source` copies SVG sources alongside the rendered PNGs
|
|
115
|
+
|
|
116
|
+
Change the template once, run `npx open-assets render`, and every destination updates. Unchanged templates are skipped automatically.
|
|
117
|
+
|
|
78
118
|
## End-to-End Screenshot Pipeline
|
|
79
119
|
|
|
80
120
|
### 1. Initialize
|
|
@@ -87,7 +127,16 @@ Creates a `assets.json`, sample HTML templates, and a `public/` directory for sh
|
|
|
87
127
|
|
|
88
128
|
### 2. Design with Claude Code
|
|
89
129
|
|
|
90
|
-
|
|
130
|
+
The easiest way to get the skill is the Claude Code plugin marketplace. Inside Claude Code, run:
|
|
131
|
+
|
|
132
|
+
```
|
|
133
|
+
/plugin marketplace add Parra-Inc/open-assets
|
|
134
|
+
/plugin install open-assets@open-assets
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
The skill is installed once, works in every project, and updates with `/plugin marketplace update open-assets`.
|
|
138
|
+
|
|
139
|
+
Alternatively, copy the skill into a single project:
|
|
91
140
|
|
|
92
141
|
```bash
|
|
93
142
|
# Using the built-in command
|
|
@@ -123,10 +172,10 @@ Opens a live preview UI at `http://localhost:3200` with zoom/pan controls and ex
|
|
|
123
172
|
### 4. Export
|
|
124
173
|
|
|
125
174
|
```bash
|
|
126
|
-
npx open-assets render
|
|
175
|
+
npx open-assets render
|
|
127
176
|
```
|
|
128
177
|
|
|
129
|
-
Exports every template at every configured export size into `./exports/`, organized as `exports/{collection}/{size}/{template}.png`.
|
|
178
|
+
Exports every template at every configured export size into `./exports/`, skipping anything that hasn't changed, organized as `exports/{collection}/{size}/{template}.png`.
|
|
130
179
|
|
|
131
180
|
### 5. Upload to App Store Connect / Google Play
|
|
132
181
|
|
|
@@ -141,6 +190,7 @@ Capture real app screenshots via Playwright or XCTest, then use them inside your
|
|
|
141
190
|
npx playwright test --project=screenshots
|
|
142
191
|
|
|
143
192
|
# 2. Export marketing screenshots with those captures embedded
|
|
193
|
+
# (--force because captured images aren't checksummed by the cache)
|
|
144
194
|
npx open-assets render --force
|
|
145
195
|
```
|
|
146
196
|
|
|
@@ -152,10 +202,60 @@ Reference captured screenshots in your HTML templates:
|
|
|
152
202
|
The `assets.json` `command` field stores the export command so automation tools know what to run:
|
|
153
203
|
```json
|
|
154
204
|
{
|
|
155
|
-
"command": "npx open-assets render
|
|
205
|
+
"command": "npx open-assets render"
|
|
156
206
|
}
|
|
157
207
|
```
|
|
158
208
|
|
|
209
|
+
## Localization
|
|
210
|
+
|
|
211
|
+
Ship screenshots in every language you support, from the same templates. Add a localizations file (an iOS `.xcstrings`-inspired format), reference keys in templates with `{{key}}`, and every template renders once per locale:
|
|
212
|
+
|
|
213
|
+
```json
|
|
214
|
+
{
|
|
215
|
+
"sourceLanguage": "en",
|
|
216
|
+
"strings": {
|
|
217
|
+
"hero_title": {
|
|
218
|
+
"localizations": {
|
|
219
|
+
"en": { "value": "Track your tax days" },
|
|
220
|
+
"de": { "value": "Verfolge deine Steuertage" },
|
|
221
|
+
"ja": { "value": "税金の日を追跡する" },
|
|
222
|
+
"ar": { "value": "تتبع أيام الضرائب الخاصة بك" }
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
Wire it to a collection in `assets.json`:
|
|
230
|
+
|
|
231
|
+
```json
|
|
232
|
+
{
|
|
233
|
+
"id": "screenshots",
|
|
234
|
+
"localizations": "localizations.json",
|
|
235
|
+
"locales": ["en", "de", "ja", "ar"]
|
|
236
|
+
}
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Then use the keys in any template:
|
|
240
|
+
|
|
241
|
+
```html
|
|
242
|
+
<h1>{{hero_title}}</h1>
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
What you get:
|
|
246
|
+
|
|
247
|
+
- **Per-locale exports**: output paths become `exports/{collection}/{locale}/{size}/{template}.png`, ready for App Store Connect's per-language screenshot slots
|
|
248
|
+
- **RTL support**: right-to-left locales (Arabic, Hebrew, Persian, Urdu) automatically render with `dir="rtl"` set on the document
|
|
249
|
+
- **Locale-aware numbers**: `{{n:1234}}` renders as `1,234` in English and `1.234` in German via `Intl.NumberFormat`
|
|
250
|
+
- **Fallback chain**: exact locale (`es-419`), then base language (`es`), then the source language
|
|
251
|
+
|
|
252
|
+
Render all locales, or just one:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npx open-assets render --collection screenshots # every locale
|
|
256
|
+
npx open-assets render --collection screenshots --locale ja # just Japanese
|
|
257
|
+
```
|
|
258
|
+
|
|
159
259
|
## CLI Commands
|
|
160
260
|
|
|
161
261
|
### `open-assets dev [dir]`
|
|
@@ -191,8 +291,8 @@ Options:
|
|
|
191
291
|
Render assets headlessly via the command line, without opening a browser.
|
|
192
292
|
|
|
193
293
|
```bash
|
|
194
|
-
open-assets render # Render
|
|
195
|
-
open-assets render --force #
|
|
294
|
+
open-assets render # Render everything at every export size
|
|
295
|
+
open-assets render --force # Re-render everything, ignoring the cache
|
|
196
296
|
open-assets render --collection screenshots # Render a specific collection
|
|
197
297
|
open-assets render --template 01-hero # Render a single template
|
|
198
298
|
open-assets render --size iphone-6.9 # Use a named export size
|
|
@@ -206,28 +306,32 @@ Options:
|
|
|
206
306
|
| Flag | Env Var | Default | Description |
|
|
207
307
|
|------|---------|---------|-------------|
|
|
208
308
|
| `--collection <id>` | — | all | Render only the collection with this ID |
|
|
309
|
+
| `--tag <tag>` | — | all | Render only collections with this tag |
|
|
209
310
|
| `--template <name>` | — | all | Render only the template with this name |
|
|
210
311
|
| `--size <name>` | — | — | Use a named export size from config |
|
|
312
|
+
| `--locale <code>` | — | all | Render only this locale (e.g. `en`, `ar`, `ja`) |
|
|
211
313
|
| `--width <px>` | — | — | Custom output width |
|
|
212
314
|
| `--height <px>` | — | — | Custom output height |
|
|
213
|
-
| `-f, --force` | — | — |
|
|
315
|
+
| `-f, --force` | — | — | Re-render everything, ignoring the incremental cache |
|
|
214
316
|
| `-o, --output <dir>` | `OPEN_ASSETS_OUTPUT` | `./exports` | Output directory |
|
|
215
317
|
| `--config <path>` | `OPEN_ASSETS_CONFIG` | `assets.json` | Path to config file |
|
|
216
|
-
| `--parallel <count>` | `OPEN_ASSETS_PARALLEL` | `1` | Number of parallel renders |
|
|
217
318
|
| `--render-timeout <ms>` | `OPEN_ASSETS_RENDER_TIMEOUT` | `30000` | Puppeteer render timeout |
|
|
218
319
|
| `--json` | — | — | Output results as JSON |
|
|
219
320
|
| `-q, --quiet` | `OPEN_ASSETS_QUIET` | `false` | Suppress progress logs |
|
|
220
321
|
|
|
221
|
-
**Selective export
|
|
322
|
+
**Selective export**: flags compose naturally:
|
|
222
323
|
```bash
|
|
223
324
|
# Single template at a single device size
|
|
224
325
|
open-assets render --collection screenshots --template 01-hero --size iphone-6.9
|
|
225
326
|
|
|
226
327
|
# One template at all device sizes
|
|
227
|
-
open-assets render --collection screenshots --template 01-hero
|
|
328
|
+
open-assets render --collection screenshots --template 01-hero
|
|
228
329
|
|
|
229
330
|
# All templates at one device size
|
|
230
331
|
open-assets render --collection screenshots --size iphone-6.9
|
|
332
|
+
|
|
333
|
+
# All templates in one language
|
|
334
|
+
open-assets render --collection screenshots --locale ja
|
|
231
335
|
```
|
|
232
336
|
|
|
233
337
|
**Output structure**: `exports/{collection}/{size}/{template}.png`
|
|
@@ -272,7 +376,7 @@ open-assets validate # Check current directory
|
|
|
272
376
|
open-assets validate ./assets # Check specific directory
|
|
273
377
|
```
|
|
274
378
|
|
|
275
|
-
Returns exit code 1 if any errors are found
|
|
379
|
+
Returns exit code 1 if any errors are found, useful in CI pipelines.
|
|
276
380
|
|
|
277
381
|
### `open-assets skills [dir]`
|
|
278
382
|
|
|
@@ -286,6 +390,13 @@ open-assets skills ./my-app # Install to a specific project
|
|
|
286
390
|
npx skills add https://github.com/Parra-Inc/open-assets --skill open-assets
|
|
287
391
|
```
|
|
288
392
|
|
|
393
|
+
Prefer a global, per-user install? Use the Claude Code plugin marketplace instead: the skill then works in every project without copying files:
|
|
394
|
+
|
|
395
|
+
```
|
|
396
|
+
/plugin marketplace add Parra-Inc/open-assets
|
|
397
|
+
/plugin install open-assets@open-assets
|
|
398
|
+
```
|
|
399
|
+
|
|
289
400
|
### `open-assets init [dir]`
|
|
290
401
|
|
|
291
402
|
Scaffold a new project with a `assets.json`, sample HTML templates, and a `public/` directory.
|
|
@@ -304,7 +415,7 @@ Your project needs a `assets.json` at its root. This file defines the collection
|
|
|
304
415
|
"version": 1,
|
|
305
416
|
"name": "My App",
|
|
306
417
|
"publicDir": "public",
|
|
307
|
-
"command": "npx open-assets render
|
|
418
|
+
"command": "npx open-assets render",
|
|
308
419
|
"collections": [ ... ]
|
|
309
420
|
}
|
|
310
421
|
```
|
|
@@ -317,6 +428,7 @@ Your project needs a `assets.json` at its root. This file defines the collection
|
|
|
317
428
|
| `name` | string | yes | App display name |
|
|
318
429
|
| `publicDir` | string | no | Directory for shared assets (auto-served by dev server) |
|
|
319
430
|
| `command` | string | no | Export command for automation tools and CI |
|
|
431
|
+
| `tags` | array | no | Tag definitions (`{ id, label }`) for grouping collections |
|
|
320
432
|
| `collections` | array | yes | Asset collection definitions |
|
|
321
433
|
|
|
322
434
|
### Collection Schema (Unified)
|
|
@@ -345,8 +457,11 @@ All collections follow the same structure. No `type` field needed.
|
|
|
345
457
|
|-------|------|-------------|
|
|
346
458
|
| `id` | string | Unique collection identifier (used in CLI `--collection`) |
|
|
347
459
|
| `label` | string | Display name in the collection selector |
|
|
348
|
-
| `
|
|
460
|
+
| `tags` | array | Tag ids applied to this collection (filter renders with `--tag`) |
|
|
461
|
+
| `sourceSize` | object | `{ width, height }`: the dimensions templates are authored at |
|
|
349
462
|
| `borderRadius` | number | Border radius for preview frames (px) |
|
|
463
|
+
| `localizations` | string | Path to a localizations JSON file (see [Localization](#localization)) |
|
|
464
|
+
| `locales` | array | Optional locale filter. Omit to render every locale in the localizations file |
|
|
350
465
|
| `templates` | array | Source files to render |
|
|
351
466
|
| `templates[].src` | string | Path to HTML/SVG file (relative to project root) |
|
|
352
467
|
| `templates[].name` | string | Filename for exports (used by `--template` flag) |
|
|
@@ -354,14 +469,14 @@ All collections follow the same structure. No `type` field needed.
|
|
|
354
469
|
| `export` | array | Array of export sizes and output actions |
|
|
355
470
|
| `export[].name` | string | Size identifier (used by `--size` flag) |
|
|
356
471
|
| `export[].label` | string | Display label |
|
|
357
|
-
| `export[].size` | object | `{ width, height }
|
|
472
|
+
| `export[].size` | object | `{ width, height }`: output dimensions in pixels |
|
|
358
473
|
| `export[].outFile` | string | Optional output path for this size (supports .png, .jpg) |
|
|
359
474
|
| `export[].type` | string | Output action type (`xcode`, `copy-source`). Entries with `type` are post-render actions, not sizes |
|
|
360
475
|
| `customExport` | object | Optional `{ defaultWidth, defaultHeight }` for custom size UI |
|
|
361
476
|
|
|
362
477
|
### Output Types
|
|
363
478
|
|
|
364
|
-
Export entries with a `type` field are post-render actions
|
|
479
|
+
Export entries with a `type` field are post-render actions that run after every render:
|
|
365
480
|
|
|
366
481
|
| Type | Config | Description |
|
|
367
482
|
|------|--------|-------------|
|
|
@@ -487,7 +602,7 @@ Export entries with a `type` field are post-render actions (run with `--force`):
|
|
|
487
602
|
The `render` command maintains a `assets.lock` file that stores SHA256 checksums of each source HTML/SVG file. On subsequent renders, unchanged assets are skipped automatically:
|
|
488
603
|
|
|
489
604
|
```
|
|
490
|
-
$ open-assets render
|
|
605
|
+
$ open-assets render
|
|
491
606
|
Skipping 01-hero at 1320x2868 (unchanged)
|
|
492
607
|
Rendering 03-new-screen at 1320x2868...
|
|
493
608
|
→ exports/screenshots/iphone-6.9/03-new-screen.png
|
|
@@ -497,7 +612,7 @@ Done. 1 asset(s) rendered, 1 skipped (unchanged) in 1.2s.
|
|
|
497
612
|
|
|
498
613
|
Use `--force` to re-render everything regardless of the cache.
|
|
499
614
|
|
|
500
|
-
**Limitation**: Only source HTML/SVG files are checksummed. Changes to referenced assets (images in `publicDir`, compiled Tailwind CSS) won't trigger re-renders
|
|
615
|
+
**Limitation**: Only source HTML/SVG files are checksummed. Changes to referenced assets (images in `publicDir`, compiled Tailwind CSS) won't trigger re-renders, so use `--force` when those change.
|
|
501
616
|
|
|
502
617
|
Commit `assets.lock` to your repository so teammates and CI benefit from the cache.
|
|
503
618
|
|
|
@@ -522,7 +637,7 @@ jobs:
|
|
|
522
637
|
node-version: 20
|
|
523
638
|
- run: npm ci
|
|
524
639
|
- run: npx open-assets validate
|
|
525
|
-
- run: npx open-assets render --
|
|
640
|
+
- run: npx open-assets render --json --quiet
|
|
526
641
|
- uses: actions/upload-artifact@v4
|
|
527
642
|
with:
|
|
528
643
|
name: screenshots
|
|
@@ -550,6 +665,7 @@ jobs:
|
|
|
550
665
|
project/
|
|
551
666
|
assets.json
|
|
552
667
|
assets.lock # Auto-generated cache (commit this)
|
|
668
|
+
localizations.json # Localized strings (optional)
|
|
553
669
|
public/ # Shared assets (configured via publicDir)
|
|
554
670
|
logo-round.png
|
|
555
671
|
social/
|
|
@@ -570,7 +686,7 @@ project/
|
|
|
570
686
|
default.html
|
|
571
687
|
dist/
|
|
572
688
|
styles.css # Compiled Tailwind
|
|
573
|
-
exports/ # Rendered output (
|
|
689
|
+
exports/ # Rendered output (commit this)
|
|
574
690
|
screenshots/
|
|
575
691
|
iphone-6.9/
|
|
576
692
|
01-hero.png
|
package/bin/open-assets.mjs
CHANGED
|
@@ -92,10 +92,9 @@ program
|
|
|
92
92
|
.option("--locale <code>", "Render only this locale (e.g. en, ar, ja)")
|
|
93
93
|
.option("--width <px>", "Output width in pixels (custom size)")
|
|
94
94
|
.option("--height <px>", "Output height in pixels (custom size)")
|
|
95
|
-
.option("-f, --force", "
|
|
95
|
+
.option("-f, --force", "Re-render all assets, ignoring the incremental cache")
|
|
96
96
|
.option("-o, --output <dir>", "Output directory (env: OPEN_ASSETS_OUTPUT)", env("OPEN_ASSETS_OUTPUT", "./exports"))
|
|
97
97
|
.option("--config <path>", "Path to config file (env: OPEN_ASSETS_CONFIG)", env("OPEN_ASSETS_CONFIG", "assets.json"))
|
|
98
|
-
.option("--parallel <count>", "Number of parallel renders (env: OPEN_ASSETS_PARALLEL)", env("OPEN_ASSETS_PARALLEL", "1"))
|
|
99
98
|
.option("--render-timeout <ms>", "Puppeteer render timeout in ms", env("OPEN_ASSETS_RENDER_TIMEOUT", "30000"))
|
|
100
99
|
.option("--json", "Output results as JSON (for CI/scripting)")
|
|
101
100
|
.option("-q, --quiet", "Suppress progress logs", env("OPEN_ASSETS_QUIET") === "true")
|
|
@@ -116,7 +115,7 @@ program
|
|
|
116
115
|
|
|
117
116
|
const log = opts.quiet ? undefined : (msg) => console.log(msg);
|
|
118
117
|
const deps = {
|
|
119
|
-
|
|
118
|
+
renderVariants: renderer.renderVariants,
|
|
120
119
|
runXcodeOutput: renderer.runXcodeOutput,
|
|
121
120
|
closeBrowser: renderer.closeBrowser,
|
|
122
121
|
readLockfile: lockfile.readLockfile,
|
package/lib/init.mjs
CHANGED
package/lib/lockfile.mjs
CHANGED
|
@@ -91,14 +91,17 @@ export function computeChecksum(filePath) {
|
|
|
91
91
|
|
|
92
92
|
/**
|
|
93
93
|
* Check if an asset variant is up-to-date based on its stored checksums.
|
|
94
|
-
* Returns true if
|
|
94
|
+
* Returns true if the source and export config checksums match, the entry was
|
|
95
|
+
* recorded for the same output path, and the output file exists.
|
|
96
|
+
* @param {string} [projectDir] - Base directory for resolving relative output paths
|
|
95
97
|
*/
|
|
96
|
-
export function isUpToDate(lockData, assetKey, variantKey, currentChecksum, outputPath, exportChecksum) {
|
|
98
|
+
export function isUpToDate(lockData, assetKey, variantKey, currentChecksum, outputPath, exportChecksum, projectDir = ".") {
|
|
97
99
|
const entry = lockData.assets?.[assetKey]?.[variantKey];
|
|
98
100
|
if (!entry) return false;
|
|
99
101
|
if (entry.sourceChecksum !== currentChecksum) return false;
|
|
100
102
|
if (exportChecksum && entry.exportChecksum !== exportChecksum) return false;
|
|
101
|
-
if (
|
|
103
|
+
if (entry.outputPath !== outputPath) return false;
|
|
104
|
+
if (!existsSync(resolve(projectDir, outputPath))) return false;
|
|
102
105
|
return true;
|
|
103
106
|
}
|
|
104
107
|
|
package/lib/manifest.mjs
CHANGED
|
@@ -83,14 +83,13 @@ export function filterTemplates(templates, templateName) {
|
|
|
83
83
|
|
|
84
84
|
/**
|
|
85
85
|
* Determine which sizes to render for a collection given CLI options.
|
|
86
|
+
* By default every configured export size is rendered; --width/--height or
|
|
87
|
+
* --size narrow the selection.
|
|
86
88
|
* @param {object} collection - The collection from the config
|
|
87
|
-
* @param {{ width?: string|number, height?: string|number, size?: string,
|
|
89
|
+
* @param {{ width?: string|number, height?: string|number, size?: string, platform?: string }} opts
|
|
88
90
|
* @returns {{ sizes: object[], warning?: string }}
|
|
89
91
|
*/
|
|
90
92
|
export function resolveRenderSizes(collection, opts = {}) {
|
|
91
|
-
const sourceW = collection.sourceSize.width;
|
|
92
|
-
const sourceH = collection.sourceSize.height;
|
|
93
|
-
|
|
94
93
|
if (opts.width && opts.height) {
|
|
95
94
|
const w = typeof opts.width === "number" ? opts.width : parseInt(opts.width);
|
|
96
95
|
const h = typeof opts.height === "number" ? opts.height : parseInt(opts.height);
|
|
@@ -116,17 +115,6 @@ export function resolveRenderSizes(collection, opts = {}) {
|
|
|
116
115
|
};
|
|
117
116
|
}
|
|
118
117
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
return { sizes };
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// Default: render at source size
|
|
125
|
-
return {
|
|
126
|
-
sizes: [{
|
|
127
|
-
name: `${sourceW}x${sourceH}`,
|
|
128
|
-
label: `${sourceW}x${sourceH}`,
|
|
129
|
-
size: { width: sourceW, height: sourceH },
|
|
130
|
-
}],
|
|
131
|
-
};
|
|
118
|
+
// Default: render at every configured export size
|
|
119
|
+
return { sizes: flatSizes(collection) };
|
|
132
120
|
}
|