@extenshi/cli 0.23.1 → 0.25.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.
Files changed (114) hide show
  1. package/README.md +1 -1
  2. package/dist/amo-source.d.ts +88 -17
  3. package/dist/amo-source.d.ts.map +1 -1
  4. package/dist/amo-source.js +442 -116
  5. package/dist/amo-source.js.map +1 -1
  6. package/dist/amowebstore-md.d.ts +26 -0
  7. package/dist/amowebstore-md.d.ts.map +1 -1
  8. package/dist/amowebstore-md.js +32 -3
  9. package/dist/amowebstore-md.js.map +1 -1
  10. package/dist/auto-update.d.ts +46 -3
  11. package/dist/auto-update.d.ts.map +1 -1
  12. package/dist/auto-update.js +94 -19
  13. package/dist/auto-update.js.map +1 -1
  14. package/dist/chromewebstore-md.d.ts +7 -0
  15. package/dist/chromewebstore-md.d.ts.map +1 -1
  16. package/dist/chromewebstore-md.js +20 -3
  17. package/dist/chromewebstore-md.js.map +1 -1
  18. package/dist/cli.js +73 -20
  19. package/dist/cli.js.map +1 -1
  20. package/dist/compliance-review.d.ts +5 -1
  21. package/dist/compliance-review.d.ts.map +1 -1
  22. package/dist/compliance-review.js +10 -5
  23. package/dist/compliance-review.js.map +1 -1
  24. package/dist/cws-policies.d.ts.map +1 -1
  25. package/dist/cws-policies.js +4 -0
  26. package/dist/cws-policies.js.map +1 -1
  27. package/dist/edgewebstore-md.d.ts +14 -0
  28. package/dist/edgewebstore-md.d.ts.map +1 -1
  29. package/dist/edgewebstore-md.js +20 -5
  30. package/dist/edgewebstore-md.js.map +1 -1
  31. package/dist/evidence-ingest.d.ts +67 -5
  32. package/dist/evidence-ingest.d.ts.map +1 -1
  33. package/dist/evidence-ingest.js +146 -21
  34. package/dist/evidence-ingest.js.map +1 -1
  35. package/dist/generate-listing.d.ts +18 -6
  36. package/dist/generate-listing.d.ts.map +1 -1
  37. package/dist/generate-listing.js +62 -19
  38. package/dist/generate-listing.js.map +1 -1
  39. package/dist/json-ld.d.ts +43 -5
  40. package/dist/json-ld.d.ts.map +1 -1
  41. package/dist/json-ld.js +53 -1
  42. package/dist/json-ld.js.map +1 -1
  43. package/dist/landing-sections.d.ts +21 -3
  44. package/dist/landing-sections.d.ts.map +1 -1
  45. package/dist/landing-sections.js +63 -17
  46. package/dist/landing-sections.js.map +1 -1
  47. package/dist/listing-checks.d.ts +15 -9
  48. package/dist/listing-checks.d.ts.map +1 -1
  49. package/dist/listing-checks.js +54 -46
  50. package/dist/listing-checks.js.map +1 -1
  51. package/dist/listing-data-flows.d.ts +140 -0
  52. package/dist/listing-data-flows.d.ts.map +1 -0
  53. package/dist/listing-data-flows.js +454 -0
  54. package/dist/listing-data-flows.js.map +1 -0
  55. package/dist/listing.d.ts +48 -0
  56. package/dist/listing.d.ts.map +1 -1
  57. package/dist/listing.js +201 -23
  58. package/dist/listing.js.map +1 -1
  59. package/dist/localize-parity.d.ts +26 -0
  60. package/dist/localize-parity.d.ts.map +1 -0
  61. package/dist/localize-parity.js +227 -0
  62. package/dist/localize-parity.js.map +1 -0
  63. package/dist/localize.d.ts +6 -0
  64. package/dist/localize.d.ts.map +1 -1
  65. package/dist/localize.js +4 -4
  66. package/dist/localize.js.map +1 -1
  67. package/dist/media.d.ts.map +1 -1
  68. package/dist/media.js +1 -2
  69. package/dist/media.js.map +1 -1
  70. package/dist/package.d.ts +13 -0
  71. package/dist/package.d.ts.map +1 -1
  72. package/dist/package.js +1 -1
  73. package/dist/package.js.map +1 -1
  74. package/dist/page.d.ts +16 -0
  75. package/dist/page.d.ts.map +1 -1
  76. package/dist/page.js +49 -4
  77. package/dist/page.js.map +1 -1
  78. package/dist/permission-justifications.d.ts +19 -1
  79. package/dist/permission-justifications.d.ts.map +1 -1
  80. package/dist/permission-justifications.js +129 -0
  81. package/dist/permission-justifications.js.map +1 -1
  82. package/dist/png.d.ts +40 -0
  83. package/dist/png.d.ts.map +1 -0
  84. package/dist/png.js +266 -0
  85. package/dist/png.js.map +1 -0
  86. package/dist/review-checks.d.ts +54 -13
  87. package/dist/review-checks.d.ts.map +1 -1
  88. package/dist/review-checks.js +367 -56
  89. package/dist/review-checks.js.map +1 -1
  90. package/dist/review-risk.d.ts +8 -3
  91. package/dist/review-risk.d.ts.map +1 -1
  92. package/dist/review-risk.js +14 -4
  93. package/dist/review-risk.js.map +1 -1
  94. package/dist/review-stores.d.ts +63 -0
  95. package/dist/review-stores.d.ts.map +1 -0
  96. package/dist/review-stores.js +92 -0
  97. package/dist/review-stores.js.map +1 -0
  98. package/dist/screenshots-scenes.d.ts +13 -0
  99. package/dist/screenshots-scenes.d.ts.map +1 -1
  100. package/dist/screenshots-scenes.js +20 -2
  101. package/dist/screenshots-scenes.js.map +1 -1
  102. package/dist/screenshots.d.ts +6 -4
  103. package/dist/screenshots.d.ts.map +1 -1
  104. package/dist/screenshots.js +31 -11
  105. package/dist/screenshots.js.map +1 -1
  106. package/dist/smoke.d.ts +54 -6
  107. package/dist/smoke.d.ts.map +1 -1
  108. package/dist/smoke.js +302 -26
  109. package/dist/smoke.js.map +1 -1
  110. package/dist/store-assets.d.ts +20 -3
  111. package/dist/store-assets.d.ts.map +1 -1
  112. package/dist/store-assets.js +17 -7
  113. package/dist/store-assets.js.map +1 -1
  114. package/package.json +1 -1
@@ -0,0 +1,454 @@
1
+ /**
2
+ * What data the PACKAGE moves, for `extenshi generate-listing` — not only what
3
+ * its permissions allow.
4
+ *
5
+ * `privacyPracticesForManifest` (review-checks.ts) answers "which data types
6
+ * does a permission make you declare". That leaves out everything a package
7
+ * does without a sensitive permission: a bundled payment SDK talking to its
8
+ * API, settings in `storage.sync`, the categories the developer already
9
+ * declared to Firefox. A paid extension holding only `storage` therefore got
10
+ * "no Privacy-practices questions" (DX report 2026-10-10, §2 row 8). This
11
+ * module reads those flows from the package and turns them into the same kind
12
+ * of output: QUESTIONS for the dashboard, with the evidence next to each one —
13
+ * never a verdict written on the developer's behalf.
14
+ *
15
+ * Store rules this module encodes, with their sources:
16
+ * - CWS "Privacy practices": data types are disclosed on the dashboard and
17
+ * must match the privacy policy —
18
+ * https://developer.chrome.com/docs/webstore/cws-dashboard-privacy
19
+ * - CWS user data covers data processed or stored only on the device, web
20
+ * browsing activity includes "the domains or URLs the browser interacts
21
+ * with", account numbers are personally identifiable information, and a
22
+ * product that keeps user data only in `storage.sync` still needs a privacy
23
+ * policy — User Data FAQ #3, #4, #14:
24
+ * https://developer.chrome.com/docs/webstore/program-policies/user-data-faq
25
+ * - CWS Limited Use certification —
26
+ * https://developer.chrome.com/docs/webstore/program-policies/limited-use
27
+ * - Edge: Partner Center's Privacy page has a Data usage section and needs a
28
+ * privacy policy URL once personal information is accessed, transmitted or
29
+ * collected — https://learn.microsoft.com/en-us/microsoft-edge/extensions/publish/publish-extension
30
+ * - AMO: "data transmission" is data handled outside the add-on or the local
31
+ * browser; `required` holds `none` OR categories; `technicalAndInteraction`
32
+ * can only be optional —
33
+ * https://extensionworkshop.com/documentation/develop/firefox-builtin-data-consent/ and
34
+ * https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/manifest.json/browser_specific_settings
35
+ * - AMO: listings must disclose when payment is required to enable any
36
+ * functionality; data from private browsing sessions must not be stored —
37
+ * https://extensionworkshop.com/documentation/publish/add-on-policies/
38
+ */
39
+ import { detectMinifiedFiles } from './amo-source-detect.js';
40
+ import { readLocaleMessages } from './listing.js';
41
+ import { privacyPracticesForManifest, resolveMessage } from './review-checks.js';
42
+ const CODE_FILE_RE = /\.(?:m?js|cjs|html?)$/i;
43
+ /**
44
+ * The names `extenshi-pay-sdk/rollup.config.js` and
45
+ * `extenshi-storage-sdk/rollup.config.js` pass to their build banner
46
+ * (`/*! <name> v<semver> … commit <sha> · built by \`<cmd>\` *\/`), and the
47
+ * file names a vendored copy usually keeps. Either is enough: a bundler may
48
+ * keep the banner but rename the file, or a hand-vendored copy may lose it.
49
+ */
50
+ const SDKS = [
51
+ { kind: 'pay', banner: 'ExtenshiPay SDK', file: /(?:^|\/)extenshi-pay[^/]*\.m?js$/i },
52
+ { kind: 'storage', banner: 'ExtenshiStorage SDK', file: /(?:^|\/)extenshi-storage[^/]*\.m?js$/i },
53
+ ];
54
+ /** A Pay publishable key literal (`pk_ext_` + 32 hex) — the SDK cannot run without one. */
55
+ const PAY_KEY_RE = /\bpk_ext_[0-9a-f]{32}\b/;
56
+ /**
57
+ * Read a build banner of the shape this repo's SDKs emit, in the first ~2 KB:
58
+ * `<name> v<semver>`, then `commit <sha>`, then `built by <command>`. The same
59
+ * three pieces `amo-source-detect.ts` requires for "has provenance".
60
+ */
61
+ export function parseBuildBanner(content) {
62
+ const head = content.slice(0, 2000);
63
+ const named = /^[\s/*!]*([^\n]{1,80}?)\s+v(\d+\.\d+\.\d+[0-9A-Za-z.+-]*)/m.exec(head);
64
+ if (!named)
65
+ return null;
66
+ const name = named[1].replace(/^[\s/*!]+/, '').trim();
67
+ if (!name)
68
+ return null;
69
+ const rest = head.slice(named.index + named[0].length);
70
+ const commit = /commit\s+([0-9a-f]{7,40})/i.exec(rest)?.[1];
71
+ const built = /built by\s+(?:`([^`]+)`|([^\n*]+?))\s*(?:\*\/|\*|\)|$)/im.exec(rest);
72
+ const buildCommand = (built?.[1] ?? built?.[2])?.trim();
73
+ return { name, version: named[2], ...(commit ? { commit } : {}), ...(buildCommand ? { buildCommand } : {}) };
74
+ }
75
+ function detectSdkBundles(files) {
76
+ const out = [];
77
+ for (const [path, content] of files) {
78
+ if (!/\.(?:m?js|cjs)$/i.test(path))
79
+ continue;
80
+ for (const sdk of SDKS) {
81
+ const at = content.indexOf(`${sdk.banner} v`);
82
+ if (at < 0 && !sdk.file.test(path))
83
+ continue;
84
+ // From the name on: a bundler may inline the banner after other code.
85
+ const banner = at >= 0 ? parseBuildBanner(content.slice(at)) : null;
86
+ out.push({ kind: sdk.kind, path, ...(banner ?? {}) });
87
+ break;
88
+ }
89
+ }
90
+ return out.sort((a, b) => a.path.localeCompare(b.path));
91
+ }
92
+ const STORAGE_AREA_RE = /\bstorage\s*\.\s*(sync|local|session|managed)\b/g;
93
+ /**
94
+ * Hosts named in `http(s)://` literals. Namespace URIs (`www.w3.org/2000/svg`),
95
+ * loopback and documentation domains are never requests; everything else is
96
+ * listed as found — a link the user opens and a request that carries data look
97
+ * the same to a static read, so the developer decides which is which.
98
+ */
99
+ const URL_HOST_RE = /\bhttps?:\/\/([a-z0-9](?:[a-z0-9-]*[a-z0-9])?(?:\.[a-z0-9](?:[a-z0-9-]*[a-z0-9])?)+)/gi;
100
+ const NOT_A_DESTINATION_RE = /(?:^|\.)(?:w3\.org|example\.(?:com|org|net))$|^(?:localhost|127\.0\.0\.1|0\.0\.0\.0)$/;
101
+ /** `/*! … *\/` licence/build banners at the top of a bundle name their homepage, not a destination. */
102
+ function withoutLeadingBanner(content) {
103
+ return content.replace(/^\s*\/\*[\s\S]*?\*\//, '');
104
+ }
105
+ function strings(raw) {
106
+ return Array.isArray(raw) ? raw.filter((v) => typeof v === 'string' && v.trim() !== '') : [];
107
+ }
108
+ export function detectDataFlows(manifest, files, opts = {}) {
109
+ const storage = new Map();
110
+ const hosts = new Map();
111
+ const payKeyFiles = [];
112
+ for (const [path, content] of files) {
113
+ if (!CODE_FILE_RE.test(path))
114
+ continue;
115
+ for (const m of content.matchAll(STORAGE_AREA_RE)) {
116
+ const area = m[1];
117
+ storage.set(area, (storage.get(area) ?? new Set()).add(path));
118
+ }
119
+ for (const m of withoutLeadingBanner(content).matchAll(URL_HOST_RE)) {
120
+ const host = m[1].toLowerCase();
121
+ if (NOT_A_DESTINATION_RE.test(host))
122
+ continue;
123
+ hosts.set(host, (hosts.get(host) ?? new Set()).add(path));
124
+ }
125
+ if (PAY_KEY_RE.test(content))
126
+ payKeyFiles.push(path);
127
+ }
128
+ const sdks = detectSdkBundles(files);
129
+ const dcp = manifest.browser_specific_settings?.gecko?.data_collection_permissions;
130
+ const hasPay = sdks.some((s) => s.kind === 'pay') || payKeyFiles.length > 0;
131
+ const order = ['sync', 'local', 'session', 'managed'];
132
+ return {
133
+ sdks,
134
+ payKeyFiles: payKeyFiles.sort(),
135
+ storage: order
136
+ .filter((area) => storage.has(area))
137
+ .map((area) => ({ area, files: [...storage.get(area)].sort() })),
138
+ hosts: [...hosts.entries()]
139
+ .map(([host, where]) => ({ host, files: [...where].sort() }))
140
+ .sort((a, b) => a.host.localeCompare(b.host)),
141
+ firefoxDataCollection: dcp ? { required: strings(dcp.required), optional: strings(dcp.optional) } : null,
142
+ paid: opts.payment ? opts.payment === 'required' : hasPay,
143
+ };
144
+ }
145
+ // ── Formatting helpers ───────────────────────────────────────────────────────
146
+ function fileList(files, max = 3) {
147
+ const shown = files.slice(0, max).map((f) => `\`${f}\``);
148
+ return files.length > max ? `${shown.join(', ')} +${files.length - max} more` : shown.join(', ');
149
+ }
150
+ function sdkLabel(sdk) {
151
+ const name = sdk.name ?? (sdk.kind === 'pay' ? 'ExtenshiPay SDK' : 'ExtenshiStorage SDK');
152
+ return sdk.version ? `${name} v${sdk.version}` : name;
153
+ }
154
+ function paySdk(flows) {
155
+ return flows.sdks.find((s) => s.kind === 'pay');
156
+ }
157
+ /** "ExtenshiPay SDK v0.8.0 (`libs/extenshi-pay.esm.min.js`)", or the key that proves it is wired in. */
158
+ export function payEvidence(flows) {
159
+ const sdk = paySdk(flows);
160
+ if (sdk)
161
+ return `${sdkLabel(sdk)} (\`${sdk.path}\`)`;
162
+ if (flows.payKeyFiles.length > 0)
163
+ return `an ExtenshiPay publishable key (${fileList(flows.payKeyFiles)})`;
164
+ return null;
165
+ }
166
+ const PAY_SDK_SENDS = 'https://docs.extenshi.io/developers/pay-sdk#what-the-sdk-sends';
167
+ // ── CWS / Edge "Data usage" ──────────────────────────────────────────────────
168
+ /**
169
+ * Firefox data_collection_permissions category → the Chrome Web Store data type
170
+ * covering the same data. Only categories whose definitions line up one to one
171
+ * (Extension Workshop's taxonomy vs the CWS dashboard list); `searchTerms` and
172
+ * `bookmarksInfo` have no CWS counterpart and are reported as declared instead.
173
+ */
174
+ const FIREFOX_TO_CWS = {
175
+ personallyIdentifyingInfo: 'Personally identifiable information',
176
+ healthInfo: 'Health information',
177
+ financialAndPaymentInfo: 'Financial and payment information',
178
+ authenticationInfo: 'Authentication information',
179
+ personalCommunications: 'Personal communications',
180
+ locationInfo: 'Location',
181
+ browsingActivity: 'Web history',
182
+ websiteActivity: 'User activity',
183
+ websiteContent: 'Website content',
184
+ };
185
+ /**
186
+ * Data-usage questions for CWS / Edge, from permissions (the existing
187
+ * checklist), the Pay SDK, storage areas and the Firefox declaration.
188
+ */
189
+ export function buildDataUsage(manifest, flows) {
190
+ const rows = new Map();
191
+ const add = (dataType, certain, reason) => {
192
+ const row = rows.get(dataType) ?? { dataType, certain, reasons: [] };
193
+ // Once a type certainly applies, its "if …" reasons no longer qualify it.
194
+ if (certain && !row.certain) {
195
+ row.certain = true;
196
+ row.reasons = [];
197
+ }
198
+ else if (!certain && row.certain)
199
+ return;
200
+ row.reasons.push(reason);
201
+ rows.set(dataType, row);
202
+ };
203
+ for (const { dataType, permission } of privacyPracticesForManifest(manifest)) {
204
+ add(dataType, true, `the \`${permission}\` permission — its API reads this data`);
205
+ }
206
+ const pay = payEvidence(flows);
207
+ if (pay) {
208
+ add('Financial and payment information', true, `${pay} creates checkouts and checks this installation's purchase and license with the Extenshi API`);
209
+ add('Personally identifiable information', false, 'if you treat the random installation id the Pay SDK ties each purchase to (`endUserRef`) as the ' +
210
+ "buyer's account — CWS counts account numbers as personally identifiable information");
211
+ add('Authentication information', false, 'if license recovery is enabled for your app — the Pay SDK then sends a claim secret held by the installation');
212
+ }
213
+ const kept = flows.storage.filter((s) => s.area !== 'managed');
214
+ if (kept.length > 0) {
215
+ add('Web history', false, `if what you keep in ${kept.map((s) => `\`storage.${s.area}\``).join(' / ')} includes hostnames or ` +
216
+ 'URLs (for example per-site settings) — CWS counts the domains a user visits as web browsing ' +
217
+ 'activity even when the data never leaves the device');
218
+ }
219
+ const declared = flows.firefoxDataCollection;
220
+ for (const [list, values] of [
221
+ ['required', declared?.required ?? []],
222
+ ['optional', declared?.optional ?? []],
223
+ ]) {
224
+ for (const category of values) {
225
+ const dataType = FIREFOX_TO_CWS[category];
226
+ if (dataType)
227
+ add(dataType, true, `declared to Firefox as \`${category}\` (\`data_collection_permissions.${list}\`)`);
228
+ }
229
+ }
230
+ const facts = [];
231
+ for (const sdk of flows.sdks) {
232
+ const provenance = [
233
+ sdk.commit ? `commit ${sdk.commit}` : '',
234
+ sdk.buildCommand ? `built by \`${sdk.buildCommand}\`` : '',
235
+ ]
236
+ .filter(Boolean)
237
+ .join(', ');
238
+ facts.push(`Bundled SDK: ${sdkLabel(sdk)} — \`${sdk.path}\`${provenance ? ` (${provenance})` : ''}`);
239
+ }
240
+ if (pay)
241
+ facts.push('What the Pay SDK sends: a random installation id (`endUserRef`), the SKU, the UI language and checkout ' +
242
+ 'session ids; license recovery adds a claim secret. Card details and the buyer email are entered on ' +
243
+ `hosted pages, not in the extension — ${PAY_SDK_SENDS}`);
244
+ for (const s of flows.storage)
245
+ facts.push(`\`storage.${s.area}\` is used in ${fileList(s.files)}`);
246
+ if (flows.hosts.length > 0)
247
+ facts.push(`Remote hosts named in the code: ${flows.hosts.map((h) => `\`${h.host}\` (${fileList(h.files, 2)})`).join(', ')}. ` +
248
+ 'A page the user opens is not collection; a request that carries user data is.');
249
+ const unmapped = [...(declared?.required ?? []), ...(declared?.optional ?? [])].filter((c) => c !== 'none' && c !== 'technicalAndInteraction' && !FIREFOX_TO_CWS[c]);
250
+ if (unmapped.length > 0)
251
+ facts.push(`Declared to Firefox with no one-to-one Chrome Web Store data type: ${unmapped.map((c) => `\`${c}\``).join(', ')} — decide which type covers it.`);
252
+ const sorted = [...rows.values()].sort((a, b) => Number(b.certain) - Number(a.certain) || a.dataType.localeCompare(b.dataType));
253
+ return { rows: sorted, facts };
254
+ }
255
+ /** Is a privacy policy URL required by what was found? `'conditional'` when only conditional rows exist. */
256
+ export function privacyPolicyNeed(usage) {
257
+ if (usage.rows.some((r) => r.certain))
258
+ return 'required';
259
+ return usage.rows.length > 0 ? 'conditional' : 'none';
260
+ }
261
+ /** The Data usage block shared by CHROMEWEBSTORE.md and EDGE.md. */
262
+ export function renderDataUsage(usage) {
263
+ const lines = [];
264
+ if (usage.rows.length === 0) {
265
+ lines.push('_No data-usage questions follow from the package — no permission, bundled SDK, storage area or ' +
266
+ 'Firefox declaration implies one. Re-check if the extension sends data some other way._');
267
+ }
268
+ else {
269
+ lines.push('Each line is a question the package raises — tick the type only if it is true:', '');
270
+ // Conditional reasons start with "if …"; a row with only those reads "only if …".
271
+ for (const row of usage.rows) {
272
+ lines.push(`- **${row.dataType}** — ${row.certain ? '' : 'only '}${row.reasons.join('; ')}`);
273
+ }
274
+ }
275
+ if (usage.facts.length > 0) {
276
+ lines.push('', 'Found in the package:', '', ...usage.facts.map((f) => `- ${f}`));
277
+ }
278
+ return lines.join('\n');
279
+ }
280
+ // ── AMO data_collection_permissions ──────────────────────────────────────────
281
+ /** MDN `browser_specific_settings` — the values each list may hold. */
282
+ const FIREFOX_PERSONAL_CATEGORIES = [
283
+ 'authenticationInfo',
284
+ 'bookmarksInfo',
285
+ 'browsingActivity',
286
+ 'financialAndPaymentInfo',
287
+ 'healthInfo',
288
+ 'locationInfo',
289
+ 'personalCommunications',
290
+ 'personallyIdentifyingInfo',
291
+ 'searchTerms',
292
+ 'websiteActivity',
293
+ 'websiteContent',
294
+ ];
295
+ const REQUIRED_ALLOWED = new Set(['none', ...FIREFOX_PERSONAL_CATEGORIES]);
296
+ const OPTIONAL_ALLOWED = new Set([...FIREFOX_PERSONAL_CATEGORIES, 'technicalAndInteraction']);
297
+ export function reviewAmoDataCollection(flows) {
298
+ const problems = [];
299
+ const questions = [];
300
+ const declared = flows.firefoxDataCollection;
301
+ const required = declared?.required ?? [];
302
+ const optional = declared?.optional ?? [];
303
+ if (required.includes('none') && required.length > 1)
304
+ problems.push('`required` holds `none` next to other categories — it must be `["none"]` alone or list only the categories collected.');
305
+ if (optional.includes('none'))
306
+ problems.push('`none` is only valid in `required`; remove it from `optional`.');
307
+ if (required.includes('technicalAndInteraction'))
308
+ problems.push('`technicalAndInteraction` can only be `optional` — move it out of `required`.');
309
+ const unknownRequired = required.filter((c) => !REQUIRED_ALLOWED.has(c) && c !== 'technicalAndInteraction');
310
+ const unknownOptional = optional.filter((c) => !OPTIONAL_ALLOWED.has(c) && c !== 'none');
311
+ for (const [list, unknown] of [
312
+ ['required', unknownRequired],
313
+ ['optional', unknownOptional],
314
+ ])
315
+ if (unknown.length > 0)
316
+ problems.push(`\`${list}\` has values Firefox does not know: ${unknown.map((c) => `\`${c}\``).join(', ')}.`);
317
+ const pay = payEvidence(flows);
318
+ const declaresNone = required.length === 1 && required[0] === 'none';
319
+ if (pay && !required.includes('financialAndPaymentInfo') && !optional.includes('financialAndPaymentInfo'))
320
+ questions.push(`${pay} sends purchase and license requests to the Extenshi API — data handled outside the add-on is ` +
321
+ `transmission to AMO. ${declaresNone ? '`none` says nothing leaves the add-on; ' : ''}declare ` +
322
+ '`financialAndPaymentInfo`, or tell the reviewer why it does not apply.');
323
+ if (declaresNone && !pay && flows.hosts.length > 0)
324
+ questions.push(`\`none\` says nothing leaves the add-on, and the code names ${flows.hosts
325
+ .map((h) => `\`${h.host}\``)
326
+ .join(', ')} — if any request there carries user data, declare its category instead.`);
327
+ return { problems, questions };
328
+ }
329
+ // ── Reviewer / certification notes ───────────────────────────────────────────
330
+ /**
331
+ * The keys a macOS tester presses: `MacCtrl` is Control, and plain `Ctrl` — in
332
+ * the `mac` binding or in a `default` used on macOS — becomes Command (Chrome
333
+ * commands API reference, "On macOS Ctrl is automatically converted into
334
+ * Command"). `\bCtrl\b` does not match inside `MacCtrl`.
335
+ */
336
+ function macReading(key) {
337
+ return key.replace(/\bCtrl\b/g, 'Command').replace(/\bMacCtrl\b/g, 'Control');
338
+ }
339
+ /** Publisher's `amoListingSchema` caps `approvalNotes` at 3,000 characters. */
340
+ export const AMO_APPROVAL_NOTES_MAX = 3000;
341
+ /** Long lists in a note are summarised; the AMO "Source code" section keeps the full inventory. */
342
+ const MAX_LISTED = 5;
343
+ function shortcutFacts(manifest, files) {
344
+ const commands = manifest.commands;
345
+ if (!commands || typeof commands !== 'object' || Array.isArray(commands))
346
+ return [];
347
+ const locale = typeof manifest.default_locale === 'string' ? manifest.default_locale : undefined;
348
+ let messages = null;
349
+ const describe = (raw) => {
350
+ if (typeof raw !== 'string' || !raw.trim())
351
+ return undefined;
352
+ const placeholder = /^__MSG_([A-Za-z0-9_@]+)__$/.exec(raw.trim());
353
+ if (!placeholder)
354
+ return raw.trim();
355
+ // Parsed once, and only when a description is localized.
356
+ if (messages === null)
357
+ messages = locale ? readLocaleMessages(files).get(locale) : undefined;
358
+ return messages ? resolveMessage(messages, placeholder[1])?.trim() : undefined;
359
+ };
360
+ const out = [];
361
+ for (const [name, raw] of Object.entries(commands)) {
362
+ if (!raw || typeof raw !== 'object')
363
+ continue;
364
+ const cmd = raw;
365
+ const keys = cmd.suggested_key && typeof cmd.suggested_key === 'object' ? cmd.suggested_key : {};
366
+ const def = typeof keys.default === 'string' ? keys.default : undefined;
367
+ const mac = typeof keys.mac === 'string' ? keys.mac : undefined;
368
+ if (!def && !mac)
369
+ continue;
370
+ const label = describe(cmd.description) ?? `\`${name}\``;
371
+ const macKey = macReading(mac ?? def);
372
+ if (!def)
373
+ out.push(`${label} — macOS ${macKey}`);
374
+ else
375
+ out.push(`${label} — ${def}${macKey !== def ? ` (macOS: ${macKey})` : ''}`);
376
+ }
377
+ return out;
378
+ }
379
+ function summarised(items) {
380
+ return items.length > MAX_LISTED
381
+ ? `${items.slice(0, MAX_LISTED).join('; ')}; +${items.length - MAX_LISTED} more`
382
+ : items.join('; ');
383
+ }
384
+ /** Keep the facts, in order, that fit `max` characters as `- ` bullets; say so when some do not. */
385
+ function fitFacts(facts, max) {
386
+ const trimmed = `Trimmed to the ${max}-character reviewer-notes limit — the rest is in the sections above.`;
387
+ const size = (list) => list.map((f) => `- ${f}`).join('\n').length;
388
+ if (size(facts) <= max)
389
+ return [...facts];
390
+ const out = [];
391
+ for (const fact of facts) {
392
+ if (size([...out, fact, trimmed]) > max)
393
+ break;
394
+ out.push(fact);
395
+ }
396
+ return [...out, trimmed];
397
+ }
398
+ /**
399
+ * Reviewer / certification notes: payment, private browsing, keyboard
400
+ * shortcuts as macOS testers press them, and vendored minified files with the
401
+ * provenance their build banner states.
402
+ */
403
+ export function buildReviewerNotes(manifest, files, flows, opts = {}) {
404
+ const facts = [];
405
+ const prompts = [];
406
+ if (flows.paid) {
407
+ const pay = payEvidence(flows);
408
+ facts.push(pay
409
+ ? `Payments: ${pay} handles checkout and licensing; some features need a purchase.`
410
+ : 'Payments: some features need a purchase.');
411
+ prompts.push('How a reviewer reaches the paid features: trial length, a test license, or which features stay free.');
412
+ }
413
+ if (typeof manifest.incognito === 'string') {
414
+ facts.push(`Private browsing: the manifest sets \`"incognito": "${manifest.incognito}"\`.`);
415
+ prompts.push('What the extension does in private windows — and that nothing from them is stored.');
416
+ }
417
+ const shortcuts = shortcutFacts(manifest, files);
418
+ if (shortcuts.length > 0)
419
+ facts.push(`Keyboard shortcuts: ${summarised(shortcuts)}.`);
420
+ const minified = detectMinifiedFiles(files);
421
+ const withBanner = [];
422
+ const withoutBanner = [];
423
+ for (const f of minified) {
424
+ const banner = f.hasProvenanceBanner ? parseBuildBanner(files.get(f.path) ?? '') : null;
425
+ if (!banner) {
426
+ withoutBanner.push(`\`${f.path}\``);
427
+ continue;
428
+ }
429
+ const provenance = [
430
+ banner.commit ? `commit ${banner.commit}` : '',
431
+ banner.buildCommand ? `built by \`${banner.buildCommand}\`` : '',
432
+ ]
433
+ .filter(Boolean)
434
+ .join(', ');
435
+ withBanner.push(`\`${f.path}\` is ${banner.name} v${banner.version}${provenance ? ` (${provenance})` : ''}`);
436
+ }
437
+ if (withBanner.length > 0)
438
+ facts.push(`Minified vendored files: ${summarised(withBanner)}.`);
439
+ if (withoutBanner.length > 0)
440
+ prompts.push(`Where the source of ${withoutBanner.join(', ')} is: a path in the source archive (e.g. \`vendor-src/<name>/\`), or the upstream package and version.`);
441
+ if (opts.lint)
442
+ prompts.push('Warnings from `web-ext lint` you are not fixing (for example in a vendored SDK) — each with the reason.');
443
+ return { facts: opts.maxFactsChars ? fitFacts(facts, opts.maxFactsChars) : facts, prompts };
444
+ }
445
+ /** Facts as bullets, then prompts as guidance lines, then the store's own closing guidance. */
446
+ export function renderReviewerNotes(notes, closing) {
447
+ const blocks = [];
448
+ if (notes.facts.length > 0)
449
+ blocks.push(notes.facts.map((f) => `- ${f}`).join('\n'));
450
+ for (const p of [...notes.prompts, closing])
451
+ blocks.push(`_${p}_`);
452
+ return blocks.join('\n\n');
453
+ }
454
+ //# sourceMappingURL=listing-data-flows.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"listing-data-flows.js","sourceRoot":"","sources":["../src/listing-data-flows.ts"],"names":[],"mappings":"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"}
package/dist/listing.d.ts CHANGED
@@ -58,6 +58,19 @@ export interface Listing {
58
58
  * wrote.
59
59
  */
60
60
  appliesToAllLocales?: boolean;
61
+ /**
62
+ * True when a per-locale draft did not say which locale is the default, so
63
+ * `defaultLocale` is our guess. `mergeListings` then lets the package's own
64
+ * `default_locale` decide: alphabetical order once made `ar` the default of
65
+ * an English-first listing.
66
+ */
67
+ defaultLocaleInferred?: boolean;
68
+ /**
69
+ * Problems with the input that did not stop the check but change what it
70
+ * read — text that was ignored, a default that was guessed. Reported next to
71
+ * the findings so a clean result is not mistaken for a full one.
72
+ */
73
+ warnings?: string[];
61
74
  }
62
75
  interface MessagesFile {
63
76
  [key: string]: {
@@ -90,6 +103,12 @@ export declare function listingFromArtifact(manifest: Manifest, files: FileMap):
90
103
  * { "name": "…", "shortDescription": "…", "description": "…" }
91
104
  * { "defaultLocale": "en", "locales": { "en": { … }, "ru": { … } } }
92
105
  *
106
+ * They do not mix. With `locales` present every locale — the default one
107
+ * included — has to sit inside it, and top-level text is ignored with a
108
+ * warning: applying it to a locale would mean guessing which one the developer
109
+ * meant, and checking the guess would report findings against the wrong
110
+ * translation.
111
+ *
93
112
  * Throws on a file that is not an object or that yields no usable text — unlike
94
113
  * the artifact path, the developer explicitly pointed at this file, so silence
95
114
  * would look like a passing check.
@@ -120,6 +139,35 @@ export declare function listingFromCatalog(text: {
120
139
  shortDescription?: string;
121
140
  description?: string;
122
141
  }): Listing | null;
142
+ /**
143
+ * Read a multi-locale listing markdown — the one-file-per-project shape:
144
+ *
145
+ * ## en (default)
146
+ * - **Name:** Tab Sorter
147
+ * - **Summary:** Groups the tabs in your window by site.
148
+ * - **Description:**
149
+ *
150
+ * The full description, as many paragraphs as it takes.
151
+ *
152
+ * ## ru
153
+ * - **Name:** …
154
+ *
155
+ * Name and Summary are one line each; the Description runs to the next locale
156
+ * heading. Anything before the first locale heading (notes, tables) and any
157
+ * `##` section that carries no labelled field is ignored, which is also what
158
+ * keeps a CHROMEWEBSTORE.md — whose headings are field names, not locales —
159
+ * out of this parser.
160
+ *
161
+ * Returns the same object a per-locale `listing.json` holds, plus what was
162
+ * skipped, or `null` when the file has no locale block at all.
163
+ */
164
+ export declare function listingDraftFromLocalesMd(md: string): {
165
+ draft: {
166
+ defaultLocale?: string;
167
+ locales: Record<string, Record<string, string>>;
168
+ };
169
+ warnings: string[];
170
+ } | null;
123
171
  /**
124
172
  * Assemble the listing to check: the package's localized name/description,
125
173
  * overlaid with the draft file when one was passed.
@@ -1 +1 @@
1
- {"version":3,"file":"listing.d.ts","sourceRoot":"","sources":["../src/listing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE3D,2FAA2F;AAC3F,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAA;AAE5D,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC7B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,OAAO;IACvB,MAAM,EAAE,aAAa,CAAA;IACrB,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC7B;AAUD,UAAU,YAAY;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;CAChD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAe5E;AA8BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAgCtF;AAuBD;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CA8BtD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CAyD/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,GAAG,IAAI,CAkBjB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,OAAO,EACd,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACtB,OAAO,GAAG,IAAI,CA2ChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,OAAO,GACnB,MAAM,EAAE,CAoBV"}
1
+ {"version":3,"file":"listing.d.ts","sourceRoot":"","sources":["../src/listing.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAA;AAE3D,2FAA2F;AAC3F,MAAM,MAAM,aAAa,GAAG,UAAU,GAAG,OAAO,GAAG,SAAS,CAAA;AAE5D,sFAAsF;AACtF,MAAM,WAAW,aAAa;IAC7B,0EAA0E;IAC1E,MAAM,EAAE,MAAM,CAAA;IACd,2BAA2B;IAC3B,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,oFAAoF;IACpF,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,OAAO;IACvB,MAAM,EAAE,aAAa,CAAA;IACrB,kDAAkD;IAClD,aAAa,EAAE,MAAM,CAAA;IACrB,sDAAsD;IACtD,OAAO,EAAE,aAAa,EAAE,CAAA;IACxB;;;;;;;;;;OAUG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;;;;OAKG;IACH,qBAAqB,CAAC,EAAE,OAAO,CAAA;IAC/B;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CACnB;AAUD,UAAU,YAAY;IACrB,CAAC,GAAG,EAAE,MAAM,GAAG;QAAE,OAAO,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,SAAS,CAAA;CAChD;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAe5E;AA8BD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,GAAG,IAAI,CAgCtF;AA6CD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAqEtD;AAED;;;;;;;GAOG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,EAAE,KAAK,EAAE,OAAO,GAAG,OAAO,CA8D/E;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE;IACxC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,WAAW,CAAC,EAAE,MAAM,CAAA;CACpB,GAAG,OAAO,GAAG,IAAI,CAkBjB;AAiBD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,MAAM,GAAG;IACtD,KAAK,EAAE;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;KAAE,CAAA;IAClF,QAAQ,EAAE,MAAM,EAAE,CAAA;CAClB,GAAG,IAAI,CAgEP;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC9B,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,OAAO,EACd,WAAW,CAAC,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,OAAO,GAAG,IAAI,GACtB,OAAO,GAAG,IAAI,CAmDhB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CACnC,OAAO,EAAE,OAAO,GAAG,IAAI,EACvB,WAAW,CAAC,EAAE,MAAM,EACpB,WAAW,CAAC,EAAE,OAAO,GACnB,MAAM,EAAE,CAoBV"}