extension-develop 4.1.35 → 4.1.36

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 (32) hide show
  1. package/dist/363~0.mjs +17 -0
  2. package/dist/469~0.mjs +20 -5
  3. package/dist/832~0.mjs +2770 -2761
  4. package/dist/840~0.mjs +2488 -2144
  5. package/dist/852~0.mjs +1 -0
  6. package/dist/contract/codes.json +6 -2
  7. package/dist/extension-js-devtools/build-stamp.json +2 -2
  8. package/dist/extension-js-devtools/chrome/background/service_worker.js +2 -2
  9. package/dist/extension-js-devtools/chrome/pages/welcome.js +2 -2
  10. package/dist/extension-js-devtools/chromium/background/service_worker.js +2 -2
  11. package/dist/extension-js-devtools/chromium/pages/welcome.js +2 -2
  12. package/dist/extension-js-devtools/edge/background/service_worker.js +2 -2
  13. package/dist/extension-js-devtools/edge/pages/welcome.js +2 -2
  14. package/dist/extension-js-devtools/firefox/background/scripts.js +2 -2
  15. package/dist/extension-js-devtools/firefox/pages/welcome.js +2 -2
  16. package/dist/extension-js-theme/build-stamp.json +2 -2
  17. package/dist/lib/addon-lint.d.ts +7 -3
  18. package/dist/lib/addon-reviewer-note.d.ts +32 -0
  19. package/dist/lib/build-summary.d.ts +6 -1
  20. package/dist/lib/build-toolchain.d.ts +8 -0
  21. package/dist/lib/chunk-dependency-provenance.d.ts +8 -0
  22. package/dist/lib/development-artifacts.d.ts +2 -0
  23. package/dist/lib/loopback-origins.d.ts +6 -0
  24. package/dist/lib/messages.d.ts +12 -1
  25. package/dist/lib/messaging.d.ts +1 -0
  26. package/dist/lib/stable-loader-paths.d.ts +14 -0
  27. package/dist/plugin-web-extension/feature-manifest/manifest-lib/edge-options-notice.d.ts +4 -0
  28. package/dist/plugin-web-extension/feature-manifest/messages.d.ts +1 -0
  29. package/dist/plugin-web-extension/feature-scripts/steps/add-base-uri-runtime-module.d.ts +5 -0
  30. package/dist/plugin-web-extension/feature-scripts/steps/stamp-webkit-utf8-bom.d.ts +9 -0
  31. package/dist/rspack-config~0.mjs +211 -20
  32. package/package.json +1 -1
package/dist/840~0.mjs CHANGED
@@ -10,15 +10,15 @@ import { DefinePlugin, WebpackError } from "@rspack/core";
10
10
  import { pathToFileURL } from "node:url";
11
11
  import { EventEmitter } from "node:events";
12
12
  import { browserRowValue, CODES, ENVELOPE, prefix as messaging_prefix, humanLine, card, debugLine, isDebug, claimCardKey, isMachineOutput } from "./852~0.mjs";
13
- import { package_namespaceObject, DEV_COMMAND_DEFAULTS, stampReadyDistExtensionId, takeCodedWarnings, mergeOptionLayers, shouldWarnPortConflict, stampReadyKnownExtensionId, assertNoManagedDependencyConflicts, recordCodedWarning, falseProfileSource, START_BUILD_DEFAULTS, resolveCompanionExtensionsConfig, BUILD_COMMAND_DEFAULTS, getSpecialFoldersDataForProjectRoot, withDarkMode } from "./832~0.mjs";
13
+ import { package_namespaceObject, DEV_COMMAND_DEFAULTS, stampReadyDistExtensionId, takeCodedWarnings, mergeOptionLayers, shouldWarnPortConflict, CONTROL_PORT_ASSET_NAME, stampReadyKnownExtensionId, assertNoManagedDependencyConflicts, recordCodedWarning, falseProfileSource, START_BUILD_DEFAULTS, resolveCompanionExtensionsConfig, BUILD_COMMAND_DEFAULTS, getSpecialFoldersDataForProjectRoot, withDarkMode } from "./832~0.mjs";
14
14
  import { stripBom, parseJsonSafe, isGeckoBasedBrowser } from "./937~0.mjs";
15
- import { buildWarningsDetails, buildOutDirInvalid, buildFailed, getBuildDistPath, getDirs, listOutputFiles, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, zipArtifactNotCreated, buildSharesDevDistText, addonLintDependencyAttribution, browserLaunchFailed, collapseHomeDir, addonLintMore, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, operaBuildUnminified, buildAssetsTree, addonLintFailed, addonLintFailedDebug, safariBuildOutputNotFound, projectInstallScriptsDisabled, addonLintFinding, buildSharesDevDist, authorInstallNotice, codedError, configResolvedChangeIgnored, projectInstallInWorkspaceRoot, addonLintNotInstalled, addonLintSummary, writingTypeDefinitions, buildComplete, buildCommandFailed, needsInstall, relativeToDir, updatingTypeDefinitions, runtimeChunkKeptInline, debugBrowser, normalizeBrowser, displayPath, debugOutputPath, safariInvalidBundleId, configBrowserOrThrow, devCommandFailed, buildShareHint, getProjectStructure, debugSplitChunksNarrowed } from "./469~0.mjs";
15
+ import { buildWarningsDetails, addonLintReviewerNote, buildOutDirInvalid, buildFailed, productionLoopbackOriginsText, getBuildDistPath, collapseHomeDir, getDirs, listOutputFiles, zipArtifactReady, projectInstallFallbackToNpm, debugDirs, zipArtifactNotCreated, addonLintDependencyAttribution, browserLaunchFailed, productionLoopbackOrigins, addonLintMore, extensionLoadRecovered, writingTypeDefinitionsError, extensionLoadStillRefused, operaBuildUnminified, buildAssetsTree, addonLintFailed, addonLintFailedDebug, projectInstallScriptsDisabled, addonLintUnsupportedApiFix, addonLintFinding, buildSharesDevDist, authorInstallNotice, codedError, configResolvedChangeIgnored, addonLintSummary, projectInstallInWorkspaceRoot, addonLintNotInstalled, writingTypeDefinitions, buildComplete, safariBuildOutputNotFound, buildCommandFailed, buildToolchain, updatingTypeDefinitions, runtimeChunkKeptInline, debugBrowser, normalizeBrowser, needsInstall, debugOutputPath, safariInvalidBundleId, relativeToDir, displayPath, configBrowserOrThrow, devCommandFailed, buildShareHint, getProjectStructure, debugSplitChunksNarrowed } from "./469~0.mjs";
16
16
  import { hasProjectDependency, findNearestProjectManifestDirSync } from "./731~0.mjs";
17
17
  import { renameSyncWithRetry } from "./206~0.mjs";
18
+ import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset } from "./640~0.mjs";
18
19
  import { loadCommandConfig, loadDefineTypes, loadBrowserConfig, loadProjectConfigDefaults, loadConfigResolvedHook, loadCustomConfig } from "./846~0.mjs";
19
20
  import { ensureSessionStateInProjectGitignore, browserDistDir, readyContractPath, buildSummaryPath, ensureSessionArtifactsIgnoreFile } from "./771~0.mjs";
20
21
  import { isResourceUnderDirs, canonicalizeDir } from "./712~0.mjs";
21
- import { getCanonicalContentScriptEntryName, parseCanonicalContentScriptAsset } from "./640~0.mjs";
22
22
  import { publicRootsFor } from "./105~0.mjs";
23
23
  import { rememberSpecialFoldersConfig } from "./471~0.mjs";
24
24
  import { fileURLToPath as __rspack_fileURLToPath } from "node:url";
@@ -554,6 +554,294 @@ function attachLifecycleStream(compiler, stream) {
554
554
  } catch {}
555
555
  });
556
556
  }
557
+ function chunkFileOf(location) {
558
+ return location.split(':')[0].replace(/\\/g, '/').replace(/^\.?\//, '');
559
+ }
560
+ function packageNameFromPath(candidate) {
561
+ const normalized = candidate.replace(/\\/g, '/');
562
+ const marker = '/node_modules/';
563
+ const at = normalized.lastIndexOf(marker);
564
+ if (-1 === at) return null;
565
+ const rest = normalized.slice(at + marker.length);
566
+ const segments = rest.split('/').filter(Boolean);
567
+ if (0 === segments.length) return null;
568
+ if (segments[0].startsWith('@')) return segments.length > 1 ? `${segments[0]}/${segments[1]}` : null;
569
+ if (segments[0].includes('@') && segments.length > 1) return packageNameFromPath(`/node_modules/${segments.slice(1).join('/')}`);
570
+ return segments[0];
571
+ }
572
+ function isAbsoluteFilePath(candidate) {
573
+ return /^([a-zA-Z]:[\\/]|[\\/])/.test(candidate);
574
+ }
575
+ function packageNameFromSourceFilename(source) {
576
+ const normalized = source.replace(/\\/g, '/');
577
+ return packageNameFromPath(normalized.startsWith('/') ? normalized : `/${normalized}`);
578
+ }
579
+ function pathOfModule(moduleObj) {
580
+ const candidate = moduleObj;
581
+ if ('string' == typeof candidate?.resource && candidate.resource) return candidate.resource;
582
+ if ('function' == typeof candidate?.identifier) {
583
+ const identifier = candidate.identifier();
584
+ if ('string' == typeof identifier && identifier) return identifier;
585
+ }
586
+ return null;
587
+ }
588
+ function collectChunkDependencyProvenance(compilation) {
589
+ const provenance = new Map();
590
+ const chunkGraph = compilation?.chunkGraph;
591
+ const chunks = compilation?.chunks;
592
+ if (!chunkGraph?.getChunkModulesIterable || !chunks) return provenance;
593
+ for (const chunk of chunks){
594
+ const files = chunk?.files;
595
+ if (!files) continue;
596
+ let modules = [];
597
+ try {
598
+ modules = Array.from(chunkGraph.getChunkModulesIterable(chunk));
599
+ } catch {
600
+ continue;
601
+ }
602
+ const packages = new Set();
603
+ let counted = 0;
604
+ let fromDependencies = 0;
605
+ for (const moduleObj of modules){
606
+ const modulePath = pathOfModule(moduleObj);
607
+ if (!modulePath) continue;
608
+ if (!isAbsoluteFilePath(modulePath)) continue;
609
+ counted += 1;
610
+ const packageName = packageNameFromPath(modulePath);
611
+ if (packageName) {
612
+ fromDependencies += 1;
613
+ packages.add(packageName);
614
+ }
615
+ }
616
+ if (0 === packages.size) continue;
617
+ const entry = {
618
+ packages: [
619
+ ...packages
620
+ ].sort(),
621
+ onlyDependencies: counted > 0 && fromDependencies === counted
622
+ };
623
+ for (const file of files){
624
+ if ('string' != typeof file || !file.endsWith('.js')) continue;
625
+ const existing = provenance.get(file);
626
+ if (!existing) {
627
+ provenance.set(file, entry);
628
+ continue;
629
+ }
630
+ provenance.set(file, {
631
+ packages: [
632
+ ...new Set([
633
+ ...existing.packages,
634
+ ...entry.packages
635
+ ])
636
+ ].sort(),
637
+ onlyDependencies: existing.onlyDependencies && entry.onlyDependencies
638
+ });
639
+ }
640
+ }
641
+ let assets;
642
+ try {
643
+ assets = compilation?.getAssets?.();
644
+ } catch {
645
+ assets = void 0;
646
+ }
647
+ for (const asset of assets || []){
648
+ const name = asset?.name;
649
+ const source = asset?.info?.sourceFilename;
650
+ if ('string' != typeof name || 'string' != typeof source) continue;
651
+ if (!/\.[cm]?js$/.test(name) || provenance.has(name)) continue;
652
+ const packageName = packageNameFromSourceFilename(source);
653
+ if (packageName) provenance.set(name, {
654
+ packages: [
655
+ packageName
656
+ ],
657
+ onlyDependencies: true
658
+ });
659
+ }
660
+ return provenance;
661
+ }
662
+ const ADDON_REVIEWER_NOTE_FILE = 'amo-reviewer-note.md';
663
+ const AUTHOR_ONLY_CODES = new Set([
664
+ 'UNSUPPORTED_API'
665
+ ]);
666
+ function licenseOf(packageJson) {
667
+ const license = packageJson.license;
668
+ if ('string' == typeof license && license.trim()) return license.trim();
669
+ if (license && 'object' == typeof license) {
670
+ const type = license.type;
671
+ if ('string' == typeof type && type.trim()) return type.trim();
672
+ }
673
+ const licenses = packageJson.licenses;
674
+ if (Array.isArray(licenses)) {
675
+ const types = licenses.map((entry)=>entry?.type).filter((type)=>'string' == typeof type && !!type);
676
+ if (types.length > 0) return types.join(' OR ');
677
+ }
678
+ return null;
679
+ }
680
+ function* ancestors(start) {
681
+ let dir = __rspack_external_node_path_806ed179.resolve(start);
682
+ while(true){
683
+ yield dir;
684
+ const parent = __rspack_external_node_path_806ed179.dirname(dir);
685
+ if (parent === dir) return;
686
+ dir = parent;
687
+ }
688
+ }
689
+ function escapeRegExp(text) {
690
+ return text.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
691
+ }
692
+ function installedPackageFacts(projectPath, name) {
693
+ for (const dir of ancestors(projectPath)){
694
+ const candidate = __rspack_external_node_path_806ed179.join(dir, 'node_modules', name, 'package.json');
695
+ if (__rspack_external_node_fs_1b05aee1.existsSync(candidate)) try {
696
+ const parsed = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(candidate, 'utf8'));
697
+ const version = 'string' == typeof parsed.version ? parsed.version : null;
698
+ return {
699
+ version,
700
+ license: licenseOf(parsed)
701
+ };
702
+ } catch {
703
+ break;
704
+ }
705
+ }
706
+ return null;
707
+ }
708
+ function versionFromNpmLock(content, name) {
709
+ try {
710
+ const lock = JSON.parse(content);
711
+ const packages = lock?.packages;
712
+ if (packages && 'object' == typeof packages) {
713
+ const entry = Object.entries(packages).find(([key])=>key.endsWith(`node_modules/${name}`));
714
+ const version = entry?.[1]?.version;
715
+ if ('string' == typeof version) return version;
716
+ }
717
+ const version = lock?.dependencies?.[name]?.version;
718
+ return 'string' == typeof version ? version : null;
719
+ } catch {
720
+ return null;
721
+ }
722
+ }
723
+ function versionFromPnpmLock(content, name) {
724
+ const key = escapeRegExp(name);
725
+ const match = content.match(new RegExp(`^ '?/?${key}[@/](\\d[^'()\\s:]*)`, 'm'));
726
+ return match ? match[1] : null;
727
+ }
728
+ function versionFromYarnLock(content, name) {
729
+ const key = escapeRegExp(name);
730
+ const match = content.match(new RegExp(`^"?${key}@[^\\n]*:\\n(?:[^\\n]*\\n)*?\\s+version:? "?([^"\\n]+)"?`, 'm'));
731
+ return match ? match[1] : null;
732
+ }
733
+ const LOCKFILE_READERS = [
734
+ [
735
+ 'package-lock.json',
736
+ versionFromNpmLock
737
+ ],
738
+ [
739
+ 'npm-shrinkwrap.json',
740
+ versionFromNpmLock
741
+ ],
742
+ [
743
+ 'pnpm-lock.yaml',
744
+ versionFromPnpmLock
745
+ ],
746
+ [
747
+ 'yarn.lock',
748
+ versionFromYarnLock
749
+ ]
750
+ ];
751
+ function lockfilePackageVersion(projectPath, name) {
752
+ for (const dir of ancestors(projectPath))for (const [file, read] of LOCKFILE_READERS){
753
+ const candidate = __rspack_external_node_path_806ed179.join(dir, file);
754
+ if (__rspack_external_node_fs_1b05aee1.existsSync(candidate)) try {
755
+ return read(__rspack_external_node_fs_1b05aee1.readFileSync(candidate, 'utf8'), name);
756
+ } catch {
757
+ return null;
758
+ }
759
+ }
760
+ return null;
761
+ }
762
+ function packageFacts(projectPath, name) {
763
+ const installed = installedPackageFacts(projectPath, name);
764
+ return {
765
+ version: installed?.version ?? lockfilePackageVersion(projectPath, name),
766
+ license: installed?.license ?? null
767
+ };
768
+ }
769
+ function classifyAddonLintLines(lines, chunkProvenance, readFacts) {
770
+ const byPackage = new Map();
771
+ const own = [];
772
+ for (const line of lines){
773
+ const provenance = AUTHOR_ONLY_CODES.has(line.code) ? void 0 : chunkProvenance?.get(chunkFileOf(line.location));
774
+ if (!provenance || 0 === provenance.packages.length) {
775
+ own.push(line);
776
+ continue;
777
+ }
778
+ for (const name of provenance.packages){
779
+ const entry = byPackage.get(name) ?? {
780
+ name,
781
+ ...readFacts(name),
782
+ findings: []
783
+ };
784
+ entry.findings.push({
785
+ line,
786
+ mixed: !provenance.onlyDependencies
787
+ });
788
+ byPackage.set(name, entry);
789
+ }
790
+ }
791
+ return {
792
+ packages: [
793
+ ...byPackage.values()
794
+ ].sort((a, b)=>a.name.localeCompare(b.name)),
795
+ own
796
+ };
797
+ }
798
+ function findingText(line) {
799
+ const where = line.location ? ` (${line.location})` : '';
800
+ return `${line.code}: ${line.message}${where}`;
801
+ }
802
+ function renderAddonReviewerNote(note, distDisplay) {
803
+ const out = [
804
+ '# Notes to reviewer',
805
+ '',
806
+ `Written by Extension.js from the addons-linter run over ${distDisplay}. Paste the bundled libraries section into the notes to reviewer field of the addons.mozilla.org submission.`,
807
+ ''
808
+ ];
809
+ out.push('## Bundled libraries', '');
810
+ if (0 === note.packages.length) out.push('No bundled library accounts for a finding in this build.', '');
811
+ for (const pkg of note.packages){
812
+ const version = pkg.version ?? 'version not found in node_modules or a lockfile';
813
+ const license = pkg.license ?? 'license not found in its package.json';
814
+ out.push(`### ${pkg.name} ${version}`, '', `${pkg.name} ${version} (${license}) is unmodified from npm. It accounts for:`, '');
815
+ for (const { line, mixed } of pkg.findings){
816
+ const hedge = mixed ? ' (this file also carries the extension author code, confirm before pasting)' : '';
817
+ out.push(`- ${findingText(line)}${hedge}`);
818
+ }
819
+ out.push('');
820
+ }
821
+ out.push('## Findings in the extension author code', '', 'These are not library noise and must not be presented as such.', '');
822
+ if (0 === note.own.length) out.push('None.', '');
823
+ for (const line of note.own)out.push(`- ${findingText(line)}`);
824
+ if (note.own.length > 0) out.push('');
825
+ return out.join('\n');
826
+ }
827
+ function addonReviewerNotePath(distPath) {
828
+ return __rspack_external_node_path_806ed179.join(__rspack_external_node_path_806ed179.dirname(__rspack_external_node_path_806ed179.resolve(distPath)), ADDON_REVIEWER_NOTE_FILE);
829
+ }
830
+ function writeAddonReviewerNote(input) {
831
+ const target = addonReviewerNotePath(input.distPath);
832
+ if (0 === input.lines.length) {
833
+ __rspack_external_node_fs_1b05aee1.rmSync(target, {
834
+ force: true
835
+ });
836
+ return null;
837
+ }
838
+ const note = classifyAddonLintLines(input.lines, input.chunkProvenance, (name)=>packageFacts(input.projectPath, name));
839
+ __rspack_external_node_fs_1b05aee1.mkdirSync(__rspack_external_node_path_806ed179.dirname(target), {
840
+ recursive: true
841
+ });
842
+ __rspack_external_node_fs_1b05aee1.writeFileSync(target, renderAddonReviewerNote(note, input.distDisplay), 'utf8');
843
+ return target;
844
+ }
557
845
  const cjsRequire = createRequire(import.meta.url);
558
846
  if (!process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION) process.env.EXTENSION_JS_OPTIONAL_DEPS_VERSION = package_namespaceObject.rE;
559
847
  function resolveDevelopRootFromDir(dir) {
@@ -1777,14 +2065,14 @@ function collectAddonLintLines(output) {
1777
2065
  return true;
1778
2066
  });
1779
2067
  }
1780
- function attributionFor(location, chunkProvenance) {
2068
+ function attributionFor(location, chunkProvenance, code = '', browser = 'firefox') {
2069
+ if (AUTHOR_ONLY_CODES.has(code)) return addonLintUnsupportedApiFix(browser);
1781
2070
  if (!chunkProvenance || 0 === chunkProvenance.size) return '';
1782
- const file = location.split(':')[0].replace(/\\/g, '/').replace(/^\.?\//, '');
1783
- const provenance = chunkProvenance.get(file);
2071
+ const provenance = chunkProvenance.get(chunkFileOf(location));
1784
2072
  if (!provenance) return '';
1785
2073
  return addonLintDependencyAttribution(provenance.packages, provenance.onlyDependencies);
1786
2074
  }
1787
- function formatAddonLintFindings(output, distDisplay, maxPrinted = ADDON_LINT_MAX_PRINTED, chunkProvenance) {
2075
+ function formatAddonLintFindings(output, distDisplay, maxPrinted = ADDON_LINT_MAX_PRINTED, chunkProvenance, browser = 'firefox') {
1788
2076
  const all = collectAddonLintLines(output);
1789
2077
  if (0 === all.length) return {
1790
2078
  findings: 0,
@@ -1795,7 +2083,7 @@ function formatAddonLintFindings(output, distDisplay, maxPrinted = ADDON_LINT_MA
1795
2083
  const shown = all.slice(0, Math.max(0, maxPrinted));
1796
2084
  const lines = [
1797
2085
  addonLintSummary(errorCount, warningCount, distDisplay),
1798
- ...shown.map((line)=>addonLintFinding(line.level, line.code, line.message, line.location, attributionFor(line.location, chunkProvenance)))
2086
+ ...shown.map((line)=>addonLintFinding(line.level, line.code, line.message, line.location, attributionFor(line.location, chunkProvenance, line.code, browser)))
1799
2087
  ];
1800
2088
  if (all.length > shown.length) lines.push(addonLintMore(all.length - shown.length, distDisplay));
1801
2089
  return {
@@ -1803,6 +2091,24 @@ function formatAddonLintFindings(output, distDisplay, maxPrinted = ADDON_LINT_MA
1803
2091
  lines
1804
2092
  };
1805
2093
  }
2094
+ function reviewerNoteFor(input, output, chunkProvenance) {
2095
+ try {
2096
+ const written = writeAddonReviewerNote({
2097
+ projectPath: input.projectPath,
2098
+ distPath: input.distPath,
2099
+ distDisplay: input.distDisplay,
2100
+ lines: collectAddonLintLines(output),
2101
+ chunkProvenance
2102
+ });
2103
+ if (!written) return null;
2104
+ return {
2105
+ path: written,
2106
+ line: addonLintReviewerNote(__rspack_external_node_path_806ed179.join(__rspack_external_node_path_806ed179.dirname(input.distDisplay), ADDON_REVIEWER_NOTE_FILE))
2107
+ };
2108
+ } catch {
2109
+ return null;
2110
+ }
2111
+ }
1806
2112
  class AddonLintTimeout extends Error {
1807
2113
  }
1808
2114
  function withTimeout(promise, ms) {
@@ -1868,9 +2174,11 @@ async function runAddonLint(input) {
1868
2174
  const output = await withTimeout(instance.run({
1869
2175
  _console: silentConsole()
1870
2176
  }), input.timeoutMs ?? ADDON_LINT_TIMEOUT_MS);
2177
+ const chunkProvenance = input.chunkProvenance?.();
1871
2178
  return {
1872
2179
  status: 'linted',
1873
- ...formatAddonLintFindings(output, input.distDisplay, ADDON_LINT_MAX_PRINTED, input.chunkProvenance?.())
2180
+ ...formatAddonLintFindings(output, input.distDisplay, ADDON_LINT_MAX_PRINTED, chunkProvenance, input.browser),
2181
+ reviewerNote: reviewerNoteFor(input, output, chunkProvenance)
1874
2182
  };
1875
2183
  } catch (error) {
1876
2184
  return failedAddonLint(error, input.distDisplay);
@@ -2007,84 +2315,20 @@ function getBuildSummary(browser, info, outputPath, outputFiles, codes) {
2007
2315
  } : {}
2008
2316
  };
2009
2317
  }
2010
- function packageNameFromPath(candidate) {
2011
- const normalized = candidate.replace(/\\/g, '/');
2012
- const marker = '/node_modules/';
2013
- const at = normalized.lastIndexOf(marker);
2014
- if (-1 === at) return null;
2015
- const rest = normalized.slice(at + marker.length);
2016
- const segments = rest.split('/').filter(Boolean);
2017
- if (0 === segments.length) return null;
2018
- if (segments[0].startsWith('@')) return segments.length > 1 ? `${segments[0]}/${segments[1]}` : null;
2019
- if (segments[0].includes('@') && segments.length > 1) return packageNameFromPath(`/node_modules/${segments.slice(1).join('/')}`);
2020
- return segments[0];
2021
- }
2022
- function isAbsoluteFilePath(candidate) {
2023
- return /^([a-zA-Z]:[\\/]|[\\/])/.test(candidate);
2024
- }
2025
- function pathOfModule(moduleObj) {
2026
- const candidate = moduleObj;
2027
- if ('string' == typeof candidate?.resource && candidate.resource) return candidate.resource;
2028
- if ('function' == typeof candidate?.identifier) {
2029
- const identifier = candidate.identifier();
2030
- if ('string' == typeof identifier && identifier) return identifier;
2031
- }
2032
- return null;
2033
- }
2034
- function collectChunkDependencyProvenance(compilation) {
2035
- const provenance = new Map();
2036
- const chunkGraph = compilation?.chunkGraph;
2037
- const chunks = compilation?.chunks;
2038
- if (!chunkGraph?.getChunkModulesIterable || !chunks) return provenance;
2039
- for (const chunk of chunks){
2040
- const files = chunk?.files;
2041
- if (!files) continue;
2042
- let modules = [];
2043
- try {
2044
- modules = Array.from(chunkGraph.getChunkModulesIterable(chunk));
2045
- } catch {
2046
- continue;
2047
- }
2048
- const packages = new Set();
2049
- let counted = 0;
2050
- let fromDependencies = 0;
2051
- for (const moduleObj of modules){
2052
- const modulePath = pathOfModule(moduleObj);
2053
- if (!modulePath) continue;
2054
- if (!isAbsoluteFilePath(modulePath)) continue;
2055
- counted += 1;
2056
- const packageName = packageNameFromPath(modulePath);
2057
- if (packageName) {
2058
- fromDependencies += 1;
2059
- packages.add(packageName);
2060
- }
2061
- }
2062
- if (0 === packages.size) continue;
2063
- const entry = {
2064
- packages: [
2065
- ...packages
2066
- ].sort(),
2067
- onlyDependencies: counted > 0 && fromDependencies === counted
2068
- };
2069
- for (const file of files){
2070
- if ('string' != typeof file || !file.endsWith('.js')) continue;
2071
- const existing = provenance.get(file);
2072
- if (!existing) {
2073
- provenance.set(file, entry);
2074
- continue;
2075
- }
2076
- provenance.set(file, {
2077
- packages: [
2078
- ...new Set([
2079
- ...existing.packages,
2080
- ...entry.packages
2081
- ])
2082
- ].sort(),
2083
- onlyDependencies: existing.onlyDependencies && entry.onlyDependencies
2084
- });
2318
+ const USER_AGENT_HEAD = /^([A-Za-z][\w.-]*)\/(\S+)/;
2319
+ function getBuildToolchain(env = process.env, nodeVersion = process.version) {
2320
+ const agent = String(env.npm_config_user_agent || '').trim();
2321
+ const head = USER_AGENT_HEAD.exec(agent);
2322
+ if (!head || '?' === head[2]) return {
2323
+ node: nodeVersion
2324
+ };
2325
+ return {
2326
+ node: nodeVersion,
2327
+ package_manager: {
2328
+ name: head[1].toLowerCase(),
2329
+ version: head[2]
2085
2330
  }
2086
- }
2087
- return provenance;
2331
+ };
2088
2332
  }
2089
2333
  const OPEN_AT_TOP = new Set([
2090
2334
  'module',
@@ -2234,2174 +2478,2274 @@ class ConfigResolvedPlugin {
2234
2478
  compiler.hooks.watchRun.tapPromise(ConfigResolvedPlugin.name, run);
2235
2479
  }
2236
2480
  }
2237
- function projectInstallStdio() {
2238
- return isMachineOutput() ? [
2239
- 'inherit',
2240
- 2,
2241
- 2
2242
- ] : 'inherit';
2481
+ const DEV_CONTENT_SCRIPT_REGISTRY_ASSET = "content_scripts/dev-registry.json";
2482
+ const DEV_CONTENT_SCRIPT_MARKER_KEY = '__extjsDevContentScripts';
2483
+ const DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY = '__extjsDevCsStub';
2484
+ const DEV_CONTENT_SCRIPT_ID_PREFIX = 'extjs-dev-cs-';
2485
+ const DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY = '__extjsDevStaticReload';
2486
+ const DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY = '__extjsDevStaticBundles';
2487
+ function devContentScriptStubAssetName(index) {
2488
+ return `content_scripts/dev-stub-${index}.js`;
2243
2489
  }
2244
- async function ensureUserProjectDependencies(packageJsonDir) {
2245
- const member = findWorkspaceMember(packageJsonDir);
2246
- if (!needsInstall(packageJsonDir, member?.root)) return;
2247
- const pm = member && workspaceManagerOverride(member) || resolvePackageManager({
2248
- cwd: member?.root ?? packageJsonDir
2249
- });
2250
- const suppression = installScriptSuppression(pm);
2251
- const target = projectInstallTarget(pm, packageJsonDir, member);
2252
- const cmd = buildInstallCommand(pm, [
2253
- 'install',
2254
- ...suppression.args,
2255
- ...target.args
2256
- ]);
2257
- if (suppression.args.length || Object.keys(suppression.env).length) console.warn(projectInstallScriptsDisabled(pm.name));
2258
- if (target.cwd !== packageJsonDir) console.warn(projectInstallInWorkspaceRoot(target.cwd, pm.name));
2259
- try {
2260
- await execInstallCommand(cmd.command, cmd.args, {
2261
- cwd: target.cwd,
2262
- stdio: projectInstallStdio(),
2263
- env: suppression.env
2264
- });
2265
- } catch (error) {
2266
- if ('npm' === pm.name) throw error;
2267
- if ('deno' === pm.name) throw error;
2268
- console.warn(projectInstallFallbackToNpm(pm.name));
2269
- const npmPm = resolveNpmPackageManager();
2270
- const npmSuppression = installScriptSuppression(npmPm);
2271
- const npmCmd = buildInstallCommand(npmPm, [
2272
- 'install',
2273
- '--no-package-lock',
2274
- ...npmSuppression.args
2275
- ]);
2276
- await execInstallCommand(npmCmd.command, npmCmd.args, {
2277
- cwd: packageJsonDir,
2278
- stdio: projectInstallStdio(),
2279
- env: npmSuppression.env
2280
- });
2281
- }
2490
+ function devContentScriptCssMarkerAssetName(index) {
2491
+ return `content_scripts/dev-css-${index}.js`;
2282
2492
  }
2283
- async function ensureDevelopArtifacts() {
2284
- const developRoot = findExtensionDevelopRoot();
2285
- if (!developRoot) return;
2286
- const requiredFiles = [
2287
- __rspack_external_node_path_806ed179.join(developRoot, 'dist', "ensure-hmr-for-scripts.js"),
2288
- __rspack_external_node_path_806ed179.join(developRoot, 'dist', "minimum-script-file.js")
2289
- ];
2290
- const missing = requiredFiles.filter((file)=>!__rspack_external_node_fs_1b05aee1.existsSync(file));
2291
- if (0 === missing.length) return;
2292
- const pm = resolvePackageManager({
2293
- cwd: developRoot
2294
- });
2295
- const command = buildInstallCommand(pm, [
2296
- 'run',
2297
- 'compile'
2298
- ]);
2299
- const isAuthor = isDebug();
2300
- const stdio = isAuthor ? 'inherit' : 'ignore';
2301
- if (isAuthor) console.warn(authorInstallNotice('extension-develop build artifacts (dist missing)'));
2302
- await execInstallCommand(command.command, command.args, {
2303
- cwd: developRoot,
2304
- stdio
2305
- });
2493
+ const DEV_CONTENT_SCRIPT_STAND_IN_ASSET = /^content_scripts\/dev-(?:stub|css)-\d+\.js$/;
2494
+ function isDevContentScriptStandInAsset(assetName) {
2495
+ return DEV_CONTENT_SCRIPT_STAND_IN_ASSET.test(assetName);
2306
2496
  }
2307
- const EXTENSION_ENV_TYPES_PACKAGE = 'extension';
2308
- const STYLE_TYPE = 'Readonly<Record<string, string>>';
2309
- const EXTENSION_ENV_WILDCARD_MODULES = Object.freeze([
2310
- {
2311
- pattern: '*.css',
2312
- type: STYLE_TYPE
2313
- },
2314
- {
2315
- pattern: '*.scss',
2316
- type: STYLE_TYPE
2317
- },
2318
- {
2319
- pattern: '*.sass',
2320
- type: STYLE_TYPE
2321
- },
2322
- {
2323
- pattern: '*.less',
2324
- type: STYLE_TYPE
2325
- },
2326
- {
2327
- pattern: '*.module.css',
2328
- type: STYLE_TYPE
2329
- },
2330
- {
2331
- pattern: '*.module.scss',
2332
- type: STYLE_TYPE
2333
- },
2334
- {
2335
- pattern: '*.module.sass',
2336
- type: STYLE_TYPE
2337
- },
2338
- {
2339
- pattern: '*.module.less',
2340
- type: STYLE_TYPE
2341
- },
2342
- {
2343
- pattern: '*.png',
2344
- type: 'string'
2345
- },
2346
- {
2347
- pattern: '*.jpg',
2348
- type: 'string'
2349
- },
2350
- {
2351
- pattern: '*.jpeg',
2352
- type: 'string'
2353
- },
2354
- {
2355
- pattern: '*.gif',
2356
- type: 'string'
2357
- },
2358
- {
2359
- pattern: '*.webp',
2360
- type: 'string'
2361
- },
2362
- {
2363
- pattern: '*.avif',
2364
- type: 'string'
2365
- },
2366
- {
2367
- pattern: '*.ico',
2368
- type: 'string'
2369
- },
2370
- {
2371
- pattern: '*.bmp',
2372
- type: 'string'
2373
- },
2374
- {
2375
- pattern: '*.svg',
2376
- type: 'any'
2377
- },
2378
- {
2379
- pattern: '*?raw',
2380
- type: 'string'
2381
- },
2382
- {
2383
- pattern: '*?url',
2384
- type: 'string'
2385
- }
2386
- ]);
2387
- function renderWildcardModuleDeclarations(modules = EXTENSION_ENV_WILDCARD_MODULES) {
2388
- return modules.map(({ pattern, type })=>`declare module '${pattern}' {\n const content: ${type}\n export default content\n}\n`).join('');
2497
+ const HASHED_CONTENT_SCRIPT_ASSET = /^content_scripts\/content-(\d+)(?:\.[a-f0-9]+)?\.js$/i;
2498
+ function contentScriptEntryForAsset(assetName) {
2499
+ const match = HASHED_CONTENT_SCRIPT_ASSET.exec(assetName);
2500
+ if (!match) return;
2501
+ return getCanonicalContentScriptEntryName(Number(match[1]));
2389
2502
  }
2390
- function renderDefineDeclarations(defineTypes = {}) {
2391
- return Object.entries(defineTypes).filter(([name])=>/^[A-Za-z_$][\w$]*$/.test(name)).map(([name, type])=>`declare const ${name}: ${type}\n`).join('');
2503
+ function stringList(value) {
2504
+ return Array.isArray(value) ? value.filter((item)=>'string' == typeof item) : [];
2392
2505
  }
2393
- function renderExtensionEnvTypes(typePath = EXTENSION_ENV_TYPES_PACKAGE, defineTypes = {}, { inlineAssetTypes = false } = {}) {
2394
- const defineDeclarations = renderDefineDeclarations(defineTypes);
2395
- const assetDeclarations = inlineAssetTypes ? `\n// Asset and stylesheet imports: the ${typePath} package does not resolve
2396
- // from this project, so the declares it ships are written here instead.
2397
- ${renderWildcardModuleDeclarations()}` : '';
2398
- return `\
2399
- // Required Extension.js types for TypeScript projects.
2400
- // This file is auto-generated and should not be excluded.
2401
- // If you need additional types, consider creating a new *.d.ts file and
2402
- // referencing it in the "include" array of your tsconfig.json file.
2403
- // See https://www.typescriptlang.org/tsconfig#include for more information.
2404
- /// <reference types="${typePath}/types" />
2405
-
2406
- // Polyfill types for browser.* APIs
2407
- /// <reference types="${typePath}/types/polyfill" />
2408
- ${assetDeclarations}${defineDeclarations ? `\n${defineDeclarations}` : ''}`;
2506
+ function runAtOf(value) {
2507
+ if ('document_start' === value || 'document_end' === value) return value;
2508
+ return 'document_idle';
2409
2509
  }
2410
- function resolvesExtensionPackage(packageJsonDir) {
2411
- let dir = __rspack_external_node_path_806ed179.resolve(packageJsonDir);
2412
- while(true){
2413
- const packageJson = __rspack_external_node_path_806ed179.join(dir, 'node_modules', EXTENSION_ENV_TYPES_PACKAGE, 'package.json');
2414
- if (existsSync(packageJson)) return true;
2415
- const parent = __rspack_external_node_path_806ed179.dirname(dir);
2416
- if (parent === dir) return false;
2417
- dir = parent;
2510
+ function canonicalIndexOf(entry) {
2511
+ for (const file of [
2512
+ ...stringList(entry.js),
2513
+ ...stringList(entry.css)
2514
+ ]){
2515
+ const parsed = parseCanonicalContentScriptAsset(file);
2516
+ if (parsed) return parsed.index;
2418
2517
  }
2419
2518
  }
2420
- async function generateExtensionTypes(manifestDir, packageJsonDir) {
2421
- const extensionEnvFile = __rspack_external_node_path_806ed179.join(packageJsonDir, 'extension-env.d.ts');
2422
- const fileContent = renderExtensionEnvTypes(void 0, await loadDefineTypes(packageJsonDir), {
2423
- inlineAssetTypes: !resolvesExtensionPackage(packageJsonDir)
2424
- });
2425
- try {
2426
- await __rspack_external_node_fs_promises_3b710708.access(extensionEnvFile);
2427
- const existingContent = await __rspack_external_node_fs_promises_3b710708.readFile(extensionEnvFile, 'utf8');
2428
- if (existingContent === fileContent) return;
2429
- humanLine(updatingTypeDefinitions(extensionEnvFile));
2430
- await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
2431
- } catch (err) {
2432
- const manifestText = await __rspack_external_node_fs_promises_3b710708.readFile(__rspack_external_node_path_806ed179.join(manifestDir, 'manifest.json'), 'utf8');
2433
- const manifest = parseJsonSafe(manifestText);
2434
- humanLine(writingTypeDefinitions(manifest));
2435
- try {
2436
- await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
2437
- } catch (writeErr) {
2438
- recordCodedWarning(CODES.E_TYPES_EMIT, `Writing ${extensionEnvFile} failed: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
2439
- humanLine(writingTypeDefinitionsError(writeErr));
2519
+ function planDevContentScripts(manifest) {
2520
+ if (3 !== manifest.manifest_version) return;
2521
+ const groups = manifest.content_scripts;
2522
+ if (!Array.isArray(groups) || 0 === groups.length) return;
2523
+ const entries = [];
2524
+ const stubs = {};
2525
+ const nextGroups = groups.map((group)=>{
2526
+ const index = canonicalIndexOf(group);
2527
+ const matches = stringList(group.matches);
2528
+ const js = stringList(group.js);
2529
+ const css = stringList(group.css);
2530
+ if (void 0 === index || 0 === matches.length) return group;
2531
+ if (0 === js.length && 0 === css.length) return group;
2532
+ const entryName = getCanonicalContentScriptEntryName(index);
2533
+ const excludeMatches = stringList(group.exclude_matches);
2534
+ if ('document_start' === group.run_at && 'MAIN' !== group.world) {
2535
+ entries.push({
2536
+ id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
2537
+ entry: entryName,
2538
+ matches,
2539
+ ...excludeMatches.length > 0 ? {
2540
+ excludeMatches
2541
+ } : {},
2542
+ js,
2543
+ css,
2544
+ runAt: 'document_start',
2545
+ allFrames: true === group.all_frames,
2546
+ world: 'ISOLATED',
2547
+ stubOnly: false,
2548
+ static: true
2549
+ });
2550
+ return group;
2440
2551
  }
2441
- }
2442
- }
2443
- function live_dev_session_isProcessAlive(pid) {
2444
- try {
2445
- process.kill(pid, 0);
2446
- return true;
2447
- } catch (error) {
2448
- return error?.code === 'EPERM';
2449
- }
2450
- }
2451
- function findLiveDevSession(projectPath, browser) {
2452
- let contract;
2453
- try {
2454
- contract = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(readyContractPath(projectPath, browser), 'utf-8'));
2455
- } catch {
2456
- return null;
2457
- }
2458
- if (!contract || 'object' != typeof contract) return null;
2459
- if ('dev' !== contract.command) return null;
2460
- if ('starting' !== contract.status && 'ready' !== contract.status) return null;
2461
- const pid = Number(contract.pid);
2462
- if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return null;
2463
- if (!live_dev_session_isProcessAlive(pid)) return null;
2464
- const distPath = 'string' == typeof contract.distPath && contract.distPath ? __rspack_external_node_path_806ed179.resolve(contract.distPath) : '';
2465
- return {
2466
- distPath,
2467
- pid
2468
- };
2469
- }
2470
- const BACKGROUND_PAGE_ENTRY = 'background/index';
2471
- function classifyEntrySurface(entryName) {
2472
- if (entryName === BACKGROUND_PAGE_ENTRY) return 'page';
2473
- if (entryName.startsWith('background')) return 'background';
2474
- if (entryName.startsWith("content_scripts/")) return "content_script";
2475
- if (entryName.startsWith("scripts/")) return "script";
2476
- if (entryName.startsWith("user_scripts/")) return "script";
2477
- return 'page';
2478
- }
2479
- function isPageChunkName(name) {
2480
- return 'string' == typeof name && name.length > 0 && 'page' === classifyEntrySurface(name);
2481
- }
2482
- function isSurfaceLockedChunkName(name) {
2483
- return 'string' == typeof name && 'page' !== classifyEntrySurface(name);
2484
- }
2485
- function canBeInitial(chunk) {
2486
- return 'function' == typeof chunk.canBeInitial ? chunk.canBeInitial() : true;
2487
- }
2488
- function pageInitialChunks(chunk) {
2489
- return canBeInitial(chunk) && isPageChunkName(chunk.name);
2490
- }
2491
- const FRAMEWORK_PACKAGE_PATTERN = /[\\/]node_modules[\\/](react|react-dom|scheduler|preact|vue|@vue|svelte|solid-js|lit|lit-html|lit-element|@lit)[\\/]/;
2492
- const SCRIPT_MODULE_TYPE = /^javascript\//;
2493
- const SHARED_CHUNK_DIR = 'shared';
2494
- function defaultSplitChunks() {
2495
- return {
2496
- chunks: pageInitialChunks,
2497
- cacheGroups: {
2498
- default: false,
2499
- defaultVendors: false,
2500
- framework: {
2501
- name: `${SHARED_CHUNK_DIR}/framework`,
2502
- filename: `${SHARED_CHUNK_DIR}/framework.js`,
2503
- test: FRAMEWORK_PACKAGE_PATTERN,
2504
- type: SCRIPT_MODULE_TYPE,
2505
- priority: 40,
2506
- enforce: true,
2507
- reuseExistingChunk: true
2508
- },
2509
- commons: {
2510
- name: `${SHARED_CHUNK_DIR}/commons`,
2511
- filename: `${SHARED_CHUNK_DIR}/commons.js`,
2512
- type: SCRIPT_MODULE_TYPE,
2513
- minChunks: 2,
2514
- minSize: 0,
2515
- priority: 20,
2516
- reuseExistingChunk: true
2517
- }
2518
- }
2519
- };
2520
- }
2521
- function narrowedSelector(option, isLocked) {
2522
- if ('all' === option) return (chunk)=>!isLocked(chunk.name);
2523
- return (chunk)=>('function' == typeof chunk.canBeInitial ? chunk.canBeInitial() : true) && !isLocked(chunk.name);
2524
- }
2525
- function narrowChunks(chunks, isLocked) {
2526
- if ('all' === chunks || 'initial' === chunks) return narrowedSelector(chunks, isLocked);
2527
- }
2528
- function lockedChunkName(config) {
2529
- const userEntries = new Set(userEntryNames(config));
2530
- return (name)=>isSurfaceLockedChunkName(name) || 'string' == typeof name && userEntries.has(name);
2531
- }
2532
- function normalizeSplitChunks(config) {
2533
- const splitChunks = config.optimization?.splitChunks;
2534
- if (!splitChunks || 'object' != typeof splitChunks) return {
2535
- config,
2536
- narrowed: []
2537
- };
2538
- const isLocked = lockedChunkName(config);
2539
- const narrowed = [];
2540
- const next = {
2541
- ...splitChunks
2542
- };
2543
- const topLevel = narrowChunks(splitChunks.chunks, isLocked);
2544
- if (topLevel) {
2545
- next.chunks = topLevel;
2546
- narrowed.push('splitChunks.chunks');
2547
- }
2548
- if (splitChunks.cacheGroups && 'object' == typeof splitChunks.cacheGroups) {
2549
- const cacheGroups = {};
2550
- for (const [key, group] of Object.entries(splitChunks.cacheGroups)){
2551
- const groupSelector = group && 'object' == typeof group ? narrowChunks(group.chunks, isLocked) : void 0;
2552
- if (groupSelector && group && 'object' == typeof group) {
2553
- cacheGroups[key] = {
2554
- ...group,
2555
- chunks: groupSelector
2556
- };
2557
- narrowed.push(`splitChunks.cacheGroups.${key}.chunks`);
2558
- } else cacheGroups[key] = group;
2559
- }
2560
- next.cacheGroups = cacheGroups;
2561
- }
2562
- if (0 === narrowed.length) return {
2563
- config,
2564
- narrowed
2565
- };
2552
+ const stubOnly = stringList(group.include_globs).length > 0 || stringList(group.exclude_globs).length > 0;
2553
+ const cssMarkerAsset = 0 === js.length ? devContentScriptCssMarkerAssetName(index) : void 0;
2554
+ if (cssMarkerAsset) stubs[cssMarkerAsset] = buildDevContentScriptMarkerPrelude(entryName, cssMarkerAsset);
2555
+ entries.push({
2556
+ id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
2557
+ entry: entryName,
2558
+ matches,
2559
+ ...excludeMatches.length > 0 ? {
2560
+ excludeMatches
2561
+ } : {},
2562
+ js: cssMarkerAsset ? [
2563
+ cssMarkerAsset
2564
+ ] : js,
2565
+ css,
2566
+ runAt: runAtOf(group.run_at),
2567
+ allFrames: true === group.all_frames,
2568
+ world: 'MAIN' === group.world ? 'MAIN' : 'ISOLATED',
2569
+ ...true === group.match_origin_as_fallback ? {
2570
+ matchOriginAsFallback: true
2571
+ } : {},
2572
+ stubOnly
2573
+ });
2574
+ const stubAsset = devContentScriptStubAssetName(index);
2575
+ stubs[stubAsset] = buildDevContentScriptStubSource(entryName);
2576
+ const { css: _css, world: _world, ...rest } = group;
2577
+ return {
2578
+ ...rest,
2579
+ js: [
2580
+ stubAsset
2581
+ ]
2582
+ };
2583
+ });
2584
+ if (0 === entries.length) return;
2566
2585
  return {
2567
- config: {
2568
- ...config,
2569
- optimization: {
2570
- ...config.optimization,
2571
- splitChunks: next
2572
- }
2586
+ manifest: {
2587
+ ...manifest,
2588
+ content_scripts: nextGroups
2573
2589
  },
2574
- narrowed
2590
+ registry: {
2591
+ version: 1,
2592
+ entries
2593
+ },
2594
+ stubs
2575
2595
  };
2576
2596
  }
2577
- function applySplitChunksGuard(config) {
2578
- const { config: next, narrowed } = normalizeSplitChunks(config);
2579
- if (narrowed.length > 0 && isDebug()) debugLine(debugSplitChunksNarrowed(narrowed));
2580
- return keepRuntimeInline(keepUserEntriesWhole(next));
2581
- }
2582
- function keepRuntimeInline(config) {
2583
- const runtimeChunk = config.optimization?.runtimeChunk;
2584
- if (!runtimeChunk) return config;
2585
- console.warn(runtimeChunkKeptInline(runtimeChunk));
2586
- return {
2587
- ...config,
2588
- optimization: {
2589
- ...config.optimization,
2590
- runtimeChunk: false
2591
- }
2592
- };
2597
+ function buildDevContentScriptStubSource(entryName) {
2598
+ return `;(function(){try{var c=globalThis.chrome;if(!c||!c.runtime||!c.runtime.sendMessage)return;c.runtime.sendMessage({${DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY}:{entry:${JSON.stringify(entryName)}}},function(){try{void c.runtime.lastError}catch(e){}})}catch(e){}})();\n`;
2593
2599
  }
2594
- function userEntryNames(config) {
2595
- const entry = config.entry;
2596
- if (!entry || 'object' != typeof entry || Array.isArray(entry)) return [];
2597
- return Object.keys(entry);
2600
+ function buildDevContentScriptMarkerPrelude(entryName, assetName) {
2601
+ return `;(function(){try{var g=globalThis,k=${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};(g[k]=g[k]||{})[${JSON.stringify(entryName)}]=${JSON.stringify(assetName)}}catch(e){}})();\n`;
2598
2602
  }
2599
- function keepUserEntriesWhole(config) {
2600
- const names = new Set(userEntryNames(config));
2601
- const splitChunks = config.optimization?.splitChunks;
2602
- if (0 === names.size || !splitChunks || 'object' != typeof splitChunks) return config;
2603
- const withoutUserEntries = (chunks)=>{
2604
- if ('function' != typeof chunks) return;
2605
- return (chunk)=>!names.has(String(chunk.name)) && chunks(chunk);
2606
- };
2607
- let changed = false;
2608
- const next = {
2609
- ...splitChunks
2610
- };
2611
- const topLevel = withoutUserEntries(splitChunks.chunks);
2612
- if (topLevel) {
2613
- next.chunks = topLevel;
2614
- changed = true;
2603
+ const DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE = `;(function () {
2604
+ try {
2605
+ var g = (typeof globalThis !== "undefined" ? globalThis : self);
2606
+ if (!g || g.__extjsDevContentScriptsInstalled) return;
2607
+ var chrome = g.chrome;
2608
+ if (!chrome || !chrome.runtime || !chrome.scripting || !chrome.tabs) return;
2609
+ g.__extjsDevContentScriptsInstalled = true;
2610
+
2611
+ var REGISTRY = ${JSON.stringify(DEV_CONTENT_SCRIPT_REGISTRY_ASSET)};
2612
+ var MARKER = ${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};
2613
+ var STUB = ${JSON.stringify(DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY)};
2614
+ var ID_PREFIX = ${JSON.stringify(DEV_CONTENT_SCRIPT_ID_PREFIX)};
2615
+ var STATIC_RELOAD_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY)};
2616
+ var STATIC_BUNDLES_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY)};
2617
+ // The file a frame runs says nothing about which extension generation
2618
+ // injected it, so every probe also stamps the booting worker's token.
2619
+ var GENERATION_KEY = "generation";
2620
+ var GENERATION = Math.random().toString(36).slice(2) + Date.now().toString(36);
2621
+ var registry = null;
2622
+ var ready = false;
2623
+ var whenReady = [];
2624
+
2625
+ function noop() { try { void chrome.runtime.lastError; } catch (e) {
2626
+ // Ignore
2627
+ } }
2628
+ function isString(v) { return typeof v === "string"; }
2629
+ function injectableUrl(url) { return typeof url === "string" && /^(https?|file|ftp):/i.test(url); }
2630
+ function call(fn) { if (fn) { try { fn(); } catch (e) {
2631
+ // Ignore
2632
+ } } }
2633
+ function onReady(fn) { if (ready) call(fn); else whenReady.push(fn); }
2634
+ function markReady() {
2635
+ ready = true;
2636
+ var fns = whenReady;
2637
+ whenReady = [];
2638
+ for (var i = 0; i < fns.length; i++) call(fns[i]);
2615
2639
  }
2616
- if (splitChunks.cacheGroups && 'object' == typeof splitChunks.cacheGroups) {
2617
- const cacheGroups = {};
2618
- for (const [key, group] of Object.entries(splitChunks.cacheGroups)){
2619
- const groupSelector = group && 'object' == typeof group ? withoutUserEntries(group.chunks) : void 0;
2620
- if (groupSelector && group && 'object' == typeof group) {
2621
- cacheGroups[key] = {
2622
- ...group,
2623
- chunks: groupSelector
2624
- };
2625
- changed = true;
2626
- } else cacheGroups[key] = group;
2627
- }
2628
- next.cacheGroups = cacheGroups;
2640
+
2641
+ // The registry is read FROM DISK every time: the bundles it names are
2642
+ // content-hashed and the worker outlives many edits.
2643
+ function load(cb) {
2644
+ try {
2645
+ if (typeof g.fetch !== "function") return cb(null);
2646
+ g.fetch(chrome.runtime.getURL(REGISTRY), {cache: "no-store"})
2647
+ .then(function (r) { return r && r.ok ? r.json() : null; })
2648
+ .then(function (reg) { cb(reg && Array.isArray(reg.entries) ? reg : null); })
2649
+ .catch(function () { cb(null); });
2650
+ } catch (e) { cb(null); }
2629
2651
  }
2630
- if (!changed) return config;
2631
- return {
2632
- ...config,
2633
- optimization: {
2634
- ...config.optimization,
2635
- splitChunks: next
2636
- }
2637
- };
2638
- }
2639
- function isValidBundleId(value) {
2640
- return /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*$/.test(value);
2641
- }
2642
- function resolveSafariIdentity(merged) {
2643
- if (merged.bundleId && !isValidBundleId(merged.bundleId)) throw new Error(safariInvalidBundleId(merged.bundleId));
2644
- return {
2645
- appName: merged.appName,
2646
- bundleId: merged.bundleId,
2647
- developmentTeam: merged.developmentTeam,
2648
- macOsOnly: merged.macOsOnly,
2649
- forceRegenerate: merged.forceRegenerate,
2650
- safariBinary: merged.safariBinary
2651
- };
2652
- }
2653
- const ARTIFACTS_KEY = '__extensionJsZipArtifacts';
2654
- function recordZipArtifact(carrier, artifact) {
2655
- if (!carrier || 'object' != typeof carrier) return;
2656
- const host = carrier;
2657
- if (!Array.isArray(host[ARTIFACTS_KEY])) host[ARTIFACTS_KEY] = [];
2658
- host[ARTIFACTS_KEY].push(artifact);
2659
- }
2660
- function getZipArtifacts(carrier) {
2661
- if (!carrier || 'object' != typeof carrier) return [];
2662
- const host = carrier;
2663
- return Array.isArray(host[ARTIFACTS_KEY]) ? host[ARTIFACTS_KEY] : [];
2664
- }
2665
- const FAILURES_KEY = '__extensionJsZipFailures';
2666
- function recordZipFailure(carrier, failure) {
2667
- if (!carrier || 'object' != typeof carrier) return;
2668
- const host = carrier;
2669
- if (!Array.isArray(host[FAILURES_KEY])) host[FAILURES_KEY] = [];
2670
- host[FAILURES_KEY].push(failure);
2671
- }
2672
- function getZipFailures(carrier) {
2673
- if (!carrier || 'object' != typeof carrier) return [];
2674
- const host = carrier;
2675
- return Array.isArray(host[FAILURES_KEY]) ? host[FAILURES_KEY] : [];
2676
- }
2677
- function hasDependency(projectPath, packageName) {
2678
- return hasProjectDependency(projectPath, packageName);
2679
- }
2680
- function isUsingJSFramework(projectPath) {
2681
- const frameworks = [
2682
- 'react',
2683
- 'vue',
2684
- '@angular/core',
2685
- 'svelte',
2686
- 'solid-js',
2687
- 'preact'
2688
- ];
2689
- return frameworks.some((fw)=>hasDependency(projectPath, fw));
2690
- }
2691
- function isUsingIntegration(name) {
2692
- return `integration use=${name}`;
2693
- }
2694
- function vueTwoSingleFileComponent(version, files) {
2695
- const list = files.map((file)=>`- ${pintor.underline(file)}`).join('\n');
2696
- return `Vue ${version} is installed, and Extension.js compiles .vue files for Vue 3 only.\n${list}\nVue 2 reached end of life in December 2023 and vue-loader 15 cannot read the loader rules this build uses.\nUpgrade to ${pintor.yellow('vue@3')} with ${pintor.yellow('vue-loader@17')}, or write these components as render functions.`;
2697
- }
2698
- function creatingTSConfig() {
2699
- return `${messaging_prefix('info')} Creating a default tsconfig.json…`;
2700
- }
2701
- function svelteCompilerRuntimeMismatch(compilerVersion, projectVersion) {
2702
- return `${messaging_prefix('warn')} Svelte ${pintor.blue(compilerVersion)} compiles this project, which pins svelte ${pintor.blue(projectVersion)}.\nThe build uses ${pintor.blue(compilerVersion)} for both, so the output links. Add ${pintor.blue('svelte-loader')} to the project to compile with ${pintor.blue(projectVersion)} instead.`;
2703
- }
2704
- function isUsingCustomLoader(loaderPath) {
2705
- return `${messaging_prefix('debug')} loader custom=${loaderPath}`;
2706
- }
2707
- function jsFrameworksIntegrationsEnabled(integrations) {
2708
- const names = integrations.length > 0 ? integrations.join(',') : 'none';
2709
- return `${messaging_prefix('debug')} js integrations=${integrations.length} names=${names}`;
2710
- }
2711
- function jsFrameworksConfigsDetected(tsConfigPath, tsRoot, targets) {
2712
- const val = (v)=>v || 'none';
2713
- const tgt = targets?.length ? targets.join(',') : 'default';
2714
- return `${messaging_prefix('debug')} js config tsconfig=${val(tsConfigPath)} tsRoot=${val(tsRoot)} swcTargets="${tgt}"`;
2715
- }
2716
- function jsFrameworksHmrSummary(enabled, frameworks) {
2717
- const names = frameworks.length > 0 ? frameworks.join(',') : 'none';
2718
- return `${messaging_prefix('debug')} js hmr=${enabled ? 'enabled' : 'disabled'} frameworks=${names}`;
2719
- }
2720
- let userMessageDelivered = false;
2721
- function isUsingReact(projectPath) {
2722
- if (hasDependency(projectPath, 'react')) {
2723
- if (!userMessageDelivered) {
2724
- if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('React')}`);
2725
- userMessageDelivered = true;
2726
- }
2727
- return true;
2652
+
2653
+ // Every field is sent: updateContentScripts keeps any key left out, so a
2654
+ // dropped exclude_matches, css file or fallback would outlive the edit.
2655
+ function registrationOf(e) {
2656
+ return {
2657
+ id: e.id,
2658
+ matches: e.matches,
2659
+ excludeMatches: Array.isArray(e.excludeMatches) ? e.excludeMatches.filter(isString) : [],
2660
+ js: (e.js || []).filter(isString),
2661
+ css: (e.css || []).filter(isString),
2662
+ runAt: e.runAt === "document_start" || e.runAt === "document_end" ? e.runAt : "document_idle",
2663
+ allFrames: !!e.allFrames,
2664
+ world: e.world === "MAIN" ? "MAIN" : "ISOLATED",
2665
+ matchOriginAsFallback: e.matchOriginAsFallback === true,
2666
+ persistAcrossSessions: false
2667
+ };
2728
2668
  }
2729
- return false;
2730
- }
2731
- async function maybeUseReact(projectPath, options = {}) {
2732
- if (!isUsingReact(projectPath)) return;
2733
- const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
2734
- let reactPath;
2735
- let reactDomPath;
2736
- let reactDomClientPath;
2737
- let jsxRuntimePath;
2738
- let jsxDevRuntimePath;
2739
- try {
2740
- reactPath = requireFromProject.resolve('react');
2741
- } catch {}
2742
- try {
2743
- reactDomPath = requireFromProject.resolve('react-dom');
2744
- } catch {}
2745
- try {
2746
- reactDomClientPath = requireFromProject.resolve('react-dom/client');
2747
- } catch {}
2748
- try {
2749
- jsxRuntimePath = requireFromProject.resolve('react/jsx-runtime');
2750
- } catch {}
2751
- try {
2752
- jsxDevRuntimePath = requireFromProject.resolve('react/jsx-dev-runtime');
2753
- } catch {}
2754
- const alias = {};
2755
- if (reactPath) alias.react$ = reactPath;
2756
- if (reactDomPath) alias['react-dom$'] = reactDomPath;
2757
- if (reactDomClientPath) alias['react-dom/client'] = reactDomClientPath;
2758
- if (jsxRuntimePath) alias['react/jsx-runtime'] = jsxRuntimePath;
2759
- if (jsxDevRuntimePath) alias['react/jsx-dev-runtime'] = jsxDevRuntimePath;
2760
- if (true === options.disableRefresh) return {
2761
- plugins: [],
2762
- loaders: void 0,
2763
- alias
2764
- };
2765
- resolveOptionalContractPackageWithoutInstall({
2766
- contractId: 'react-refresh',
2767
- projectPath,
2768
- dependencyId: 'react-refresh'
2769
- });
2770
- const ReactRefreshPlugin = loadOptionalContractModuleWithoutInstall({
2771
- contractId: 'react-refresh',
2772
- projectPath,
2773
- dependencyId: '@rspack/plugin-react-refresh',
2774
- moduleAdapter: (mod)=>mod && (mod.default || mod.ReactRefreshRspackPlugin) || mod
2775
- });
2776
- const refreshEntry = resolveReactRefreshEntry(projectPath);
2777
- const reactPlugins = [
2778
- new ReactRefreshPlugin({
2779
- overlay: false,
2780
- injectEntry: !refreshEntry,
2781
- ...void 0 === options.refreshExclude ? {} : {
2782
- exclude: options.refreshExclude
2669
+
2670
+ // Register what the registry names, update what is already registered,
2671
+ // drop dev registrations it no longer names. Idempotent per entry id.
2672
+ function sync(reg, done) {
2673
+ try {
2674
+ if (!chrome.scripting.registerContentScripts || !chrome.scripting.getRegisteredContentScripts) return call(done);
2675
+ var wanted = [];
2676
+ for (var i = 0; i < reg.entries.length; i++) {
2677
+ var e = reg.entries[i] || {};
2678
+ if (e.stubOnly || e.static || !isString(e.id) || !Array.isArray(e.matches) || !e.matches.length) continue;
2679
+ var r = registrationOf(e);
2680
+ if (!r.js.length && !r.css.length) continue;
2681
+ wanted.push(r);
2682
+ }
2683
+ chrome.scripting.getRegisteredContentScripts(function (existing) {
2684
+ noop();
2685
+ var have = {};
2686
+ if (existing) {
2687
+ for (var k = 0; k < existing.length; k++) {
2688
+ if (existing[k] && isString(existing[k].id)) have[existing[k].id] = true;
2783
2689
  }
2784
- })
2785
- ];
2786
- return {
2787
- plugins: reactPlugins,
2788
- loaders: void 0,
2789
- alias
2790
- };
2791
- }
2792
- function resolveReactRefreshEntry(projectPath) {
2793
- try {
2794
- const pluginMain = resolveOptionalContractPackageWithoutInstall({
2795
- contractId: 'react-refresh',
2796
- projectPath,
2797
- dependencyId: '@rspack/plugin-react-refresh'
2690
+ }
2691
+ var toRegister = [], toUpdate = [], toDrop = [], keep = {};
2692
+ for (var j = 0; j < wanted.length; j++) {
2693
+ keep[wanted[j].id] = true;
2694
+ (have[wanted[j].id] ? toUpdate : toRegister).push(wanted[j]);
2695
+ }
2696
+ for (var id in have) {
2697
+ if (id.indexOf(ID_PREFIX) === 0 && !keep[id]) toDrop.push(id);
2698
+ }
2699
+ var ops = [];
2700
+ if (toDrop.length && chrome.scripting.unregisterContentScripts) ops.push(["unregisterContentScripts", {ids: toDrop}]);
2701
+ if (toUpdate.length && chrome.scripting.updateContentScripts) ops.push(["updateContentScripts", toUpdate]);
2702
+ if (toRegister.length) ops.push(["registerContentScripts", toRegister]);
2703
+ var pending = ops.length;
2704
+ if (!pending) return call(done);
2705
+ var step = function () { pending--; if (pending <= 0) call(done); };
2706
+ for (var o = 0; o < ops.length; o++) {
2707
+ try { chrome.scripting[ops[o][0]](ops[o][1], function () { noop(); step(); }); } catch (e) { step(); }
2708
+ }
2798
2709
  });
2799
- const marker = `${__rspack_external_node_path_806ed179.sep}@rspack${__rspack_external_node_path_806ed179.sep}plugin-react-refresh${__rspack_external_node_path_806ed179.sep}`;
2800
- const at = String(pluginMain || '').lastIndexOf(marker);
2801
- if (-1 === at) return;
2802
- const root = String(pluginMain).slice(0, at + marker.length);
2803
- const entry = __rspack_external_node_path_806ed179.join(root, 'client', 'reactRefreshEntry.js');
2804
- return __rspack_external_node_fs_1b05aee1.existsSync(entry) ? entry : void 0;
2805
- } catch {
2806
- return;
2807
- }
2808
- }
2809
- let preact_userMessageDelivered = false;
2810
- function isUsingPreact(projectPath) {
2811
- if (hasDependency(projectPath, 'preact')) {
2812
- if (!preact_userMessageDelivered) {
2813
- if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Preact')}`);
2814
- preact_userMessageDelivered = true;
2815
- }
2816
- return true;
2710
+ } catch (e) { call(done); }
2817
2711
  }
2818
- return false;
2819
- }
2820
- async function maybeUsePreact(projectPath) {
2821
- if (!isUsingPreact(projectPath)) return;
2822
- const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
2823
- const resolveFromProject = (id)=>{
2824
- try {
2825
- return requireFromProject.resolve(id);
2826
- } catch {
2827
- return;
2828
- }
2829
- };
2830
- const preactPkgJson = resolveFromProject('preact/package.json');
2831
- const preactDir = preactPkgJson ? __rspack_external_node_path_806ed179.dirname(preactPkgJson) : void 0;
2832
- const preactCompat = resolveFromProject('preact/compat');
2833
- const preactTestUtils = resolveFromProject('preact/test-utils');
2834
- const preactJsxRuntime = resolveFromProject('preact/jsx-runtime');
2835
- const preactJsxDevRuntime = resolveFromProject('preact/jsx-dev-runtime');
2836
- const alias = {};
2837
- if (preactJsxRuntime) alias['preact/jsx-runtime'] = preactJsxRuntime;
2838
- if (preactJsxDevRuntime) alias['preact/jsx-dev-runtime'] = preactJsxDevRuntime;
2839
- if (preactDir) alias.preact = preactDir;
2840
- if (!isUsingReact(projectPath)) {
2841
- if (preactCompat) {
2842
- alias.react = preactCompat;
2843
- alias['react-dom'] = preactCompat;
2844
- }
2845
- if (preactTestUtils) alias['react-dom/test-utils'] = preactTestUtils;
2846
- if (preactJsxRuntime) alias['react/jsx-runtime'] = preactJsxRuntime;
2847
- if (preactJsxDevRuntime) alias['react/jsx-dev-runtime'] = preactJsxDevRuntime;
2848
- }
2849
- return {
2850
- plugins: [],
2851
- loaders: void 0,
2852
- alias
2853
- };
2854
- }
2855
- const RAW_RESOURCE_QUERY = /(?:^\?|&)raw(?:&|=|$)/;
2856
- const NOT_RAW_RESOURCE_QUERY = {
2857
- not: [
2858
- RAW_RESOURCE_QUERY
2859
- ]
2860
- };
2861
- function normalizePath(filePath) {
2862
- return filePath.replace(/\\/g, '/');
2863
- }
2864
- function tryReadJson(filePath) {
2865
- try {
2866
- return JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(filePath, 'utf-8'));
2867
- } catch {
2868
- return;
2869
- }
2870
- }
2871
- function findPackageRootFromEntry(entryPath, packageName) {
2872
- let currentDir = __rspack_external_node_path_806ed179.dirname(entryPath);
2873
- while(true){
2874
- const packageJsonPath = __rspack_external_node_path_806ed179.join(currentDir, 'package.json');
2875
- const packageJson = tryReadJson(packageJsonPath);
2876
- if (packageJson?.name === packageName) return currentDir;
2877
- const parentDir = __rspack_external_node_path_806ed179.dirname(currentDir);
2878
- if (parentDir === currentDir) return;
2879
- currentDir = parentDir;
2712
+
2713
+ // Inject one entry into the frames of a tab whose world does not already
2714
+ // run the current file, or on a heal ran it for a previous extension
2715
+ // generation. Chromium's own injection sets the same marker.
2716
+ function inject(e, target, sameGeneration, done) {
2717
+ var world = e.world === "MAIN" ? "MAIN" : "ISOLATED";
2718
+ var js = (e.js || []).filter(isString), css = (e.css || []).filter(isString);
2719
+ var probe = {target: target, world: world, injectImmediately: true,
2720
+ args: [MARKER, GENERATION_KEY, e.entry, js[0] || "", GENERATION, !!sameGeneration],
2721
+ func: function (key, genKey, entry, file, gen, needGen) {
2722
+ try {
2723
+ var g = globalThis, m = g[key] = g[key] || {}, gens = m[genKey] = m[genKey] || {};
2724
+ var covered = m[entry] === file && (!needGen || gens[entry] === gen);
2725
+ gens[entry] = gen;
2726
+ return covered;
2727
+ } catch (x) { return false; }
2728
+ }};
2729
+ try {
2730
+ chrome.scripting.executeScript(probe, function (results) {
2731
+ noop();
2732
+ var frameIds = [];
2733
+ if (results) {
2734
+ for (var i = 0; i < results.length; i++) {
2735
+ var r = results[i];
2736
+ if (!r || r.result === true) continue;
2737
+ frameIds.push(typeof r.frameId === "number" ? r.frameId : 0);
2738
+ }
2739
+ }
2740
+ if (!frameIds.length) return call(done);
2741
+ var into = {tabId: target.tabId, frameIds: frameIds};
2742
+ if (css.length && chrome.scripting.insertCSS) {
2743
+ try { chrome.scripting.insertCSS({target: into, files: css}, noop); } catch (x) {
2744
+ // Ignore
2745
+ }
2746
+ }
2747
+ if (!js.length) return call(done);
2748
+ try {
2749
+ chrome.scripting.executeScript({target: into, files: js, world: world, injectImmediately: true}, function () { noop(); call(done); });
2750
+ } catch (x) { call(done); }
2751
+ });
2752
+ } catch (x) { call(done); }
2880
2753
  }
2881
- }
2882
- function resolvePackageRoot(requireFromProject, projectRoot, packageName) {
2883
- try {
2884
- return __rspack_external_node_path_806ed179.dirname(requireFromProject.resolve(`${packageName}/package.json`));
2885
- } catch {}
2886
- try {
2887
- const entryPath = requireFromProject.resolve(packageName);
2888
- const discovered = findPackageRootFromEntry(entryPath, packageName);
2889
- if (discovered) return discovered;
2890
- } catch {}
2891
- const guessedPackageDir = __rspack_external_node_path_806ed179.join(projectRoot, 'node_modules', ...packageName.split('/'));
2892
- if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(guessedPackageDir, 'package.json'))) return guessedPackageDir;
2893
- }
2894
- function getWorkspaceDependencyNames(projectRoot) {
2895
- const packageJsonPath = __rspack_external_node_path_806ed179.join(projectRoot, 'package.json');
2896
- try {
2897
- const packageJson = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(packageJsonPath, 'utf-8'));
2898
- const dependencySections = [
2899
- packageJson.dependencies,
2900
- packageJson.devDependencies,
2901
- packageJson.peerDependencies,
2902
- packageJson.optionalDependencies
2903
- ];
2904
- const names = new Set();
2905
- for (const section of dependencySections)if (section && 'object' == typeof section) {
2906
- for (const [name, version] of Object.entries(section))if ('string' == typeof version) {
2907
- if (version.startsWith('workspace:') || version.startsWith('link:') || version.startsWith('file:')) names.add(name);
2754
+
2755
+ // The open tabs an entry matches, exclude_matches honored, tabs still
2756
+ // loading skipped when asked: Chromium injects those itself on landing.
2757
+ function tabsFor(e, completeOnly, cb) {
2758
+ var matches = Array.isArray(e.matches) ? e.matches : [];
2759
+ if (!matches.length) return cb([]);
2760
+ var excludes = Array.isArray(e.excludeMatches) ? e.excludeMatches : [];
2761
+ var collect = function (excludedIds) {
2762
+ try {
2763
+ chrome.tabs.query({url: matches}, function (tabs) {
2764
+ noop();
2765
+ var out = [];
2766
+ for (var i = 0; tabs && i < tabs.length; i++) {
2767
+ var t = tabs[i];
2768
+ if (!t || t.id == null || !injectableUrl(t.url) || excludedIds[t.id]) continue;
2769
+ if (completeOnly && t.status === "loading") continue;
2770
+ out.push(t);
2908
2771
  }
2909
- }
2910
- return Array.from(names);
2911
- } catch {
2912
- return [];
2772
+ cb(out);
2773
+ });
2774
+ } catch (x) { cb([]); }
2775
+ };
2776
+ if (!excludes.length) return collect({});
2777
+ try {
2778
+ chrome.tabs.query({url: excludes}, function (tabs) {
2779
+ noop();
2780
+ var ids = {};
2781
+ for (var i = 0; tabs && i < tabs.length; i++) if (tabs[i] && tabs[i].id != null) ids[tabs[i].id] = true;
2782
+ collect(ids);
2783
+ });
2784
+ } catch (x) { collect({}); }
2913
2785
  }
2914
- }
2915
- function resolveTranspilePackageDirs(projectRoot, transpilePackages) {
2916
- const autoWorkspacePackages = getWorkspaceDependencyNames(projectRoot);
2917
- const packageNames = Array.from(new Set([
2918
- ...autoWorkspacePackages,
2919
- ...transpilePackages || []
2920
- ].map((entry)=>String(entry || '').trim()).filter(Boolean)));
2921
- if (0 === packageNames.length) return [];
2922
- const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectRoot, 'package.json'));
2923
- const resolvedDirs = new Set();
2924
- for (const packageName of packageNames){
2925
- const packageDir = resolvePackageRoot(requireFromProject, projectRoot, packageName);
2926
- if (packageDir) {
2927
- resolvedDirs.add(normalizePath(packageDir));
2928
- try {
2929
- resolvedDirs.add(normalizePath(__rspack_external_node_fs_1b05aee1.realpathSync(packageDir)));
2930
- } catch {}
2786
+
2787
+ // The boot read can fail or land on a registry mid-write, and the file on
2788
+ // disk can name an entry the loaded one does not. One re-read per need,
2789
+ // shared by the callers waiting on it, and no re-sync of an unchanged file.
2790
+ var refreshing = [];
2791
+ function refresh(cb) {
2792
+ refreshing.push(cb);
2793
+ if (refreshing.length > 1) return;
2794
+ var finish = function () {
2795
+ var fns = refreshing;
2796
+ refreshing = [];
2797
+ for (var i = 0; i < fns.length; i++) call(fns[i]);
2798
+ };
2799
+ load(function (reg) {
2800
+ if (!reg) return finish();
2801
+ var same = false;
2802
+ try { same = !!registry && JSON.stringify(reg) === JSON.stringify(registry); } catch (e) {
2803
+ // Ignore
2931
2804
  }
2805
+ registry = reg;
2806
+ if (same) return finish();
2807
+ sync(reg, finish);
2808
+ });
2932
2809
  }
2933
- return Array.from(resolvedDirs);
2934
- }
2935
- function createNodeModulesExclude(transpilePackageDirs) {
2936
- return (resourcePath)=>{
2937
- if (!/[\\/]node_modules[\\/]/.test(resourcePath)) return false;
2938
- return !transpilePackageDirs.some((dir)=>isSubPath(resourcePath, dir));
2939
- };
2940
- }
2941
- function isSubPath(resourcePath, directoryPath) {
2942
- return isResourceUnderDirs(resourcePath, [
2943
- canonicalizeDir(directoryPath)
2944
- ]);
2945
- }
2946
- let solid_userMessageDelivered = false;
2947
- function isUsingSolid(projectPath) {
2948
- const using = hasDependency(projectPath, 'solid-js');
2949
- if (using && !solid_userMessageDelivered) {
2950
- if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Solid')}`);
2951
- solid_userMessageDelivered = true;
2810
+
2811
+ function entriesFor(name) {
2812
+ var out = [];
2813
+ if (!registry) return out;
2814
+ for (var i = 0; i < registry.entries.length; i++) {
2815
+ var e = registry.entries[i];
2816
+ if (e && !e.static && e.entry === name) out.push(e);
2817
+ }
2818
+ return out;
2952
2819
  }
2953
- return using;
2954
- }
2955
- function pickEsmCondition(entry) {
2956
- if ('string' == typeof entry) return entry;
2957
- if (!entry || 'object' != typeof entry) return;
2958
- const conditions = entry;
2959
- for (const name of [
2960
- 'browser',
2961
- 'import',
2962
- 'module',
2963
- 'default'
2964
- ]){
2965
- const picked = pickEsmCondition(conditions[name]);
2966
- if (picked) return picked;
2820
+
2821
+ function onStub(msg, sender) {
2822
+ if (!msg || !isString(msg.entry) || !sender || !sender.tab || sender.tab.id == null) return;
2823
+ var tabId = sender.tab.id;
2824
+ var frameId = typeof sender.frameId === "number" ? sender.frameId : 0;
2825
+ onReady(function () {
2826
+ var serve = function () {
2827
+ var entries = entriesFor(msg.entry);
2828
+ for (var i = 0; i < entries.length; i++) inject(entries[i], {tabId: tabId, frameIds: [frameId]}, false);
2829
+ };
2830
+ if (entriesFor(msg.entry).length) return serve();
2831
+ refresh(serve);
2832
+ });
2967
2833
  }
2968
- }
2969
- function resolveSolidHyperscript(resolveFromProject) {
2970
- const packageJsonPath = resolveFromProject('solid-js/package.json');
2971
- if (packageJsonPath) try {
2972
- const packageJson = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(packageJsonPath, 'utf-8'));
2973
- const subpath = pickEsmCondition(packageJson?.exports?.['./h']);
2974
- if (subpath) {
2975
- const esmPath = __rspack_external_node_path_806ed179.resolve(__rspack_external_node_path_806ed179.dirname(packageJsonPath), subpath);
2976
- if (__rspack_external_node_fs_1b05aee1.existsSync(esmPath)) return esmPath;
2977
- }
2978
- } catch {}
2979
- return resolveFromProject('solid-js/h/dist/h.js') || resolveFromProject('solid-js/h');
2980
- }
2981
- function solidBabelOptions(input) {
2982
- return {
2983
- babelrc: false,
2984
- configFile: false,
2985
- sourceMaps: true,
2986
- compact: false,
2987
- sourceType: 'module',
2988
- parserOpts: {
2989
- strictMode: false
2990
- },
2991
- presets: [
2992
- [
2993
- input.solidPreset,
2994
- {
2995
- development: input.development
2996
- }
2997
- ],
2998
- ...input.typescript ? [
2999
- [
3000
- input.typescriptPreset,
3001
- {
3002
- isTSX: true,
3003
- allExtensions: true,
3004
- onlyRemoveTypeImports: true
3005
- }
3006
- ]
3007
- ] : []
3008
- ]
3009
- };
3010
- }
3011
- async function maybeUseSolid(projectPath, mode = 'development', transpilePackageDirs = []) {
3012
- if (!isUsingSolid(projectPath)) return;
3013
- const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
3014
- const resolveFromProject = (id)=>{
3015
- try {
3016
- return requireFromProject.resolve(id);
3017
- } catch {
3018
- return;
3019
- }
3020
- };
3021
- const resolveContractPackage = (dependencyId)=>ensureOptionalContractPackageResolved({
3022
- contractId: 'solid',
3023
- projectPath,
3024
- dependencyId
3025
- });
3026
- const babelLoader = await resolveContractPackage('babel-loader');
3027
- const solidPreset = await resolveContractPackage('babel-preset-solid');
3028
- const typescriptPreset = await resolveContractPackage("@babel/preset-typescript");
3029
- const adapter = resolveDevelopDistFile('solid-jsx-runtime');
3030
- const hyperscript = resolveSolidHyperscript(resolveFromProject);
3031
- const alias = {
3032
- 'solid-js/jsx-runtime$': adapter,
3033
- 'solid-js/jsx-dev-runtime$': adapter
3034
- };
3035
- if (hyperscript) alias['solid-js/h$'] = hyperscript;
3036
- const development = 'development' === mode;
3037
- const excludeNodeModules = createNodeModulesExclude(transpilePackageDirs);
3038
- const javascriptOptions = solidBabelOptions({
3039
- solidPreset,
3040
- typescriptPreset,
3041
- typescript: false,
3042
- development
3043
- });
3044
- const loaders = [
3045
- {
3046
- test: /\.(jsx|mjsx)$/,
3047
- exclude: excludeNodeModules,
3048
- resourceQuery: NOT_RAW_RESOURCE_QUERY,
3049
- loader: babelLoader,
3050
- options: javascriptOptions
3051
- },
3052
- {
3053
- test: /\.(tsx|mtsx)$/,
3054
- exclude: excludeNodeModules,
3055
- resourceQuery: NOT_RAW_RESOURCE_QUERY,
3056
- loader: babelLoader,
3057
- options: solidBabelOptions({
3058
- solidPreset,
3059
- typescriptPreset,
3060
- typescript: true,
3061
- development
3062
- })
3063
- },
3064
- {
3065
- test: /\.(js|mjs|cjs)$/,
3066
- exclude: excludeNodeModules,
3067
- resourceQuery: NOT_RAW_RESOURCE_QUERY,
3068
- loader: resolveDevelopDistFile('solid-jsx-gate-loader'),
3069
- options: {
3070
- ...javascriptOptions,
3071
- babelLoader
2834
+
2835
+ // After a worker restart the open tabs still run the previous generation,
2836
+ // and Chromium never injects into a tab that finished loading before it.
2837
+ function heal(done) {
2838
+ onReady(function () {
2839
+ if (registry) return healEntries(done);
2840
+ refresh(function () { healEntries(done); });
2841
+ });
2842
+ }
2843
+
2844
+ function healEntries(done) {
2845
+ if (!registry) return call(done);
2846
+ var pending = 1;
2847
+ var step = function () { pending--; if (pending <= 0) call(done); };
2848
+ for (var i = 0; i < registry.entries.length; i++) {
2849
+ (function (e) {
2850
+ if (!e || e.stubOnly || e.static) return;
2851
+ pending++;
2852
+ tabsFor(e, true, function (tabs) {
2853
+ var left = tabs.length;
2854
+ if (!left) return step();
2855
+ for (var t = 0; t < tabs.length; t++) {
2856
+ inject(e, {tabId: tabs[t].id, allFrames: !!e.allFrames}, true, function () { if (--left === 0) step(); });
3072
2857
  }
3073
- }
3074
- ];
3075
- return {
3076
- plugins: [],
3077
- loaders,
3078
- alias
3079
- };
3080
- }
3081
- let load_loader_options_userMessageDelivered = false;
3082
- function resolveLoaderConfigPath(projectPath, framework) {
3083
- const candidates = [
3084
- __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.ts`),
3085
- __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.mts`),
3086
- __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.js`),
3087
- __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.mjs`)
3088
- ];
3089
- return candidates.find((p)=>__rspack_external_node_fs_1b05aee1.existsSync(p)) || null;
3090
- }
3091
- function load_loader_options_isPlainObject(value) {
3092
- return 'object' == typeof value && null !== value && !Array.isArray(value);
3093
- }
3094
- function mergeLoaderOptions(defaults, custom) {
3095
- if (!load_loader_options_isPlainObject(custom)) return {
3096
- ...defaults
3097
- };
3098
- const merged = {
3099
- ...defaults,
3100
- ...custom
3101
- };
3102
- for (const [key, value] of Object.entries(custom))if (load_loader_options_isPlainObject(defaults[key]) && load_loader_options_isPlainObject(value)) merged[key] = {
3103
- ...defaults[key],
3104
- ...value
3105
- };
3106
- return merged;
3107
- }
3108
- async function loadLoaderOptions(projectPath, framework) {
3109
- const configPath = resolveLoaderConfigPath(projectPath, framework);
3110
- if (configPath) {
3111
- if (!load_loader_options_userMessageDelivered && isDebug()) {
3112
- const display = __rspack_external_node_path_806ed179.basename(configPath);
3113
- debugLine(isUsingCustomLoader(display));
3114
- load_loader_options_userMessageDelivered = true;
3115
- }
3116
- try {
3117
- const module = await import(pathToFileURL(configPath).href);
3118
- return module.default || module;
3119
- } catch (err) {
3120
- const error = err;
3121
- console.error(`Error loading ${framework} loader options: ${error.message}`);
3122
- throw err;
3123
- }
2858
+ });
2859
+ })(registry.entries[i]);
2860
+ }
2861
+ step();
3124
2862
  }
3125
- return null;
3126
- }
3127
- let vue_userMessageDelivered = false;
3128
- function isUsingVue(projectPath) {
3129
- const using = hasDependency(projectPath, 'vue');
3130
- if (using && !vue_userMessageDelivered) {
3131
- if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Vue')}`);
3132
- vue_userMessageDelivered = true;
2863
+
2864
+ // Reload every tab the given entries match, each once.
2865
+ function reloadTabs(entries, done) {
2866
+ var seen = {};
2867
+ var pending = 1;
2868
+ var step = function () { pending--; if (pending <= 0) call(done); };
2869
+ for (var i = 0; i < entries.length; i++) {
2870
+ pending++;
2871
+ tabsFor(entries[i], false, function (tabs) {
2872
+ for (var t = 0; t < tabs.length; t++) {
2873
+ var id = tabs[t].id;
2874
+ if (seen[id]) continue;
2875
+ seen[id] = true;
2876
+ try { chrome.tabs.reload(id, {}, noop); } catch (x) {
2877
+ // Ignore
2878
+ }
2879
+ }
2880
+ step();
2881
+ });
2882
+ }
2883
+ step();
3133
2884
  }
3134
- return using;
3135
- }
3136
- function resolveVueBundlerEntry(requireFromProject, id) {
3137
- try {
3138
- const manifestPath = requireFromProject.resolve(`${id}/package.json`);
3139
- const manifest = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf8'));
3140
- if ('string' == typeof manifest.module && manifest.module) {
3141
- const entry = __rspack_external_node_path_806ed179.join(__rspack_external_node_path_806ed179.dirname(manifestPath), manifest.module);
3142
- if (__rspack_external_node_fs_1b05aee1.existsSync(entry)) return entry;
2885
+
2886
+ // Only an extension reload ships a static entry's edit. The next generation
2887
+ // reloads the tabs it matches, and the producer's flag heals the rest.
2888
+ function reloadExtensionFor(entries) {
2889
+ var names = [];
2890
+ for (var i = 0; i < entries.length; i++) names.push(entries[i].entry);
2891
+ try {
2892
+ if (chrome.storage && chrome.storage.local) {
2893
+ var flags = {__extjsDevPendingReinject: Date.now()};
2894
+ flags[STATIC_RELOAD_KEY] = {entries: names, at: Date.now()};
2895
+ chrome.storage.local.set(flags, noop);
3143
2896
  }
3144
- } catch {}
3145
- try {
3146
- return requireFromProject.resolve(id);
3147
- } catch {
3148
- return;
3149
- }
3150
- }
3151
- function readInstalledVueVersion(requireFromProject) {
3152
- try {
3153
- const manifestPath = requireFromProject.resolve('vue/package.json');
3154
- const version = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf8')).version;
3155
- return 'string' == typeof version ? version : void 0;
3156
- } catch {
3157
- return;
2897
+ } catch (e) {
2898
+ // Ignore
2899
+ }
2900
+ // The producer's restart also brings the url-override tabs back.
2901
+ if (typeof g.__extjsDevRestartExtension === "function") {
2902
+ try { g.__extjsDevRestartExtension(150); return; } catch (e) {
2903
+ // Ignore
2904
+ }
2905
+ }
2906
+ setTimeout(function () { try { chrome.runtime.reload(); } catch (e) {
2907
+ // Ignore
2908
+ } }, 150);
3158
2909
  }
3159
- }
3160
- class RefuseVueTwoSingleFileComponents {
3161
- version;
3162
- constructor(version){
3163
- this.version = version;
2910
+
2911
+ function staticBundlesOf(e) {
2912
+ return (e.js || []).filter(isString).concat((e.css || []).filter(isString)).join("\\n");
3164
2913
  }
3165
- apply(compiler) {
3166
- const name = RefuseVueTwoSingleFileComponents.name;
3167
- compiler.hooks.thisCompilation.tap(name, (compilation)=>{
3168
- compilation.hooks.finishModules.tap(name, (modules)=>{
3169
- const files = new Set();
3170
- for (const module of modules){
3171
- const { resource = '', type } = module;
3172
- const file = resource.split('?')[0];
3173
- if ('asset/source' === type && file.endsWith('.vue')) files.add(file);
3174
- }
3175
- if (0 === files.size) return;
3176
- const sorted = [
3177
- ...files
3178
- ].sort();
3179
- const error = new WebpackError(vueTwoSingleFileComponent(this.version, sorted));
3180
- error.file = __rspack_external_node_path_806ed179.relative(compiler.context, sorted[0]);
3181
- error.stack = '';
3182
- compilation.errors.push(error);
3183
- });
3184
- });
3185
- }
3186
- }
3187
- function vueTwoWithoutLoader(requireFromProject, version) {
3188
- const alias = {};
3189
- const vuePath = resolveVueBundlerEntry(requireFromProject, 'vue');
3190
- if (vuePath) alias.vue$ = vuePath;
3191
- return {
3192
- plugins: [
3193
- new RefuseVueTwoSingleFileComponents(version)
3194
- ],
3195
- loaders: [
3196
- {
3197
- test: /\.vue$/,
3198
- type: 'asset/source'
2914
+
2915
+ // The static entries' hashed bundle names, as recorded by the previous
2916
+ // generation: a service worker reload ships a shared module's edit to a
2917
+ // static entry too, and nothing but the name says its tabs are stale.
2918
+ function healStaticEntries() {
2919
+ try {
2920
+ if (!chrome.storage || !chrome.storage.local) return;
2921
+ chrome.storage.local.get([STATIC_RELOAD_KEY, STATIC_BUNDLES_KEY], function (res) {
2922
+ noop();
2923
+ var flag = res && res[STATIC_RELOAD_KEY];
2924
+ var recorded = res && res[STATIC_BUNDLES_KEY];
2925
+ if (flag) {
2926
+ try { chrome.storage.local.remove(STATIC_RELOAD_KEY, noop); } catch (e) {
2927
+ // Ignore
3199
2928
  }
3200
- ],
3201
- alias
3202
- };
3203
- }
3204
- async function maybeUseVue(projectPath, mode = 'development', transpilePackageDirs = []) {
3205
- if (!isUsingVue(projectPath)) return;
3206
- const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
3207
- const installedVersion = readInstalledVueVersion(requireFromProject);
3208
- if (installedVersion && /^2\./.test(installedVersion)) return vueTwoWithoutLoader(requireFromProject, installedVersion);
3209
- const vueLoaderPath = await ensureOptionalContractPackageResolved({
3210
- contractId: 'vue',
3211
- projectPath,
3212
- dependencyId: 'vue-loader'
3213
- });
3214
- const VueLoaderPlugin = await ensureOptionalContractModuleLoaded({
3215
- contractId: 'vue',
3216
- projectPath,
3217
- dependencyId: 'vue-loader',
3218
- moduleAdapter: (mod)=>mod?.VueLoaderPlugin || mod?.default?.VueLoaderPlugin
3219
- });
3220
- const customOptions = await loadLoaderOptions(projectPath, 'vue');
3221
- const defaultLoaders = [
3222
- {
3223
- test: /\.vue$/,
3224
- loader: vueLoaderPath,
3225
- options: mergeLoaderOptions({
3226
- experimentalInlineMatchResource: true
3227
- }, customOptions),
3228
- exclude: createNodeModulesExclude(transpilePackageDirs)
3229
- }
3230
- ];
3231
- const isProd = 'production' === mode;
3232
- const defaultPlugins = [
3233
- new VueLoaderPlugin(),
3234
- new DefinePlugin({
3235
- __VUE_OPTIONS_API__: JSON.stringify(true),
3236
- __VUE_PROD_DEVTOOLS__: JSON.stringify(!isProd),
3237
- __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(!isProd)
3238
- })
3239
- ];
3240
- const resolveFromProject = (id)=>resolveVueBundlerEntry(requireFromProject, id);
3241
- const alias = {};
3242
- const vuePath = resolveFromProject('vue');
3243
- const vueRuntimeDom = resolveFromProject('@vue/runtime-dom');
3244
- const vueRuntimeCore = resolveFromProject('@vue/runtime-core');
3245
- const vueShared = resolveFromProject('@vue/shared');
3246
- if (vuePath) alias.vue$ = vuePath;
3247
- if (vueRuntimeDom) alias['@vue/runtime-dom'] = vueRuntimeDom;
3248
- if (vueRuntimeCore) alias['@vue/runtime-core'] = vueRuntimeCore;
3249
- if (vueShared) alias['@vue/shared'] = vueShared;
3250
- return {
3251
- plugins: defaultPlugins,
3252
- loaders: defaultLoaders,
3253
- alias
3254
- };
3255
- }
3256
- function isUsingJsxFramework(projectPath) {
3257
- return isUsingReact(projectPath) || isUsingPreact(projectPath) || isUsingSolid(projectPath) || isUsingVue(projectPath);
3258
- }
3259
- function getJsxImportSource(projectPath) {
3260
- if (isUsingSolid(projectPath)) return 'solid-js';
3261
- if (isUsingPreact(projectPath) && !isUsingReact(projectPath)) return 'preact';
3262
- if (isUsingVue(projectPath) && !isUsingReact(projectPath) && !isUsingPreact(projectPath)) return 'vue';
3263
- return 'react';
3264
- }
3265
- function swcParserForFile(resourcePath, jsxInPlainJs) {
3266
- const clean = String(resourcePath || '').split('?')[0];
3267
- const ext = __rspack_external_node_path_806ed179.extname(clean).toLowerCase();
3268
- if ('.tsx' === ext || '.mtsx' === ext) return {
3269
- syntax: "typescript",
3270
- tsx: true,
3271
- dynamicImport: true
3272
- };
3273
- if ('.ts' === ext || '.mts' === ext || '.cts' === ext) return {
3274
- syntax: "typescript",
3275
- tsx: false,
3276
- dynamicImport: true
3277
- };
3278
- if ('.jsx' === ext || '.mjsx' === ext) return {
3279
- syntax: "ecmascript",
3280
- jsx: true,
3281
- dynamicImport: true
3282
- };
3283
- return {
3284
- syntax: "ecmascript",
3285
- jsx: jsxInPlainJs,
3286
- dynamicImport: true
3287
- };
3288
- }
3289
- let hasShownUserMessage = false;
3290
- function findNearestPackageJsonDirectory(startPath) {
3291
- return findNearestProjectManifestDirSync(startPath, 6);
3292
- }
3293
- const NON_SOURCE_DIRS = new Set([
3294
- 'node_modules',
3295
- 'dist',
3296
- 'public'
3297
- ]);
3298
- const MAX_SOURCE_SCAN_DEPTH = 4;
3299
- function hasTypeScriptSourceFiles(projectPath, depth = 0) {
3300
- if (depth > MAX_SOURCE_SCAN_DEPTH) return false;
3301
- try {
3302
- const entries = __rspack_external_node_fs_1b05aee1.readdirSync(projectPath, {
3303
- withFileTypes: true
3304
- });
3305
- return entries.some((entry)=>{
3306
- if (entry.isFile()) {
3307
- const name = entry.name;
3308
- if (!/\.(ts|tsx|mts|cts|mtsx)$/i.test(name)) return false;
3309
- if (/\.(d\.ts|d\.mts|d\.cts|d\.mtsx)$/i.test(name)) return false;
3310
- if (/\.(spec|test)\.(ts|tsx|mts|cts|mtsx)$/i.test(name)) return false;
3311
- return true;
2929
+ }
2930
+ var flagged = flag && typeof flag.at === "number" && Date.now() - flag.at <= 30000 && Array.isArray(flag.entries) ? flag.entries : [];
2931
+ var known = recorded && typeof recorded === "object" ? recorded : null;
2932
+ onReady(function () {
2933
+ if (!registry) return;
2934
+ var entries = [];
2935
+ var current = {};
2936
+ for (var i = 0; i < registry.entries.length; i++) {
2937
+ var e = registry.entries[i];
2938
+ if (!e || !e.static || !isString(e.entry)) continue;
2939
+ current[e.entry] = staticBundlesOf(e);
2940
+ var changed = known && isString(known[e.entry]) && known[e.entry] !== current[e.entry];
2941
+ if (changed || flagged.indexOf(e.entry) !== -1) entries.push(e);
3312
2942
  }
3313
- if (entry.isDirectory()) {
3314
- if (entry.name.startsWith('.') || NON_SOURCE_DIRS.has(entry.name)) return false;
3315
- const sub = __rspack_external_node_path_806ed179.join(projectPath, entry.name);
3316
- if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(sub, 'package.json'))) return false;
3317
- return hasTypeScriptSourceFiles(sub, depth + 1);
2943
+ try {
2944
+ var record = {};
2945
+ record[STATIC_BUNDLES_KEY] = current;
2946
+ chrome.storage.local.set(record, noop);
2947
+ } catch (e) {
2948
+ // Ignore
3318
2949
  }
3319
- return false;
2950
+ if (entries.length) reloadTabs(entries);
2951
+ });
2952
+ });
2953
+ } catch (e) {
2954
+ // Ignore
2955
+ }
2956
+ }
2957
+
2958
+ // A content script edit: re-register at the new files and reload the tabs
2959
+ // the edited entries match, or the extension when a static one is edited.
2960
+ function reload(names, done) {
2961
+ load(function (reg) {
2962
+ if (!reg) return call(function () { done(false); });
2963
+ registry = reg;
2964
+ var wanted = Array.isArray(names) && names.length ? names : null;
2965
+ var edited = [], statics = [];
2966
+ for (var i = 0; i < reg.entries.length; i++) {
2967
+ var e = reg.entries[i];
2968
+ if (!e || (wanted && wanted.indexOf(e.entry) === -1)) continue;
2969
+ (e.static ? statics : edited).push(e);
2970
+ }
2971
+ if (statics.length) {
2972
+ reloadExtensionFor(statics);
2973
+ return call(function () { done(true); });
2974
+ }
2975
+ sync(reg, function () {
2976
+ markReady();
2977
+ reloadTabs(edited, function () { done(true); });
3320
2978
  });
2979
+ });
2980
+ }
2981
+
2982
+ try {
2983
+ chrome.runtime.onMessage.addListener(function (msg, sender) {
2984
+ if (!msg || !msg[STUB]) return;
2985
+ onStub(msg[STUB], sender);
2986
+ });
2987
+ } catch (e) {
2988
+ // Ignore
2989
+ }
2990
+
2991
+ g.__extjsDevContentScripts = {heal: heal, reload: reload, isReady: function () { return ready; }};
2992
+
2993
+ load(function (reg) {
2994
+ registry = reg;
2995
+ if (!reg) return markReady();
2996
+ sync(reg, markReady);
2997
+ });
2998
+ healStaticEntries();
2999
+ } catch (e) {
3000
+ // Ignore
3001
+ }
3002
+ })();
3003
+ `;
3004
+ const DEV_HOT_UPDATES_DIR = 'hot';
3005
+ const CONTENT_SCRIPTS_DIR = "content_scripts";
3006
+ function exists(target) {
3007
+ try {
3008
+ __rspack_external_node_fs_1b05aee1.lstatSync(target);
3009
+ return true;
3321
3010
  } catch {
3322
3011
  return false;
3323
3012
  }
3324
3013
  }
3325
- function hasTypeScriptDependency(projectPath) {
3326
- const manifestDirectory = findNearestPackageJsonDirectory(projectPath);
3327
- if (!manifestDirectory) return false;
3328
- return hasProjectDependency(manifestDirectory, "typescript");
3329
- }
3330
- function isUsingTypeScript(projectPath) {
3331
- const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
3332
- if (!tsConfigFilePath) return false;
3333
- return hasTypeScriptDependency(projectPath) || hasTypeScriptSourceFiles(projectPath);
3334
- }
3335
- function ensureTypeScriptConfig(projectPath) {
3336
- const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
3337
- const hasDep = hasTypeScriptDependency(projectPath);
3338
- const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
3339
- if (hasTsFiles || hasDep && tsConfigFilePath) {
3340
- if (tsConfigFilePath) {
3341
- if (!hasShownUserMessage && isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
3342
- } else {
3343
- if (!hasShownUserMessage) humanLine(creatingTSConfig());
3344
- writeTsConfig(projectPath);
3345
- }
3346
- hasShownUserMessage = true;
3014
+ function devContentScriptStandIns(distPath) {
3015
+ let names = [];
3016
+ try {
3017
+ names = __rspack_external_node_fs_1b05aee1.readdirSync(__rspack_external_node_path_806ed179.join(distPath, CONTENT_SCRIPTS_DIR)).map((name)=>String(name));
3018
+ } catch {
3019
+ return [];
3347
3020
  }
3021
+ return names.map((name)=>`${CONTENT_SCRIPTS_DIR}/${name}`).filter((name)=>isDevContentScriptStandInAsset(name)).sort();
3348
3022
  }
3349
- function defaultTypeScriptConfig(projectPath, _opts) {
3350
- const usesJsFramework = isUsingJSFramework(projectPath);
3351
- const jsxImportSource = usesJsFramework ? {
3352
- jsxImportSource: getJsxImportSource(projectPath)
3353
- } : {};
3354
- return {
3355
- compilerOptions: {
3356
- allowJs: true,
3357
- allowSyntheticDefaultImports: true,
3358
- esModuleInterop: true,
3359
- forceConsistentCasingInFileNames: true,
3360
- jsx: usesJsFramework ? 'react-jsx' : 'preserve',
3361
- ...jsxImportSource,
3362
- lib: [
3363
- 'dom',
3364
- 'dom.iterable',
3365
- 'esnext'
3366
- ],
3367
- moduleResolution: 'bundler',
3368
- module: 'esnext',
3369
- resolveJsonModule: true,
3370
- strict: true,
3371
- target: 'esnext',
3372
- isolatedModules: false,
3373
- skipLibCheck: true
3374
- },
3375
- exclude: [
3376
- 'node_modules',
3377
- 'dist'
3378
- ]
3379
- };
3380
- }
3381
- function getUserTypeScriptConfigFile(projectPath) {
3382
- const searchDirs = [
3383
- findNearestPackageJsonDirectory(projectPath),
3384
- projectPath
3023
+ function removeDevelopmentArtifacts(distPath) {
3024
+ const candidates = [
3025
+ CONTROL_PORT_ASSET_NAME,
3026
+ DEV_HOT_UPDATES_DIR,
3027
+ DEV_CONTENT_SCRIPT_REGISTRY_ASSET,
3028
+ ...devContentScriptStandIns(distPath)
3385
3029
  ];
3386
- for (const dir of searchDirs){
3387
- if (!dir) continue;
3388
- const tsconfigPath = __rspack_external_node_path_806ed179.join(dir, 'tsconfig.json');
3389
- if (__rspack_external_node_fs_1b05aee1.existsSync(tsconfigPath)) return tsconfigPath;
3030
+ const removed = [];
3031
+ for (const relative of candidates){
3032
+ const target = __rspack_external_node_path_806ed179.join(distPath, relative);
3033
+ if (exists(target)) try {
3034
+ __rspack_external_node_fs_1b05aee1.rmSync(target, {
3035
+ recursive: true,
3036
+ force: true
3037
+ });
3038
+ removed.push(relative);
3039
+ } catch {}
3390
3040
  }
3041
+ return removed;
3391
3042
  }
3392
- function getUserJsConfigFile(projectPath) {
3393
- const searchDirs = [
3394
- findNearestPackageJsonDirectory(projectPath),
3395
- projectPath
3396
- ];
3397
- for (const dir of searchDirs){
3398
- if (!dir) continue;
3399
- const jsconfigPath = __rspack_external_node_path_806ed179.join(dir, 'jsconfig.json');
3400
- if (__rspack_external_node_fs_1b05aee1.existsSync(jsconfigPath)) return jsconfigPath;
3043
+ function projectInstallStdio() {
3044
+ return isMachineOutput() ? [
3045
+ 'inherit',
3046
+ 2,
3047
+ 2
3048
+ ] : 'inherit';
3049
+ }
3050
+ async function ensureUserProjectDependencies(packageJsonDir) {
3051
+ const member = findWorkspaceMember(packageJsonDir);
3052
+ if (!needsInstall(packageJsonDir, member?.root)) return;
3053
+ const pm = member && workspaceManagerOverride(member) || resolvePackageManager({
3054
+ cwd: member?.root ?? packageJsonDir
3055
+ });
3056
+ const suppression = installScriptSuppression(pm);
3057
+ const target = projectInstallTarget(pm, packageJsonDir, member);
3058
+ const cmd = buildInstallCommand(pm, [
3059
+ 'install',
3060
+ ...suppression.args,
3061
+ ...target.args
3062
+ ]);
3063
+ if (suppression.args.length || Object.keys(suppression.env).length) console.warn(projectInstallScriptsDisabled(pm.name));
3064
+ if (target.cwd !== packageJsonDir) console.warn(projectInstallInWorkspaceRoot(target.cwd, pm.name));
3065
+ try {
3066
+ await execInstallCommand(cmd.command, cmd.args, {
3067
+ cwd: target.cwd,
3068
+ stdio: projectInstallStdio(),
3069
+ env: suppression.env
3070
+ });
3071
+ } catch (error) {
3072
+ if ('npm' === pm.name) throw error;
3073
+ if ('deno' === pm.name) throw error;
3074
+ console.warn(projectInstallFallbackToNpm(pm.name));
3075
+ const npmPm = resolveNpmPackageManager();
3076
+ const npmSuppression = installScriptSuppression(npmPm);
3077
+ const npmCmd = buildInstallCommand(npmPm, [
3078
+ 'install',
3079
+ '--no-package-lock',
3080
+ ...npmSuppression.args
3081
+ ]);
3082
+ await execInstallCommand(npmCmd.command, npmCmd.args, {
3083
+ cwd: packageJsonDir,
3084
+ stdio: projectInstallStdio(),
3085
+ env: npmSuppression.env
3086
+ });
3401
3087
  }
3402
3088
  }
3403
- function writeTsConfig(projectPath) {
3404
- const targetDir = findNearestPackageJsonDirectory(projectPath) || projectPath;
3405
- __rspack_external_node_fs_1b05aee1.writeFileSync(__rspack_external_node_path_806ed179.join(targetDir, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
3406
- mode: 'development'
3407
- }), null, 2));
3089
+ async function ensureDevelopArtifacts() {
3090
+ const developRoot = findExtensionDevelopRoot();
3091
+ if (!developRoot) return;
3092
+ const requiredFiles = [
3093
+ __rspack_external_node_path_806ed179.join(developRoot, 'dist', "ensure-hmr-for-scripts.js"),
3094
+ __rspack_external_node_path_806ed179.join(developRoot, 'dist', "minimum-script-file.js")
3095
+ ];
3096
+ const missing = requiredFiles.filter((file)=>!__rspack_external_node_fs_1b05aee1.existsSync(file));
3097
+ if (0 === missing.length) return;
3098
+ const pm = resolvePackageManager({
3099
+ cwd: developRoot
3100
+ });
3101
+ const command = buildInstallCommand(pm, [
3102
+ 'run',
3103
+ 'compile'
3104
+ ]);
3105
+ const isAuthor = isDebug();
3106
+ const stdio = isAuthor ? 'inherit' : 'ignore';
3107
+ if (isAuthor) console.warn(authorInstallNotice('extension-develop build artifacts (dist missing)'));
3108
+ await execInstallCommand(command.command, command.args, {
3109
+ cwd: developRoot,
3110
+ stdio
3111
+ });
3408
3112
  }
3409
- const reportedBuildFailures = new WeakSet();
3410
- function printBuildCard(manifestPath, browser, distPath) {
3411
- if (!claimCardKey(`${browser}::${__rspack_external_node_path_806ed179.resolve(distPath)}`)) return;
3412
- let extensionLabel = '';
3413
- try {
3414
- const manifest = parseJsonSafe(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf-8'));
3415
- const name = String(manifest?.name || '').trim();
3416
- const version = String(manifest?.version || '').trim();
3417
- extensionLabel = name && version ? `${name} ${version}` : name;
3418
- } catch {}
3419
- const browserLabel = browserRowValue(String(browser || ''));
3420
- const suffix = process.env.EXTENSION_CLI_UPDATE_SUFFIX || '';
3421
- if (suffix) delete process.env.EXTENSION_CLI_UPDATE_SUFFIX;
3422
- humanLine(' ');
3423
- humanLine(card({
3424
- version: process.env.EXTENSION_DEVELOP_VERSION || process.env.EXTENSION_CLI_VERSION,
3425
- suffix,
3426
- rows: [
3427
- {
3428
- label: 'Browser',
3429
- value: browserLabel
3430
- },
3431
- {
3432
- label: 'Extension',
3433
- value: extensionLabel
3434
- },
3435
- {
3436
- label: 'Output',
3437
- value: collapseHomeDir(distPath)
3438
- }
3439
- ]
3440
- }));
3441
- humanLine(' ');
3442
- process.env.EXTENSION_CLI_BANNER_PRINTED = 'true';
3113
+ const EXTENSION_ENV_TYPES_PACKAGE = 'extension';
3114
+ const STYLE_TYPE = 'Readonly<Record<string, string>>';
3115
+ const EXTENSION_ENV_WILDCARD_MODULES = Object.freeze([
3116
+ {
3117
+ pattern: '*.css',
3118
+ type: STYLE_TYPE
3119
+ },
3120
+ {
3121
+ pattern: '*.scss',
3122
+ type: STYLE_TYPE
3123
+ },
3124
+ {
3125
+ pattern: '*.sass',
3126
+ type: STYLE_TYPE
3127
+ },
3128
+ {
3129
+ pattern: '*.less',
3130
+ type: STYLE_TYPE
3131
+ },
3132
+ {
3133
+ pattern: '*.module.css',
3134
+ type: STYLE_TYPE
3135
+ },
3136
+ {
3137
+ pattern: '*.module.scss',
3138
+ type: STYLE_TYPE
3139
+ },
3140
+ {
3141
+ pattern: '*.module.sass',
3142
+ type: STYLE_TYPE
3143
+ },
3144
+ {
3145
+ pattern: '*.module.less',
3146
+ type: STYLE_TYPE
3147
+ },
3148
+ {
3149
+ pattern: '*.png',
3150
+ type: 'string'
3151
+ },
3152
+ {
3153
+ pattern: '*.jpg',
3154
+ type: 'string'
3155
+ },
3156
+ {
3157
+ pattern: '*.jpeg',
3158
+ type: 'string'
3159
+ },
3160
+ {
3161
+ pattern: '*.gif',
3162
+ type: 'string'
3163
+ },
3164
+ {
3165
+ pattern: '*.webp',
3166
+ type: 'string'
3167
+ },
3168
+ {
3169
+ pattern: '*.avif',
3170
+ type: 'string'
3171
+ },
3172
+ {
3173
+ pattern: '*.ico',
3174
+ type: 'string'
3175
+ },
3176
+ {
3177
+ pattern: '*.bmp',
3178
+ type: 'string'
3179
+ },
3180
+ {
3181
+ pattern: '*.svg',
3182
+ type: 'any'
3183
+ },
3184
+ {
3185
+ pattern: '*?raw',
3186
+ type: 'string'
3187
+ },
3188
+ {
3189
+ pattern: '*?url',
3190
+ type: 'string'
3191
+ }
3192
+ ]);
3193
+ function renderWildcardModuleDeclarations(modules = EXTENSION_ENV_WILDCARD_MODULES) {
3194
+ return modules.map(({ pattern, type })=>`declare module '${pattern}' {\n const content: ${type}\n export default content\n}\n`).join('');
3443
3195
  }
3444
- function resolveOutDir(raw, packageJsonDir) {
3445
- if (null == raw) return;
3446
- if ('string' != typeof raw || !raw.trim()) throw new Error(buildOutDirInvalid(String(raw)));
3447
- const resolved = __rspack_external_node_path_806ed179.resolve(packageJsonDir, raw.trim());
3448
- if (resolved === __rspack_external_node_path_806ed179.resolve(packageJsonDir)) throw new Error(buildOutDirInvalid(raw));
3449
- return raw.trim();
3196
+ function renderDefineDeclarations(defineTypes = {}) {
3197
+ return Object.entries(defineTypes).filter(([name])=>/^[A-Za-z_$][\w$]*$/.test(name)).map(([name, type])=>`declare const ${name}: ${type}\n`).join('');
3450
3198
  }
3451
- async function extensionBuild(pathOrRemoteUrl, buildOptions) {
3452
- const projectStructure = await getProjectStructure(pathOrRemoteUrl);
3453
- const isVitest = 'true' === process.env.VITEST;
3454
- const shouldExitOnError = (buildOptions?.exitOnError ?? false) && !isVitest;
3455
- const { manifestDir, packageJsonDir } = getDirs(projectStructure);
3456
- const commandKey = buildOptions?.metadataCommand === 'start' ? 'start' : 'build';
3457
- const configBrowser = buildOptions?.browser ? void 0 : configBrowserOrThrow((await loadCommandConfig(packageJsonDir, commandKey)).browser, commandKey);
3458
- const browser = normalizeBrowser(buildOptions?.browser || configBrowser || 'chrome', buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary, buildOptions?.safariBinary);
3459
- let distPath = '';
3460
- let stagingDistPath = '';
3461
- const isAuthor = isDebug();
3199
+ function renderExtensionEnvTypes(typePath = EXTENSION_ENV_TYPES_PACKAGE, defineTypes = {}, { inlineAssetTypes = false } = {}) {
3200
+ const defineDeclarations = renderDefineDeclarations(defineTypes);
3201
+ const assetDeclarations = inlineAssetTypes ? `\n// Asset and stylesheet imports: the ${typePath} package does not resolve
3202
+ // from this project, so the declares it ships are written here instead.
3203
+ ${renderWildcardModuleDeclarations()}` : '';
3204
+ return `\
3205
+ // Required Extension.js types for TypeScript projects.
3206
+ // This file is auto-generated and should not be excluded.
3207
+ // If you need additional types, consider creating a new *.d.ts file and
3208
+ // referencing it in the "include" array of your tsconfig.json file.
3209
+ // See https://www.typescriptlang.org/tsconfig#include for more information.
3210
+ /// <reference types="${typePath}/types" />
3211
+
3212
+ // Polyfill types for browser.* APIs
3213
+ /// <reference types="${typePath}/types/polyfill" />
3214
+ ${assetDeclarations}${defineDeclarations ? `\n${defineDeclarations}` : ''}`;
3215
+ }
3216
+ function resolvesExtensionPackage(packageJsonDir) {
3217
+ let dir = __rspack_external_node_path_806ed179.resolve(packageJsonDir);
3218
+ while(true){
3219
+ const packageJson = __rspack_external_node_path_806ed179.join(dir, 'node_modules', EXTENSION_ENV_TYPES_PACKAGE, 'package.json');
3220
+ if (existsSync(packageJson)) return true;
3221
+ const parent = __rspack_external_node_path_806ed179.dirname(dir);
3222
+ if (parent === dir) return false;
3223
+ dir = parent;
3224
+ }
3225
+ }
3226
+ async function generateExtensionTypes(manifestDir, packageJsonDir) {
3227
+ const extensionEnvFile = __rspack_external_node_path_806ed179.join(packageJsonDir, 'extension-env.d.ts');
3228
+ const fileContent = renderExtensionEnvTypes(void 0, await loadDefineTypes(packageJsonDir), {
3229
+ inlineAssetTypes: !resolvesExtensionPackage(packageJsonDir)
3230
+ });
3462
3231
  try {
3463
- takeCodedWarnings();
3464
- await ensureDevelopArtifacts();
3465
- if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
3466
- ensureTypeScriptConfig(manifestDir);
3467
- if (isUsingTypeScript(manifestDir)) await generateExtensionTypes(manifestDir, packageJsonDir);
3468
- const [{ rspack }, { merge }, { handleStatsErrors, isEmitTimeWarning }, { default: webpackConfig }] = await Promise.all([
3469
- import("@rspack/core"),
3470
- import("webpack-merge"),
3471
- import("./stats-handler~0.mjs"),
3472
- import("./rspack-config~0.mjs")
3473
- ]);
3474
- const debug = isAuthor;
3475
- const userManifestPath = projectStructure.packageJsonPath || projectStructure.denoJsonPath;
3476
- if (userManifestPath) assertNoManagedDependencyConflicts(userManifestPath, packageJsonDir);
3477
- const projectConfig = await loadProjectConfigDefaults(packageJsonDir);
3478
- const commandConfig = await loadCommandConfig(packageJsonDir, commandKey);
3479
- const outDir = resolveOutDir(buildOptions?.outDir ?? commandConfig.outDir, packageJsonDir);
3480
- distPath = getBuildDistPath(packageJsonDir, browser, outDir);
3481
- stagingDistPath = stagingDistPathFor(distPath);
3482
- const liveDevSession = findLiveDevSession(packageJsonDir, browser);
3483
- if (liveDevSession && __rspack_external_node_path_806ed179.resolve(liveDevSession.distPath || browserDistDir(packageJsonDir, browser)) === __rspack_external_node_path_806ed179.resolve(distPath)) {
3484
- const distDisplay = displayPath(distPath);
3485
- recordCodedWarning(CODES.E_DEV_SESSION_DIST_SHARED, buildSharesDevDistText(distDisplay, liveDevSession.pid));
3486
- console.warn(buildSharesDevDist(browser, distDisplay, liveDevSession.pid));
3487
- }
3488
- const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
3489
- const foldersConfig = commandConfig.folders ?? browserConfig.folders ?? projectConfig.folders;
3490
- rememberSpecialFoldersConfig(packageJsonDir, foldersConfig);
3491
- const specialFoldersData = getSpecialFoldersDataForProjectRoot(packageJsonDir, foldersConfig);
3492
- const mergedBuildOptions = mergeOptionLayers('start' === commandKey ? START_BUILD_DEFAULTS : BUILD_COMMAND_DEFAULTS, projectConfig, browserConfig, commandConfig, buildOptions);
3493
- const silent = Boolean(mergedBuildOptions.silent);
3494
- const safariPackager = 'safari' === browser || 'webkit-based' === browser ? buildOptions?.safariPackager : void 0;
3495
- const safariIdentity = safariPackager ? resolveSafariIdentity(mergedBuildOptions) : void 0;
3496
- removeStaleStagingDirs(distPath);
3497
- if (debug) {
3498
- debugLine(debugDirs(manifestDir, packageJsonDir));
3499
- debugLine(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
3500
- debugLine(debugOutputPath(distPath));
3232
+ await __rspack_external_node_fs_promises_3b710708.access(extensionEnvFile);
3233
+ const existingContent = await __rspack_external_node_fs_promises_3b710708.readFile(extensionEnvFile, 'utf8');
3234
+ if (existingContent === fileContent) return;
3235
+ humanLine(updatingTypeDefinitions(extensionEnvFile));
3236
+ await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
3237
+ } catch (err) {
3238
+ const manifestText = await __rspack_external_node_fs_promises_3b710708.readFile(__rspack_external_node_path_806ed179.join(manifestDir, 'manifest.json'), 'utf8');
3239
+ const manifest = parseJsonSafe(manifestText);
3240
+ humanLine(writingTypeDefinitions(manifest));
3241
+ try {
3242
+ await __rspack_external_node_fs_promises_3b710708.writeFile(extensionEnvFile, fileContent);
3243
+ } catch (writeErr) {
3244
+ recordCodedWarning(CODES.E_TYPES_EMIT, `Writing ${extensionEnvFile} failed: ${writeErr instanceof Error ? writeErr.message : String(writeErr)}`);
3245
+ humanLine(writingTypeDefinitionsError(writeErr));
3501
3246
  }
3502
- const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? browserConfig.extensions ?? projectConfig.extensions ?? specialFoldersData.extensions;
3503
- const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
3504
- projectRoot: packageJsonDir,
3505
- browser,
3506
- config: mergedExtensionsConfig
3247
+ }
3248
+ }
3249
+ function live_dev_session_isProcessAlive(pid) {
3250
+ try {
3251
+ process.kill(pid, 0);
3252
+ return true;
3253
+ } catch (error) {
3254
+ return error?.code === 'EPERM';
3255
+ }
3256
+ }
3257
+ function findLiveDevSession(projectPath, browser) {
3258
+ let contract;
3259
+ try {
3260
+ contract = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(readyContractPath(projectPath, browser), 'utf-8'));
3261
+ } catch {
3262
+ return null;
3263
+ }
3264
+ if (!contract || 'object' != typeof contract) return null;
3265
+ if ('dev' !== contract.command) return null;
3266
+ if ('starting' !== contract.status && 'ready' !== contract.status) return null;
3267
+ const pid = Number(contract.pid);
3268
+ if (!Number.isInteger(pid) || pid <= 0 || pid === process.pid) return null;
3269
+ if (!live_dev_session_isProcessAlive(pid)) return null;
3270
+ const distPath = 'string' == typeof contract.distPath && contract.distPath ? __rspack_external_node_path_806ed179.resolve(contract.distPath) : '';
3271
+ return {
3272
+ distPath,
3273
+ pid
3274
+ };
3275
+ }
3276
+ function hostOf(pattern) {
3277
+ const match = /^(?:\*|[a-z][a-z0-9+.-]*):\/\/(\[[^\]]+\]|[^/:]+)/i.exec(pattern.trim());
3278
+ return match ? match[1].toLowerCase() : null;
3279
+ }
3280
+ function isLoopbackPattern(pattern) {
3281
+ if ('string' != typeof pattern) return false;
3282
+ const host = hostOf(pattern);
3283
+ if (!host) return false;
3284
+ if ('localhost' === host || host.endsWith('.localhost')) return true;
3285
+ if ('[::1]' === host || '0.0.0.0' === host) return true;
3286
+ return /^127(?:\.\d{1,3}){3}$/.test(host);
3287
+ }
3288
+ function strings(value) {
3289
+ return Array.isArray(value) ? value.filter((item)=>'string' == typeof item) : [];
3290
+ }
3291
+ function findLoopbackOrigins(manifest) {
3292
+ if (!manifest || 'object' != typeof manifest) return [];
3293
+ const m = manifest;
3294
+ const found = [];
3295
+ const add = (patterns, where)=>{
3296
+ for (const pattern of patterns)if (isLoopbackPattern(pattern)) found.push({
3297
+ pattern,
3298
+ where
3507
3299
  });
3508
- const resolvedMode = buildOptions?.mode === 'development' || buildOptions?.mode === 'none' || buildOptions?.mode === 'production' ? buildOptions.mode : 'production';
3509
- if ('development' === resolvedMode || 'production' === resolvedMode) process.env.NODE_ENV = resolvedMode;
3510
- const baseConfig = webpackConfig(projectStructure, {
3511
- ...mergedBuildOptions,
3512
- extensions: resolvedExtensionsConfig,
3513
- browser,
3514
- mode: resolvedMode,
3515
- minify: mergedBuildOptions.minify ?? 'opera' !== browser,
3516
- metadataCommand: buildOptions?.metadataCommand || 'build',
3517
- output: {
3518
- clean: false,
3519
- path: stagingDistPath,
3520
- finalPath: distPath
3300
+ };
3301
+ const contentScripts = Array.isArray(m.content_scripts) ? m.content_scripts : [];
3302
+ contentScripts.forEach((entry, index)=>{
3303
+ if (entry && 'object' == typeof entry) add(strings(entry.matches), `content_scripts[${index}].matches`);
3304
+ });
3305
+ add(strings(m.host_permissions), 'host_permissions');
3306
+ add(strings(m.optional_host_permissions), 'optional_host_permissions');
3307
+ add(strings(m.permissions), 'permissions');
3308
+ add(strings(m.optional_permissions), 'optional_permissions');
3309
+ const externally = m.externally_connectable;
3310
+ if (externally && 'object' == typeof externally) add(strings(externally.matches), 'externally_connectable.matches');
3311
+ const resources = Array.isArray(m.web_accessible_resources) ? m.web_accessible_resources : [];
3312
+ resources.forEach((entry, index)=>{
3313
+ if (entry && 'object' == typeof entry) add(strings(entry.matches), `web_accessible_resources[${index}].matches`);
3314
+ });
3315
+ return found;
3316
+ }
3317
+ const BACKGROUND_PAGE_ENTRY = 'background/index';
3318
+ function classifyEntrySurface(entryName) {
3319
+ if (entryName === BACKGROUND_PAGE_ENTRY) return 'page';
3320
+ if (entryName.startsWith('background')) return 'background';
3321
+ if (entryName.startsWith("content_scripts/")) return "content_script";
3322
+ if (entryName.startsWith("scripts/")) return "script";
3323
+ if (entryName.startsWith("user_scripts/")) return "script";
3324
+ return 'page';
3325
+ }
3326
+ function isPageChunkName(name) {
3327
+ return 'string' == typeof name && name.length > 0 && 'page' === classifyEntrySurface(name);
3328
+ }
3329
+ function isSurfaceLockedChunkName(name) {
3330
+ return 'string' == typeof name && 'page' !== classifyEntrySurface(name);
3331
+ }
3332
+ function canBeInitial(chunk) {
3333
+ return 'function' == typeof chunk.canBeInitial ? chunk.canBeInitial() : true;
3334
+ }
3335
+ function pageInitialChunks(chunk) {
3336
+ return canBeInitial(chunk) && isPageChunkName(chunk.name);
3337
+ }
3338
+ const FRAMEWORK_PACKAGE_PATTERN = /[\\/]node_modules[\\/](react|react-dom|scheduler|preact|vue|@vue|svelte|solid-js|lit|lit-html|lit-element|@lit)[\\/]/;
3339
+ const SCRIPT_MODULE_TYPE = /^javascript\//;
3340
+ const SHARED_CHUNK_DIR = 'shared';
3341
+ function defaultSplitChunks() {
3342
+ return {
3343
+ chunks: pageInitialChunks,
3344
+ cacheGroups: {
3345
+ default: false,
3346
+ defaultVendors: false,
3347
+ framework: {
3348
+ name: `${SHARED_CHUNK_DIR}/framework`,
3349
+ filename: `${SHARED_CHUNK_DIR}/framework.js`,
3350
+ test: FRAMEWORK_PACKAGE_PATTERN,
3351
+ type: SCRIPT_MODULE_TYPE,
3352
+ priority: 40,
3353
+ enforce: true,
3354
+ reuseExistingChunk: true
3355
+ },
3356
+ commons: {
3357
+ name: `${SHARED_CHUNK_DIR}/commons`,
3358
+ filename: `${SHARED_CHUNK_DIR}/commons.js`,
3359
+ type: SCRIPT_MODULE_TYPE,
3360
+ minChunks: 2,
3361
+ minSize: 0,
3362
+ priority: 20,
3363
+ reuseExistingChunk: true
3521
3364
  }
3522
- });
3523
- const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>{
3524
- const name = plugin?.constructor.name;
3525
- if ('plugin-browsers' === name) return false;
3526
- return !(liveDevSession && 'plugin-playwright' === name);
3527
- });
3528
- const hookContext = {
3529
- browser,
3530
- mode: resolvedMode,
3531
- command: buildOptions?.metadataCommand || 'build'
3532
- };
3533
- const userExtensionConfig = await loadCustomConfig(packageJsonDir, hookContext);
3534
- const userConfig = userExtensionConfig({
3535
- ...baseConfig,
3536
- plugins: allPluginsButBrowserRunners
3537
- });
3538
- const compilerConfig = applySplitChunksGuard(merge(userConfig));
3539
- compilerConfig.stats = false;
3540
- const configResolved = await loadConfigResolvedHook(packageJsonDir);
3541
- if (configResolved) compilerConfig.plugins = [
3542
- ...compilerConfig.plugins || [],
3543
- new ConfigResolvedPlugin(configResolved, hookContext)
3544
- ];
3545
- const compileContext = 'string' == typeof compilerConfig.context && compilerConfig.context ? __rspack_external_node_path_806ed179.resolve(compilerConfig.context) : packageJsonDir;
3546
- const mergedOutputPath = 'string' == typeof compilerConfig.output?.path ? __rspack_external_node_path_806ed179.resolve(compileContext, compilerConfig.output.path) : '';
3547
- const useStagingSwap = mergedOutputPath === __rspack_external_node_path_806ed179.resolve(stagingDistPath);
3548
- const displayDistPath = useStagingSwap || !mergedOutputPath ? distPath : mergedOutputPath;
3549
- if (!useStagingSwap && mergedOutputPath) try {
3550
- __rspack_external_node_fs_1b05aee1.rmSync(mergedOutputPath, {
3551
- recursive: true,
3552
- force: true
3553
- });
3554
- } catch {}
3555
- const compiler = rspack(compilerConfig);
3556
- let summary = {
3557
- browser,
3558
- output_path: distPath,
3559
- total_assets: 0,
3560
- total_bytes: 0,
3561
- largest_asset_bytes: 0,
3562
- warnings_count: 0,
3563
- errors_count: 0
3564
- };
3565
- await new Promise((resolve, reject)=>{
3566
- compiler.run(async (err, stats)=>{
3567
- if (err) {
3568
- console.error(err.stack || err);
3569
- removeStagingDir(stagingDistPath);
3570
- return reject(err);
3571
- }
3572
- if (!stats || 'function' != typeof stats.hasErrors) {
3573
- removeStagingDir(stagingDistPath);
3574
- return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
3575
- }
3576
- const outputFiles = listOutputFiles(useStagingSwap ? stagingDistPath : displayDistPath);
3577
- try {
3578
- printBuildCard(projectStructure.manifestPath, browser, displayDistPath);
3579
- if (!silent) {
3580
- const assetsTree = buildAssetsTree(stats, outputFiles);
3581
- if (assetsTree) humanLine(assetsTree);
3582
- }
3583
- } catch {}
3584
- if (stats.hasErrors()) {
3585
- removeStagingDir(stagingDistPath);
3586
- handleStatsErrors(stats);
3587
- let errorCount = 1;
3588
- try {
3589
- const info = stats.toJson({
3590
- all: false,
3591
- errors: true
3592
- });
3593
- errorCount = Math.max(1, info?.errors?.length || 1);
3594
- } catch {}
3595
- console.error(buildFailed(errorCount));
3596
- if (!shouldExitOnError) {
3597
- const { details, truncated } = compilationDiagnostics(stats.compilation, packageJsonDir);
3598
- const failure = Object.assign(new Error('Build failed with errors'), {
3599
- code: CODES.E_COMPILE,
3600
- diagnostics: details,
3601
- truncated
3602
- });
3603
- reportedBuildFailures.add(failure);
3604
- return reject(failure);
3605
- }
3606
- process.exit(1);
3607
- } else {
3608
- if (useStagingSwap && __rspack_external_node_fs_1b05aee1.existsSync(stagingDistPath)) {
3609
- try {
3610
- promoteStagingDist(stagingDistPath, distPath);
3611
- } catch (promoteError) {
3612
- removeStagingDir(stagingDistPath);
3613
- return reject(promoteError);
3614
- }
3615
- if (!liveDevSession) stampReadyDistExtensionId(packageJsonDir, browser, distPath);
3616
- }
3617
- const info = stats?.toJson({
3618
- all: false,
3619
- assets: true,
3620
- warnings: true,
3621
- errors: true
3622
- });
3623
- summary = getBuildSummary(browser, info, displayDistPath, outputFiles, warningCodes(stats.compilation));
3624
- const codedWarnings = takeCodedWarnings();
3625
- if (codedWarnings.length > 0) summary = {
3626
- ...summary,
3627
- warnings_count: summary.warnings_count + codedWarnings.length,
3628
- warnings: [
3629
- ...summary.warnings || [],
3630
- ...codedWarnings
3631
- ]
3632
- };
3633
- const distDisplay = displayPath(displayDistPath);
3634
- const lintLines = [];
3635
- try {
3636
- const lint = await runAddonLint({
3637
- projectPath: packageJsonDir,
3638
- distPath: displayDistPath,
3639
- distDisplay,
3640
- browser,
3641
- mode: resolvedMode,
3642
- enabled: mergedBuildOptions.addonLint,
3643
- chunkProvenance: ()=>collectChunkDependencyProvenance(stats.compilation)
3644
- });
3645
- summary = {
3646
- ...summary,
3647
- addon_lint: summarizeAddonLint(lint)
3648
- };
3649
- if ('missing' === lint.status && lint.hint) lintLines.push(lint.hint);
3650
- else if ('failed' === lint.status) {
3651
- lintLines.push(lint.line);
3652
- if (isDebug()) lintLines.push(lint.debugLine);
3653
- } else if ('linted' === lint.status && lint.findings > 0) {
3654
- lintLines.push(...lint.lines);
3655
- summary = {
3656
- ...summary,
3657
- warnings_count: summary.warnings_count + lint.findings,
3658
- warnings: [
3659
- ...summary.warnings || [],
3660
- ...lint.lines.map((line)=>stripAnsi(line))
3661
- ]
3662
- };
3663
- }
3664
- } catch (lintError) {
3665
- const lint = failedAddonLint(lintError, distDisplay);
3666
- summary = {
3667
- ...summary,
3668
- addon_lint: summarizeAddonLint(lint)
3669
- };
3670
- lintLines.push(lint.line);
3671
- }
3672
- const zipArtifacts = getZipArtifacts(stats.compilation).map((artifact)=>({
3673
- kind: artifact.kind,
3674
- path: useStagingSwap && artifact.path.startsWith(stagingDistPath) ? distPath + artifact.path.slice(stagingDistPath.length) : artifact.path,
3675
- size: artifact.size
3676
- }));
3677
- if (zipArtifacts.length > 0) summary = {
3678
- ...summary,
3679
- zip_artifacts: zipArtifacts
3680
- };
3681
- try {
3682
- const summaryFile = buildSummaryPath(packageJsonDir, browser);
3683
- __rspack_external_node_fs_1b05aee1.mkdirSync(__rspack_external_node_path_806ed179.dirname(summaryFile), {
3684
- recursive: true
3685
- });
3686
- ensureSessionArtifactsIgnoreFile(packageJsonDir);
3687
- ensureSessionStateInProjectGitignore(packageJsonDir);
3688
- __rspack_external_node_fs_1b05aee1.writeFileSync(summaryFile, JSON.stringify(summary));
3689
- } catch {}
3690
- if ((info?.warnings || []).length > 0) {
3691
- const warningDetails = buildWarningsDetails((info?.warnings || []).filter((warning)=>!isEmitTimeWarning(warning)));
3692
- if (warningDetails) humanLine(warningDetails);
3693
- }
3694
- for (const line of lintLines)humanLine(line);
3695
- if ('production' === resolvedMode && 'opera' === browser && void 0 === mergedBuildOptions.minify) humanLine(operaBuildUnminified());
3696
- humanLine(buildComplete(browser, distDisplay, summary.total_bytes, resolvedMode));
3697
- for (const artifact of zipArtifacts){
3698
- const zipDisplay = relativeToDir(artifact.path, process.cwd()) || artifact.path;
3699
- humanLine(zipArtifactReady(zipDisplay, artifact.size));
3700
- }
3701
- const zipFailures = getZipFailures(stats.compilation);
3702
- if (zipFailures.length > 0) {
3703
- for (const failure of zipFailures){
3704
- const failureDisplay = relativeToDir(failure.path, process.cwd()) || failure.path;
3705
- console.error(zipArtifactNotCreated(failure.kind, failureDisplay, failure.reason));
3706
- }
3707
- reject(Object.assign(new Error(`${zipFailures.length} requested archive${1 === zipFailures.length ? ' was' : 's were'} not created`), {
3708
- code: 'E_ZIP_SKIPPED'
3709
- }));
3710
- return;
3711
- }
3712
- const shareHint = buildShareHint();
3713
- if (shareHint) humanLine(shareHint);
3714
- resolve();
3715
- }
3716
- });
3717
- });
3718
- if (safariPackager && safariIdentity) {
3719
- if (!__rspack_external_node_fs_1b05aee1.existsSync(displayDistPath)) throw new Error(safariBuildOutputNotFound(displayDistPath));
3720
- const safari = await safariPackager(displayDistPath, 'full', safariIdentity);
3721
- if (safari) {
3722
- summary = {
3723
- ...summary,
3724
- safari
3725
- };
3726
- try {
3727
- __rspack_external_node_fs_1b05aee1.writeFileSync(buildSummaryPath(packageJsonDir, browser), JSON.stringify(summary));
3728
- } catch {}
3729
- if (safari.bundleId && !liveDevSession) stampReadyKnownExtensionId(packageJsonDir, browser, `${safari.bundleId}.Extension`);
3730
- }
3731
- }
3732
- return summary;
3733
- } catch (error) {
3734
- if (stagingDistPath) removeStagingDir(stagingDistPath);
3735
- const alreadyReported = error instanceof Error && reportedBuildFailures.has(error);
3736
- if (!alreadyReported) {
3737
- if (isDebug()) console.error(error);
3738
- else console.error(buildCommandFailed(error));
3739
- console.error(buildFailed(1));
3740
3365
  }
3741
- if (!shouldExitOnError) throw error;
3742
- process.exit(1);
3743
- }
3366
+ };
3744
3367
  }
3745
- function reloadingExtensionForStaticContentScript(label) {
3746
- return `${messaging_prefix('info')} Reloading the extension for ${label}: a ${pintor.blue('document_start')} content script is read once when the extension loads, so the pages it matches reload too.`;
3368
+ function narrowedSelector(option, isLocked) {
3369
+ if ('all' === option) return (chunk)=>!isLocked(chunk.name);
3370
+ return (chunk)=>('function' == typeof chunk.canBeInitial ? chunk.canBeInitial() : true) && !isLocked(chunk.name);
3747
3371
  }
3748
- function backgroundIsRequiredMessageOnly(backgroundChunkName) {
3749
- return `Check the ${pintor.blue(backgroundChunkName.replace('/', '.'))} field in your ${pintor.blue('manifest.json')} file.`;
3372
+ function narrowChunks(chunks, isLocked) {
3373
+ if ('all' === chunks || 'initial' === chunks) return narrowedSelector(chunks, isLocked);
3750
3374
  }
3751
- function reloadKindFor(type) {
3752
- if ('service-worker' === type) return 'background';
3753
- if ("content-scripts" === type) return 'content';
3754
- if ('page' === type) return 'page';
3755
- return 'full';
3375
+ function lockedChunkName(config) {
3376
+ const userEntries = new Set(userEntryNames(config));
3377
+ return (name)=>isSurfaceLockedChunkName(name) || 'string' == typeof name && userEntries.has(name);
3756
3378
  }
3757
- function viaBroker(broker, instruction) {
3758
- return broker.broadcastReload({
3759
- type: instruction.type,
3760
- changedContentScriptEntries: instruction.changedContentScriptEntries,
3761
- label: instruction.label,
3762
- changedFiles: instruction.changedAssets,
3763
- ...instruction.changedScriptFiles?.length ? {
3764
- changedScriptFiles: instruction.changedScriptFiles
3765
- } : {}
3766
- });
3379
+ function normalizeSplitChunks(config) {
3380
+ const splitChunks = config.optimization?.splitChunks;
3381
+ if (!splitChunks || 'object' != typeof splitChunks) return {
3382
+ config,
3383
+ narrowed: []
3384
+ };
3385
+ const isLocked = lockedChunkName(config);
3386
+ const narrowed = [];
3387
+ const next = {
3388
+ ...splitChunks
3389
+ };
3390
+ const topLevel = narrowChunks(splitChunks.chunks, isLocked);
3391
+ if (topLevel) {
3392
+ next.chunks = topLevel;
3393
+ narrowed.push('splitChunks.chunks');
3394
+ }
3395
+ if (splitChunks.cacheGroups && 'object' == typeof splitChunks.cacheGroups) {
3396
+ const cacheGroups = {};
3397
+ for (const [key, group] of Object.entries(splitChunks.cacheGroups)){
3398
+ const groupSelector = group && 'object' == typeof group ? narrowChunks(group.chunks, isLocked) : void 0;
3399
+ if (groupSelector && group && 'object' == typeof group) {
3400
+ cacheGroups[key] = {
3401
+ ...group,
3402
+ chunks: groupSelector
3403
+ };
3404
+ narrowed.push(`splitChunks.cacheGroups.${key}.chunks`);
3405
+ } else cacheGroups[key] = group;
3406
+ }
3407
+ next.cacheGroups = cacheGroups;
3408
+ }
3409
+ if (0 === narrowed.length) return {
3410
+ config,
3411
+ narrowed
3412
+ };
3413
+ return {
3414
+ config: {
3415
+ ...config,
3416
+ optimization: {
3417
+ ...config.optimization,
3418
+ splitChunks: next
3419
+ }
3420
+ },
3421
+ narrowed
3422
+ };
3767
3423
  }
3768
- function formatReloadingLine(label) {
3769
- return `${messaging_prefix('info')} Reloading ${label}…`;
3424
+ function applySplitChunksGuard(config) {
3425
+ const { config: next, narrowed } = normalizeSplitChunks(config);
3426
+ if (narrowed.length > 0 && isDebug()) debugLine(debugSplitChunksNarrowed(narrowed));
3427
+ return keepRuntimeInline(keepUserEntriesWhole(next));
3770
3428
  }
3771
- function formatUnappliedReloadLine(label) {
3772
- return `${messaging_prefix('warn')} ${label} compiled but the extension never confirmed the reload, so this edit may not be live. Save again, or reload the extension from the browser.`;
3429
+ function keepRuntimeInline(config) {
3430
+ const runtimeChunk = config.optimization?.runtimeChunk;
3431
+ if (!runtimeChunk) return config;
3432
+ console.warn(runtimeChunkKeptInline(runtimeChunk));
3433
+ return {
3434
+ ...config,
3435
+ optimization: {
3436
+ ...config.optimization,
3437
+ runtimeChunk: false
3438
+ }
3439
+ };
3773
3440
  }
3774
- function formatQueuedReloadLine(label) {
3775
- return `${messaging_prefix('info')} Queued ${label} for the extension to apply when it reconnects.`;
3441
+ function userEntryNames(config) {
3442
+ const entry = config.entry;
3443
+ if (!entry || 'object' != typeof entry || Array.isArray(entry)) return [];
3444
+ return Object.keys(entry);
3776
3445
  }
3777
- async function dispatchReload(instruction, executor) {
3778
- if (!instruction) return;
3779
- if ('true' === process.env.EXTENSION_NO_RELOAD) return;
3780
- if (executor.broker) {
3781
- const notified = viaBroker(executor.broker, instruction);
3782
- if (notified > 0) {
3783
- const ack = await executor.broker.awaitReloadAck?.() ?? 'not-expected';
3784
- if ('unacked' === ack) {
3785
- if (instruction.label) console.warn(formatUnappliedReloadLine(instruction.label));
3786
- return;
3787
- }
3788
- executor.broker.noteReloadApplied?.(reloadKindFor(instruction.type), instruction.label);
3789
- if (instruction.label) humanLine(instruction.staticContentScriptEntries?.length ? reloadingExtensionForStaticContentScript(instruction.label) : formatReloadingLine(instruction.label));
3790
- return;
3446
+ function keepUserEntriesWhole(config) {
3447
+ const names = new Set(userEntryNames(config));
3448
+ const splitChunks = config.optimization?.splitChunks;
3449
+ if (0 === names.size || !splitChunks || 'object' != typeof splitChunks) return config;
3450
+ const withoutUserEntries = (chunks)=>{
3451
+ if ('function' != typeof chunks) return;
3452
+ return (chunk)=>!names.has(String(chunk.name)) && chunks(chunk);
3453
+ };
3454
+ let changed = false;
3455
+ const next = {
3456
+ ...splitChunks
3457
+ };
3458
+ const topLevel = withoutUserEntries(splitChunks.chunks);
3459
+ if (topLevel) {
3460
+ next.chunks = topLevel;
3461
+ changed = true;
3462
+ }
3463
+ if (splitChunks.cacheGroups && 'object' == typeof splitChunks.cacheGroups) {
3464
+ const cacheGroups = {};
3465
+ for (const [key, group] of Object.entries(splitChunks.cacheGroups)){
3466
+ const groupSelector = group && 'object' == typeof group ? withoutUserEntries(group.chunks) : void 0;
3467
+ if (groupSelector && group && 'object' == typeof group) {
3468
+ cacheGroups[key] = {
3469
+ ...group,
3470
+ chunks: groupSelector
3471
+ };
3472
+ changed = true;
3473
+ } else cacheGroups[key] = group;
3791
3474
  }
3792
- const warning = executor.broker.undeliveredReloadWarning?.(executor.producerRestartExpected ? {
3793
- producerRestartExpected: true
3794
- } : void 0);
3795
- if (warning) return void console.warn(warning);
3796
- if (executor.producerRestartExpected && instruction.label) humanLine(formatQueuedReloadLine(instruction.label));
3475
+ next.cacheGroups = cacheGroups;
3797
3476
  }
3477
+ if (!changed) return config;
3478
+ return {
3479
+ ...config,
3480
+ optimization: {
3481
+ ...config.optimization,
3482
+ splitChunks: next
3483
+ }
3484
+ };
3798
3485
  }
3799
- function isForcedFullPath(normalized) {
3800
- return normalized.includes('manifest.json') || normalized.includes('_locales/');
3486
+ function isValidBundleId(value) {
3487
+ return /^[A-Za-z0-9-]+(\.[A-Za-z0-9-]+)*$/.test(value);
3801
3488
  }
3802
- function isHotAsset(normalized) {
3803
- return normalized.startsWith('hot/') || normalized.includes('.hot-update.');
3489
+ function resolveSafariIdentity(merged) {
3490
+ if (merged.bundleId && !isValidBundleId(merged.bundleId)) throw new Error(safariInvalidBundleId(merged.bundleId));
3491
+ return {
3492
+ appName: merged.appName,
3493
+ bundleId: merged.bundleId,
3494
+ developmentTeam: merged.developmentTeam,
3495
+ macOsOnly: merged.macOsOnly,
3496
+ forceRegenerate: merged.forceRegenerate,
3497
+ safariBinary: merged.safariBinary
3498
+ };
3804
3499
  }
3805
- function isDirectory(absolute) {
3806
- try {
3807
- return __rspack_external_node_fs_1b05aee1.statSync(absolute).isDirectory();
3808
- } catch {
3809
- return false;
3810
- }
3500
+ const ARTIFACTS_KEY = '__extensionJsZipArtifacts';
3501
+ function recordZipArtifact(carrier, artifact) {
3502
+ if (!carrier || 'object' != typeof carrier) return;
3503
+ const host = carrier;
3504
+ if (!Array.isArray(host[ARTIFACTS_KEY])) host[ARTIFACTS_KEY] = [];
3505
+ host[ARTIFACTS_KEY].push(artifact);
3811
3506
  }
3812
- function normalizeChangedPath(file, contextDir) {
3813
- const raw = String(file || '');
3814
- if (!raw) return;
3815
- if (__rspack_external_node_path_806ed179.isAbsolute(raw) && isDirectory(raw)) return;
3816
- const normalized = __rspack_external_node_path_806ed179.isAbsolute(raw) ? __rspack_external_node_path_806ed179.relative(contextDir, raw).replace(/\\/g, '/') : raw.replace(/\\/g, '/');
3817
- if (!normalized) return;
3818
- return normalized;
3507
+ function getZipArtifacts(carrier) {
3508
+ if (!carrier || 'object' != typeof carrier) return [];
3509
+ const host = carrier;
3510
+ return Array.isArray(host[ARTIFACTS_KEY]) ? host[ARTIFACTS_KEY] : [];
3819
3511
  }
3820
- function pushChanged(into, file, contextDir, markForced) {
3821
- const normalized = normalizeChangedPath(file, contextDir);
3822
- if (!normalized) return;
3823
- if (!into.includes(normalized)) into.push(normalized);
3824
- if (isForcedFullPath(normalized)) markForced();
3512
+ const FAILURES_KEY = '__extensionJsZipFailures';
3513
+ function recordZipFailure(carrier, failure) {
3514
+ if (!carrier || 'object' != typeof carrier) return;
3515
+ const host = carrier;
3516
+ if (!Array.isArray(host[FAILURES_KEY])) host[FAILURES_KEY] = [];
3517
+ host[FAILURES_KEY].push(failure);
3825
3518
  }
3826
- function createChangedSourcesTracker(compiler) {
3827
- let forcedFull = false;
3828
- let changedSources = [];
3829
- let heldForcedFull = false;
3830
- let heldSources = [];
3831
- let writtenAssets = [];
3832
- const contextDir = ()=>compiler.options.context || '';
3833
- const ingest = (files, into, markForced)=>{
3834
- if (!files) return;
3835
- const ctx = contextDir();
3836
- for (const file of files)pushChanged(into, file, ctx, markForced);
3837
- };
3838
- const foldRecoveryIntoCurrent = ()=>{
3839
- const recovering = heldSources.length > 0 || heldForcedFull;
3840
- if (!recovering) return;
3841
- for (const file of heldSources)if (!changedSources.includes(file)) changedSources.push(file);
3842
- for (const file of writtenAssets)if (!changedSources.includes(file)) changedSources.push(file);
3843
- forcedFull = forcedFull || heldForcedFull || writtenAssets.some((file)=>isForcedFullPath(file));
3844
- heldSources = [];
3845
- heldForcedFull = false;
3846
- };
3847
- const markForced = ()=>{
3848
- forcedFull = true;
3849
- };
3850
- compiler.hooks.watchRun.tap('extjs-reload-changed-sources', ()=>{
3851
- forcedFull = false;
3852
- changedSources = [];
3853
- writtenAssets = [];
3854
- ingest(compiler.modifiedFiles, changedSources, markForced);
3855
- });
3856
- compiler.hooks.done?.tap?.('extjs-reload-changed-sources-done', (stats)=>{
3857
- const compilation = stats?.compilation;
3858
- ingest(compilation?.modifiedFiles, changedSources, markForced);
3859
- ingest(compiler.modifiedFiles, changedSources, markForced);
3860
- if (compilation?.errors && compilation.errors.length > 0) {
3861
- heldForcedFull = heldForcedFull || forcedFull;
3862
- for (const file of changedSources)if (!heldSources.includes(file)) heldSources.push(file);
3863
- return;
3864
- }
3865
- foldRecoveryIntoCurrent();
3866
- });
3867
- compiler.hooks.assetEmitted?.tap?.('extjs-reload-changed-sources-emitted', (file)=>{
3868
- const normalized = normalizeChangedPath(file, contextDir());
3869
- if (!normalized || isHotAsset(normalized)) return;
3870
- if (!writtenAssets.includes(normalized)) writtenAssets.push(normalized);
3871
- });
3872
- return {
3873
- snapshot: ()=>{
3874
- foldRecoveryIntoCurrent();
3875
- return {
3876
- forcedFull,
3877
- changedSources
3878
- };
3879
- }
3880
- };
3519
+ function getZipFailures(carrier) {
3520
+ if (!carrier || 'object' != typeof carrier) return [];
3521
+ const host = carrier;
3522
+ return Array.isArray(host[FAILURES_KEY]) ? host[FAILURES_KEY] : [];
3881
3523
  }
3882
- const DEV_CONTENT_SCRIPT_REGISTRY_ASSET = "content_scripts/dev-registry.json";
3883
- const DEV_CONTENT_SCRIPT_MARKER_KEY = '__extjsDevContentScripts';
3884
- const DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY = '__extjsDevCsStub';
3885
- const DEV_CONTENT_SCRIPT_ID_PREFIX = 'extjs-dev-cs-';
3886
- const DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY = '__extjsDevStaticReload';
3887
- const DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY = '__extjsDevStaticBundles';
3888
- function devContentScriptStubAssetName(index) {
3889
- return `content_scripts/dev-stub-${index}.js`;
3524
+ function hasDependency(projectPath, packageName) {
3525
+ return hasProjectDependency(projectPath, packageName);
3890
3526
  }
3891
- function devContentScriptCssMarkerAssetName(index) {
3892
- return `content_scripts/dev-css-${index}.js`;
3527
+ function isUsingJSFramework(projectPath) {
3528
+ const frameworks = [
3529
+ 'react',
3530
+ 'vue',
3531
+ '@angular/core',
3532
+ 'svelte',
3533
+ 'solid-js',
3534
+ 'preact'
3535
+ ];
3536
+ return frameworks.some((fw)=>hasDependency(projectPath, fw));
3893
3537
  }
3894
- const DEV_CONTENT_SCRIPT_STAND_IN_ASSET = /^content_scripts\/dev-(?:stub|css)-\d+\.js$/;
3895
- function isDevContentScriptStandInAsset(assetName) {
3896
- return DEV_CONTENT_SCRIPT_STAND_IN_ASSET.test(assetName);
3538
+ function isUsingIntegration(name) {
3539
+ return `integration use=${name}`;
3897
3540
  }
3898
- const HASHED_CONTENT_SCRIPT_ASSET = /^content_scripts\/content-(\d+)(?:\.[a-f0-9]+)?\.js$/i;
3899
- function contentScriptEntryForAsset(assetName) {
3900
- const match = HASHED_CONTENT_SCRIPT_ASSET.exec(assetName);
3901
- if (!match) return;
3902
- return getCanonicalContentScriptEntryName(Number(match[1]));
3541
+ function vueTwoSingleFileComponent(version, files) {
3542
+ const list = files.map((file)=>`- ${pintor.underline(file)}`).join('\n');
3543
+ return `Vue ${version} is installed, and Extension.js compiles .vue files for Vue 3 only.\n${list}\nVue 2 reached end of life in December 2023 and vue-loader 15 cannot read the loader rules this build uses.\nUpgrade to ${pintor.yellow('vue@3')} with ${pintor.yellow('vue-loader@17')}, or write these components as render functions.`;
3903
3544
  }
3904
- function stringList(value) {
3905
- return Array.isArray(value) ? value.filter((item)=>'string' == typeof item) : [];
3545
+ function creatingTSConfig() {
3546
+ return `${messaging_prefix('info')} Creating a default tsconfig.json…`;
3906
3547
  }
3907
- function runAtOf(value) {
3908
- if ('document_start' === value || 'document_end' === value) return value;
3909
- return 'document_idle';
3548
+ function svelteCompilerRuntimeMismatch(compilerVersion, projectVersion) {
3549
+ return `${messaging_prefix('warn')} Svelte ${pintor.blue(compilerVersion)} compiles this project, which pins svelte ${pintor.blue(projectVersion)}.\nThe build uses ${pintor.blue(compilerVersion)} for both, so the output links. Add ${pintor.blue('svelte-loader')} to the project to compile with ${pintor.blue(projectVersion)} instead.`;
3910
3550
  }
3911
- function canonicalIndexOf(entry) {
3912
- for (const file of [
3913
- ...stringList(entry.js),
3914
- ...stringList(entry.css)
3915
- ]){
3916
- const parsed = parseCanonicalContentScriptAsset(file);
3917
- if (parsed) return parsed.index;
3551
+ function isUsingCustomLoader(loaderPath) {
3552
+ return `${messaging_prefix('debug')} loader custom=${loaderPath}`;
3553
+ }
3554
+ function jsFrameworksIntegrationsEnabled(integrations) {
3555
+ const names = integrations.length > 0 ? integrations.join(',') : 'none';
3556
+ return `${messaging_prefix('debug')} js integrations=${integrations.length} names=${names}`;
3557
+ }
3558
+ function jsFrameworksConfigsDetected(tsConfigPath, tsRoot, targets) {
3559
+ const val = (v)=>v || 'none';
3560
+ const tgt = targets?.length ? targets.join(',') : 'default';
3561
+ return `${messaging_prefix('debug')} js config tsconfig=${val(tsConfigPath)} tsRoot=${val(tsRoot)} swcTargets="${tgt}"`;
3562
+ }
3563
+ function jsFrameworksHmrSummary(enabled, frameworks) {
3564
+ const names = frameworks.length > 0 ? frameworks.join(',') : 'none';
3565
+ return `${messaging_prefix('debug')} js hmr=${enabled ? 'enabled' : 'disabled'} frameworks=${names}`;
3566
+ }
3567
+ let userMessageDelivered = false;
3568
+ function isUsingReact(projectPath) {
3569
+ if (hasDependency(projectPath, 'react')) {
3570
+ if (!userMessageDelivered) {
3571
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('React')}`);
3572
+ userMessageDelivered = true;
3573
+ }
3574
+ return true;
3918
3575
  }
3576
+ return false;
3919
3577
  }
3920
- function planDevContentScripts(manifest) {
3921
- if (3 !== manifest.manifest_version) return;
3922
- const groups = manifest.content_scripts;
3923
- if (!Array.isArray(groups) || 0 === groups.length) return;
3924
- const entries = [];
3925
- const stubs = {};
3926
- const nextGroups = groups.map((group)=>{
3927
- const index = canonicalIndexOf(group);
3928
- const matches = stringList(group.matches);
3929
- const js = stringList(group.js);
3930
- const css = stringList(group.css);
3931
- if (void 0 === index || 0 === matches.length) return group;
3932
- if (0 === js.length && 0 === css.length) return group;
3933
- const entryName = getCanonicalContentScriptEntryName(index);
3934
- const excludeMatches = stringList(group.exclude_matches);
3935
- if ('document_start' === group.run_at && 'MAIN' !== group.world) {
3936
- entries.push({
3937
- id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
3938
- entry: entryName,
3939
- matches,
3940
- ...excludeMatches.length > 0 ? {
3941
- excludeMatches
3942
- } : {},
3943
- js,
3944
- css,
3945
- runAt: 'document_start',
3946
- allFrames: true === group.all_frames,
3947
- world: 'ISOLATED',
3948
- stubOnly: false,
3949
- static: true
3950
- });
3951
- return group;
3952
- }
3953
- const stubOnly = stringList(group.include_globs).length > 0 || stringList(group.exclude_globs).length > 0;
3954
- const cssMarkerAsset = 0 === js.length ? devContentScriptCssMarkerAssetName(index) : void 0;
3955
- if (cssMarkerAsset) stubs[cssMarkerAsset] = buildDevContentScriptMarkerPrelude(entryName, cssMarkerAsset);
3956
- entries.push({
3957
- id: `${DEV_CONTENT_SCRIPT_ID_PREFIX}${index}`,
3958
- entry: entryName,
3959
- matches,
3960
- ...excludeMatches.length > 0 ? {
3961
- excludeMatches
3962
- } : {},
3963
- js: cssMarkerAsset ? [
3964
- cssMarkerAsset
3965
- ] : js,
3966
- css,
3967
- runAt: runAtOf(group.run_at),
3968
- allFrames: true === group.all_frames,
3969
- world: 'MAIN' === group.world ? 'MAIN' : 'ISOLATED',
3970
- ...true === group.match_origin_as_fallback ? {
3971
- matchOriginAsFallback: true
3972
- } : {},
3973
- stubOnly
3974
- });
3975
- const stubAsset = devContentScriptStubAssetName(index);
3976
- stubs[stubAsset] = buildDevContentScriptStubSource(entryName);
3977
- const { css: _css, world: _world, ...rest } = group;
3978
- return {
3979
- ...rest,
3980
- js: [
3981
- stubAsset
3982
- ]
3983
- };
3578
+ async function maybeUseReact(projectPath, options = {}) {
3579
+ if (!isUsingReact(projectPath)) return;
3580
+ const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
3581
+ let reactPath;
3582
+ let reactDomPath;
3583
+ let reactDomClientPath;
3584
+ let jsxRuntimePath;
3585
+ let jsxDevRuntimePath;
3586
+ try {
3587
+ reactPath = requireFromProject.resolve('react');
3588
+ } catch {}
3589
+ try {
3590
+ reactDomPath = requireFromProject.resolve('react-dom');
3591
+ } catch {}
3592
+ try {
3593
+ reactDomClientPath = requireFromProject.resolve('react-dom/client');
3594
+ } catch {}
3595
+ try {
3596
+ jsxRuntimePath = requireFromProject.resolve('react/jsx-runtime');
3597
+ } catch {}
3598
+ try {
3599
+ jsxDevRuntimePath = requireFromProject.resolve('react/jsx-dev-runtime');
3600
+ } catch {}
3601
+ const alias = {};
3602
+ if (reactPath) alias.react$ = reactPath;
3603
+ if (reactDomPath) alias['react-dom$'] = reactDomPath;
3604
+ if (reactDomClientPath) alias['react-dom/client'] = reactDomClientPath;
3605
+ if (jsxRuntimePath) alias['react/jsx-runtime'] = jsxRuntimePath;
3606
+ if (jsxDevRuntimePath) alias['react/jsx-dev-runtime'] = jsxDevRuntimePath;
3607
+ if (true === options.disableRefresh) return {
3608
+ plugins: [],
3609
+ loaders: void 0,
3610
+ alias
3611
+ };
3612
+ resolveOptionalContractPackageWithoutInstall({
3613
+ contractId: 'react-refresh',
3614
+ projectPath,
3615
+ dependencyId: 'react-refresh'
3984
3616
  });
3985
- if (0 === entries.length) return;
3617
+ const ReactRefreshPlugin = loadOptionalContractModuleWithoutInstall({
3618
+ contractId: 'react-refresh',
3619
+ projectPath,
3620
+ dependencyId: '@rspack/plugin-react-refresh',
3621
+ moduleAdapter: (mod)=>mod && (mod.default || mod.ReactRefreshRspackPlugin) || mod
3622
+ });
3623
+ const refreshEntry = resolveReactRefreshEntry(projectPath);
3624
+ const reactPlugins = [
3625
+ new ReactRefreshPlugin({
3626
+ overlay: false,
3627
+ injectEntry: !refreshEntry,
3628
+ ...void 0 === options.refreshExclude ? {} : {
3629
+ exclude: options.refreshExclude
3630
+ }
3631
+ })
3632
+ ];
3986
3633
  return {
3987
- manifest: {
3988
- ...manifest,
3989
- content_scripts: nextGroups
3990
- },
3991
- registry: {
3992
- version: 1,
3993
- entries
3994
- },
3995
- stubs
3634
+ plugins: reactPlugins,
3635
+ loaders: void 0,
3636
+ alias
3996
3637
  };
3997
3638
  }
3998
- function buildDevContentScriptStubSource(entryName) {
3999
- return `;(function(){try{var c=globalThis.chrome;if(!c||!c.runtime||!c.runtime.sendMessage)return;c.runtime.sendMessage({${DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY}:{entry:${JSON.stringify(entryName)}}},function(){try{void c.runtime.lastError}catch(e){}})}catch(e){}})();\n`;
4000
- }
4001
- function buildDevContentScriptMarkerPrelude(entryName, assetName) {
4002
- return `;(function(){try{var g=globalThis,k=${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};(g[k]=g[k]||{})[${JSON.stringify(entryName)}]=${JSON.stringify(assetName)}}catch(e){}})();\n`;
3639
+ function resolveReactRefreshEntry(projectPath) {
3640
+ try {
3641
+ const pluginMain = resolveOptionalContractPackageWithoutInstall({
3642
+ contractId: 'react-refresh',
3643
+ projectPath,
3644
+ dependencyId: '@rspack/plugin-react-refresh'
3645
+ });
3646
+ const marker = `${__rspack_external_node_path_806ed179.sep}@rspack${__rspack_external_node_path_806ed179.sep}plugin-react-refresh${__rspack_external_node_path_806ed179.sep}`;
3647
+ const at = String(pluginMain || '').lastIndexOf(marker);
3648
+ if (-1 === at) return;
3649
+ const root = String(pluginMain).slice(0, at + marker.length);
3650
+ const entry = __rspack_external_node_path_806ed179.join(root, 'client', 'reactRefreshEntry.js');
3651
+ return __rspack_external_node_fs_1b05aee1.existsSync(entry) ? entry : void 0;
3652
+ } catch {
3653
+ return;
3654
+ }
4003
3655
  }
4004
- const DEV_CONTENT_SCRIPTS_RUNTIME_SOURCE = `;(function () {
4005
- try {
4006
- var g = (typeof globalThis !== "undefined" ? globalThis : self);
4007
- if (!g || g.__extjsDevContentScriptsInstalled) return;
4008
- var chrome = g.chrome;
4009
- if (!chrome || !chrome.runtime || !chrome.scripting || !chrome.tabs) return;
4010
- g.__extjsDevContentScriptsInstalled = true;
4011
-
4012
- var REGISTRY = ${JSON.stringify(DEV_CONTENT_SCRIPT_REGISTRY_ASSET)};
4013
- var MARKER = ${JSON.stringify(DEV_CONTENT_SCRIPT_MARKER_KEY)};
4014
- var STUB = ${JSON.stringify(DEV_CONTENT_SCRIPT_STUB_MESSAGE_KEY)};
4015
- var ID_PREFIX = ${JSON.stringify(DEV_CONTENT_SCRIPT_ID_PREFIX)};
4016
- var STATIC_RELOAD_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_RELOAD_KEY)};
4017
- var STATIC_BUNDLES_KEY = ${JSON.stringify(DEV_CONTENT_SCRIPT_STATIC_BUNDLES_KEY)};
4018
- // The file a frame runs says nothing about which extension generation
4019
- // injected it, so every probe also stamps the booting worker's token.
4020
- var GENERATION_KEY = "generation";
4021
- var GENERATION = Math.random().toString(36).slice(2) + Date.now().toString(36);
4022
- var registry = null;
4023
- var ready = false;
4024
- var whenReady = [];
4025
-
4026
- function noop() { try { void chrome.runtime.lastError; } catch (e) {
4027
- // Ignore
4028
- } }
4029
- function isString(v) { return typeof v === "string"; }
4030
- function injectableUrl(url) { return typeof url === "string" && /^(https?|file|ftp):/i.test(url); }
4031
- function call(fn) { if (fn) { try { fn(); } catch (e) {
4032
- // Ignore
4033
- } } }
4034
- function onReady(fn) { if (ready) call(fn); else whenReady.push(fn); }
4035
- function markReady() {
4036
- ready = true;
4037
- var fns = whenReady;
4038
- whenReady = [];
4039
- for (var i = 0; i < fns.length; i++) call(fns[i]);
3656
+ let preact_userMessageDelivered = false;
3657
+ function isUsingPreact(projectPath) {
3658
+ if (hasDependency(projectPath, 'preact')) {
3659
+ if (!preact_userMessageDelivered) {
3660
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Preact')}`);
3661
+ preact_userMessageDelivered = true;
3662
+ }
3663
+ return true;
4040
3664
  }
4041
-
4042
- // The registry is read FROM DISK every time: the bundles it names are
4043
- // content-hashed and the worker outlives many edits.
4044
- function load(cb) {
4045
- try {
4046
- if (typeof g.fetch !== "function") return cb(null);
4047
- g.fetch(chrome.runtime.getURL(REGISTRY), {cache: "no-store"})
4048
- .then(function (r) { return r && r.ok ? r.json() : null; })
4049
- .then(function (reg) { cb(reg && Array.isArray(reg.entries) ? reg : null); })
4050
- .catch(function () { cb(null); });
4051
- } catch (e) { cb(null); }
3665
+ return false;
3666
+ }
3667
+ async function maybeUsePreact(projectPath) {
3668
+ if (!isUsingPreact(projectPath)) return;
3669
+ const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
3670
+ const resolveFromProject = (id)=>{
3671
+ try {
3672
+ return requireFromProject.resolve(id);
3673
+ } catch {
3674
+ return;
3675
+ }
3676
+ };
3677
+ const preactPkgJson = resolveFromProject('preact/package.json');
3678
+ const preactDir = preactPkgJson ? __rspack_external_node_path_806ed179.dirname(preactPkgJson) : void 0;
3679
+ const preactCompat = resolveFromProject('preact/compat');
3680
+ const preactTestUtils = resolveFromProject('preact/test-utils');
3681
+ const preactJsxRuntime = resolveFromProject('preact/jsx-runtime');
3682
+ const preactJsxDevRuntime = resolveFromProject('preact/jsx-dev-runtime');
3683
+ const alias = {};
3684
+ if (preactJsxRuntime) alias['preact/jsx-runtime'] = preactJsxRuntime;
3685
+ if (preactJsxDevRuntime) alias['preact/jsx-dev-runtime'] = preactJsxDevRuntime;
3686
+ if (preactDir) alias.preact = preactDir;
3687
+ if (!isUsingReact(projectPath)) {
3688
+ if (preactCompat) {
3689
+ alias.react = preactCompat;
3690
+ alias['react-dom'] = preactCompat;
3691
+ }
3692
+ if (preactTestUtils) alias['react-dom/test-utils'] = preactTestUtils;
3693
+ if (preactJsxRuntime) alias['react/jsx-runtime'] = preactJsxRuntime;
3694
+ if (preactJsxDevRuntime) alias['react/jsx-dev-runtime'] = preactJsxDevRuntime;
4052
3695
  }
4053
-
4054
- // Every field is sent: updateContentScripts keeps any key left out, so a
4055
- // dropped exclude_matches, css file or fallback would outlive the edit.
4056
- function registrationOf(e) {
4057
- return {
4058
- id: e.id,
4059
- matches: e.matches,
4060
- excludeMatches: Array.isArray(e.excludeMatches) ? e.excludeMatches.filter(isString) : [],
4061
- js: (e.js || []).filter(isString),
4062
- css: (e.css || []).filter(isString),
4063
- runAt: e.runAt === "document_start" || e.runAt === "document_end" ? e.runAt : "document_idle",
4064
- allFrames: !!e.allFrames,
4065
- world: e.world === "MAIN" ? "MAIN" : "ISOLATED",
4066
- matchOriginAsFallback: e.matchOriginAsFallback === true,
4067
- persistAcrossSessions: false
4068
- };
3696
+ return {
3697
+ plugins: [],
3698
+ loaders: void 0,
3699
+ alias
3700
+ };
3701
+ }
3702
+ const RAW_RESOURCE_QUERY = /(?:^\?|&)raw(?:&|=|$)/;
3703
+ const NOT_RAW_RESOURCE_QUERY = {
3704
+ not: [
3705
+ RAW_RESOURCE_QUERY
3706
+ ]
3707
+ };
3708
+ function normalizePath(filePath) {
3709
+ return filePath.replace(/\\/g, '/');
3710
+ }
3711
+ function tryReadJson(filePath) {
3712
+ try {
3713
+ return JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(filePath, 'utf-8'));
3714
+ } catch {
3715
+ return;
4069
3716
  }
4070
-
4071
- // Register what the registry names, update what is already registered,
4072
- // drop dev registrations it no longer names. Idempotent per entry id.
4073
- function sync(reg, done) {
4074
- try {
4075
- if (!chrome.scripting.registerContentScripts || !chrome.scripting.getRegisteredContentScripts) return call(done);
4076
- var wanted = [];
4077
- for (var i = 0; i < reg.entries.length; i++) {
4078
- var e = reg.entries[i] || {};
4079
- if (e.stubOnly || e.static || !isString(e.id) || !Array.isArray(e.matches) || !e.matches.length) continue;
4080
- var r = registrationOf(e);
4081
- if (!r.js.length && !r.css.length) continue;
4082
- wanted.push(r);
4083
- }
4084
- chrome.scripting.getRegisteredContentScripts(function (existing) {
4085
- noop();
4086
- var have = {};
4087
- if (existing) {
4088
- for (var k = 0; k < existing.length; k++) {
4089
- if (existing[k] && isString(existing[k].id)) have[existing[k].id] = true;
4090
- }
4091
- }
4092
- var toRegister = [], toUpdate = [], toDrop = [], keep = {};
4093
- for (var j = 0; j < wanted.length; j++) {
4094
- keep[wanted[j].id] = true;
4095
- (have[wanted[j].id] ? toUpdate : toRegister).push(wanted[j]);
4096
- }
4097
- for (var id in have) {
4098
- if (id.indexOf(ID_PREFIX) === 0 && !keep[id]) toDrop.push(id);
4099
- }
4100
- var ops = [];
4101
- if (toDrop.length && chrome.scripting.unregisterContentScripts) ops.push(["unregisterContentScripts", {ids: toDrop}]);
4102
- if (toUpdate.length && chrome.scripting.updateContentScripts) ops.push(["updateContentScripts", toUpdate]);
4103
- if (toRegister.length) ops.push(["registerContentScripts", toRegister]);
4104
- var pending = ops.length;
4105
- if (!pending) return call(done);
4106
- var step = function () { pending--; if (pending <= 0) call(done); };
4107
- for (var o = 0; o < ops.length; o++) {
4108
- try { chrome.scripting[ops[o][0]](ops[o][1], function () { noop(); step(); }); } catch (e) { step(); }
4109
- }
4110
- });
4111
- } catch (e) { call(done); }
4112
- }
4113
-
4114
- // Inject one entry into the frames of a tab whose world does not already
4115
- // run the current file, or on a heal ran it for a previous extension
4116
- // generation. Chromium's own injection sets the same marker.
4117
- function inject(e, target, sameGeneration, done) {
4118
- var world = e.world === "MAIN" ? "MAIN" : "ISOLATED";
4119
- var js = (e.js || []).filter(isString), css = (e.css || []).filter(isString);
4120
- var probe = {target: target, world: world, injectImmediately: true,
4121
- args: [MARKER, GENERATION_KEY, e.entry, js[0] || "", GENERATION, !!sameGeneration],
4122
- func: function (key, genKey, entry, file, gen, needGen) {
4123
- try {
4124
- var g = globalThis, m = g[key] = g[key] || {}, gens = m[genKey] = m[genKey] || {};
4125
- var covered = m[entry] === file && (!needGen || gens[entry] === gen);
4126
- gens[entry] = gen;
4127
- return covered;
4128
- } catch (x) { return false; }
4129
- }};
4130
- try {
4131
- chrome.scripting.executeScript(probe, function (results) {
4132
- noop();
4133
- var frameIds = [];
4134
- if (results) {
4135
- for (var i = 0; i < results.length; i++) {
4136
- var r = results[i];
4137
- if (!r || r.result === true) continue;
4138
- frameIds.push(typeof r.frameId === "number" ? r.frameId : 0);
4139
- }
4140
- }
4141
- if (!frameIds.length) return call(done);
4142
- var into = {tabId: target.tabId, frameIds: frameIds};
4143
- if (css.length && chrome.scripting.insertCSS) {
4144
- try { chrome.scripting.insertCSS({target: into, files: css}, noop); } catch (x) {
4145
- // Ignore
4146
- }
4147
- }
4148
- if (!js.length) return call(done);
4149
- try {
4150
- chrome.scripting.executeScript({target: into, files: js, world: world, injectImmediately: true}, function () { noop(); call(done); });
4151
- } catch (x) { call(done); }
4152
- });
4153
- } catch (x) { call(done); }
3717
+ }
3718
+ function findPackageRootFromEntry(entryPath, packageName) {
3719
+ let currentDir = __rspack_external_node_path_806ed179.dirname(entryPath);
3720
+ while(true){
3721
+ const packageJsonPath = __rspack_external_node_path_806ed179.join(currentDir, 'package.json');
3722
+ const packageJson = tryReadJson(packageJsonPath);
3723
+ if (packageJson?.name === packageName) return currentDir;
3724
+ const parentDir = __rspack_external_node_path_806ed179.dirname(currentDir);
3725
+ if (parentDir === currentDir) return;
3726
+ currentDir = parentDir;
4154
3727
  }
4155
-
4156
- // The open tabs an entry matches, exclude_matches honored, tabs still
4157
- // loading skipped when asked: Chromium injects those itself on landing.
4158
- function tabsFor(e, completeOnly, cb) {
4159
- var matches = Array.isArray(e.matches) ? e.matches : [];
4160
- if (!matches.length) return cb([]);
4161
- var excludes = Array.isArray(e.excludeMatches) ? e.excludeMatches : [];
4162
- var collect = function (excludedIds) {
4163
- try {
4164
- chrome.tabs.query({url: matches}, function (tabs) {
4165
- noop();
4166
- var out = [];
4167
- for (var i = 0; tabs && i < tabs.length; i++) {
4168
- var t = tabs[i];
4169
- if (!t || t.id == null || !injectableUrl(t.url) || excludedIds[t.id]) continue;
4170
- if (completeOnly && t.status === "loading") continue;
4171
- out.push(t);
3728
+ }
3729
+ function resolvePackageRoot(requireFromProject, projectRoot, packageName) {
3730
+ try {
3731
+ return __rspack_external_node_path_806ed179.dirname(requireFromProject.resolve(`${packageName}/package.json`));
3732
+ } catch {}
3733
+ try {
3734
+ const entryPath = requireFromProject.resolve(packageName);
3735
+ const discovered = findPackageRootFromEntry(entryPath, packageName);
3736
+ if (discovered) return discovered;
3737
+ } catch {}
3738
+ const guessedPackageDir = __rspack_external_node_path_806ed179.join(projectRoot, 'node_modules', ...packageName.split('/'));
3739
+ if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(guessedPackageDir, 'package.json'))) return guessedPackageDir;
3740
+ }
3741
+ function getWorkspaceDependencyNames(projectRoot) {
3742
+ const packageJsonPath = __rspack_external_node_path_806ed179.join(projectRoot, 'package.json');
3743
+ try {
3744
+ const packageJson = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(packageJsonPath, 'utf-8'));
3745
+ const dependencySections = [
3746
+ packageJson.dependencies,
3747
+ packageJson.devDependencies,
3748
+ packageJson.peerDependencies,
3749
+ packageJson.optionalDependencies
3750
+ ];
3751
+ const names = new Set();
3752
+ for (const section of dependencySections)if (section && 'object' == typeof section) {
3753
+ for (const [name, version] of Object.entries(section))if ('string' == typeof version) {
3754
+ if (version.startsWith('workspace:') || version.startsWith('link:') || version.startsWith('file:')) names.add(name);
4172
3755
  }
4173
- cb(out);
4174
- });
4175
- } catch (x) { cb([]); }
4176
- };
4177
- if (!excludes.length) return collect({});
4178
- try {
4179
- chrome.tabs.query({url: excludes}, function (tabs) {
4180
- noop();
4181
- var ids = {};
4182
- for (var i = 0; tabs && i < tabs.length; i++) if (tabs[i] && tabs[i].id != null) ids[tabs[i].id] = true;
4183
- collect(ids);
4184
- });
4185
- } catch (x) { collect({}); }
4186
- }
4187
-
4188
- // The boot read can fail or land on a registry mid-write, and the file on
4189
- // disk can name an entry the loaded one does not. One re-read per need,
4190
- // shared by the callers waiting on it, and no re-sync of an unchanged file.
4191
- var refreshing = [];
4192
- function refresh(cb) {
4193
- refreshing.push(cb);
4194
- if (refreshing.length > 1) return;
4195
- var finish = function () {
4196
- var fns = refreshing;
4197
- refreshing = [];
4198
- for (var i = 0; i < fns.length; i++) call(fns[i]);
4199
- };
4200
- load(function (reg) {
4201
- if (!reg) return finish();
4202
- var same = false;
4203
- try { same = !!registry && JSON.stringify(reg) === JSON.stringify(registry); } catch (e) {
4204
- // Ignore
4205
3756
  }
4206
- registry = reg;
4207
- if (same) return finish();
4208
- sync(reg, finish);
4209
- });
3757
+ return Array.from(names);
3758
+ } catch {
3759
+ return [];
4210
3760
  }
4211
-
4212
- function entriesFor(name) {
4213
- var out = [];
4214
- if (!registry) return out;
4215
- for (var i = 0; i < registry.entries.length; i++) {
4216
- var e = registry.entries[i];
4217
- if (e && !e.static && e.entry === name) out.push(e);
4218
- }
4219
- return out;
3761
+ }
3762
+ function resolveTranspilePackageDirs(projectRoot, transpilePackages) {
3763
+ const autoWorkspacePackages = getWorkspaceDependencyNames(projectRoot);
3764
+ const packageNames = Array.from(new Set([
3765
+ ...autoWorkspacePackages,
3766
+ ...transpilePackages || []
3767
+ ].map((entry)=>String(entry || '').trim()).filter(Boolean)));
3768
+ if (0 === packageNames.length) return [];
3769
+ const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectRoot, 'package.json'));
3770
+ const resolvedDirs = new Set();
3771
+ for (const packageName of packageNames){
3772
+ const packageDir = resolvePackageRoot(requireFromProject, projectRoot, packageName);
3773
+ if (packageDir) {
3774
+ resolvedDirs.add(normalizePath(packageDir));
3775
+ try {
3776
+ resolvedDirs.add(normalizePath(__rspack_external_node_fs_1b05aee1.realpathSync(packageDir)));
3777
+ } catch {}
3778
+ }
4220
3779
  }
4221
-
4222
- function onStub(msg, sender) {
4223
- if (!msg || !isString(msg.entry) || !sender || !sender.tab || sender.tab.id == null) return;
4224
- var tabId = sender.tab.id;
4225
- var frameId = typeof sender.frameId === "number" ? sender.frameId : 0;
4226
- onReady(function () {
4227
- var serve = function () {
4228
- var entries = entriesFor(msg.entry);
4229
- for (var i = 0; i < entries.length; i++) inject(entries[i], {tabId: tabId, frameIds: [frameId]}, false);
4230
- };
4231
- if (entriesFor(msg.entry).length) return serve();
4232
- refresh(serve);
4233
- });
3780
+ return Array.from(resolvedDirs);
3781
+ }
3782
+ function createNodeModulesExclude(transpilePackageDirs) {
3783
+ return (resourcePath)=>{
3784
+ if (!/[\\/]node_modules[\\/]/.test(resourcePath)) return false;
3785
+ return !transpilePackageDirs.some((dir)=>isSubPath(resourcePath, dir));
3786
+ };
3787
+ }
3788
+ function isSubPath(resourcePath, directoryPath) {
3789
+ return isResourceUnderDirs(resourcePath, [
3790
+ canonicalizeDir(directoryPath)
3791
+ ]);
3792
+ }
3793
+ let solid_userMessageDelivered = false;
3794
+ function isUsingSolid(projectPath) {
3795
+ const using = hasDependency(projectPath, 'solid-js');
3796
+ if (using && !solid_userMessageDelivered) {
3797
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Solid')}`);
3798
+ solid_userMessageDelivered = true;
4234
3799
  }
4235
-
4236
- // After a worker restart the open tabs still run the previous generation,
4237
- // and Chromium never injects into a tab that finished loading before it.
4238
- function heal(done) {
4239
- onReady(function () {
4240
- if (registry) return healEntries(done);
4241
- refresh(function () { healEntries(done); });
4242
- });
3800
+ return using;
3801
+ }
3802
+ function pickEsmCondition(entry) {
3803
+ if ('string' == typeof entry) return entry;
3804
+ if (!entry || 'object' != typeof entry) return;
3805
+ const conditions = entry;
3806
+ for (const name of [
3807
+ 'browser',
3808
+ 'import',
3809
+ 'module',
3810
+ 'default'
3811
+ ]){
3812
+ const picked = pickEsmCondition(conditions[name]);
3813
+ if (picked) return picked;
4243
3814
  }
4244
-
4245
- function healEntries(done) {
4246
- if (!registry) return call(done);
4247
- var pending = 1;
4248
- var step = function () { pending--; if (pending <= 0) call(done); };
4249
- for (var i = 0; i < registry.entries.length; i++) {
4250
- (function (e) {
4251
- if (!e || e.stubOnly || e.static) return;
4252
- pending++;
4253
- tabsFor(e, true, function (tabs) {
4254
- var left = tabs.length;
4255
- if (!left) return step();
4256
- for (var t = 0; t < tabs.length; t++) {
4257
- inject(e, {tabId: tabs[t].id, allFrames: !!e.allFrames}, true, function () { if (--left === 0) step(); });
3815
+ }
3816
+ function resolveSolidHyperscript(resolveFromProject) {
3817
+ const packageJsonPath = resolveFromProject('solid-js/package.json');
3818
+ if (packageJsonPath) try {
3819
+ const packageJson = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(packageJsonPath, 'utf-8'));
3820
+ const subpath = pickEsmCondition(packageJson?.exports?.['./h']);
3821
+ if (subpath) {
3822
+ const esmPath = __rspack_external_node_path_806ed179.resolve(__rspack_external_node_path_806ed179.dirname(packageJsonPath), subpath);
3823
+ if (__rspack_external_node_fs_1b05aee1.existsSync(esmPath)) return esmPath;
3824
+ }
3825
+ } catch {}
3826
+ return resolveFromProject('solid-js/h/dist/h.js') || resolveFromProject('solid-js/h');
3827
+ }
3828
+ function solidBabelOptions(input) {
3829
+ return {
3830
+ babelrc: false,
3831
+ configFile: false,
3832
+ sourceMaps: true,
3833
+ compact: false,
3834
+ sourceType: 'module',
3835
+ parserOpts: {
3836
+ strictMode: false
3837
+ },
3838
+ presets: [
3839
+ [
3840
+ input.solidPreset,
3841
+ {
3842
+ development: input.development
3843
+ }
3844
+ ],
3845
+ ...input.typescript ? [
3846
+ [
3847
+ input.typescriptPreset,
3848
+ {
3849
+ isTSX: true,
3850
+ allExtensions: true,
3851
+ onlyRemoveTypeImports: true
3852
+ }
3853
+ ]
3854
+ ] : []
3855
+ ]
3856
+ };
3857
+ }
3858
+ async function maybeUseSolid(projectPath, mode = 'development', transpilePackageDirs = []) {
3859
+ if (!isUsingSolid(projectPath)) return;
3860
+ const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
3861
+ const resolveFromProject = (id)=>{
3862
+ try {
3863
+ return requireFromProject.resolve(id);
3864
+ } catch {
3865
+ return;
3866
+ }
3867
+ };
3868
+ const resolveContractPackage = (dependencyId)=>ensureOptionalContractPackageResolved({
3869
+ contractId: 'solid',
3870
+ projectPath,
3871
+ dependencyId
3872
+ });
3873
+ const babelLoader = await resolveContractPackage('babel-loader');
3874
+ const solidPreset = await resolveContractPackage('babel-preset-solid');
3875
+ const typescriptPreset = await resolveContractPackage("@babel/preset-typescript");
3876
+ const adapter = resolveDevelopDistFile('solid-jsx-runtime');
3877
+ const hyperscript = resolveSolidHyperscript(resolveFromProject);
3878
+ const alias = {
3879
+ 'solid-js/jsx-runtime$': adapter,
3880
+ 'solid-js/jsx-dev-runtime$': adapter
3881
+ };
3882
+ if (hyperscript) alias['solid-js/h$'] = hyperscript;
3883
+ const development = 'development' === mode;
3884
+ const excludeNodeModules = createNodeModulesExclude(transpilePackageDirs);
3885
+ const javascriptOptions = solidBabelOptions({
3886
+ solidPreset,
3887
+ typescriptPreset,
3888
+ typescript: false,
3889
+ development
3890
+ });
3891
+ const loaders = [
3892
+ {
3893
+ test: /\.(jsx|mjsx)$/,
3894
+ exclude: excludeNodeModules,
3895
+ resourceQuery: NOT_RAW_RESOURCE_QUERY,
3896
+ loader: babelLoader,
3897
+ options: javascriptOptions
3898
+ },
3899
+ {
3900
+ test: /\.(tsx|mtsx)$/,
3901
+ exclude: excludeNodeModules,
3902
+ resourceQuery: NOT_RAW_RESOURCE_QUERY,
3903
+ loader: babelLoader,
3904
+ options: solidBabelOptions({
3905
+ solidPreset,
3906
+ typescriptPreset,
3907
+ typescript: true,
3908
+ development
3909
+ })
3910
+ },
3911
+ {
3912
+ test: /\.(js|mjs|cjs)$/,
3913
+ exclude: excludeNodeModules,
3914
+ resourceQuery: NOT_RAW_RESOURCE_QUERY,
3915
+ loader: resolveDevelopDistFile('solid-jsx-gate-loader'),
3916
+ options: {
3917
+ ...javascriptOptions,
3918
+ babelLoader
4258
3919
  }
4259
- });
4260
- })(registry.entries[i]);
4261
- }
4262
- step();
3920
+ }
3921
+ ];
3922
+ return {
3923
+ plugins: [],
3924
+ loaders,
3925
+ alias
3926
+ };
3927
+ }
3928
+ let load_loader_options_userMessageDelivered = false;
3929
+ function resolveLoaderConfigPath(projectPath, framework) {
3930
+ const candidates = [
3931
+ __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.ts`),
3932
+ __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.mts`),
3933
+ __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.js`),
3934
+ __rspack_external_node_path_806ed179.join(projectPath, `${framework}.loader.mjs`)
3935
+ ];
3936
+ return candidates.find((p)=>__rspack_external_node_fs_1b05aee1.existsSync(p)) || null;
3937
+ }
3938
+ function load_loader_options_isPlainObject(value) {
3939
+ return 'object' == typeof value && null !== value && !Array.isArray(value);
3940
+ }
3941
+ function mergeLoaderOptions(defaults, custom) {
3942
+ if (!load_loader_options_isPlainObject(custom)) return {
3943
+ ...defaults
3944
+ };
3945
+ const merged = {
3946
+ ...defaults,
3947
+ ...custom
3948
+ };
3949
+ for (const [key, value] of Object.entries(custom))if (load_loader_options_isPlainObject(defaults[key]) && load_loader_options_isPlainObject(value)) merged[key] = {
3950
+ ...defaults[key],
3951
+ ...value
3952
+ };
3953
+ return merged;
3954
+ }
3955
+ async function loadLoaderOptions(projectPath, framework) {
3956
+ const configPath = resolveLoaderConfigPath(projectPath, framework);
3957
+ if (configPath) {
3958
+ if (!load_loader_options_userMessageDelivered && isDebug()) {
3959
+ const display = __rspack_external_node_path_806ed179.basename(configPath);
3960
+ debugLine(isUsingCustomLoader(display));
3961
+ load_loader_options_userMessageDelivered = true;
3962
+ }
3963
+ try {
3964
+ const module = await import(pathToFileURL(configPath).href);
3965
+ return module.default || module;
3966
+ } catch (err) {
3967
+ const error = err;
3968
+ console.error(`Error loading ${framework} loader options: ${error.message}`);
3969
+ throw err;
3970
+ }
4263
3971
  }
4264
-
4265
- // Reload every tab the given entries match, each once.
4266
- function reloadTabs(entries, done) {
4267
- var seen = {};
4268
- var pending = 1;
4269
- var step = function () { pending--; if (pending <= 0) call(done); };
4270
- for (var i = 0; i < entries.length; i++) {
4271
- pending++;
4272
- tabsFor(entries[i], false, function (tabs) {
4273
- for (var t = 0; t < tabs.length; t++) {
4274
- var id = tabs[t].id;
4275
- if (seen[id]) continue;
4276
- seen[id] = true;
4277
- try { chrome.tabs.reload(id, {}, noop); } catch (x) {
4278
- // Ignore
4279
- }
4280
- }
4281
- step();
3972
+ return null;
3973
+ }
3974
+ let vue_userMessageDelivered = false;
3975
+ function isUsingVue(projectPath) {
3976
+ const using = hasDependency(projectPath, 'vue');
3977
+ if (using && !vue_userMessageDelivered) {
3978
+ if (isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('Vue')}`);
3979
+ vue_userMessageDelivered = true;
3980
+ }
3981
+ return using;
3982
+ }
3983
+ function resolveVueBundlerEntry(requireFromProject, id) {
3984
+ try {
3985
+ const manifestPath = requireFromProject.resolve(`${id}/package.json`);
3986
+ const manifest = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf8'));
3987
+ if ('string' == typeof manifest.module && manifest.module) {
3988
+ const entry = __rspack_external_node_path_806ed179.join(__rspack_external_node_path_806ed179.dirname(manifestPath), manifest.module);
3989
+ if (__rspack_external_node_fs_1b05aee1.existsSync(entry)) return entry;
3990
+ }
3991
+ } catch {}
3992
+ try {
3993
+ return requireFromProject.resolve(id);
3994
+ } catch {
3995
+ return;
3996
+ }
3997
+ }
3998
+ function readInstalledVueVersion(requireFromProject) {
3999
+ try {
4000
+ const manifestPath = requireFromProject.resolve('vue/package.json');
4001
+ const version = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf8')).version;
4002
+ return 'string' == typeof version ? version : void 0;
4003
+ } catch {
4004
+ return;
4005
+ }
4006
+ }
4007
+ class RefuseVueTwoSingleFileComponents {
4008
+ version;
4009
+ constructor(version){
4010
+ this.version = version;
4011
+ }
4012
+ apply(compiler) {
4013
+ const name = RefuseVueTwoSingleFileComponents.name;
4014
+ compiler.hooks.thisCompilation.tap(name, (compilation)=>{
4015
+ compilation.hooks.finishModules.tap(name, (modules)=>{
4016
+ const files = new Set();
4017
+ for (const module of modules){
4018
+ const { resource = '', type } = module;
4019
+ const file = resource.split('?')[0];
4020
+ if ('asset/source' === type && file.endsWith('.vue')) files.add(file);
4021
+ }
4022
+ if (0 === files.size) return;
4023
+ const sorted = [
4024
+ ...files
4025
+ ].sort();
4026
+ const error = new WebpackError(vueTwoSingleFileComponent(this.version, sorted));
4027
+ error.file = __rspack_external_node_path_806ed179.relative(compiler.context, sorted[0]);
4028
+ error.stack = '';
4029
+ compilation.errors.push(error);
4030
+ });
4282
4031
  });
4283
- }
4284
- step();
4285
4032
  }
4286
-
4287
- // Only an extension reload ships a static entry's edit. The next generation
4288
- // reloads the tabs it matches, and the producer's flag heals the rest.
4289
- function reloadExtensionFor(entries) {
4290
- var names = [];
4291
- for (var i = 0; i < entries.length; i++) names.push(entries[i].entry);
4292
- try {
4293
- if (chrome.storage && chrome.storage.local) {
4294
- var flags = {__extjsDevPendingReinject: Date.now()};
4295
- flags[STATIC_RELOAD_KEY] = {entries: names, at: Date.now()};
4296
- chrome.storage.local.set(flags, noop);
4033
+ }
4034
+ function vueTwoWithoutLoader(requireFromProject, version) {
4035
+ const alias = {};
4036
+ const vuePath = resolveVueBundlerEntry(requireFromProject, 'vue');
4037
+ if (vuePath) alias.vue$ = vuePath;
4038
+ return {
4039
+ plugins: [
4040
+ new RefuseVueTwoSingleFileComponents(version)
4041
+ ],
4042
+ loaders: [
4043
+ {
4044
+ test: /\.vue$/,
4045
+ type: 'asset/source'
4046
+ }
4047
+ ],
4048
+ alias
4049
+ };
4050
+ }
4051
+ async function maybeUseVue(projectPath, mode = 'development', transpilePackageDirs = []) {
4052
+ if (!isUsingVue(projectPath)) return;
4053
+ const requireFromProject = createRequire(__rspack_external_node_path_806ed179.join(projectPath, 'package.json'));
4054
+ const installedVersion = readInstalledVueVersion(requireFromProject);
4055
+ if (installedVersion && /^2\./.test(installedVersion)) return vueTwoWithoutLoader(requireFromProject, installedVersion);
4056
+ const vueLoaderPath = await ensureOptionalContractPackageResolved({
4057
+ contractId: 'vue',
4058
+ projectPath,
4059
+ dependencyId: 'vue-loader'
4060
+ });
4061
+ const VueLoaderPlugin = await ensureOptionalContractModuleLoaded({
4062
+ contractId: 'vue',
4063
+ projectPath,
4064
+ dependencyId: 'vue-loader',
4065
+ moduleAdapter: (mod)=>mod?.VueLoaderPlugin || mod?.default?.VueLoaderPlugin
4066
+ });
4067
+ const customOptions = await loadLoaderOptions(projectPath, 'vue');
4068
+ const defaultLoaders = [
4069
+ {
4070
+ test: /\.vue$/,
4071
+ loader: vueLoaderPath,
4072
+ options: mergeLoaderOptions({
4073
+ experimentalInlineMatchResource: true
4074
+ }, customOptions),
4075
+ exclude: createNodeModulesExclude(transpilePackageDirs)
4076
+ }
4077
+ ];
4078
+ const isProd = 'production' === mode;
4079
+ const defaultPlugins = [
4080
+ new VueLoaderPlugin(),
4081
+ new DefinePlugin({
4082
+ __VUE_OPTIONS_API__: JSON.stringify(true),
4083
+ __VUE_PROD_DEVTOOLS__: JSON.stringify(!isProd),
4084
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: JSON.stringify(!isProd)
4085
+ })
4086
+ ];
4087
+ const resolveFromProject = (id)=>resolveVueBundlerEntry(requireFromProject, id);
4088
+ const alias = {};
4089
+ const vuePath = resolveFromProject('vue');
4090
+ const vueRuntimeDom = resolveFromProject('@vue/runtime-dom');
4091
+ const vueRuntimeCore = resolveFromProject('@vue/runtime-core');
4092
+ const vueShared = resolveFromProject('@vue/shared');
4093
+ if (vuePath) alias.vue$ = vuePath;
4094
+ if (vueRuntimeDom) alias['@vue/runtime-dom'] = vueRuntimeDom;
4095
+ if (vueRuntimeCore) alias['@vue/runtime-core'] = vueRuntimeCore;
4096
+ if (vueShared) alias['@vue/shared'] = vueShared;
4097
+ return {
4098
+ plugins: defaultPlugins,
4099
+ loaders: defaultLoaders,
4100
+ alias
4101
+ };
4102
+ }
4103
+ function isUsingJsxFramework(projectPath) {
4104
+ return isUsingReact(projectPath) || isUsingPreact(projectPath) || isUsingSolid(projectPath) || isUsingVue(projectPath);
4105
+ }
4106
+ function getJsxImportSource(projectPath) {
4107
+ if (isUsingSolid(projectPath)) return 'solid-js';
4108
+ if (isUsingPreact(projectPath) && !isUsingReact(projectPath)) return 'preact';
4109
+ if (isUsingVue(projectPath) && !isUsingReact(projectPath) && !isUsingPreact(projectPath)) return 'vue';
4110
+ return 'react';
4111
+ }
4112
+ function swcParserForFile(resourcePath, jsxInPlainJs) {
4113
+ const clean = String(resourcePath || '').split('?')[0];
4114
+ const ext = __rspack_external_node_path_806ed179.extname(clean).toLowerCase();
4115
+ if ('.tsx' === ext || '.mtsx' === ext) return {
4116
+ syntax: "typescript",
4117
+ tsx: true,
4118
+ dynamicImport: true
4119
+ };
4120
+ if ('.ts' === ext || '.mts' === ext || '.cts' === ext) return {
4121
+ syntax: "typescript",
4122
+ tsx: false,
4123
+ dynamicImport: true
4124
+ };
4125
+ if ('.jsx' === ext || '.mjsx' === ext) return {
4126
+ syntax: "ecmascript",
4127
+ jsx: true,
4128
+ dynamicImport: true
4129
+ };
4130
+ return {
4131
+ syntax: "ecmascript",
4132
+ jsx: jsxInPlainJs,
4133
+ dynamicImport: true
4134
+ };
4135
+ }
4136
+ let hasShownUserMessage = false;
4137
+ function findNearestPackageJsonDirectory(startPath) {
4138
+ return findNearestProjectManifestDirSync(startPath, 6);
4139
+ }
4140
+ const NON_SOURCE_DIRS = new Set([
4141
+ 'node_modules',
4142
+ 'dist',
4143
+ 'public'
4144
+ ]);
4145
+ const MAX_SOURCE_SCAN_DEPTH = 4;
4146
+ function hasTypeScriptSourceFiles(projectPath, depth = 0) {
4147
+ if (depth > MAX_SOURCE_SCAN_DEPTH) return false;
4148
+ try {
4149
+ const entries = __rspack_external_node_fs_1b05aee1.readdirSync(projectPath, {
4150
+ withFileTypes: true
4151
+ });
4152
+ return entries.some((entry)=>{
4153
+ if (entry.isFile()) {
4154
+ const name = entry.name;
4155
+ if (!/\.(ts|tsx|mts|cts|mtsx)$/i.test(name)) return false;
4156
+ if (/\.(d\.ts|d\.mts|d\.cts|d\.mtsx)$/i.test(name)) return false;
4157
+ if (/\.(spec|test)\.(ts|tsx|mts|cts|mtsx)$/i.test(name)) return false;
4158
+ return true;
4159
+ }
4160
+ if (entry.isDirectory()) {
4161
+ if (entry.name.startsWith('.') || NON_SOURCE_DIRS.has(entry.name)) return false;
4162
+ const sub = __rspack_external_node_path_806ed179.join(projectPath, entry.name);
4163
+ if (__rspack_external_node_fs_1b05aee1.existsSync(__rspack_external_node_path_806ed179.join(sub, 'package.json'))) return false;
4164
+ return hasTypeScriptSourceFiles(sub, depth + 1);
4165
+ }
4166
+ return false;
4167
+ });
4168
+ } catch {
4169
+ return false;
4170
+ }
4171
+ }
4172
+ function hasTypeScriptDependency(projectPath) {
4173
+ const manifestDirectory = findNearestPackageJsonDirectory(projectPath);
4174
+ if (!manifestDirectory) return false;
4175
+ return hasProjectDependency(manifestDirectory, "typescript");
4176
+ }
4177
+ function isUsingTypeScript(projectPath) {
4178
+ const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
4179
+ if (!tsConfigFilePath) return false;
4180
+ return hasTypeScriptDependency(projectPath) || hasTypeScriptSourceFiles(projectPath);
4181
+ }
4182
+ function ensureTypeScriptConfig(projectPath) {
4183
+ const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
4184
+ const hasDep = hasTypeScriptDependency(projectPath);
4185
+ const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
4186
+ if (hasTsFiles || hasDep && tsConfigFilePath) {
4187
+ if (tsConfigFilePath) {
4188
+ if (!hasShownUserMessage && isDebug()) debugLine(`${messaging_prefix('debug')} ${isUsingIntegration('TypeScript')}`);
4189
+ } else {
4190
+ if (!hasShownUserMessage) humanLine(creatingTSConfig());
4191
+ writeTsConfig(projectPath);
4192
+ }
4193
+ hasShownUserMessage = true;
4194
+ }
4195
+ }
4196
+ function defaultTypeScriptConfig(projectPath, _opts) {
4197
+ const usesJsFramework = isUsingJSFramework(projectPath);
4198
+ const jsxImportSource = usesJsFramework ? {
4199
+ jsxImportSource: getJsxImportSource(projectPath)
4200
+ } : {};
4201
+ return {
4202
+ compilerOptions: {
4203
+ allowJs: true,
4204
+ allowSyntheticDefaultImports: true,
4205
+ esModuleInterop: true,
4206
+ forceConsistentCasingInFileNames: true,
4207
+ jsx: usesJsFramework ? 'react-jsx' : 'preserve',
4208
+ ...jsxImportSource,
4209
+ lib: [
4210
+ 'dom',
4211
+ 'dom.iterable',
4212
+ 'esnext'
4213
+ ],
4214
+ moduleResolution: 'bundler',
4215
+ module: 'esnext',
4216
+ resolveJsonModule: true,
4217
+ strict: true,
4218
+ target: 'esnext',
4219
+ isolatedModules: false,
4220
+ skipLibCheck: true
4221
+ },
4222
+ exclude: [
4223
+ 'node_modules',
4224
+ 'dist'
4225
+ ]
4226
+ };
4227
+ }
4228
+ function getUserTypeScriptConfigFile(projectPath) {
4229
+ const searchDirs = [
4230
+ findNearestPackageJsonDirectory(projectPath),
4231
+ projectPath
4232
+ ];
4233
+ for (const dir of searchDirs){
4234
+ if (!dir) continue;
4235
+ const tsconfigPath = __rspack_external_node_path_806ed179.join(dir, 'tsconfig.json');
4236
+ if (__rspack_external_node_fs_1b05aee1.existsSync(tsconfigPath)) return tsconfigPath;
4237
+ }
4238
+ }
4239
+ function getUserJsConfigFile(projectPath) {
4240
+ const searchDirs = [
4241
+ findNearestPackageJsonDirectory(projectPath),
4242
+ projectPath
4243
+ ];
4244
+ for (const dir of searchDirs){
4245
+ if (!dir) continue;
4246
+ const jsconfigPath = __rspack_external_node_path_806ed179.join(dir, 'jsconfig.json');
4247
+ if (__rspack_external_node_fs_1b05aee1.existsSync(jsconfigPath)) return jsconfigPath;
4248
+ }
4249
+ }
4250
+ function writeTsConfig(projectPath) {
4251
+ const targetDir = findNearestPackageJsonDirectory(projectPath) || projectPath;
4252
+ __rspack_external_node_fs_1b05aee1.writeFileSync(__rspack_external_node_path_806ed179.join(targetDir, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
4253
+ mode: 'development'
4254
+ }), null, 2));
4255
+ }
4256
+ const reportedBuildFailures = new WeakSet();
4257
+ function printBuildCard(manifestPath, browser, distPath) {
4258
+ if (!claimCardKey(`${browser}::${__rspack_external_node_path_806ed179.resolve(distPath)}`)) return;
4259
+ let extensionLabel = '';
4260
+ try {
4261
+ const manifest = parseJsonSafe(__rspack_external_node_fs_1b05aee1.readFileSync(manifestPath, 'utf-8'));
4262
+ const name = String(manifest?.name || '').trim();
4263
+ const version = String(manifest?.version || '').trim();
4264
+ extensionLabel = name && version ? `${name} ${version}` : name;
4265
+ } catch {}
4266
+ const browserLabel = browserRowValue(String(browser || ''));
4267
+ const suffix = process.env.EXTENSION_CLI_UPDATE_SUFFIX || '';
4268
+ if (suffix) delete process.env.EXTENSION_CLI_UPDATE_SUFFIX;
4269
+ humanLine(' ');
4270
+ humanLine(card({
4271
+ version: process.env.EXTENSION_DEVELOP_VERSION || process.env.EXTENSION_CLI_VERSION,
4272
+ suffix,
4273
+ rows: [
4274
+ {
4275
+ label: 'Browser',
4276
+ value: browserLabel
4277
+ },
4278
+ {
4279
+ label: 'Extension',
4280
+ value: extensionLabel
4281
+ },
4282
+ {
4283
+ label: 'Output',
4284
+ value: collapseHomeDir(distPath)
4285
+ }
4286
+ ]
4287
+ }));
4288
+ humanLine(' ');
4289
+ process.env.EXTENSION_CLI_BANNER_PRINTED = 'true';
4290
+ }
4291
+ function resolveOutDir(raw, packageJsonDir) {
4292
+ if (null == raw) return;
4293
+ if ('string' != typeof raw || !raw.trim()) throw new Error(buildOutDirInvalid(String(raw)));
4294
+ const resolved = __rspack_external_node_path_806ed179.resolve(packageJsonDir, raw.trim());
4295
+ if (resolved === __rspack_external_node_path_806ed179.resolve(packageJsonDir)) throw new Error(buildOutDirInvalid(raw));
4296
+ return raw.trim();
4297
+ }
4298
+ function warnProductionLoopbackOrigins(distPath) {
4299
+ let manifest;
4300
+ try {
4301
+ manifest = JSON.parse(__rspack_external_node_fs_1b05aee1.readFileSync(__rspack_external_node_path_806ed179.join(distPath, 'manifest.json'), 'utf-8'));
4302
+ } catch {
4303
+ return;
4304
+ }
4305
+ const origins = findLoopbackOrigins(manifest);
4306
+ if (0 === origins.length) return;
4307
+ recordCodedWarning(CODES.E_PROD_LOOPBACK_ORIGIN, productionLoopbackOriginsText(origins));
4308
+ console.warn(productionLoopbackOrigins(origins));
4309
+ }
4310
+ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
4311
+ const projectStructure = await getProjectStructure(pathOrRemoteUrl);
4312
+ const isVitest = 'true' === process.env.VITEST;
4313
+ const shouldExitOnError = (buildOptions?.exitOnError ?? false) && !isVitest;
4314
+ const { manifestDir, packageJsonDir } = getDirs(projectStructure);
4315
+ const commandKey = buildOptions?.metadataCommand === 'start' ? 'start' : 'build';
4316
+ const configBrowser = buildOptions?.browser ? void 0 : configBrowserOrThrow((await loadCommandConfig(packageJsonDir, commandKey)).browser, commandKey);
4317
+ const browser = normalizeBrowser(buildOptions?.browser || configBrowser || 'chrome', buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary, buildOptions?.safariBinary);
4318
+ let distPath = '';
4319
+ let stagingDistPath = '';
4320
+ const isAuthor = isDebug();
4321
+ try {
4322
+ takeCodedWarnings();
4323
+ await ensureDevelopArtifacts();
4324
+ if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
4325
+ ensureTypeScriptConfig(manifestDir);
4326
+ if (isUsingTypeScript(manifestDir)) await generateExtensionTypes(manifestDir, packageJsonDir);
4327
+ const [{ rspack }, { merge }, { handleStatsErrors, isEmitTimeWarning }, { default: webpackConfig }] = await Promise.all([
4328
+ import("@rspack/core"),
4329
+ import("webpack-merge"),
4330
+ import("./stats-handler~0.mjs"),
4331
+ import("./rspack-config~0.mjs")
4332
+ ]);
4333
+ const debug = isAuthor;
4334
+ const userManifestPath = projectStructure.packageJsonPath || projectStructure.denoJsonPath;
4335
+ if (userManifestPath) assertNoManagedDependencyConflicts(userManifestPath, packageJsonDir);
4336
+ const projectConfig = await loadProjectConfigDefaults(packageJsonDir);
4337
+ const commandConfig = await loadCommandConfig(packageJsonDir, commandKey);
4338
+ const outDir = resolveOutDir(buildOptions?.outDir ?? commandConfig.outDir, packageJsonDir);
4339
+ distPath = getBuildDistPath(packageJsonDir, browser, outDir);
4340
+ stagingDistPath = stagingDistPathFor(distPath);
4341
+ const liveDevSession = findLiveDevSession(packageJsonDir, browser);
4342
+ if (liveDevSession && __rspack_external_node_path_806ed179.resolve(liveDevSession.distPath || browserDistDir(packageJsonDir, browser)) === __rspack_external_node_path_806ed179.resolve(distPath)) throw codedError(CODES.E_DEV_SESSION_DIST_SHARED, buildSharesDevDist(browser, displayPath(distPath), liveDevSession.pid));
4343
+ const browserConfig = await loadBrowserConfig(packageJsonDir, browser);
4344
+ const foldersConfig = commandConfig.folders ?? browserConfig.folders ?? projectConfig.folders;
4345
+ rememberSpecialFoldersConfig(packageJsonDir, foldersConfig);
4346
+ const specialFoldersData = getSpecialFoldersDataForProjectRoot(packageJsonDir, foldersConfig);
4347
+ const mergedBuildOptions = mergeOptionLayers('start' === commandKey ? START_BUILD_DEFAULTS : BUILD_COMMAND_DEFAULTS, projectConfig, browserConfig, commandConfig, buildOptions);
4348
+ const silent = Boolean(mergedBuildOptions.silent);
4349
+ const safariPackager = 'safari' === browser || 'webkit-based' === browser ? buildOptions?.safariPackager : void 0;
4350
+ const safariIdentity = safariPackager ? resolveSafariIdentity(mergedBuildOptions) : void 0;
4351
+ removeStaleStagingDirs(distPath);
4352
+ if (debug) {
4353
+ debugLine(debugDirs(manifestDir, packageJsonDir));
4354
+ debugLine(debugBrowser(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
4355
+ debugLine(debugOutputPath(distPath));
4356
+ }
4357
+ const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? browserConfig.extensions ?? projectConfig.extensions ?? specialFoldersData.extensions;
4358
+ const resolvedExtensionsConfig = await resolveCompanionExtensionsConfig({
4359
+ projectRoot: packageJsonDir,
4360
+ browser,
4361
+ config: mergedExtensionsConfig
4362
+ });
4363
+ const resolvedMode = buildOptions?.mode === 'development' || buildOptions?.mode === 'none' || buildOptions?.mode === 'production' ? buildOptions.mode : 'production';
4364
+ if ('development' === resolvedMode || 'production' === resolvedMode) process.env.NODE_ENV = resolvedMode;
4365
+ const buildType = 'development' === resolvedMode ? 'development' : 'production';
4366
+ const baseConfig = webpackConfig(projectStructure, {
4367
+ ...mergedBuildOptions,
4368
+ extensions: resolvedExtensionsConfig,
4369
+ browser,
4370
+ mode: resolvedMode,
4371
+ minify: mergedBuildOptions.minify ?? 'opera' !== browser,
4372
+ metadataCommand: buildOptions?.metadataCommand || 'build',
4373
+ output: {
4374
+ clean: false,
4375
+ path: stagingDistPath,
4376
+ finalPath: distPath
4377
+ }
4378
+ });
4379
+ const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>{
4380
+ const name = plugin?.constructor.name;
4381
+ if ('plugin-browsers' === name) return false;
4382
+ return !(liveDevSession && 'plugin-playwright' === name);
4383
+ });
4384
+ const hookContext = {
4385
+ browser,
4386
+ mode: resolvedMode,
4387
+ command: buildOptions?.metadataCommand || 'build'
4388
+ };
4389
+ const userExtensionConfig = await loadCustomConfig(packageJsonDir, hookContext);
4390
+ const userConfig = userExtensionConfig({
4391
+ ...baseConfig,
4392
+ plugins: allPluginsButBrowserRunners
4393
+ });
4394
+ const compilerConfig = applySplitChunksGuard(merge(userConfig));
4395
+ compilerConfig.stats = false;
4396
+ const configResolved = await loadConfigResolvedHook(packageJsonDir);
4397
+ if (configResolved) compilerConfig.plugins = [
4398
+ ...compilerConfig.plugins || [],
4399
+ new ConfigResolvedPlugin(configResolved, hookContext)
4400
+ ];
4401
+ const compileContext = 'string' == typeof compilerConfig.context && compilerConfig.context ? __rspack_external_node_path_806ed179.resolve(compilerConfig.context) : packageJsonDir;
4402
+ const mergedOutputPath = 'string' == typeof compilerConfig.output?.path ? __rspack_external_node_path_806ed179.resolve(compileContext, compilerConfig.output.path) : '';
4403
+ const useStagingSwap = mergedOutputPath === __rspack_external_node_path_806ed179.resolve(stagingDistPath);
4404
+ const displayDistPath = useStagingSwap || !mergedOutputPath ? distPath : mergedOutputPath;
4405
+ if (!useStagingSwap && mergedOutputPath) try {
4406
+ __rspack_external_node_fs_1b05aee1.rmSync(mergedOutputPath, {
4407
+ recursive: true,
4408
+ force: true
4409
+ });
4410
+ } catch {}
4411
+ const compiler = rspack(compilerConfig);
4412
+ let summary = {
4413
+ browser,
4414
+ buildType,
4415
+ output_path: distPath,
4416
+ total_assets: 0,
4417
+ total_bytes: 0,
4418
+ largest_asset_bytes: 0,
4419
+ warnings_count: 0,
4420
+ errors_count: 0
4421
+ };
4422
+ await new Promise((resolve, reject)=>{
4423
+ compiler.run(async (err, stats)=>{
4424
+ if (err) {
4425
+ console.error(err.stack || err);
4426
+ removeStagingDir(stagingDistPath);
4427
+ return reject(err);
4428
+ }
4429
+ if (!stats || 'function' != typeof stats.hasErrors) {
4430
+ removeStagingDir(stagingDistPath);
4431
+ return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
4432
+ }
4433
+ const outputFiles = listOutputFiles(useStagingSwap ? stagingDistPath : displayDistPath);
4434
+ try {
4435
+ printBuildCard(projectStructure.manifestPath, browser, displayDistPath);
4436
+ if (!silent) {
4437
+ const assetsTree = buildAssetsTree(stats, outputFiles);
4438
+ if (assetsTree) humanLine(assetsTree);
4439
+ }
4440
+ } catch {}
4441
+ if (stats.hasErrors()) {
4442
+ removeStagingDir(stagingDistPath);
4443
+ handleStatsErrors(stats);
4444
+ let errorCount = 1;
4445
+ try {
4446
+ const info = stats.toJson({
4447
+ all: false,
4448
+ errors: true
4449
+ });
4450
+ errorCount = Math.max(1, info?.errors?.length || 1);
4451
+ } catch {}
4452
+ console.error(buildFailed(errorCount));
4453
+ if (!shouldExitOnError) {
4454
+ const { details, truncated } = compilationDiagnostics(stats.compilation, packageJsonDir);
4455
+ const failure = Object.assign(new Error('Build failed with errors'), {
4456
+ code: CODES.E_COMPILE,
4457
+ diagnostics: details,
4458
+ truncated
4459
+ });
4460
+ reportedBuildFailures.add(failure);
4461
+ return reject(failure);
4462
+ }
4463
+ process.exit(1);
4464
+ } else {
4465
+ if (useStagingSwap && __rspack_external_node_fs_1b05aee1.existsSync(stagingDistPath)) {
4466
+ try {
4467
+ promoteStagingDist(stagingDistPath, distPath);
4468
+ } catch (promoteError) {
4469
+ removeStagingDir(stagingDistPath);
4470
+ return reject(promoteError);
4471
+ }
4472
+ if (!liveDevSession) stampReadyDistExtensionId(packageJsonDir, browser, distPath);
4473
+ }
4474
+ if ('production' === buildType) {
4475
+ removeDevelopmentArtifacts(displayDistPath);
4476
+ warnProductionLoopbackOrigins(displayDistPath);
4477
+ }
4478
+ const info = stats?.toJson({
4479
+ all: false,
4480
+ assets: true,
4481
+ warnings: true,
4482
+ errors: true
4483
+ });
4484
+ summary = {
4485
+ ...summary,
4486
+ ...getBuildSummary(browser, info, displayDistPath, outputFiles, warningCodes(stats.compilation)),
4487
+ toolchain: getBuildToolchain()
4488
+ };
4489
+ const codedWarnings = takeCodedWarnings();
4490
+ if (codedWarnings.length > 0) summary = {
4491
+ ...summary,
4492
+ warnings_count: summary.warnings_count + codedWarnings.length,
4493
+ warnings: [
4494
+ ...summary.warnings || [],
4495
+ ...codedWarnings
4496
+ ]
4497
+ };
4498
+ const distDisplay = displayPath(displayDistPath);
4499
+ const lintLines = [];
4500
+ try {
4501
+ const lint = await runAddonLint({
4502
+ projectPath: packageJsonDir,
4503
+ distPath: displayDistPath,
4504
+ distDisplay,
4505
+ browser,
4506
+ mode: resolvedMode,
4507
+ enabled: mergedBuildOptions.addonLint,
4508
+ chunkProvenance: ()=>collectChunkDependencyProvenance(stats.compilation)
4509
+ });
4510
+ summary = {
4511
+ ...summary,
4512
+ addon_lint: summarizeAddonLint(lint)
4513
+ };
4514
+ if ('missing' === lint.status && lint.hint) lintLines.push(lint.hint);
4515
+ else if ('failed' === lint.status) {
4516
+ lintLines.push(lint.line);
4517
+ if (isDebug()) lintLines.push(lint.debugLine);
4518
+ } else if ('linted' === lint.status && lint.findings > 0) {
4519
+ lintLines.push(...lint.lines);
4520
+ if (lint.reviewerNote) lintLines.push(lint.reviewerNote.line);
4521
+ summary = {
4522
+ ...summary,
4523
+ warnings_count: summary.warnings_count + lint.findings,
4524
+ warnings: [
4525
+ ...summary.warnings || [],
4526
+ ...lint.lines.map((line)=>stripAnsi(line))
4527
+ ]
4528
+ };
4529
+ }
4530
+ } catch (lintError) {
4531
+ const lint = failedAddonLint(lintError, distDisplay);
4532
+ summary = {
4533
+ ...summary,
4534
+ addon_lint: summarizeAddonLint(lint)
4535
+ };
4536
+ lintLines.push(lint.line);
4537
+ }
4538
+ const zipArtifacts = getZipArtifacts(stats.compilation).map((artifact)=>({
4539
+ kind: artifact.kind,
4540
+ path: useStagingSwap && artifact.path.startsWith(stagingDistPath) ? distPath + artifact.path.slice(stagingDistPath.length) : artifact.path,
4541
+ size: artifact.size
4542
+ }));
4543
+ if (zipArtifacts.length > 0) summary = {
4544
+ ...summary,
4545
+ zip_artifacts: zipArtifacts
4546
+ };
4547
+ try {
4548
+ const summaryFile = buildSummaryPath(packageJsonDir, browser);
4549
+ __rspack_external_node_fs_1b05aee1.mkdirSync(__rspack_external_node_path_806ed179.dirname(summaryFile), {
4550
+ recursive: true
4551
+ });
4552
+ ensureSessionArtifactsIgnoreFile(packageJsonDir);
4553
+ ensureSessionStateInProjectGitignore(packageJsonDir);
4554
+ __rspack_external_node_fs_1b05aee1.writeFileSync(summaryFile, JSON.stringify(summary));
4555
+ } catch {}
4556
+ if ((info?.warnings || []).length > 0) {
4557
+ const warningDetails = buildWarningsDetails((info?.warnings || []).filter((warning)=>!isEmitTimeWarning(warning)));
4558
+ if (warningDetails) humanLine(warningDetails);
4559
+ }
4560
+ for (const line of lintLines)humanLine(line);
4561
+ if ('production' === resolvedMode && 'opera' === browser && void 0 === mergedBuildOptions.minify) humanLine(operaBuildUnminified());
4562
+ humanLine(buildComplete(browser, distDisplay, summary.total_bytes, resolvedMode));
4563
+ if ('production' === resolvedMode && summary.toolchain) humanLine(buildToolchain(summary.toolchain));
4564
+ for (const artifact of zipArtifacts){
4565
+ const zipDisplay = relativeToDir(artifact.path, process.cwd()) || artifact.path;
4566
+ humanLine(zipArtifactReady(zipDisplay, artifact.size));
4567
+ }
4568
+ const zipFailures = getZipFailures(stats.compilation);
4569
+ if (zipFailures.length > 0) {
4570
+ for (const failure of zipFailures){
4571
+ const failureDisplay = relativeToDir(failure.path, process.cwd()) || failure.path;
4572
+ console.error(zipArtifactNotCreated(failure.kind, failureDisplay, failure.reason));
4573
+ }
4574
+ reject(Object.assign(new Error(`${zipFailures.length} requested archive${1 === zipFailures.length ? ' was' : 's were'} not created`), {
4575
+ code: 'E_ZIP_SKIPPED'
4576
+ }));
4577
+ return;
4578
+ }
4579
+ const shareHint = buildShareHint();
4580
+ if (shareHint) humanLine(shareHint);
4581
+ resolve();
4582
+ }
4583
+ });
4584
+ });
4585
+ if (safariPackager && safariIdentity) {
4586
+ if (!__rspack_external_node_fs_1b05aee1.existsSync(displayDistPath)) throw new Error(safariBuildOutputNotFound(displayDistPath));
4587
+ const safari = await safariPackager(displayDistPath, 'full', safariIdentity);
4588
+ if (safari) {
4589
+ summary = {
4590
+ ...summary,
4591
+ safari
4592
+ };
4593
+ try {
4594
+ __rspack_external_node_fs_1b05aee1.writeFileSync(buildSummaryPath(packageJsonDir, browser), JSON.stringify(summary));
4595
+ } catch {}
4596
+ if (safari.bundleId && !liveDevSession) stampReadyKnownExtensionId(packageJsonDir, browser, `${safari.bundleId}.Extension`);
4597
+ }
4297
4598
  }
4298
- } catch (e) {
4299
- // Ignore
4300
- }
4301
- // The producer's restart also brings the url-override tabs back.
4302
- if (typeof g.__extjsDevRestartExtension === "function") {
4303
- try { g.__extjsDevRestartExtension(150); return; } catch (e) {
4304
- // Ignore
4599
+ return summary;
4600
+ } catch (error) {
4601
+ if (stagingDistPath) removeStagingDir(stagingDistPath);
4602
+ const alreadyReported = error instanceof Error && reportedBuildFailures.has(error);
4603
+ if (!alreadyReported) {
4604
+ if (isDebug()) console.error(error);
4605
+ else console.error(buildCommandFailed(error));
4606
+ console.error(buildFailed(1));
4305
4607
  }
4306
- }
4307
- setTimeout(function () { try { chrome.runtime.reload(); } catch (e) {
4308
- // Ignore
4309
- } }, 150);
4310
- }
4311
-
4312
- function staticBundlesOf(e) {
4313
- return (e.js || []).filter(isString).concat((e.css || []).filter(isString)).join("\\n");
4608
+ if (!shouldExitOnError) throw error;
4609
+ process.exit(1);
4314
4610
  }
4315
-
4316
- // The static entries' hashed bundle names, as recorded by the previous
4317
- // generation: a service worker reload ships a shared module's edit to a
4318
- // static entry too, and nothing but the name says its tabs are stale.
4319
- function healStaticEntries() {
4320
- try {
4321
- if (!chrome.storage || !chrome.storage.local) return;
4322
- chrome.storage.local.get([STATIC_RELOAD_KEY, STATIC_BUNDLES_KEY], function (res) {
4323
- noop();
4324
- var flag = res && res[STATIC_RELOAD_KEY];
4325
- var recorded = res && res[STATIC_BUNDLES_KEY];
4326
- if (flag) {
4327
- try { chrome.storage.local.remove(STATIC_RELOAD_KEY, noop); } catch (e) {
4328
- // Ignore
4329
- }
4330
- }
4331
- var flagged = flag && typeof flag.at === "number" && Date.now() - flag.at <= 30000 && Array.isArray(flag.entries) ? flag.entries : [];
4332
- var known = recorded && typeof recorded === "object" ? recorded : null;
4333
- onReady(function () {
4334
- if (!registry) return;
4335
- var entries = [];
4336
- var current = {};
4337
- for (var i = 0; i < registry.entries.length; i++) {
4338
- var e = registry.entries[i];
4339
- if (!e || !e.static || !isString(e.entry)) continue;
4340
- current[e.entry] = staticBundlesOf(e);
4341
- var changed = known && isString(known[e.entry]) && known[e.entry] !== current[e.entry];
4342
- if (changed || flagged.indexOf(e.entry) !== -1) entries.push(e);
4343
- }
4344
- try {
4345
- var record = {};
4346
- record[STATIC_BUNDLES_KEY] = current;
4347
- chrome.storage.local.set(record, noop);
4348
- } catch (e) {
4349
- // Ignore
4611
+ }
4612
+ function reloadingExtensionForStaticContentScript(label) {
4613
+ return `${messaging_prefix('info')} Reloading the extension for ${label}: a ${pintor.blue('document_start')} content script is read once when the extension loads, so the pages it matches reload too.`;
4614
+ }
4615
+ function backgroundIsRequiredMessageOnly(backgroundChunkName) {
4616
+ return `Check the ${pintor.blue(backgroundChunkName.replace('/', '.'))} field in your ${pintor.blue('manifest.json')} file.`;
4617
+ }
4618
+ function reloadKindFor(type) {
4619
+ if ('service-worker' === type) return 'background';
4620
+ if ("content-scripts" === type) return 'content';
4621
+ if ('page' === type) return 'page';
4622
+ return 'full';
4623
+ }
4624
+ function viaBroker(broker, instruction) {
4625
+ return broker.broadcastReload({
4626
+ type: instruction.type,
4627
+ changedContentScriptEntries: instruction.changedContentScriptEntries,
4628
+ label: instruction.label,
4629
+ changedFiles: instruction.changedAssets,
4630
+ ...instruction.changedScriptFiles?.length ? {
4631
+ changedScriptFiles: instruction.changedScriptFiles
4632
+ } : {}
4633
+ });
4634
+ }
4635
+ function formatReloadingLine(label) {
4636
+ return `${messaging_prefix('info')} Reloading ${label}…`;
4637
+ }
4638
+ function formatUnappliedReloadLine(label) {
4639
+ return `${messaging_prefix('warn')} ${label} compiled but the extension never confirmed the reload, so this edit may not be live. Save again, or reload the extension from the browser.`;
4640
+ }
4641
+ function formatQueuedReloadLine(label) {
4642
+ return `${messaging_prefix('info')} Queued ${label} for the extension to apply when it reconnects.`;
4643
+ }
4644
+ async function dispatchReload(instruction, executor) {
4645
+ if (!instruction) return;
4646
+ if ('true' === process.env.EXTENSION_NO_RELOAD) return;
4647
+ if (executor.broker) {
4648
+ const notified = viaBroker(executor.broker, instruction);
4649
+ if (notified > 0) {
4650
+ const ack = await executor.broker.awaitReloadAck?.() ?? 'not-expected';
4651
+ if ('unacked' === ack) {
4652
+ if (instruction.label) console.warn(formatUnappliedReloadLine(instruction.label));
4653
+ return;
4350
4654
  }
4351
- if (entries.length) reloadTabs(entries);
4352
- });
4353
- });
4354
- } catch (e) {
4355
- // Ignore
4356
- }
4357
- }
4358
-
4359
- // A content script edit: re-register at the new files and reload the tabs
4360
- // the edited entries match, or the extension when a static one is edited.
4361
- function reload(names, done) {
4362
- load(function (reg) {
4363
- if (!reg) return call(function () { done(false); });
4364
- registry = reg;
4365
- var wanted = Array.isArray(names) && names.length ? names : null;
4366
- var edited = [], statics = [];
4367
- for (var i = 0; i < reg.entries.length; i++) {
4368
- var e = reg.entries[i];
4369
- if (!e || (wanted && wanted.indexOf(e.entry) === -1)) continue;
4370
- (e.static ? statics : edited).push(e);
4371
- }
4372
- if (statics.length) {
4373
- reloadExtensionFor(statics);
4374
- return call(function () { done(true); });
4655
+ executor.broker.noteReloadApplied?.(reloadKindFor(instruction.type), instruction.label);
4656
+ if (instruction.label) humanLine(instruction.staticContentScriptEntries?.length ? reloadingExtensionForStaticContentScript(instruction.label) : formatReloadingLine(instruction.label));
4657
+ return;
4375
4658
  }
4376
- sync(reg, function () {
4377
- markReady();
4378
- reloadTabs(edited, function () { done(true); });
4379
- });
4380
- });
4659
+ const warning = executor.broker.undeliveredReloadWarning?.(executor.producerRestartExpected ? {
4660
+ producerRestartExpected: true
4661
+ } : void 0);
4662
+ if (warning) return void console.warn(warning);
4663
+ if (executor.producerRestartExpected && instruction.label) humanLine(formatQueuedReloadLine(instruction.label));
4381
4664
  }
4382
-
4665
+ }
4666
+ function isForcedFullPath(normalized) {
4667
+ return normalized.includes('manifest.json') || normalized.includes('_locales/');
4668
+ }
4669
+ function isHotAsset(normalized) {
4670
+ return normalized.startsWith('hot/') || normalized.includes('.hot-update.');
4671
+ }
4672
+ function isDirectory(absolute) {
4383
4673
  try {
4384
- chrome.runtime.onMessage.addListener(function (msg, sender) {
4385
- if (!msg || !msg[STUB]) return;
4386
- onStub(msg[STUB], sender);
4387
- });
4388
- } catch (e) {
4389
- // Ignore
4674
+ return __rspack_external_node_fs_1b05aee1.statSync(absolute).isDirectory();
4675
+ } catch {
4676
+ return false;
4390
4677
  }
4391
-
4392
- g.__extjsDevContentScripts = {heal: heal, reload: reload, isReady: function () { return ready; }};
4393
-
4394
- load(function (reg) {
4395
- registry = reg;
4396
- if (!reg) return markReady();
4397
- sync(reg, markReady);
4678
+ }
4679
+ function normalizeChangedPath(file, contextDir) {
4680
+ const raw = String(file || '');
4681
+ if (!raw) return;
4682
+ if (__rspack_external_node_path_806ed179.isAbsolute(raw) && isDirectory(raw)) return;
4683
+ const normalized = __rspack_external_node_path_806ed179.isAbsolute(raw) ? __rspack_external_node_path_806ed179.relative(contextDir, raw).replace(/\\/g, '/') : raw.replace(/\\/g, '/');
4684
+ if (!normalized) return;
4685
+ return normalized;
4686
+ }
4687
+ function pushChanged(into, file, contextDir, markForced) {
4688
+ const normalized = normalizeChangedPath(file, contextDir);
4689
+ if (!normalized) return;
4690
+ if (!into.includes(normalized)) into.push(normalized);
4691
+ if (isForcedFullPath(normalized)) markForced();
4692
+ }
4693
+ function createChangedSourcesTracker(compiler) {
4694
+ let forcedFull = false;
4695
+ let changedSources = [];
4696
+ let heldForcedFull = false;
4697
+ let heldSources = [];
4698
+ let writtenAssets = [];
4699
+ const contextDir = ()=>compiler.options.context || '';
4700
+ const ingest = (files, into, markForced)=>{
4701
+ if (!files) return;
4702
+ const ctx = contextDir();
4703
+ for (const file of files)pushChanged(into, file, ctx, markForced);
4704
+ };
4705
+ const foldRecoveryIntoCurrent = ()=>{
4706
+ const recovering = heldSources.length > 0 || heldForcedFull;
4707
+ if (!recovering) return;
4708
+ for (const file of heldSources)if (!changedSources.includes(file)) changedSources.push(file);
4709
+ for (const file of writtenAssets)if (!changedSources.includes(file)) changedSources.push(file);
4710
+ forcedFull = forcedFull || heldForcedFull || writtenAssets.some((file)=>isForcedFullPath(file));
4711
+ heldSources = [];
4712
+ heldForcedFull = false;
4713
+ };
4714
+ const markForced = ()=>{
4715
+ forcedFull = true;
4716
+ };
4717
+ compiler.hooks.watchRun.tap('extjs-reload-changed-sources', ()=>{
4718
+ forcedFull = false;
4719
+ changedSources = [];
4720
+ writtenAssets = [];
4721
+ ingest(compiler.modifiedFiles, changedSources, markForced);
4398
4722
  });
4399
- healStaticEntries();
4400
- } catch (e) {
4401
- // Ignore
4402
- }
4403
- })();
4404
- `;
4723
+ compiler.hooks.done?.tap?.('extjs-reload-changed-sources-done', (stats)=>{
4724
+ const compilation = stats?.compilation;
4725
+ ingest(compilation?.modifiedFiles, changedSources, markForced);
4726
+ ingest(compiler.modifiedFiles, changedSources, markForced);
4727
+ if (compilation?.errors && compilation.errors.length > 0) {
4728
+ heldForcedFull = heldForcedFull || forcedFull;
4729
+ for (const file of changedSources)if (!heldSources.includes(file)) heldSources.push(file);
4730
+ return;
4731
+ }
4732
+ foldRecoveryIntoCurrent();
4733
+ });
4734
+ compiler.hooks.assetEmitted?.tap?.('extjs-reload-changed-sources-emitted', (file)=>{
4735
+ const normalized = normalizeChangedPath(file, contextDir());
4736
+ if (!normalized || isHotAsset(normalized)) return;
4737
+ if (!writtenAssets.includes(normalized)) writtenAssets.push(normalized);
4738
+ });
4739
+ return {
4740
+ snapshot: ()=>{
4741
+ foldRecoveryIntoCurrent();
4742
+ return {
4743
+ forcedFull,
4744
+ changedSources
4745
+ };
4746
+ }
4747
+ };
4748
+ }
4405
4749
  function formatReloadContextLabel(context, files) {
4406
4750
  if (!files.length) return context;
4407
4751
  const shown = files.slice(0, 2).join(', ');