extension-develop 4.0.16 → 4.0.17

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/dist/101.mjs CHANGED
@@ -7,6 +7,7 @@ import { fetchExtensionFromStore } from "extension-from-store";
7
7
  import node_fs from "node:fs";
8
8
  import node_path from "node:path";
9
9
  import { getSpecialFoldersData } from "browser-extension-manifest-fields";
10
+ import { fmt, isDebug, artifactNoun as messaging_artifactNoun, prefix as messaging_prefix, card } from "./349.mjs";
10
11
  import { stripBom, parseJsonSafe } from "./23.mjs";
11
12
  import { findNearestDenoConfigSync, validateDenoConfig, PROJECT_MANIFEST_FILENAMES, readProjectDependencies } from "./80.mjs";
12
13
  import { readyContractPath, browserArtifactsDir, eventsPath as session_paths_eventsPath } from "./494.mjs";
@@ -17,72 +18,8 @@ import * as __rspack_external_node_fs_5ea92f0c from "node:fs";
17
18
  import * as __rspack_external_node_os_74b4b876 from "node:os";
18
19
  import * as __rspack_external_node_path_c5b9b54f from "node:path";
19
20
  import * as __rspack_external_node_vm_bd3d9cea from "node:vm";
20
- __rspack_external_node_path_c5b9b54f.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
21
- const CHROMIUM_BASED_BROWSERS = [
22
- 'chrome',
23
- 'edge',
24
- 'brave',
25
- 'opera',
26
- 'vivaldi',
27
- 'yandex'
28
- ];
29
- const GECKO_BASED_BROWSERS = [
30
- 'firefox',
31
- 'waterfox',
32
- 'librewolf'
33
- ];
34
- const CHROMIUM_FAMILY_ALIASES = [
35
- 'chromium',
36
- 'chrome',
37
- 'edge',
38
- 'chromium-based'
39
- ];
40
- const GECKO_FAMILY_ALIASES = [
41
- 'firefox',
42
- 'gecko-based'
43
- ];
44
- [
45
- ...CHROMIUM_BASED_BROWSERS,
46
- ...GECKO_BASED_BROWSERS
47
- ];
48
- function isChromiumBasedBrowser(browser) {
49
- return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
50
- }
51
- function constants_isGeckoBasedBrowser(browser) {
52
- return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
53
- }
54
- const fmt = {
55
- heading: (title)=>pintor.underline(pintor.blue(title)),
56
- label: (key)=>pintor.gray(key.toUpperCase()),
57
- val: (value)=>pintor.underline(value),
58
- code: (value)=>pintor.blue(value),
59
- bullet: (value)=>`- ${value}`,
60
- block (title, rows) {
61
- const head = fmt.heading(title);
62
- const body = rows.map(([key, value])=>`${fmt.label(key)} ${value}`).join('\n');
63
- return `${head}\n${body}`;
64
- },
65
- truncate (input, max = 800) {
66
- const s = (()=>{
67
- try {
68
- return 'string' == typeof input ? input : JSON.stringify(input);
69
- } catch {
70
- return String(input);
71
- }
72
- })();
73
- return s.length > max ? `${s.slice(0, max)}…` : s;
74
- }
75
- };
76
21
  function getLoggingPrefix(type) {
77
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
78
- if (isAuthor) {
79
- const base = 'error' === type ? 'ERROR Author says' : '⏵⏵⏵ Author says';
80
- return pintor.brightMagenta(base);
81
- }
82
- if ('error' === type) return pintor.red('ERROR');
83
- if ('warn' === type) return pintor.brightYellow('⏵⏵⏵');
84
- if ('info' === type) return pintor.gray('⏵⏵⏵');
85
- return pintor.green('⏵⏵⏵');
22
+ return messaging_prefix(type);
86
23
  }
87
24
  function isPathLike(input) {
88
25
  return input.includes('/') || input.includes('\\') || __rspack_external_node_path_c5b9b54f.isAbsolute(input);
@@ -91,17 +28,17 @@ function resolvedWorkspaceManifest(projectPath, manifestPath) {
91
28
  const manifestDir = __rspack_external_node_path_c5b9b54f.dirname(manifestPath);
92
29
  const packageDir = 'src' === __rspack_external_node_path_c5b9b54f.basename(manifestDir) ? __rspack_external_node_path_c5b9b54f.dirname(manifestDir) : manifestDir;
93
30
  const display = __rspack_external_node_path_c5b9b54f.relative(projectPath, packageDir) || packageDir;
94
- return `${getLoggingPrefix('info')} ${pintor.gray('Workspace root detected, resolved extension package:')} ${pintor.brightBlue(display)}`;
31
+ return `${getLoggingPrefix('info')} ${pintor.gray('Workspace root detected.')}\n${pintor.gray('PACKAGE')} ${pintor.brightBlue(display)}`;
95
32
  }
96
33
  function remoteFetchTimedOut(target, ms) {
97
34
  return `${getLoggingPrefix('error')} Timed out after ${pintor.yellow(`${Math.round(ms / 1000)}s`)} fetching ${pintor.underline(target)}.\n${pintor.red('Check your network, or set EXTENSION_FETCH_TIMEOUT_MS to allow more time.')}`;
98
35
  }
99
36
  function manifestInvalidJson(manifestPath, error) {
100
37
  const detail = error instanceof Error ? error.message : String(error);
101
- return `${getLoggingPrefix('error')} Could not parse manifest.json. It is not valid JSON.\n${pintor.red('Fix the syntax error and try again.')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\n${pintor.red(detail)}`;
38
+ return `${getLoggingPrefix('error')} Could not parse manifest.json.\nIt is not valid JSON.\n${pintor.red('Fix the syntax error and try again.')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}\n${pintor.red(detail)}`;
102
39
  }
103
40
  function notAnExtensionManifestError(manifestPath) {
104
- return `${getLoggingPrefix('error')} manifest.json is not a browser extension manifest. It has no ${pintor.yellow('manifest_version')} field.\n${pintor.red('This looks like a PWA web-app manifest. Point Extension.js at the directory that contains your extension manifest.')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}`;
41
+ return `${getLoggingPrefix('error')} manifest.json is not a browser extension manifest.\nIt has no ${pintor.yellow('manifest_version')} field.\n${pintor.red('This looks like a PWA web-app manifest.')}\n${pintor.red('Point Extension.js at the directory that contains your extension manifest.')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}`;
105
42
  }
106
43
  function manifestNotFoundError(manifestPath, candidates = []) {
107
44
  const base = `${getLoggingPrefix('error')} Manifest file not found.\n${pintor.red('Ensure the path to your extension exists and try again.')}\n${pintor.red('NOT FOUND')}\n${pintor.gray('PATH')} ${pintor.underline(manifestPath)}`;
@@ -117,13 +54,13 @@ function manifestNotFoundError(manifestPath, candidates = []) {
117
54
  return `${base}\n\n${pintor.gray(hint)}\n${pintor.brightBlue(suggestions)}`;
118
55
  }
119
56
  function previewing(browser) {
120
- return `${getLoggingPrefix('info')} Previewing the extension on ${capitalizedBrowserName(browser)}...`;
57
+ return `${getLoggingPrefix('info')} Preview the extension on ${capitalizedBrowserName(browser)}.`;
121
58
  }
122
59
  function previewSkippedNoBrowser(browser) {
123
- return `${getLoggingPrefix('info')} Skipping browser launch for ${capitalizedBrowserName(browser)} (no-browser).`;
60
+ return `${getLoggingPrefix('info')} Skip the browser launch for ${capitalizedBrowserName(browser)} (no-browser).`;
124
61
  }
125
62
  function extensionLoadRecovered() {
126
- return `${getLoggingPrefix('success')} The browser accepted the extension. It is running now.`;
63
+ return `${getLoggingPrefix('success')} The browser accepted the extension.\nIt is running now.`;
127
64
  }
128
65
  function extensionLoadStillRefused(reason) {
129
66
  return `${getLoggingPrefix('error')} The browser still refuses to load this extension.\n${pintor.gray('REASON')} ${pintor.red(reason)}`;
@@ -132,13 +69,13 @@ function browserLaunchFailed(browser, reason) {
132
69
  return `${getLoggingPrefix('error')} ${capitalizedBrowserName(browser)} could not be started, so the extension is NOT running.\n${reason}\nThe dev server keeps watching, but nothing will load until this is fixed.`;
133
70
  }
134
71
  function authorInstallNotice(target) {
135
- return `${getLoggingPrefix('warn')} Author mode: installing ${target}.`;
72
+ return `${messaging_prefix('debug')} install target=${target}`;
136
73
  }
137
74
  function projectInstallFallbackToNpm(pmName) {
138
- return `${getLoggingPrefix('warn')} Dependency install with ${pmName} failed. Retrying once with npm so the build can continue.`;
75
+ return `${getLoggingPrefix('warn')} Dependency install with ${pmName} failed.\nExtension.js retries once with npm so the build can continue.`;
139
76
  }
140
77
  function projectInstallScriptsDisabled(pmName) {
141
- return `${getLoggingPrefix('info')} Installing project dependencies with ${pmName}. Lifecycle scripts are disabled for safety, set EXTENSION_ALLOW_INSTALL_SCRIPTS=true to run them.`;
78
+ return `${getLoggingPrefix('info')} Install the project dependencies with ${pmName}.\nLifecycle scripts are disabled for safety.\nSet EXTENSION_ALLOW_INSTALL_SCRIPTS=true to run them.`;
142
79
  }
143
80
  function buildWebpack(projectDir, stats, browser) {
144
81
  const statsJson = stats?.toJson?.({
@@ -159,7 +96,7 @@ function buildWebpack(projectDir, stats, browser) {
159
96
  };
160
97
  }
161
98
  const assets = statsJson?.assets || [];
162
- const heading = `${getLoggingPrefix('info')} Building ${pintor.blue(manifest.name)} extension using ${capitalizedBrowserName(browser)} defaults...\n`;
99
+ const heading = `${getLoggingPrefix('info')} Build ${pintor.blue(manifest.name)} with the ${capitalizedBrowserName(browser)} defaults.\n`;
163
100
  const buildTime = `\nBuild completed in ${((statsJson?.time || 0) / 1000).toFixed(2)} seconds.\n`;
164
101
  const buildTarget = `Build Target: ${pintor.gray(capitalizedBrowserName(browser))}\n`;
165
102
  const buildStatus = `Build Status: ${stats?.hasErrors?.() ? pintor.red('Failed') : pintor.green('Success')}\n`;
@@ -176,7 +113,7 @@ function buildWebpack(projectDir, stats, browser) {
176
113
  return output;
177
114
  }
178
115
  function buildSuccess() {
179
- return `${getLoggingPrefix('success')} Build succeeded with no warnings. Your extension is ${pintor.green('ready for deployment')}.`;
116
+ return `${getLoggingPrefix('success')} Build succeeded with no warnings.\nYour extension is ${pintor.green('ready for deployment')}.`;
180
117
  }
181
118
  function getWarningMessage(warning) {
182
119
  if (!warning) return '';
@@ -230,7 +167,7 @@ function suggestedHintForWarning(category) {
230
167
  return 'Re-run with EXTENSION_VERBOSE=1 to inspect full warning details.';
231
168
  }
232
169
  function buildSuccessWithWarnings(warningCount) {
233
- return `${getLoggingPrefix('warn')} Build succeeded with ${warningCount} warning(s). Your extension is ${pintor.green('ready for deployment')}.`;
170
+ return `${getLoggingPrefix('warn')} Build succeeded with ${warningCount} warning(s).\nYour extension is ${pintor.green('ready for deployment')}.`;
234
171
  }
235
172
  function buildWarningsDetails(warnings) {
236
173
  if (!Array.isArray(warnings) || 0 === warnings.length) return '';
@@ -251,7 +188,7 @@ function buildWarningsDetails(warnings) {
251
188
  return blocks.join('\n\n');
252
189
  }
253
190
  function fetchingProjectPath(owner, project) {
254
- return fmt.block('Fetching project', [
191
+ return fmt.block('Fetch project', [
255
192
  [
256
193
  'URL',
257
194
  fmt.val(`https://github.com/${owner}/${project}`)
@@ -260,37 +197,37 @@ function fetchingProjectPath(owner, project) {
260
197
  }
261
198
  function downloadingProjectPath(projectName) {
262
199
  const formatted = isPathLike(projectName) ? pintor.underline(projectName) : pintor.yellow(projectName);
263
- return `${getLoggingPrefix('info')} Downloading ${formatted}...`;
200
+ return `${getLoggingPrefix('info')} Download ${formatted}.`;
264
201
  }
265
202
  function creatingProjectPath(projectPath) {
266
- return `${getLoggingPrefix('info')} Creating a new browser extension...\n${pintor.gray('PATH')} ${pintor.underline(projectPath)}`;
203
+ return `${getLoggingPrefix('info')} Create a new browser extension.\n${pintor.gray('PATH')} ${pintor.underline(projectPath)}`;
267
204
  }
268
205
  function downloadedProjectFolderNotFound(cwd, candidates) {
269
206
  return `${getLoggingPrefix('error')} Downloaded project folder not found.\n${pintor.gray('PATH')} ${pintor.underline(cwd)}\n${pintor.gray('Tried')} ${pintor.underline(candidates.join(', '))}`;
270
207
  }
271
208
  function packagingSourceFiles(zipPath) {
272
- return `${getLoggingPrefix('info')} Packaging source files. Files in ${pintor.yellow('.gitignore')} will be excluded...\n${pintor.gray('PATH')} ${pintor.underline(zipPath)}.`;
209
+ return `${messaging_prefix('debug')} zip pack=source gitignore=excluded path=${zipPath}`;
273
210
  }
274
211
  function packagingDistributionFiles(zipPath) {
275
- return `${getLoggingPrefix('info')} Packaging extension distribution files...\n${pintor.gray('PATH')} ${pintor.underline(zipPath)}`;
212
+ return `${messaging_prefix('debug')} zip pack=dist path=${zipPath}`;
276
213
  }
277
214
  function treeWithSourceAndDistFiles(browser, name, sourceZip, destZip) {
278
- return `📦 Package name: ${pintor.blue(`${name}`)}, Target Browser: ${capitalizedBrowserName(browser)}\n ${pintor.gray('└─')} ${pintor.underline(`${sourceZip}`)} ${pintor.gray('(source)')}\n ${pintor.gray('└─')} ${pintor.underline(`${destZip}`)} ${pintor.gray('(distribution)')}`;
215
+ return `${messaging_prefix('debug')} zip name=${name} browser=${String(browser)} source=${sourceZip} dist=${destZip}`;
279
216
  }
280
217
  function treeWithDistFilesbrowser(name, ext, browser, zipPath) {
281
- return `📦 Package name: ${pintor.blue(`${name}.${ext}`)}, Target Browser: ${capitalizedBrowserName(browser)}\n ${pintor.gray('└─')} ${pintor.underline(`${zipPath}`)} ${pintor.gray('(distribution)')}`;
218
+ return `${messaging_prefix('debug')} zip name=${name}.${ext} browser=${String(browser)} dist=${zipPath}`;
282
219
  }
283
220
  function treeWithSourceFiles(name, ext, browser, zipPath) {
284
- return `📦 Package name: ${pintor.blue(`${name}-source.${ext}`)}, Target Browser: ${capitalizedBrowserName(browser)}\n ${pintor.gray('└─')} ${pintor.underline(`${zipPath}`)} ${pintor.gray('(source)')}`;
221
+ return `${messaging_prefix('debug')} zip name=${name}-source.${ext} browser=${String(browser)} source=${zipPath}`;
285
222
  }
286
223
  function writingTypeDefinitions(manifest) {
287
- return `${getLoggingPrefix('info')} Writing type definitions for ${pintor.blue(manifest.name || '')}...`;
224
+ return `${getLoggingPrefix('info')} Write the type definitions for ${pintor.blue(manifest.name || '')}.`;
288
225
  }
289
226
  function writingTypeDefinitionsError(error) {
290
- return `${getLoggingPrefix('error')} Failed to write the extension type definition.\n${pintor.red(String(error))}`;
227
+ return `${getLoggingPrefix('error')} Failed to write the extension type definition.\nCheck the file permissions, then try again.\n${pintor.red(String(error))}`;
291
228
  }
292
229
  function downloadingText(url) {
293
- return fmt.block('Downloading extension', [
230
+ return fmt.block('Download extension', [
294
231
  [
295
232
  'URL',
296
233
  fmt.val(url)
@@ -298,22 +235,22 @@ function downloadingText(url) {
298
235
  ]);
299
236
  }
300
237
  function unpackagingExtension(zipFilePath) {
301
- return `${getLoggingPrefix('info')} Unpackaging browser extension...\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
238
+ return `${getLoggingPrefix('info')} Unpackage the browser extension.\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
302
239
  }
303
240
  function unpackagedSuccessfully() {
304
241
  return `${getLoggingPrefix('info')} Browser extension unpackaged ${pintor.green('successfully')}.`;
305
242
  }
306
243
  function failedToDownloadOrExtractZIPFileError(error) {
307
- return `${getLoggingPrefix('error')} Failed to download or extract ZIP file.\n${pintor.red(String(error))}`;
244
+ return `${getLoggingPrefix('error')} Failed to download or extract ZIP file.\nCheck the URL and your network, then try again.\n${pintor.red(String(error))}`;
308
245
  }
309
246
  function invalidRemoteZip(url, contentType) {
310
- return `${getLoggingPrefix('error')} Remote URL does not appear to be a ZIP archive.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('Content-Type')} ${pintor.underline(contentType || 'unknown')}`;
247
+ return `${getLoggingPrefix('error')} Remote URL does not appear to be a ZIP archive.\nUse a direct-download URL, or download the file and pass the local path.\n${pintor.gray('URL')} ${pintor.underline(url)}\n${pintor.gray('Content-Type')} ${pintor.underline(contentType || 'unknown')}`;
311
248
  }
312
249
  function notAZipArchive(source, contentType) {
313
- return `${getLoggingPrefix('error')} The downloaded content is not a ZIP archive.\n${pintor.gray('SOURCE')} ${pintor.underline(source)}\n` + (contentType ? `${pintor.gray('Content-Type')} ${pintor.underline(contentType)}\n` : '') + "This usually means the URL requires authentication (for example a Slack, Google Drive, or Dropbox file page) and returned an HTML login page instead of the file. Download the ZIP through the browser and pass the local path instead, or use a direct-download URL.";
250
+ return `${getLoggingPrefix('error')} The downloaded content is not a ZIP archive.\n${pintor.gray('SOURCE')} ${pintor.underline(source)}\n` + (contentType ? `${pintor.gray('Content-Type')} ${pintor.underline(contentType)}\n` : '') + "This usually means the URL requires authentication (for example a Slack, Google Drive, or Dropbox file page) and returned an HTML login " + `page instead of the file.\n` + "Download the ZIP through the browser and pass the local path instead, or use a direct-download URL.";
314
251
  }
315
252
  function localZipNotFound(zipFilePath) {
316
- return `${getLoggingPrefix('error')} ZIP file not found.\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
253
+ return `${getLoggingPrefix('error')} ZIP file not found.\nCheck the path and try again.\n${pintor.gray('PATH')} ${pintor.underline(zipFilePath)}`;
317
254
  }
318
255
  function capitalizedBrowserName(browser) {
319
256
  const b = String(browser || '');
@@ -404,33 +341,31 @@ function getWarningBody(warning) {
404
341
  ].filter((value)=>'string' == typeof value && value.trim().length > 0).join('\n');
405
342
  }
406
343
  function isUsingExperimentalConfig(integration) {
407
- return `${getLoggingPrefix('info')} Using ${pintor.yellow(String(integration))}.`;
344
+ return `${messaging_prefix('debug')} config using=${String(integration)}`;
408
345
  }
409
346
  function debugDirs(manifestDir, packageJsonDir) {
410
- return `${getLoggingPrefix('info')} Directories\n${pintor.gray('MANIFEST_DIR')} ${pintor.underline(manifestDir)}\n${pintor.gray('PACKAGE_JSON_DIR')} ${pintor.underline(packageJsonDir)}`;
347
+ return `${messaging_prefix('debug')} dirs manifest=${manifestDir} pkg=${packageJsonDir}`;
411
348
  }
412
349
  function debugBrowser(browser, chromiumBinary, geckoBinary) {
413
- return `${getLoggingPrefix('info')} Browser Target\n${pintor.gray('BROWSER')} ${pintor.yellow(String(browser))}\n${pintor.gray('CHROMIUM_BINARY')} ${pintor.underline(String(chromiumBinary || 'auto'))}\n${pintor.gray('GECKO_BINARY')} ${pintor.underline(String(geckoBinary || 'auto'))}`;
350
+ return `${messaging_prefix('debug')} browser target=${String(browser)} chromiumBinary=${String(chromiumBinary || 'auto')} geckoBinary=${String(geckoBinary || 'auto')}`;
414
351
  }
415
352
  function debugOutputPath(pathValue) {
416
- return `${getLoggingPrefix('info')} Output Path\n${pintor.gray('PATH')} ${pintor.underline(pathValue)}`;
353
+ return `${messaging_prefix('debug')} output path=${pathValue}`;
417
354
  }
418
355
  function debugPreviewOutput(outputPath, distPath) {
419
- return `${getLoggingPrefix('info')} Preview Output\n${pintor.gray('OUTPUT')} ${pintor.underline(outputPath)}\n${pintor.gray('DIST')} ${pintor.underline(distPath)}`;
356
+ return `${messaging_prefix('debug')} preview output=${outputPath} dist=${distPath}`;
420
357
  }
421
358
  function debugContextPath(packageJsonDir) {
422
- return `${getLoggingPrefix('info')} Context\n${pintor.gray('CONTEXT')} ${pintor.underline(packageJsonDir)}`;
359
+ return `${messaging_prefix('debug')} context path=${packageJsonDir}`;
423
360
  }
424
361
  function debugExtensionsToLoad(extensions) {
425
- const header = `${getLoggingPrefix('info')} Extensions To Load (${extensions.length})`;
426
- const list = extensions.map((e)=>`- ${pintor.underline(e)}`).join('\n');
427
- return `${header}\n${list}`;
362
+ return `${messaging_prefix('debug')} extensions count=${extensions.length} paths=${extensions.join(',')}`;
428
363
  }
429
364
  function noCompanionExtensionsResolved() {
430
365
  return `${getLoggingPrefix('warn')} No companion extensions resolved from ${pintor.underline('extensions')} config.\n${pintor.gray('Ensure each companion extension is an unpacked extension directory containing a manifest.json (e.g., ./extensions/<name>/manifest.json).')}`;
431
366
  }
432
367
  function configLoadingError(configPath, error) {
433
- return `${pintor.red('ERROR')} ${pintor.brightBlue('config load failed')}\n${fmt.label('PATH')} ${fmt.val(configPath)}\n` + pintor.red(fmt.truncate(error, 1200));
368
+ return `${getLoggingPrefix('error')} Could not load ${pintor.brightBlue('extension.config.js')}.\nFix the config file, then run the command again.\n${fmt.label('PATH')} ${fmt.val(configPath)}\n` + pintor.red(fmt.truncate(error, 1200));
434
369
  }
435
370
  function buildCommandFailed(error) {
436
371
  const message = (()=>{
@@ -448,7 +383,7 @@ function devCommandFailed(error) {
448
383
  }
449
384
  function managedDependencyConflict(duplicates, userPackageJsonPath) {
450
385
  const list = duplicates.map((d)=>`- ${pintor.yellow(d)}`).join('\n');
451
- return `${getLoggingPrefix('error')} Your project declares dependencies that are managed by ${pintor.blue('Extension.js')} and referenced in ${pintor.underline('extension.config.js')}\n${pintor.red('This can cause version conflicts and break the development/build process.')}\n\n${pintor.gray('Managed dependencies (remove these from your package.json):')}\n${list}\n\n${pintor.gray('PATH')} ${pintor.underline(userPackageJsonPath)}\nIf you need a different version, open an issue so we can consider bundling it safely.\nOperation aborted.`;
386
+ return `${getLoggingPrefix('error')} Your project declares dependencies that are managed by ${pintor.blue('Extension.js')} and referenced in ${pintor.underline('extension.config.js')}.\n${pintor.red('This can cause version conflicts and break the development/build process.')}\n\n${pintor.gray('Managed dependencies (remove these from your package.json):')}\n${list}\n\n${pintor.gray('PATH')} ${pintor.underline(userPackageJsonPath)}\nIf you need a different version, open an issue so we can consider bundling it safely.\nOperation aborted.`;
452
387
  }
453
388
  function loadCommonJsConfigWithStableDirname(absolutePath) {
454
389
  const code = __rspack_external_node_fs_5ea92f0c.readFileSync(absolutePath, 'utf-8');
@@ -701,14 +636,14 @@ async function config_loader_isUsingExperimentalConfig(projectPath) {
701
636
  const configPath = findConfigFile(projectPath);
702
637
  if (configPath) {
703
638
  if (!userMessageDelivered) {
704
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(isUsingExperimentalConfig('extension.config.js'));
639
+ if (isDebug()) console.log(isUsingExperimentalConfig('extension.config.js'));
705
640
  userMessageDelivered = true;
706
641
  }
707
642
  return true;
708
643
  }
709
644
  return false;
710
645
  }
711
- var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.16","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","acorn":"^8.16.0","adm-zip":"^0.6.0","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.12","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
646
+ var package_namespaceObject = /*#__PURE__*/ JSON.parse('{"rE":"4.0.17","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.1.1","@rspack/dev-server":"2.1.0","@rspack/plugin-preact-refresh":"2.0.1","@rspack/plugin-react-refresh":"2.0.2","@vue/compiler-sfc":"3.5.26","acorn":"^8.16.0","adm-zip":"^0.6.0","browser-extension-manifest-fields":"^2.2.9","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","dotenv":"^17.2.3","es-module-lexer":"^2.1.0","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.6.7","less-loader":"13.0.0","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.12","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","prefers-yarn":"2.0.1","react-refresh":"0.18.0","sass-loader":"17.0.0","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3","ws":"^8.20.1"}}');
712
647
  function asAbsolute(p) {
713
648
  return __rspack_external_node_path_c5b9b54f.isAbsolute(p) ? p : __rspack_external_node_path_c5b9b54f.resolve(p);
714
649
  }
@@ -1161,10 +1096,44 @@ function assertNoManagedDependencyConflicts(userManifestPath, projectPath) {
1161
1096
  const configSource = __rspack_external_node_fs_5ea92f0c.readFileSync(configPath, 'utf-8');
1162
1097
  duplicates = userDeps.filter((d)=>managedDeps.has(d)).filter((d)=>isReferencedAsModuleSpecifier(configSource, d)).sort();
1163
1098
  } catch (error) {
1164
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.warn(error);
1099
+ if (isDebug()) console.warn(error);
1165
1100
  }
1166
1101
  if (duplicates.length > 0) throw new Error(managedDependencyConflict(duplicates, userManifestPath));
1167
1102
  }
1103
+ __rspack_external_node_path_c5b9b54f.join(process.cwd(), 'node_modules/extension-develop/dist/certs');
1104
+ const CHROMIUM_BASED_BROWSERS = [
1105
+ 'chrome',
1106
+ 'edge',
1107
+ 'brave',
1108
+ 'opera',
1109
+ 'vivaldi',
1110
+ 'yandex'
1111
+ ];
1112
+ const GECKO_BASED_BROWSERS = [
1113
+ 'firefox',
1114
+ 'waterfox',
1115
+ 'librewolf'
1116
+ ];
1117
+ const CHROMIUM_FAMILY_ALIASES = [
1118
+ 'chromium',
1119
+ 'chrome',
1120
+ 'edge',
1121
+ 'chromium-based'
1122
+ ];
1123
+ const GECKO_FAMILY_ALIASES = [
1124
+ 'firefox',
1125
+ 'gecko-based'
1126
+ ];
1127
+ [
1128
+ ...CHROMIUM_BASED_BROWSERS,
1129
+ ...GECKO_BASED_BROWSERS
1130
+ ];
1131
+ function isChromiumBasedBrowser(browser) {
1132
+ return CHROMIUM_BASED_BROWSERS.includes(browser) || String(browser).includes('chromium');
1133
+ }
1134
+ function isGeckoBasedBrowser(browser) {
1135
+ return GECKO_BASED_BROWSERS.includes(browser) || String(browser).includes('gecko') || String(browser).includes('firefox');
1136
+ }
1168
1137
  function isDir(p) {
1169
1138
  try {
1170
1139
  return __rspack_external_node_fs_5ea92f0c.existsSync(p) && __rspack_external_node_fs_5ea92f0c.statSync(p).isDirectory();
@@ -1209,7 +1178,7 @@ function isSubpathOf(parent, child) {
1209
1178
  return '' !== rel && !rel.startsWith('..') && !__rspack_external_node_path_c5b9b54f.isAbsolute(rel);
1210
1179
  }
1211
1180
  function getBrowserFolder(browser) {
1212
- if (browser && constants_isGeckoBasedBrowser(String(browser))) return 'firefox';
1181
+ if (browser && isGeckoBasedBrowser(String(browser))) return 'firefox';
1213
1182
  if ('edge' === browser) return 'edge';
1214
1183
  return 'chrome';
1215
1184
  }
@@ -1282,7 +1251,7 @@ function findExtensionRoots(dir, maxDepth = 3) {
1282
1251
  return found;
1283
1252
  }
1284
1253
  async function runExtensionFromStore(url, outDir) {
1285
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
1254
+ const isAuthor = isDebug();
1286
1255
  await fetchExtensionFromStore(url, {
1287
1256
  outDir,
1288
1257
  extract: true,
@@ -1601,19 +1570,11 @@ function sanitize(obj) {
1601
1570
  }
1602
1571
  const cjsRequire = createRequire(import.meta.url);
1603
1572
  function messages_getLoggingPrefix(type) {
1604
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
1605
- if (isAuthor) {
1606
- const base = 'error' === type ? 'ERROR Author says' : '⏵⏵⏵ Author says';
1607
- return pintor.brightMagenta(base);
1608
- }
1609
- if ('error' === type) return pintor.red('ERROR');
1610
- if ('warn' === type) return pintor.brightYellow('⏵⏵⏵');
1611
- if ('info' === type) return pintor.gray('⏵⏵⏵');
1612
- return pintor.green('⏵⏵⏵');
1573
+ return messaging_prefix(type);
1613
1574
  }
1614
1575
  function messages_ready(mode, browser) {
1615
1576
  const key = String(browser || '').toLowerCase();
1616
- const extensionOutput = constants_isGeckoBasedBrowser(key) || 'edge' === key ? 'Add-on' : 'Extension';
1577
+ const extensionOutput = messaging_artifactNoun(key);
1617
1578
  const cap = 'firefox' === key || 'gecko-based' === key || 'firefox-based' === key ? 'Firefox' : String(browser || '').charAt(0).toUpperCase() + String(browser || '').slice(1);
1618
1579
  const pretty = pintor.green(`ready for ${mode}`);
1619
1580
  return `${messages_getLoggingPrefix('info')} ${cap} ${extensionOutput} ${pretty}.`;
@@ -1643,32 +1604,43 @@ function browserRunnerDisabled(args) {
1643
1604
  const browserLabel = capitalizeToken(String(args.browser || 'unknown'));
1644
1605
  const runId = String(ready?.runId || '').trim();
1645
1606
  const pid = Number.isInteger(ready?.pid) ? String(ready?.pid) : '';
1646
- const runLabel = runId ? `${pintor.gray(runId)}${pid ? ` · ${pintor.gray(`PID ${pid}`)}` : ''}` : pid ? pintor.gray(`PID ${pid}`) : pintor.gray('n/a');
1607
+ const runLabel = runId ? `${runId}${pid ? ` · PID ${pid}` : ''}` : pid ? `PID ${pid}` : '';
1647
1608
  const extensionName = String(manifest?.name || 'Extension');
1648
1609
  const extensionVersion = String(manifest?.version || '').trim();
1649
1610
  const extensionLabel = extensionVersion ? `${extensionName} ${extensionVersion}` : extensionName;
1650
1611
  const extensionJsVersion = getExtensionVersion();
1651
- return [
1652
- ` 🧩 ${pintor.brightBlue('Extension.js')} ${pintor.gray(extensionJsVersion)}`,
1653
- ` Browser ${pintor.gray(args.browserModeLabel || `${browserLabel} (build-only mode)`)}`,
1654
- ` Extension ${pintor.gray(extensionLabel)}`,
1655
- ` Run ID ${runLabel}`
1656
- ].join('\n');
1612
+ return card({
1613
+ version: extensionJsVersion,
1614
+ rows: [
1615
+ {
1616
+ label: 'Browser',
1617
+ value: args.browserModeLabel || `${browserLabel} (build-only mode)`
1618
+ },
1619
+ {
1620
+ label: 'Extension',
1621
+ value: extensionLabel
1622
+ },
1623
+ {
1624
+ label: 'Run ID',
1625
+ value: runLabel
1626
+ }
1627
+ ]
1628
+ });
1657
1629
  }
1658
1630
  function portInUse(requestedPort, newPort) {
1659
- return `Port: Requested port ${pintor.brightBlue(requestedPort.toString())} is in use; using ${pintor.brightBlue(newPort.toString())} instead.`;
1631
+ return `The requested port ${pintor.brightBlue(requestedPort.toString())} is in use.\nThe dev server uses ${pintor.brightBlue(newPort.toString())} instead.`;
1660
1632
  }
1661
1633
  function extensionJsRunnerError(error) {
1662
- return `Extension.js Runner Error:\n${pintor.red(String(error))}`;
1634
+ return `Extension.js could not start the runner.\n${pintor.red(String(error))}`;
1663
1635
  }
1664
1636
  function autoExitModeEnabled(ms) {
1665
- return `Auto-exit enabled. Will exit after ${pintor.brightBlue(ms.toString())} ms if idle.`;
1637
+ return `Auto-exit is enabled.\nThe process exits after ${pintor.brightBlue(ms.toString())} ms if idle.`;
1666
1638
  }
1667
1639
  function autoExitTriggered(ms) {
1668
- return `Auto-exit triggered after ${pintor.brightBlue(ms.toString())} ms. Cleaning up...`;
1640
+ return `Auto-exit triggered after ${pintor.brightBlue(ms.toString())} ms.\nClean up and exit.`;
1669
1641
  }
1670
1642
  function autoExitForceKill(ms) {
1671
- return `Force-killing process after ${pintor.brightBlue(ms.toString())} ms to ensure exit.`;
1643
+ return `Force-kill the process after ${pintor.brightBlue(ms.toString())} ms to ensure exit.`;
1672
1644
  }
1673
1645
  function devServerStartTimeout(ms) {
1674
1646
  return [
@@ -1682,7 +1654,7 @@ function bundlerFatalError(error) {
1682
1654
  return `Build failed to start:\n${pintor.red(text)}`;
1683
1655
  }
1684
1656
  function bundlerRecompiling() {
1685
- return "Recompiling due to file changes…";
1657
+ return "Recompile due to file changes…";
1686
1658
  }
1687
1659
  function noEntrypointsDetected(port) {
1688
1660
  return [
@@ -1706,7 +1678,7 @@ function getDarkModeDefaults(browser) {
1706
1678
  ],
1707
1679
  preferences: {}
1708
1680
  };
1709
- if (constants_isGeckoBasedBrowser(String(browser))) return {
1681
+ if (isGeckoBasedBrowser(String(browser))) return {
1710
1682
  browserFlags: [],
1711
1683
  preferences: {
1712
1684
  'ui.systemUsesDarkTheme': 1,
@@ -1894,6 +1866,7 @@ function createPlaywrightMetadataWriter(options) {
1894
1866
  if (foreignLiveDevSession) console.warn(`[extension] a live dev session (pid ${foreignLiveDevSession.pid}) owns ${readyPath}; this ${options.command} run will not rewrite the session's ready.json/events.ndjson. The output dir is shared, so the dev browser may pick up freshly ${options.command}-built files. Stop the dev session first for a clean ${options.command} receipt.`);
1895
1867
  const base = {
1896
1868
  schemaVersion: 2,
1869
+ schema: 1,
1897
1870
  command: options.command,
1898
1871
  browser: options.browser,
1899
1872
  runId: getRunIdForSession(metadataDir),
@@ -2163,7 +2136,7 @@ function resolveCompanionExtensionDirs(opts) {
2163
2136
  }
2164
2137
  async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher) {
2165
2138
  const projectStructure = await getProjectStructure(pathOrRemoteUrl);
2166
- const debug = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2139
+ const debug = isDebug();
2167
2140
  const { manifestDir, packageJsonDir } = getDirs(projectStructure);
2168
2141
  const userManifestPath = projectStructure.packageJsonPath || projectStructure.denoJsonPath;
2169
2142
  if (userManifestPath) assertNoManagedDependencyConflicts(userManifestPath, packageJsonDir);
@@ -2192,20 +2165,22 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2192
2165
  }
2193
2166
  const commandConfig = await loadCommandConfig(packageJsonDir, metadataCommand);
2194
2167
  const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
2195
- console.log(previewing(browser));
2196
2168
  if (previewOptions.noBrowser) {
2197
- console.log(previewSkippedNoBrowser(browser));
2198
- metadata.writeReady();
2199
- console.log(spacerLine());
2200
2169
  const browserLabel = String(browser || 'unknown');
2170
+ console.log(spacerLine());
2201
2171
  console.log(browserRunnerDisabled({
2202
2172
  browser: browserLabel,
2203
2173
  manifestPath: projectStructure.manifestPath,
2204
2174
  readyPath: metadata.readyPath,
2205
2175
  browserModeLabel: `${browserLabel.charAt(0).toUpperCase() + browserLabel.slice(1)} (no-browser mode)`
2206
2176
  }));
2177
+ console.log(spacerLine());
2178
+ console.log(previewing(browser));
2179
+ console.log(previewSkippedNoBrowser(browser));
2180
+ metadata.writeReady();
2207
2181
  return;
2208
2182
  }
2183
+ console.log(previewing(browser));
2209
2184
  const safeBrowserConfig = sanitize(browserConfig);
2210
2185
  const safeCommandConfig = sanitize(commandConfig);
2211
2186
  const safePreviewOptions = sanitize(previewOptions);
@@ -2259,4 +2234,4 @@ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher
2259
2234
  await browserLauncher(resolvedOpts);
2260
2235
  metadata.writeReady();
2261
2236
  }
2262
- export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserLaunchFailed, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, constants_isGeckoBasedBrowser, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
2237
+ export { CHROMIUM_FAMILY_ALIASES, GECKO_FAMILY_ALIASES, PlaywrightPlugin, asAbsolute, assertNoManagedDependencyConflicts, authorInstallNotice, autoExitForceKill, autoExitModeEnabled, autoExitTriggered, browserLaunchFailed, browserRunnerDisabled, buildCommandFailed, buildSuccess, buildSuccessWithWarnings, buildWarningsDetails, buildWebpack, bundlerFatalError, bundlerRecompiling, computeExtensionsToLoad, createPlaywrightMetadataWriter, debugBrowser, debugContextPath, debugDirs, debugExtensionsToLoad, debugOutputPath, devCommandFailed, devServerStartTimeout, downloadingText, extensionJsRunnerError, extensionLoadRecovered, extensionLoadStillRefused, extensionPreview, failedToDownloadOrExtractZIPFileError, getDirs, getDistPath, getProjectStructure, getSessionRunId, getSpecialFoldersDataForCompiler, getSpecialFoldersDataForProjectRoot, invalidRemoteZip, isChromiumBasedBrowser, isGeckoBasedBrowser, loadBrowserConfig, loadCommandConfig, loadCustomConfig, localZipNotFound, manifestInvalidJson, messages_ready, needsInstall, noCompanionExtensionsResolved, noEntrypointsDetected, normalizeBrowser, notAZipArchive, package_namespaceObject, packagingDistributionFiles, packagingSourceFiles, portInUse, projectInstallFallbackToNpm, projectInstallScriptsDisabled, resolveCompanionExtensionDirs, resolveCompanionExtensionsConfig, sanitize, spacerLine, toPosixPath, treeWithDistFilesbrowser, treeWithSourceAndDistFiles, treeWithSourceFiles, unpackagedSuccessfully, unpackagingExtension, writingTypeDefinitions, writingTypeDefinitionsError };
package/dist/266.mjs CHANGED
@@ -1,27 +1,28 @@
1
1
  import { createRequire as __extjsCreateRequire } from "node:module"; const require = __extjsCreateRequire(import.meta.url);
2
2
  import pintor from "pintor";
3
+ import { prefix } from "./349.mjs";
3
4
  function importScriptsDependencyMissing(workerPath, literal, expectedPath, sourceSibling) {
4
5
  const sibling = sourceSibling ? `Found ${pintor.yellow(sourceSibling)}, but importScripts dependencies are copied as-is, not compiled.\n` : '';
5
- return `The background service_worker ${pintor.yellow(workerPath)} calls importScripts(${pintor.yellow(`'${literal}'`)}), but ${pintor.yellow(expectedPath)} is not part of the output. The call will fail at runtime.\n` + sibling + `Move the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension, or import it from the worker so it ` + "gets bundled.";
6
+ return `The background service_worker ${pintor.yellow(workerPath)} calls importScripts(${pintor.yellow(`'${literal}'`)}), but ${pintor.yellow(expectedPath)} is not part of the output.\nThe call will fail at runtime.\n` + sibling + `Move the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension, or import it from the worker so it ` + "gets bundled.";
6
7
  }
7
8
  function injectedFileDependencyMissing(assetName, literal, expectedPath, sourceSibling) {
8
9
  const sibling = sourceSibling ? `Found ${pintor.yellow(sourceSibling)}, but injected files are copied as-is, not compiled.\n` : '';
9
- return `${pintor.yellow(assetName)} injects ${pintor.yellow(`'${literal}'`)} via executeScript/insertCSS, but ${pintor.yellow(expectedPath)} is not part of the output. The injection will fail at runtime.\n` + sibling + `Move the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
10
+ return `${pintor.yellow(assetName)} injects ${pintor.yellow(`'${literal}'`)} via executeScript/insertCSS, but ${pintor.yellow(expectedPath)} is not part of the output.\nThe injection will fail at runtime.\n` + sibling + `Move the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
10
11
  }
11
12
  function fetchedFileDependencyMissing(assetName, literal, expectedPath) {
12
- return `${pintor.yellow(assetName)} loads ${pintor.yellow(`'${literal}'`)} at runtime (fetch/XMLHttpRequest/new URL), but ${pintor.yellow(expectedPath)} is not part of the output. The request will fail at runtime.\nMove the file so it resolves to ${pintor.yellow(expectedPath)} (or serve it from ${pintor.yellow('public/')}) so it ships with the extension.`;
13
+ return `${pintor.yellow(assetName)} loads ${pintor.yellow(`'${literal}'`)} at runtime (fetch/XMLHttpRequest/new URL), but ${pintor.yellow(expectedPath)} is not part of the output.\nThe request will fail at runtime.\nMove the file so it resolves to ${pintor.yellow(expectedPath)} (or serve it from ${pintor.yellow('public/')}) so it ships with the extension.`;
13
14
  }
14
15
  function getURLDependencyMissing(assetName, literal, expectedPath) {
15
- return `${pintor.yellow(assetName)} references ${pintor.yellow(`'${literal}'`)} via chrome.runtime.getURL(), but ${pintor.yellow(expectedPath)} is not part of the output. The reference will fail at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
16
+ return `${pintor.yellow(assetName)} references ${pintor.yellow(`'${literal}'`)} via chrome.runtime.getURL(), but ${pintor.yellow(expectedPath)} is not part of the output.\nThe reference will fail at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
16
17
  }
17
18
  function runtimeSetSurfaceDependencyMissing(assetName, literal, expectedPath) {
18
- return `${pintor.yellow(assetName)} sets ${pintor.yellow(`'${literal}'`)} as a runtime surface (setPopup/setOptions), but ${pintor.yellow(expectedPath)} is not part of the output. The surface will open a 404 at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
19
+ return `${pintor.yellow(assetName)} sets ${pintor.yellow(`'${literal}'`)} as a runtime surface (setPopup/setOptions), but ${pintor.yellow(expectedPath)} is not part of the output.\nThe surface will open a 404 at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
19
20
  }
20
21
  function staticImportDependencyMissing(assetName, literal, expectedPath) {
21
- return `${pintor.yellow(assetName)} (copied verbatim into the output) imports ${pintor.yellow(`'${literal}'`)}, but ${pintor.yellow(expectedPath)} is not part of the output. The import will fail at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
22
+ return `${pintor.yellow(assetName)} (copied verbatim into the output) imports ${pintor.yellow(`'${literal}'`)}, but ${pintor.yellow(expectedPath)} is not part of the output.\nThe import will fail at runtime.\nMove the file to ${pintor.yellow(expectedPath)} (or ${pintor.yellow('public/')}) so it ships with the extension.`;
22
23
  }
23
24
  function reservedScriptsFolder(relPath, indicators) {
24
25
  const reasons = indicators.map((r)=>`- ${pintor.gray(r)}`).join('\n');
25
- return `${pintor.red('ERROR')} scripts/ is a reserved folder in Extension.js.\nEvery file under ${pintor.yellow("scripts/")} is wrapped with the browser content-script mount runtime, so Node.js-only files placed here will fail to parse or run.\nRename the folder at the project root (for example ${pintor.yellow('bin/')}, ${pintor.yellow('tools/')}, ${pintor.yellow('ops/')}, ${pintor.yellow('tasks/')}, or ${pintor.yellow("ci-scripts/")}) or move the file out of scripts/.\n\n${pintor.red('NODE.JS SHAPE')}\n${reasons}\n${pintor.red('NOT ALLOWED')} ${pintor.underline(relPath)}`;
26
+ return `${prefix('error')} scripts/ is a reserved folder in Extension.js.\nEvery file under ${pintor.yellow("scripts/")} is wrapped with the browser content-script mount runtime, so Node.js-only files placed here will fail to parse or run.\nRename the folder at the project root (for example ${pintor.yellow('bin/')}, ${pintor.yellow('tools/')}, ${pintor.yellow('ops/')}, ${pintor.yellow('tasks/')}, or ${pintor.yellow("ci-scripts/")}) or move the file out of scripts/.\n\n${pintor.red('NODE.JS SHAPE')}\n${reasons}\n${pintor.red('NOT ALLOWED')} ${pintor.underline(relPath)}`;
26
27
  }
27
28
  export { fetchedFileDependencyMissing, getURLDependencyMissing, importScriptsDependencyMissing, injectedFileDependencyMissing, reservedScriptsFolder, runtimeSetSurfaceDependencyMissing, staticImportDependencyMissing };