@extenshi/cli 0.21.0 → 0.23.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 +4 -0
- package/dist/amo-source-detect.d.ts +18 -0
- package/dist/amo-source-detect.d.ts.map +1 -0
- package/dist/amo-source-detect.js +41 -0
- package/dist/amo-source-detect.js.map +1 -0
- package/dist/amo-source.d.ts +41 -0
- package/dist/amo-source.d.ts.map +1 -0
- package/dist/amo-source.js +240 -0
- package/dist/amo-source.js.map +1 -0
- package/dist/amowebstore-md.d.ts +38 -0
- package/dist/amowebstore-md.d.ts.map +1 -0
- package/dist/amowebstore-md.js +118 -0
- package/dist/amowebstore-md.js.map +1 -0
- package/dist/auto-evidence.d.ts +154 -0
- package/dist/auto-evidence.d.ts.map +1 -0
- package/dist/auto-evidence.js +297 -0
- package/dist/auto-evidence.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +366 -11
- package/dist/cli.js.map +1 -1
- package/dist/domain.d.ts +40 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +64 -0
- package/dist/domain.js.map +1 -0
- package/dist/edgewebstore-md.d.ts +26 -0
- package/dist/edgewebstore-md.d.ts.map +1 -0
- package/dist/edgewebstore-md.js +95 -0
- package/dist/edgewebstore-md.js.map +1 -0
- package/dist/evidence-ingest.d.ts +60 -0
- package/dist/evidence-ingest.d.ts.map +1 -0
- package/dist/evidence-ingest.js +141 -0
- package/dist/evidence-ingest.js.map +1 -0
- package/dist/extension-localization.d.ts +6 -1
- package/dist/extension-localization.d.ts.map +1 -1
- package/dist/extension-localization.js +4 -0
- package/dist/extension-localization.js.map +1 -1
- package/dist/firefox-rdp.d.ts +55 -0
- package/dist/firefox-rdp.d.ts.map +1 -0
- package/dist/firefox-rdp.js +203 -0
- package/dist/firefox-rdp.js.map +1 -0
- package/dist/gecko-id.d.ts +55 -0
- package/dist/gecko-id.d.ts.map +1 -0
- package/dist/gecko-id.js +132 -0
- package/dist/gecko-id.js.map +1 -0
- package/dist/generate-listing.d.ts +19 -8
- package/dist/generate-listing.d.ts.map +1 -1
- package/dist/generate-listing.js +66 -18
- package/dist/generate-listing.js.map +1 -1
- package/dist/icon.d.ts +18 -0
- package/dist/icon.d.ts.map +1 -1
- package/dist/icon.js +29 -20
- package/dist/icon.js.map +1 -1
- package/dist/landing-page.d.ts +22 -4
- package/dist/landing-page.d.ts.map +1 -1
- package/dist/landing-page.js +14 -11
- package/dist/landing-page.js.map +1 -1
- package/dist/landing-sections.d.ts +332 -0
- package/dist/landing-sections.d.ts.map +1 -0
- package/dist/landing-sections.js +1071 -0
- package/dist/landing-sections.js.map +1 -0
- package/dist/listing.d.ts +15 -0
- package/dist/listing.d.ts.map +1 -1
- package/dist/listing.js +1 -1
- package/dist/listing.js.map +1 -1
- package/dist/media.d.ts +42 -0
- package/dist/media.d.ts.map +1 -0
- package/dist/media.js +96 -0
- package/dist/media.js.map +1 -0
- package/dist/package.d.ts +163 -0
- package/dist/package.d.ts.map +1 -0
- package/dist/package.js +500 -0
- package/dist/package.js.map +1 -0
- package/dist/page.d.ts +110 -21
- package/dist/page.d.ts.map +1 -1
- package/dist/page.js +240 -10
- package/dist/page.js.map +1 -1
- package/dist/pay-contract.d.ts +42 -11
- package/dist/pay-contract.d.ts.map +1 -1
- package/dist/pay-contract.js +31 -0
- package/dist/pay-contract.js.map +1 -1
- package/dist/pay-test-cycle.d.ts +40 -0
- package/dist/pay-test-cycle.d.ts.map +1 -0
- package/dist/pay-test-cycle.js +207 -0
- package/dist/pay-test-cycle.js.map +1 -0
- package/dist/pay.d.ts +1 -1
- package/dist/pay.d.ts.map +1 -1
- package/dist/pay.js +1 -0
- package/dist/pay.js.map +1 -1
- package/dist/project.d.ts +69 -1
- package/dist/project.d.ts.map +1 -1
- package/dist/project.js +363 -54
- package/dist/project.js.map +1 -1
- package/dist/publish.d.ts +33 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +113 -2
- package/dist/publish.js.map +1 -1
- package/dist/review-checks.d.ts +13 -0
- package/dist/review-checks.d.ts.map +1 -1
- package/dist/review-checks.js.map +1 -1
- package/dist/review-risk.d.ts +10 -1
- package/dist/review-risk.d.ts.map +1 -1
- package/dist/review-risk.js +1 -0
- package/dist/review-risk.js.map +1 -1
- package/dist/scan.d.ts +3 -2
- package/dist/scan.d.ts.map +1 -1
- package/dist/scan.js +4 -2
- package/dist/scan.js.map +1 -1
- package/dist/screenshots-scenes.d.ts +1383 -0
- package/dist/screenshots-scenes.d.ts.map +1 -0
- package/dist/screenshots-scenes.js +276 -0
- package/dist/screenshots-scenes.js.map +1 -0
- package/dist/screenshots.d.ts +143 -0
- package/dist/screenshots.d.ts.map +1 -0
- package/dist/screenshots.js +558 -0
- package/dist/screenshots.js.map +1 -0
- package/dist/smoke.d.ts +81 -0
- package/dist/smoke.d.ts.map +1 -0
- package/dist/smoke.js +491 -0
- package/dist/smoke.js.map +1 -0
- package/dist/store-assets.d.ts +139 -0
- package/dist/store-assets.d.ts.map +1 -0
- package/dist/store-assets.js +582 -0
- package/dist/store-assets.js.map +1 -0
- package/dist/zip.d.ts +57 -0
- package/dist/zip.d.ts.map +1 -0
- package/dist/zip.js +134 -0
- package/dist/zip.js.map +1 -0
- package/package.json +7 -6
|
@@ -0,0 +1,582 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `extenshi icon store-assets <source>` — the store LISTING artwork each store
|
|
3
|
+
* asks for, rendered offline from one .svg / .png source.
|
|
4
|
+
*
|
|
5
|
+
* `icon preview` covers the toolbar sizes inside the package (16/32/48/128);
|
|
6
|
+
* this covers what the store dashboards ask for next to it: the Chrome Web
|
|
7
|
+
* Store promo tile and marquee, the Edge Add-ons logo and tiles, the AMO icon.
|
|
8
|
+
* Same source validation (readIconSource / svg-scrub) as the preview.
|
|
9
|
+
*
|
|
10
|
+
* Rendering is resvg compiled to WebAssembly (@resvg/resvg-wasm): no native
|
|
11
|
+
* module, no browser, no network. It is imported lazily so no other command
|
|
12
|
+
* pays for loading it.
|
|
13
|
+
*
|
|
14
|
+
* Sizes are the stores' own numbers; each spec carries the page it came from.
|
|
15
|
+
* The screenshot sizes used by `extenshi screenshots` live here too, so there is
|
|
16
|
+
* one table of store image requirements in the CLI.
|
|
17
|
+
*/
|
|
18
|
+
import { createHash } from 'node:crypto';
|
|
19
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
20
|
+
import { mkdir, writeFile } from 'node:fs/promises';
|
|
21
|
+
import { createRequire } from 'node:module';
|
|
22
|
+
import os from 'node:os';
|
|
23
|
+
import path from 'node:path';
|
|
24
|
+
import { InvalidInputError } from './expected-error.js';
|
|
25
|
+
import { readIconSource } from './icon.js';
|
|
26
|
+
// ── Store requirements (sources cited per entry) ────────────────────────────
|
|
27
|
+
/** https://developer.chrome.com/docs/webstore/images */
|
|
28
|
+
export const CWS_IMAGES_DOC = 'https://developer.chrome.com/docs/webstore/images';
|
|
29
|
+
/** https://learn.microsoft.com/en-us/microsoft-edge/extensions/publish/publish-extension (Step 7, store listing) */
|
|
30
|
+
export const EDGE_LISTING_DOC = 'https://learn.microsoft.com/en-us/microsoft-edge/extensions/publish/publish-extension#step-7-enter-store-listing-details-for-each-language';
|
|
31
|
+
/** https://mozilla.github.io/addons-server/topics/api/addons.html#addon-icon — square PNG/JPEG, 128×128 recommended; AMO derives 32/64/128. */
|
|
32
|
+
export const AMO_ICON_DOC = 'https://mozilla.github.io/addons-server/topics/api/addons.html#addon-icon';
|
|
33
|
+
/** https://extensionworkshop.com/documentation/develop/create-an-appealing-listing/ — screenshots 1280×800 (1.6:1). */
|
|
34
|
+
export const AMO_LISTING_DOC = 'https://extensionworkshop.com/documentation/develop/create-an-appealing-listing/';
|
|
35
|
+
/** https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons — 32 px default, 2× for HiDPI. */
|
|
36
|
+
export const MDN_ICONS_DOC = 'https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/icons';
|
|
37
|
+
export const STORES = ['chrome', 'edge', 'firefox'];
|
|
38
|
+
/**
|
|
39
|
+
* Listing screenshots. All three stores take 1280×800, so one capture serves
|
|
40
|
+
* every store at the default size; `small` is each store's other accepted size.
|
|
41
|
+
*/
|
|
42
|
+
export const STORE_SCREENSHOT_SPECS = {
|
|
43
|
+
// "1280x800 or 640x400 pixels", "Square corners, no padding (full bleed)", up to 5.
|
|
44
|
+
chrome: {
|
|
45
|
+
large: { width: 1280, height: 800 },
|
|
46
|
+
small: { width: 640, height: 400 },
|
|
47
|
+
max: 5,
|
|
48
|
+
doc: CWS_IMAGES_DOC,
|
|
49
|
+
note: 'Full bleed, square corners; at least 1, at most 5; 1280×800 preferred.',
|
|
50
|
+
},
|
|
51
|
+
// "The size of the screenshots must be either 640 x 480 pixels or 1280 x 800 pixels", max 6.
|
|
52
|
+
edge: {
|
|
53
|
+
large: { width: 1280, height: 800 },
|
|
54
|
+
small: { width: 640, height: 480 },
|
|
55
|
+
max: 6,
|
|
56
|
+
doc: EDGE_LISTING_DOC,
|
|
57
|
+
note: 'Optional; at most 6.',
|
|
58
|
+
},
|
|
59
|
+
// "We recommended that you capture images that are 1280x800px … use the 1.6:1 ratio."
|
|
60
|
+
firefox: {
|
|
61
|
+
large: { width: 1280, height: 800 },
|
|
62
|
+
small: { width: 640, height: 400 },
|
|
63
|
+
max: null,
|
|
64
|
+
doc: AMO_LISTING_DOC,
|
|
65
|
+
note: 'Uploaded as AMO "previews"; 1.6:1 ratio recommended.',
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
export const STORE_ASSET_SPECS = [
|
|
69
|
+
{
|
|
70
|
+
store: 'chrome',
|
|
71
|
+
id: 'icon',
|
|
72
|
+
file: 'icon-128.png',
|
|
73
|
+
width: 128,
|
|
74
|
+
height: 128,
|
|
75
|
+
kind: 'icon',
|
|
76
|
+
required: true,
|
|
77
|
+
// "The actual icon size should be 96x96 … 16 pixels per side should be transparent padding"
|
|
78
|
+
artwork: 96 / 128,
|
|
79
|
+
note: 'PNG in the package; 96×96 artwork with 16 px transparent padding.',
|
|
80
|
+
doc: CWS_IMAGES_DOC,
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
store: 'chrome',
|
|
84
|
+
id: 'promo-small',
|
|
85
|
+
file: 'promo-small-440x280.png',
|
|
86
|
+
width: 440,
|
|
87
|
+
height: 280,
|
|
88
|
+
kind: 'promo',
|
|
89
|
+
required: true,
|
|
90
|
+
note: 'Small promo tile (required). Avoid text; not locale-specific.',
|
|
91
|
+
doc: CWS_IMAGES_DOC,
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
store: 'chrome',
|
|
95
|
+
id: 'marquee',
|
|
96
|
+
file: 'marquee-1400x560.png',
|
|
97
|
+
width: 1400,
|
|
98
|
+
height: 560,
|
|
99
|
+
kind: 'marquee',
|
|
100
|
+
required: false,
|
|
101
|
+
note: 'Marquee promo tile (optional; needed to be featured in the marquee).',
|
|
102
|
+
doc: CWS_IMAGES_DOC,
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
store: 'edge',
|
|
106
|
+
id: 'logo',
|
|
107
|
+
file: 'logo-300x300.png',
|
|
108
|
+
width: 300,
|
|
109
|
+
height: 300,
|
|
110
|
+
kind: 'logo',
|
|
111
|
+
required: true,
|
|
112
|
+
// "aspect ratio of 1:1 and a recommended size of 300 x 300 pixels, with a minimum size of 128 x 128"
|
|
113
|
+
artwork: 0.84,
|
|
114
|
+
note: 'Extension logo (required per language), 1:1.',
|
|
115
|
+
doc: EDGE_LISTING_DOC,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
store: 'edge',
|
|
119
|
+
id: 'promo-small',
|
|
120
|
+
file: 'promo-small-440x280.png',
|
|
121
|
+
width: 440,
|
|
122
|
+
height: 280,
|
|
123
|
+
kind: 'promo',
|
|
124
|
+
required: false,
|
|
125
|
+
note: 'Small promotional tile (optional), exactly 440×280.',
|
|
126
|
+
doc: EDGE_LISTING_DOC,
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
store: 'edge',
|
|
130
|
+
id: 'promo-large',
|
|
131
|
+
file: 'promo-large-1400x560.png',
|
|
132
|
+
width: 1400,
|
|
133
|
+
height: 560,
|
|
134
|
+
kind: 'marquee',
|
|
135
|
+
required: false,
|
|
136
|
+
note: 'Large promotional tile (optional), PNG, exactly 1400×560.',
|
|
137
|
+
doc: EDGE_LISTING_DOC,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
store: 'firefox',
|
|
141
|
+
id: 'icon',
|
|
142
|
+
file: 'icon-128.png',
|
|
143
|
+
width: 128,
|
|
144
|
+
height: 128,
|
|
145
|
+
kind: 'icon',
|
|
146
|
+
required: true,
|
|
147
|
+
artwork: 112 / 128,
|
|
148
|
+
note: 'AMO listing icon: square PNG, 128×128 recommended (AMO derives 32/64).',
|
|
149
|
+
doc: AMO_ICON_DOC,
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
store: 'firefox',
|
|
153
|
+
id: 'icon-64',
|
|
154
|
+
file: 'icon-64.png',
|
|
155
|
+
width: 64,
|
|
156
|
+
height: 64,
|
|
157
|
+
kind: 'icon',
|
|
158
|
+
required: false,
|
|
159
|
+
artwork: 112 / 128,
|
|
160
|
+
note: 'manifest.json "icons" 2× size for HiDPI displays.',
|
|
161
|
+
doc: MDN_ICONS_DOC,
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
store: 'firefox',
|
|
165
|
+
id: 'icon-32',
|
|
166
|
+
file: 'icon-32.png',
|
|
167
|
+
width: 32,
|
|
168
|
+
height: 32,
|
|
169
|
+
kind: 'icon',
|
|
170
|
+
required: false,
|
|
171
|
+
artwork: 112 / 128,
|
|
172
|
+
note: 'manifest.json "icons" default size (add-ons manager).',
|
|
173
|
+
doc: MDN_ICONS_DOC,
|
|
174
|
+
},
|
|
175
|
+
];
|
|
176
|
+
export function parseStores(value) {
|
|
177
|
+
if (!value)
|
|
178
|
+
return [...STORES];
|
|
179
|
+
const out = [
|
|
180
|
+
...new Set(value
|
|
181
|
+
.split(',')
|
|
182
|
+
.map((s) => s.trim().toLowerCase())
|
|
183
|
+
.filter(Boolean)),
|
|
184
|
+
];
|
|
185
|
+
const bad = out.filter((s) => !STORES.includes(s));
|
|
186
|
+
if (bad.length)
|
|
187
|
+
throw new InvalidInputError(`Unknown store "${bad.join(', ')}" — use chrome, edge and/or firefox`);
|
|
188
|
+
return out;
|
|
189
|
+
}
|
|
190
|
+
let resvgReady = null;
|
|
191
|
+
export function loadResvg() {
|
|
192
|
+
resvgReady ??= (async () => {
|
|
193
|
+
const mod = await import('@resvg/resvg-wasm');
|
|
194
|
+
const require = createRequire(import.meta.url);
|
|
195
|
+
await mod.initWasm(readFileSync(require.resolve('@resvg/resvg-wasm/index_bg.wasm')));
|
|
196
|
+
return mod;
|
|
197
|
+
})();
|
|
198
|
+
return resvgReady;
|
|
199
|
+
}
|
|
200
|
+
export async function renderSvg(svg, width, fontBuffers = []) {
|
|
201
|
+
const { Resvg } = await loadResvg();
|
|
202
|
+
const resvg = new Resvg(svg, {
|
|
203
|
+
fitTo: { mode: 'width', value: width },
|
|
204
|
+
font: fontBuffers.length
|
|
205
|
+
? { fontBuffers, defaultFontFamily: 'Helvetica', sansSerifFamily: 'Helvetica' }
|
|
206
|
+
: { fontBuffers: [] },
|
|
207
|
+
shapeRendering: 2,
|
|
208
|
+
textRendering: 1,
|
|
209
|
+
imageRendering: 0,
|
|
210
|
+
});
|
|
211
|
+
const image = resvg.render();
|
|
212
|
+
const out = { width: image.width, height: image.height, pixels: image.pixels, png: image.asPng() };
|
|
213
|
+
image.free();
|
|
214
|
+
resvg.free();
|
|
215
|
+
return out;
|
|
216
|
+
}
|
|
217
|
+
function parseViewBox(svg) {
|
|
218
|
+
const root = /<svg\b[^>]*>/i.exec(svg)?.[0] ?? '';
|
|
219
|
+
const m = /\sviewBox\s*=\s*["']\s*([-\d.eE+]+)[\s,]+([-\d.eE+]+)[\s,]+([-\d.eE+]+)[\s,]+([-\d.eE+]+)\s*["']/i.exec(root);
|
|
220
|
+
if (!m)
|
|
221
|
+
return null;
|
|
222
|
+
const [x, y, width, height] = m.slice(1).map(Number);
|
|
223
|
+
return width > 0 && height > 0 ? { x, y, width, height } : null;
|
|
224
|
+
}
|
|
225
|
+
/** Intrinsic size, user coordinates and (for SVG) whether content overflows the canvas. */
|
|
226
|
+
export async function sourceInfo(source, fontBuffers = []) {
|
|
227
|
+
const { Resvg } = await loadResvg();
|
|
228
|
+
const resvg = new Resvg(source.isSvg ? source.svgSource : wrapRaster(source), {
|
|
229
|
+
font: { fontBuffers },
|
|
230
|
+
});
|
|
231
|
+
const width = resvg.width;
|
|
232
|
+
const height = resvg.height;
|
|
233
|
+
const viewBox = (source.isSvg && parseViewBox(source.svgSource)) || { x: 0, y: 0, width, height };
|
|
234
|
+
let overflow = false;
|
|
235
|
+
if (source.isSvg) {
|
|
236
|
+
// getBBox (not innerBBox, which is clipped to the canvas) is in user
|
|
237
|
+
// units; compare it against the viewBox.
|
|
238
|
+
const box = resvg.getBBox();
|
|
239
|
+
if (box) {
|
|
240
|
+
const eps = 0.5;
|
|
241
|
+
overflow =
|
|
242
|
+
box.x < viewBox.x - eps ||
|
|
243
|
+
box.y < viewBox.y - eps ||
|
|
244
|
+
box.x + box.width > viewBox.x + viewBox.width + eps ||
|
|
245
|
+
box.y + box.height > viewBox.y + viewBox.height + eps;
|
|
246
|
+
box.free();
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
resvg.free();
|
|
250
|
+
return { width, height, viewBox, overflow };
|
|
251
|
+
}
|
|
252
|
+
/** Map a box in rendered-canvas pixels of a source to its user coordinates (xMidYMid meet). */
|
|
253
|
+
export function canvasToUser(box, info) {
|
|
254
|
+
const vb = info.viewBox;
|
|
255
|
+
const s = Math.min(info.width / vb.width, info.height / vb.height);
|
|
256
|
+
const tx = (info.width - vb.width * s) / 2;
|
|
257
|
+
const ty = (info.height - vb.height * s) / 2;
|
|
258
|
+
return {
|
|
259
|
+
x: vb.x + (box.x - tx) / s,
|
|
260
|
+
y: vb.y + (box.y - ty) / s,
|
|
261
|
+
width: box.width / s,
|
|
262
|
+
height: box.height / s,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
function pngSize(png) {
|
|
266
|
+
return { width: png.readUInt32BE(16), height: png.readUInt32BE(20) };
|
|
267
|
+
}
|
|
268
|
+
/** An <svg> that paints a PNG source at its native size (so resvg can resample it). */
|
|
269
|
+
function wrapRaster(source) {
|
|
270
|
+
const { width, height } = pngSize(source.png);
|
|
271
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}"><image href="${source.dataUrl}" width="${width}" height="${height}"/></svg>`;
|
|
272
|
+
}
|
|
273
|
+
/** Bounding box of pixels with alpha > threshold, or null for a fully transparent image. */
|
|
274
|
+
export function alphaBoundingBox(pixels, width, height, threshold = 8) {
|
|
275
|
+
let minX = width;
|
|
276
|
+
let minY = height;
|
|
277
|
+
let maxX = -1;
|
|
278
|
+
let maxY = -1;
|
|
279
|
+
for (let y = 0; y < height; y++) {
|
|
280
|
+
for (let x = 0; x < width; x++) {
|
|
281
|
+
if (pixels[(y * width + x) * 4 + 3] > threshold) {
|
|
282
|
+
if (x < minX)
|
|
283
|
+
minX = x;
|
|
284
|
+
if (x > maxX)
|
|
285
|
+
maxX = x;
|
|
286
|
+
if (y < minY)
|
|
287
|
+
minY = y;
|
|
288
|
+
if (y > maxY)
|
|
289
|
+
maxY = y;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return maxX < 0 ? null : { x: minX, y: minY, width: maxX - minX + 1, height: maxY - minY + 1 };
|
|
294
|
+
}
|
|
295
|
+
/** Alpha-weighted average colour of the opaque artwork, as #rrggbb. */
|
|
296
|
+
export function dominantColor(pixels) {
|
|
297
|
+
let r = 0;
|
|
298
|
+
let g = 0;
|
|
299
|
+
let b = 0;
|
|
300
|
+
let a = 0;
|
|
301
|
+
for (let i = 0; i < pixels.length; i += 4) {
|
|
302
|
+
const w = pixels[i + 3] / 255;
|
|
303
|
+
r += pixels[i] * w;
|
|
304
|
+
g += pixels[i + 1] * w;
|
|
305
|
+
b += pixels[i + 2] * w;
|
|
306
|
+
a += w;
|
|
307
|
+
}
|
|
308
|
+
if (!a)
|
|
309
|
+
return '#6b7280';
|
|
310
|
+
const hex = (v) => Math.round(v / a)
|
|
311
|
+
.toString(16)
|
|
312
|
+
.padStart(2, '0');
|
|
313
|
+
return `#${hex(r)}${hex(g)}${hex(b)}`;
|
|
314
|
+
}
|
|
315
|
+
/** Mix a #rrggbb colour toward white by `t` (0 = colour, 1 = white). */
|
|
316
|
+
export function tint(color, t) {
|
|
317
|
+
const m = /^#([0-9a-f]{6})$/i.exec(color);
|
|
318
|
+
if (!m)
|
|
319
|
+
return color;
|
|
320
|
+
const n = Number.parseInt(m[1], 16);
|
|
321
|
+
const mix = (c) => Math.round(c + (255 - c) * t)
|
|
322
|
+
.toString(16)
|
|
323
|
+
.padStart(2, '0');
|
|
324
|
+
return `#${mix((n >> 16) & 255)}${mix((n >> 8) & 255)}${mix(n & 255)}`;
|
|
325
|
+
}
|
|
326
|
+
const SAFE_COLOR = /^(#[0-9a-f]{3,8}|[a-z]{3,20}|rgba?\([\d\s.,%]+\))$/i;
|
|
327
|
+
// ── Fonts (only when a source SVG draws text) ───────────────────────────────
|
|
328
|
+
function fontDirs() {
|
|
329
|
+
const home = os.homedir();
|
|
330
|
+
if (process.platform === 'darwin')
|
|
331
|
+
return [
|
|
332
|
+
'/System/Library/Fonts',
|
|
333
|
+
'/System/Library/Fonts/Supplemental',
|
|
334
|
+
'/Library/Fonts',
|
|
335
|
+
`${home}/Library/Fonts`,
|
|
336
|
+
];
|
|
337
|
+
if (process.platform === 'win32')
|
|
338
|
+
return [path.join(process.env.WINDIR ?? 'C:\\Windows', 'Fonts')];
|
|
339
|
+
return ['/usr/share/fonts', '/usr/local/share/fonts', `${home}/.local/share/fonts`, `${home}/.fonts`];
|
|
340
|
+
}
|
|
341
|
+
function listFontFiles(dir, depth = 0, out = []) {
|
|
342
|
+
if (depth > 3 || !existsSync(dir))
|
|
343
|
+
return out;
|
|
344
|
+
for (const entry of readdirSync(dir, { withFileTypes: true })) {
|
|
345
|
+
const full = path.join(dir, entry.name);
|
|
346
|
+
if (entry.isDirectory())
|
|
347
|
+
listFontFiles(full, depth + 1, out);
|
|
348
|
+
else if (/\.(ttf|otf|ttc)$/i.test(entry.name))
|
|
349
|
+
out.push(full);
|
|
350
|
+
}
|
|
351
|
+
return out;
|
|
352
|
+
}
|
|
353
|
+
const FALLBACK_FAMILIES = [
|
|
354
|
+
'Helvetica',
|
|
355
|
+
'Arial',
|
|
356
|
+
'DejaVuSans',
|
|
357
|
+
'LiberationSans',
|
|
358
|
+
'SegoeUI',
|
|
359
|
+
'Roboto',
|
|
360
|
+
'NotoSans',
|
|
361
|
+
];
|
|
362
|
+
const MAX_FONT_BYTES = 40 * 1024 * 1024;
|
|
363
|
+
/**
|
|
364
|
+
* resvg in WebAssembly cannot see system fonts, so text in a source SVG would
|
|
365
|
+
* silently vanish. Load only the files whose names match the families the SVG
|
|
366
|
+
* asks for (plus a common sans fallback) — not the whole font directory.
|
|
367
|
+
*/
|
|
368
|
+
export function fontsForSvg(svg, extraFiles = []) {
|
|
369
|
+
const files = [...extraFiles];
|
|
370
|
+
if (/<text\b/i.test(svg)) {
|
|
371
|
+
const requested = new Set();
|
|
372
|
+
for (const m of svg.matchAll(/font-family\s*[:=]\s*["']?([^"';>]+)/gi))
|
|
373
|
+
for (const f of m[1].split(','))
|
|
374
|
+
requested.add(f
|
|
375
|
+
.trim()
|
|
376
|
+
.replace(/^['"]|['"]$/g, '')
|
|
377
|
+
.replace(/\s+/g, '')
|
|
378
|
+
.toLowerCase());
|
|
379
|
+
const available = fontDirs().flatMap((d) => listFontFiles(d));
|
|
380
|
+
const base = (file) => path
|
|
381
|
+
.basename(file)
|
|
382
|
+
.replace(/\.(ttf|otf|ttc)$/i, '')
|
|
383
|
+
.replace(/[\s_-]+/g, '')
|
|
384
|
+
.toLowerCase();
|
|
385
|
+
const exact = (family) => available.find((file) => base(file) === family || base(file) === `${family}regular`);
|
|
386
|
+
for (const family of requested) {
|
|
387
|
+
if (!family || ['sans-serif', 'serif', 'monospace'].includes(family))
|
|
388
|
+
continue;
|
|
389
|
+
// Exact file name first ("Arial.ttf"), then the shortest prefix match, so
|
|
390
|
+
// "arial" does not pick "ArialHB.ttc" (Arial Hebrew).
|
|
391
|
+
const match = exact(family) ??
|
|
392
|
+
available
|
|
393
|
+
.filter((file) => base(file).startsWith(family))
|
|
394
|
+
.sort((a, b) => base(a).length - base(b).length)[0];
|
|
395
|
+
if (match && !files.includes(match))
|
|
396
|
+
files.push(match);
|
|
397
|
+
}
|
|
398
|
+
// One common sans as the fallback for generic or unmatched families.
|
|
399
|
+
const fallback = FALLBACK_FAMILIES.map((f) => exact(f.toLowerCase())).find(Boolean);
|
|
400
|
+
if (fallback && !files.includes(fallback))
|
|
401
|
+
files.push(fallback);
|
|
402
|
+
}
|
|
403
|
+
const buffers = [];
|
|
404
|
+
const loaded = [];
|
|
405
|
+
let total = 0;
|
|
406
|
+
for (const file of files) {
|
|
407
|
+
try {
|
|
408
|
+
const size = statSync(file).size;
|
|
409
|
+
if (total + size > MAX_FONT_BYTES)
|
|
410
|
+
continue;
|
|
411
|
+
buffers.push(readFileSync(file));
|
|
412
|
+
loaded.push(file);
|
|
413
|
+
total += size;
|
|
414
|
+
}
|
|
415
|
+
catch {
|
|
416
|
+
// unreadable font file — skip it
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
return { buffers, files: loaded };
|
|
420
|
+
}
|
|
421
|
+
// ── Composition ─────────────────────────────────────────────────────────────
|
|
422
|
+
function escAttr(v) {
|
|
423
|
+
return v.replace(/&/g, '&').replace(/"/g, '"').replace(/</g, '<');
|
|
424
|
+
}
|
|
425
|
+
const n = (v) => Number(v.toFixed(4));
|
|
426
|
+
/**
|
|
427
|
+
* The source painted into `target` (a box on the output canvas), showing only
|
|
428
|
+
* `crop` of it (in the source's user coordinates), aspect ratio preserved.
|
|
429
|
+
*
|
|
430
|
+
* An SVG source is nested INLINE (its root <svg> re-attributed) rather than
|
|
431
|
+
* referenced through <image>: resvg renders an <image>'d SVG without the font
|
|
432
|
+
* database, so any text in it would silently disappear. Root attributes other
|
|
433
|
+
* than geometry (fill="none", stroke, xmlns:*) are kept — they are inherited
|
|
434
|
+
* by the whole drawing.
|
|
435
|
+
*/
|
|
436
|
+
function placed(source, info, crop, target, mode) {
|
|
437
|
+
const geometry = `x="${n(target.x)}" y="${n(target.y)}" width="${n(target.width)}" height="${n(target.height)}" ` +
|
|
438
|
+
`viewBox="${n(crop.x)} ${n(crop.y)} ${n(crop.width)} ${n(crop.height)}" preserveAspectRatio="xMidYMid ${mode}" overflow="hidden"`;
|
|
439
|
+
if (!source.isSvg) {
|
|
440
|
+
return `<svg ${geometry}><image href="${escAttr(source.dataUrl)}" width="${info.width}" height="${info.height}"/></svg>`;
|
|
441
|
+
}
|
|
442
|
+
const markup = source.svgSource
|
|
443
|
+
.replace(/<\?xml[\s\S]*?\?>/gi, '')
|
|
444
|
+
.replace(/<!--[\s\S]*?-->/g, '');
|
|
445
|
+
const root = /<svg\b([^>]*)>/i.exec(markup);
|
|
446
|
+
if (!root)
|
|
447
|
+
throw new InvalidInputError('SVG source has no <svg> root element');
|
|
448
|
+
const kept = [...root[1].matchAll(/([\w:.-]+)\s*=\s*("[^"]*"|'[^']*')/g)]
|
|
449
|
+
.filter(([, name]) => !/^(x|y|width|height|viewBox|preserveAspectRatio|overflow)$/i.test(name))
|
|
450
|
+
.map(([whole]) => whole)
|
|
451
|
+
.join(' ');
|
|
452
|
+
return markup.replace(root[0], `<svg ${kept} ${geometry}>`);
|
|
453
|
+
}
|
|
454
|
+
async function loadArtwork(file, fonts, warnings, label) {
|
|
455
|
+
// Promo/marquee artwork may legitimately be bigger than an icon.
|
|
456
|
+
const source = readIconSource(file, { svgBytes: 2 * 1024 * 1024, pngBytes: 8 * 1024 * 1024 });
|
|
457
|
+
const loaded = source.isSvg ? fontsForSvg(source.svgSource, fonts) : { buffers: [], files: [] };
|
|
458
|
+
if (source.isSvg && /<text\b/i.test(source.svgSource) && loaded.buffers.length === 0)
|
|
459
|
+
warnings.push(`${label}: the SVG draws text but no matching font was found — pass --font <file.ttf>`);
|
|
460
|
+
const info = await sourceInfo(source, loaded.buffers);
|
|
461
|
+
if (!info.width || !info.height)
|
|
462
|
+
throw new InvalidInputError(`${label} has no size (set width/height or a viewBox)`);
|
|
463
|
+
if (info.overflow)
|
|
464
|
+
warnings.push(`${label}: some content extends past the ${info.width}×${info.height} canvas and is cut off at the edges`);
|
|
465
|
+
if (source.isSvg && /<style\b/i.test(readFileSync(source.resolved, 'utf8')))
|
|
466
|
+
warnings.push(`${label}: <style> blocks are removed by the SVG scrubber; use presentation attributes`);
|
|
467
|
+
return { source, info, fonts: loaded.buffers };
|
|
468
|
+
}
|
|
469
|
+
function sha256(bytes) {
|
|
470
|
+
return createHash('sha256').update(bytes).digest('hex');
|
|
471
|
+
}
|
|
472
|
+
/** Render every requested store's listing artwork. Exported for tests. */
|
|
473
|
+
export async function renderStoreAssets(iconPath, opts = {}) {
|
|
474
|
+
const stores = parseStores(opts.store);
|
|
475
|
+
const warnings = [];
|
|
476
|
+
for (const [flag, value] of [
|
|
477
|
+
['--background', opts.background],
|
|
478
|
+
['--icon-background', opts.iconBackground],
|
|
479
|
+
]) {
|
|
480
|
+
if (value && !SAFE_COLOR.test(value.trim()))
|
|
481
|
+
throw new InvalidInputError(`${flag} must be a CSS color (#hex, rgb() or a name)`);
|
|
482
|
+
}
|
|
483
|
+
const fonts = opts.font ?? [];
|
|
484
|
+
const icon = await loadArtwork(iconPath, fonts, warnings, path.basename(iconPath));
|
|
485
|
+
const promo = opts.promo ? await loadArtwork(opts.promo, fonts, warnings, path.basename(opts.promo)) : null;
|
|
486
|
+
const marquee = opts.marquee
|
|
487
|
+
? await loadArtwork(opts.marquee, fonts, warnings, path.basename(opts.marquee))
|
|
488
|
+
: null;
|
|
489
|
+
// One probe render of the icon: its opaque bounding box (so built-in padding
|
|
490
|
+
// is not doubled) and its colour (for the promo background).
|
|
491
|
+
const probeWidth = 512;
|
|
492
|
+
const probeScale = probeWidth / icon.info.width;
|
|
493
|
+
const probe = await renderSvg(icon.source.isSvg ? icon.source.svgSource : wrapRaster(icon.source), probeWidth, icon.fonts);
|
|
494
|
+
const bbox = alphaBoundingBox(probe.pixels, probe.width, probe.height);
|
|
495
|
+
if (!bbox)
|
|
496
|
+
throw new InvalidInputError(`${path.basename(iconPath)} renders fully transparent`);
|
|
497
|
+
const cropPx = {
|
|
498
|
+
x: bbox.x / probeScale,
|
|
499
|
+
y: bbox.y / probeScale,
|
|
500
|
+
width: bbox.width / probeScale,
|
|
501
|
+
height: bbox.height / probeScale,
|
|
502
|
+
};
|
|
503
|
+
const crop = icon.source.isSvg ? canvasToUser(cropPx, icon.info) : cropPx;
|
|
504
|
+
const background = opts.background?.trim() || tint(dominantColor(probe.pixels), 0.88);
|
|
505
|
+
const outDir = path.resolve(process.cwd(), opts.out ?? 'store-assets');
|
|
506
|
+
const assets = [];
|
|
507
|
+
for (const spec of STORE_ASSET_SPECS.filter((s) => stores.includes(s.store))) {
|
|
508
|
+
const { width: W, height: H } = spec;
|
|
509
|
+
let body;
|
|
510
|
+
let fontBuffers = icon.fonts;
|
|
511
|
+
const full = spec.kind === 'promo' ? promo : spec.kind === 'marquee' ? marquee : null;
|
|
512
|
+
if (full) {
|
|
513
|
+
// Designer artwork: cover the tile, centered.
|
|
514
|
+
const ratio = full.info.width / full.info.height;
|
|
515
|
+
if (Math.abs(ratio - W / H) / (W / H) > 0.02)
|
|
516
|
+
warnings.push(`${spec.store}/${spec.file}: artwork is ${full.info.width}×${full.info.height}, not ${W}:${H} — edges are cropped to fit`);
|
|
517
|
+
body = placed(full.source, full.info, full.info.viewBox, { x: 0, y: 0, width: W, height: H }, 'slice');
|
|
518
|
+
fontBuffers = full.fonts;
|
|
519
|
+
if (!full.source.isSvg && (full.info.width < W || full.info.height < H))
|
|
520
|
+
warnings.push(`${spec.store}/${spec.file}: raster artwork is smaller than ${W}×${H} and is upscaled`);
|
|
521
|
+
}
|
|
522
|
+
else if (spec.kind === 'promo' || spec.kind === 'marquee') {
|
|
523
|
+
// Composed from the icon: brand-tinted fill, icon centered — the stores
|
|
524
|
+
// ask for "avoid text" and "works when shrunk to half size".
|
|
525
|
+
const side = Math.round(H * 0.6);
|
|
526
|
+
const target = { x: (W - side) / 2, y: (H - side) / 2, width: side, height: side };
|
|
527
|
+
body = `<rect width="${W}" height="${H}" fill="${escAttr(background)}"/>${placed(icon.source, icon.info, crop, target, 'meet')}`;
|
|
528
|
+
}
|
|
529
|
+
else {
|
|
530
|
+
const side = W * (spec.artwork ?? 1);
|
|
531
|
+
const target = { x: (W - side) / 2, y: (H - side) / 2, width: side, height: side };
|
|
532
|
+
const bg = opts.iconBackground?.trim();
|
|
533
|
+
body = `${bg ? `<rect width="${W}" height="${H}" fill="${escAttr(bg)}"/>` : ''}${placed(icon.source, icon.info, crop, target, 'meet')}`;
|
|
534
|
+
}
|
|
535
|
+
if (!full && !icon.source.isSvg) {
|
|
536
|
+
const needed = spec.kind === 'marquee' || spec.kind === 'promo' ? H * 0.6 : W * (spec.artwork ?? 1);
|
|
537
|
+
if (crop.width < needed - 0.5 && crop.height < needed - 0.5)
|
|
538
|
+
warnings.push(`${spec.store}/${spec.file}: the PNG artwork is ${Math.round(crop.width)}×${Math.round(crop.height)} px and is upscaled to ~${Math.round(needed)} px — use an SVG or a larger PNG`);
|
|
539
|
+
}
|
|
540
|
+
const svg = `<svg xmlns="http://www.w3.org/2000/svg" width="${W}" height="${H}" viewBox="0 0 ${W} ${H}">${body}</svg>`;
|
|
541
|
+
const raster = await renderSvg(svg, W, fontBuffers);
|
|
542
|
+
if (raster.width !== W || raster.height !== H)
|
|
543
|
+
throw new Error(`Rendered ${spec.file} at ${raster.width}×${raster.height}, expected ${W}×${H}`);
|
|
544
|
+
const dir = path.join(outDir, spec.store);
|
|
545
|
+
await mkdir(dir, { recursive: true });
|
|
546
|
+
const file = path.join(dir, spec.file);
|
|
547
|
+
await writeFile(file, raster.png);
|
|
548
|
+
assets.push({
|
|
549
|
+
store: spec.store,
|
|
550
|
+
id: spec.id,
|
|
551
|
+
file: spec.file,
|
|
552
|
+
path: file,
|
|
553
|
+
width: W,
|
|
554
|
+
height: H,
|
|
555
|
+
bytes: raster.png.length,
|
|
556
|
+
sha256: sha256(raster.png),
|
|
557
|
+
required: spec.required,
|
|
558
|
+
doc: spec.doc,
|
|
559
|
+
});
|
|
560
|
+
}
|
|
561
|
+
await writeFile(path.join(outDir, 'store-assets.json'), `${JSON.stringify({
|
|
562
|
+
schemaVersion: 1,
|
|
563
|
+
source: path.basename(iconPath),
|
|
564
|
+
assets: assets.map(({ path: p, ...a }) => ({ ...a, path: path.relative(outDir, p) })),
|
|
565
|
+
warnings,
|
|
566
|
+
}, null, 2)}\n`);
|
|
567
|
+
return { outDir, assets, warnings };
|
|
568
|
+
}
|
|
569
|
+
export async function runStoreAssets(iconPath, opts) {
|
|
570
|
+
const result = await renderStoreAssets(iconPath, opts);
|
|
571
|
+
if (opts.json) {
|
|
572
|
+
console.log(JSON.stringify(result, null, 2));
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
575
|
+
process.stderr.write(`Store assets written to ${result.outDir}\n`);
|
|
576
|
+
for (const a of result.assets)
|
|
577
|
+
process.stderr.write(` ${a.store.padEnd(8)} ${path.relative(result.outDir, a.path).padEnd(34)} ${a.width}×${a.height}${a.required ? ' (required)' : ''}\n`);
|
|
578
|
+
for (const w of result.warnings)
|
|
579
|
+
process.stderr.write(` warning: ${w}\n`);
|
|
580
|
+
process.stderr.write('Screenshots are separate: extenshi screenshots <build> --scenes scenes.json (Chrome 1280×800, Edge 1280×800, AMO 1280×800).\n');
|
|
581
|
+
}
|
|
582
|
+
//# sourceMappingURL=store-assets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"store-assets.js","sourceRoot":"","sources":["../src/store-assets.ts"],"names":[],"mappings":"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"}
|