extension-develop 3.14.5 → 3.15.0-next.1

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 (51) hide show
  1. package/dist/{481.cjs → 221.cjs} +1 -1
  2. package/dist/{750.cjs → 504.cjs} +2 -2
  3. package/dist/{740.cjs → 512.cjs} +5 -4
  4. package/dist/{893.cjs → 787.cjs} +1 -1
  5. package/dist/extension-js-devtools/chrome/background/service_worker.js +2 -2
  6. package/dist/extension-js-devtools/chrome/content_scripts/content-0.js +2 -2
  7. package/dist/extension-js-devtools/chrome/content_scripts/styles.305cf4cf.css +2 -0
  8. package/dist/extension-js-devtools/chrome/devtools/index.js +1 -1
  9. package/dist/extension-js-devtools/chrome/manifest.json +1 -1
  10. package/dist/extension-js-devtools/chrome/pages/centralized-logger.css +1 -1
  11. package/dist/extension-js-devtools/chrome/pages/centralized-logger.js +1 -1
  12. package/dist/extension-js-devtools/chrome/pages/welcome.css +1 -1
  13. package/dist/extension-js-devtools/chrome/pages/welcome.js +2 -2
  14. package/dist/extension-js-devtools/chrome/scripts/logger-client.js +0 -1
  15. package/dist/extension-js-devtools/chromium/background/service_worker.js +2 -2
  16. package/dist/extension-js-devtools/chromium/content_scripts/content-0.js +2 -2
  17. package/dist/extension-js-devtools/chromium/content_scripts/styles.305cf4cf.css +2 -0
  18. package/dist/extension-js-devtools/chromium/devtools/index.js +1 -1
  19. package/dist/extension-js-devtools/chromium/manifest.json +1 -1
  20. package/dist/extension-js-devtools/chromium/pages/centralized-logger.css +1 -1
  21. package/dist/extension-js-devtools/chromium/pages/centralized-logger.js +1 -1
  22. package/dist/extension-js-devtools/chromium/pages/welcome.css +1 -1
  23. package/dist/extension-js-devtools/chromium/pages/welcome.js +2 -2
  24. package/dist/extension-js-devtools/chromium/scripts/logger-client.js +0 -1
  25. package/dist/extension-js-devtools/edge/background/service_worker.js +2 -2
  26. package/dist/extension-js-devtools/edge/content_scripts/content-0.js +2 -2
  27. package/dist/extension-js-devtools/edge/content_scripts/styles.305cf4cf.css +2 -0
  28. package/dist/extension-js-devtools/edge/devtools/index.js +1 -1
  29. package/dist/extension-js-devtools/edge/manifest.json +1 -1
  30. package/dist/extension-js-devtools/edge/pages/centralized-logger.css +1 -1
  31. package/dist/extension-js-devtools/edge/pages/centralized-logger.js +1 -1
  32. package/dist/extension-js-devtools/edge/pages/welcome.css +1 -1
  33. package/dist/extension-js-devtools/edge/pages/welcome.js +2 -2
  34. package/dist/extension-js-devtools/edge/scripts/logger-client.js +0 -1
  35. package/dist/extension-js-devtools/firefox/background/scripts.js +2 -2
  36. package/dist/extension-js-devtools/firefox/content_scripts/content-0.js +2 -2
  37. package/dist/extension-js-devtools/firefox/content_scripts/styles.305cf4cf.css +2 -0
  38. package/dist/extension-js-devtools/firefox/devtools/index.js +1 -1
  39. package/dist/extension-js-devtools/firefox/manifest.json +1 -2
  40. package/dist/extension-js-devtools/firefox/pages/centralized-logger.css +1 -1
  41. package/dist/extension-js-devtools/firefox/pages/centralized-logger.js +1 -1
  42. package/dist/extension-js-devtools/firefox/pages/welcome.css +1 -1
  43. package/dist/extension-js-devtools/firefox/pages/welcome.js +2 -2
  44. package/dist/extension-js-devtools/firefox/scripts/logger-client.js +0 -1
  45. package/dist/module.cjs +1800 -1792
  46. package/dist/preview.cjs +1187 -1187
  47. package/package.json +10 -10
  48. package/dist/extension-js-devtools/chrome/content_scripts/styles.5456c644.css +0 -2
  49. package/dist/extension-js-devtools/chromium/content_scripts/styles.5456c644.css +0 -2
  50. package/dist/extension-js-devtools/edge/content_scripts/styles.5456c644.css +0 -2
  51. package/dist/extension-js-devtools/firefox/content_scripts/styles.5456c644.css +0 -2
package/dist/module.cjs CHANGED
@@ -1487,1928 +1487,1936 @@ var __webpack_modules__ = {
1487
1487
  return Object.fromEntries(Object.entries(obj || {}).filter(([, value])=>void 0 !== value));
1488
1488
  }
1489
1489
  },
1490
- "./plugin-js-frameworks/frameworks-lib/integrations.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1491
- __webpack_require__.d(__webpack_exports__, {
1492
- qQ: ()=>isUsingJSFramework,
1493
- ws: ()=>_lib_has_dependency__rspack_import_0.w
1494
- });
1495
- var _lib_has_dependency__rspack_import_0 = __webpack_require__("./lib/has-dependency.ts");
1496
- __webpack_require__("./lib/develop-context.ts");
1497
- function isUsingJSFramework(projectPath) {
1498
- const frameworks = [
1499
- 'react',
1500
- 'vue',
1501
- '@angular/core',
1502
- 'svelte',
1503
- 'solid-js',
1504
- 'preact'
1505
- ];
1506
- return frameworks.some((fw)=>(0, _lib_has_dependency__rspack_import_0.w)(projectPath, fw));
1507
- }
1508
- },
1509
- "./plugin-js-frameworks/js-frameworks-lib/messages.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1490
+ "./module.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1491
+ __webpack_require__.r(__webpack_exports__);
1510
1492
  __webpack_require__.d(__webpack_exports__, {
1511
- Ei: ()=>jsFrameworksHmrSummary,
1512
- LR: ()=>creatingTSConfig,
1513
- MH: ()=>jsFrameworksConfigsDetected,
1514
- Ty: ()=>isUsingCustomLoader,
1515
- jH: ()=>jsFrameworksIntegrationsEnabled,
1516
- zA: ()=>isUsingIntegration
1493
+ BuildEmitter: ()=>BuildEmitter,
1494
+ extensionDev: ()=>extensionDev,
1495
+ extensionPreview: ()=>extensionPreview,
1496
+ extensionBuild: ()=>extensionBuild
1517
1497
  });
1518
- var pintor__rspack_import_0 = __webpack_require__("pintor");
1519
- var pintor__rspack_import_0_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_0);
1520
- function isUsingIntegration(name) {
1521
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Using ${pintor__rspack_import_0_default().brightBlue(name)}...`;
1522
- }
1523
- function creatingTSConfig() {
1524
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Creating default tsconfig.json...`;
1525
- }
1526
- function isUsingCustomLoader(loaderPath) {
1527
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Using custom loader: ${pintor__rspack_import_0_default().yellow(loaderPath)}.`;
1528
- }
1529
- function jsFrameworksIntegrationsEnabled(integrations) {
1530
- const list = integrations.length > 0 ? integrations.map((n)=>pintor__rspack_import_0_default().yellow(n)).join(', ') : pintor__rspack_import_0_default().gray('none');
1531
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: Integrations enabled (${pintor__rspack_import_0_default().gray(String(integrations.length))}) ${list}`;
1498
+ function getBuildSummary(browser, info) {
1499
+ const assets = info?.assets || [];
1500
+ return {
1501
+ browser,
1502
+ total_assets: assets.length,
1503
+ total_bytes: assets.reduce((n, a)=>n + (a.size || 0), 0),
1504
+ largest_asset_bytes: assets.reduce((m, a)=>Math.max(m, a.size || 0), 0),
1505
+ warnings_count: (info?.warnings || []).length,
1506
+ errors_count: (info?.errors || []).length
1507
+ };
1532
1508
  }
1533
- function jsFrameworksConfigsDetected(tsConfigPath, tsRoot, targets) {
1534
- const fmt = (v)=>v ? pintor__rspack_import_0_default().underline(v) : pintor__rspack_import_0_default().gray('none');
1535
- const tgt = targets && targets.length ? targets.map((t)=>pintor__rspack_import_0_default().gray(t)).join(', ') : pintor__rspack_import_0_default().gray('default');
1536
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: Configs\n${pintor__rspack_import_0_default().gray('TSCONFIG')} ${fmt(tsConfigPath)}\n${pintor__rspack_import_0_default().gray('TSROOT')} ${fmt(tsRoot)}\n${pintor__rspack_import_0_default().gray('SWC_TARGETS')} ${tgt}`;
1509
+ var external_module_ = __webpack_require__("module");
1510
+ var external_path_ = __webpack_require__("path");
1511
+ var external_fs_ = __webpack_require__("fs");
1512
+ var messages = __webpack_require__("./lib/messages.ts");
1513
+ async function findUpLocal(filename, options) {
1514
+ const root = external_path_.parse(options.cwd).root;
1515
+ let currentDir = options.cwd;
1516
+ while(true){
1517
+ const candidate = external_path_.join(currentDir, filename);
1518
+ try {
1519
+ const stat = await external_fs_.promises.stat(candidate);
1520
+ if (stat.isFile()) return candidate;
1521
+ } catch {}
1522
+ if (currentDir === root) return;
1523
+ currentDir = external_path_.dirname(currentDir);
1524
+ }
1537
1525
  }
1538
- function jsFrameworksHmrSummary(enabled, frameworks) {
1539
- const list = frameworks.length > 0 ? frameworks.map((n)=>pintor__rspack_import_0_default().yellow(n)).join(', ') : pintor__rspack_import_0_default().gray('none');
1540
- return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: HMR ${enabled ? pintor__rspack_import_0_default().green('enabled') : pintor__rspack_import_0_default().gray('disabled')} for ${list}`;
1526
+ async function findNearestPackageJson(manifestPath) {
1527
+ try {
1528
+ const manifestDir = external_path_.dirname(manifestPath);
1529
+ const packageJsonPath = await findUpLocal('package.json', {
1530
+ cwd: manifestDir
1531
+ });
1532
+ return packageJsonPath || null;
1533
+ } catch (error) {
1534
+ console.warn('Failed to find package.json:', error);
1535
+ return null;
1536
+ }
1541
1537
  }
1542
- },
1543
- "./plugin-js-frameworks/js-tools/typescript.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1544
- __webpack_require__.d(__webpack_exports__, {
1545
- eE: ()=>isUsingTypeScript,
1546
- hB: ()=>getUserTypeScriptConfigFile
1547
- });
1548
- var path__rspack_import_0 = __webpack_require__("path");
1549
- var fs__rspack_import_1 = __webpack_require__("fs");
1550
- var pintor__rspack_import_2 = __webpack_require__("pintor");
1551
- var pintor__rspack_import_2_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_2);
1552
- var _js_frameworks_lib_messages__rspack_import_3 = __webpack_require__("./plugin-js-frameworks/js-frameworks-lib/messages.ts");
1553
- var _frameworks_lib_integrations__rspack_import_4 = __webpack_require__("./plugin-js-frameworks/frameworks-lib/integrations.ts");
1554
- __webpack_require__("./lib/optional-deps-resolver.ts");
1555
- var _lib_parse_json_safe__rspack_import_6 = __webpack_require__("./lib/parse-json-safe.ts");
1556
- let hasShownUserMessage = false;
1557
- function findNearestPackageJsonDirectory(startPath) {
1558
- let currentDirectory = startPath;
1559
- const maxDepth = 6;
1560
- for(let i = 0; i < maxDepth; i++){
1561
- const candidate = path__rspack_import_0.join(currentDirectory, 'package.json');
1562
- if (fs__rspack_import_1.existsSync(candidate)) return currentDirectory;
1563
- const parentDirectory = path__rspack_import_0.dirname(currentDirectory);
1564
- if (parentDirectory === currentDirectory) break;
1565
- currentDirectory = parentDirectory;
1538
+ function validatePackageJson(packageJsonPath) {
1539
+ try {
1540
+ if (!external_fs_.existsSync(packageJsonPath)) return false;
1541
+ const content = external_fs_.readFileSync(packageJsonPath, 'utf-8');
1542
+ JSON.parse(content);
1543
+ return true;
1544
+ } catch (error) {
1545
+ console.warn('Invalid package.json at:', packageJsonPath, error);
1546
+ return false;
1566
1547
  }
1567
1548
  }
1568
- function hasTypeScriptSourceFiles(projectPath) {
1549
+ const isUrl = (url)=>{
1569
1550
  try {
1570
- const entries = fs__rspack_import_1.readdirSync(projectPath, {
1571
- withFileTypes: true
1551
+ new URL(url);
1552
+ return true;
1553
+ } catch (e) {
1554
+ return false;
1555
+ }
1556
+ };
1557
+ async function importUrlSourceFromGithub(pathOrRemoteUrl, text) {
1558
+ const cwd = process.cwd();
1559
+ const url = new URL(pathOrRemoteUrl);
1560
+ const segments = url.pathname.split('/').filter(Boolean);
1561
+ const repoName = segments.length >= 2 ? segments[1] : segments[segments.length - 1];
1562
+ const treeIndex = segments.indexOf('tree');
1563
+ const expectedName = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments[segments.length - 1] : repoName;
1564
+ const expectedPath = external_path_.resolve(cwd, expectedName);
1565
+ if (external_fs_.existsSync(expectedPath)) try {
1566
+ const entries = external_fs_.readdirSync(expectedPath);
1567
+ if (0 === entries.length) external_fs_.rmSync(expectedPath, {
1568
+ recursive: true,
1569
+ force: true
1572
1570
  });
1573
- return entries.some((entry)=>{
1574
- if (entry.isFile()) {
1575
- const name = entry.name;
1576
- if (!/\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
1577
- if (/\.(d\.ts|d\.mts|d\.mtsx)$/i.test(name)) return false;
1578
- if (/\.(spec|test)\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
1579
- return true;
1571
+ else {
1572
+ const hasManifest = (dir)=>{
1573
+ const stack = [
1574
+ dir
1575
+ ];
1576
+ while(stack.length){
1577
+ const current = stack.pop();
1578
+ const items = external_fs_.readdirSync(current, {
1579
+ withFileTypes: true
1580
+ });
1581
+ for (const it of items){
1582
+ if (it.isFile() && 'manifest.json' === it.name) return true;
1583
+ if (it.isDirectory() && 'node_modules' !== it.name && 'dist' !== it.name && !it.name.startsWith('.')) stack.push(external_path_.join(current, it.name));
1584
+ }
1585
+ }
1586
+ return false;
1587
+ };
1588
+ if (hasManifest(expectedPath)) return expectedPath;
1589
+ external_fs_.rmSync(expectedPath, {
1590
+ recursive: true,
1591
+ force: true
1592
+ });
1593
+ }
1594
+ } catch {}
1595
+ async function tryGitClone() {
1596
+ const { default: goGitIt } = await import("go-git-it");
1597
+ await goGitIt(pathOrRemoteUrl, cwd, text);
1598
+ }
1599
+ async function tryZipFallback() {
1600
+ const branch = -1 !== treeIndex && segments.length > treeIndex + 1 ? segments[treeIndex + 1] : 'main';
1601
+ const owner = segments[0];
1602
+ const repo = segments[1];
1603
+ const subdir = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments.slice(treeIndex + 2).join('/') : '';
1604
+ const zipUrl = `https://codeload.github.com/${owner}/${repo}/zip/refs/heads/${branch}`;
1605
+ const extractedPath = await importUrlSourceFromZip(zipUrl);
1606
+ const extractedDirs = external_fs_.readdirSync(extractedPath, {
1607
+ withFileTypes: true
1608
+ }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1609
+ const repoRootDir = extractedDirs.find((d)=>d.startsWith(`${repo}-${branch}`));
1610
+ const repoRoot = repoRootDir ? external_path_.join(extractedPath, repoRootDir) : extractedPath;
1611
+ return subdir ? external_path_.join(repoRoot, subdir) : repoRoot;
1612
+ }
1613
+ try {
1614
+ await tryGitClone();
1615
+ } catch {
1616
+ return await tryZipFallback();
1617
+ }
1618
+ const candidates = [];
1619
+ if (-1 !== treeIndex && segments.length > treeIndex + 2) candidates.push(segments[segments.length - 1]);
1620
+ candidates.push(repoName);
1621
+ for (const name of candidates){
1622
+ const p = external_path_.resolve(cwd, name);
1623
+ if (external_fs_.existsSync(p)) return p;
1624
+ }
1625
+ const dirs = external_fs_.readdirSync(cwd, {
1626
+ withFileTypes: true
1627
+ }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1628
+ for (const dir of dirs){
1629
+ const manifestPath = external_path_.join(cwd, dir, 'manifest.json');
1630
+ if (external_fs_.existsSync(manifestPath)) return external_path_.join(cwd, dir);
1631
+ }
1632
+ try {
1633
+ const dirs = external_fs_.readdirSync(cwd, {
1634
+ withFileTypes: true
1635
+ }).filter((d)=>d.isDirectory()).map((d)=>d.name);
1636
+ const ghRoot = dirs.find((d)=>/-main$|-master$/.test(d));
1637
+ if (ghRoot) return external_path_.join(cwd, ghRoot);
1638
+ } catch {}
1639
+ throw new Error(messages.ax(cwd, candidates));
1640
+ }
1641
+ async function importUrlSourceFromZip(pathOrRemoteUrl) {
1642
+ const cwd = process.cwd();
1643
+ const { downloadAndExtractZip } = await __webpack_require__.e(787).then(__webpack_require__.bind(__webpack_require__, "./lib/zip.ts"));
1644
+ const extractedPath = await downloadAndExtractZip(pathOrRemoteUrl, cwd);
1645
+ return extractedPath;
1646
+ }
1647
+ async function getProjectPath(pathOrRemoteUrl) {
1648
+ if (!pathOrRemoteUrl) return process.cwd();
1649
+ if (isUrl(pathOrRemoteUrl)) {
1650
+ const url = new URL(pathOrRemoteUrl);
1651
+ if (url.protocol.startsWith('http')) {
1652
+ const pathname = url.pathname.toLowerCase();
1653
+ if (pathname.endsWith('.zip')) return await importUrlSourceFromZip(pathOrRemoteUrl);
1654
+ if ('https://github.com' !== url.origin) {
1655
+ const urlSource = await importUrlSourceFromZip(pathOrRemoteUrl);
1656
+ return urlSource;
1580
1657
  }
1581
- if (entry.isDirectory()) {
1582
- if (![
1583
- 'src',
1584
- 'content',
1585
- 'sidebar',
1586
- 'background'
1587
- ].includes(entry.name)) return false;
1588
- const sub = path__rspack_import_0.join(projectPath, entry.name);
1589
- return hasTypeScriptSourceFiles(sub);
1658
+ const urlData = url.pathname.split('/');
1659
+ const owner = urlData.slice(1, 3)[0];
1660
+ const project = urlData.slice(1, 3)[1];
1661
+ console.log(messages.tQ(owner, project));
1662
+ const projectName = external_path_.basename(url.pathname);
1663
+ const urlSource = await importUrlSourceFromGithub(pathOrRemoteUrl, messages.F$(projectName));
1664
+ console.log(messages.W4(url.pathname));
1665
+ return urlSource;
1666
+ }
1667
+ }
1668
+ return external_path_.resolve(process.cwd(), pathOrRemoteUrl);
1669
+ }
1670
+ async function getProjectStructure(pathOrRemoteUrl) {
1671
+ const projectPath = await getProjectPath(pathOrRemoteUrl);
1672
+ const isUnderDir = (baseDir, candidatePath)=>{
1673
+ const rel = external_path_.relative(baseDir, candidatePath);
1674
+ return Boolean(rel && !rel.startsWith('..') && !external_path_.isAbsolute(rel));
1675
+ };
1676
+ const packageJsonPathFromProject = await findNearestPackageJson(external_path_.join(projectPath, 'manifest.json'));
1677
+ const packageJsonDirFromProject = packageJsonPathFromProject ? external_path_.dirname(packageJsonPathFromProject) : void 0;
1678
+ const rootManifestPath = external_path_.join(projectPath, 'manifest.json');
1679
+ const srcManifestPath = external_path_.join(projectPath, 'src', 'manifest.json');
1680
+ let manifestPath = external_fs_.existsSync(srcManifestPath) ? srcManifestPath : rootManifestPath;
1681
+ if (!external_fs_.existsSync(manifestPath)) {
1682
+ if (packageJsonDirFromProject) throw new Error(messages.dx(manifestPath));
1683
+ const findManifest = (dir)=>{
1684
+ const files = external_fs_.readdirSync(dir, {
1685
+ withFileTypes: true
1686
+ });
1687
+ for (const file of files){
1688
+ if (file.isFile() && 'manifest.json' === file.name) return external_path_.join(dir, file.name);
1689
+ if (file.isDirectory() && !file.name.startsWith('.') && 'node_modules' !== file.name && 'dist' !== file.name && 'public' !== file.name) {
1690
+ const found = findManifest(external_path_.join(dir, file.name));
1691
+ if (found) return found;
1692
+ }
1590
1693
  }
1591
- return false;
1592
- });
1593
- } catch {
1594
- return false;
1694
+ return null;
1695
+ };
1696
+ const foundManifest = findManifest(projectPath);
1697
+ if (foundManifest) manifestPath = foundManifest;
1698
+ else throw new Error(messages.dx(manifestPath));
1699
+ }
1700
+ const packageJsonPath = await findNearestPackageJson(manifestPath);
1701
+ const packageJsonDir = packageJsonPath ? external_path_.dirname(packageJsonPath) : void 0;
1702
+ if (packageJsonDir) {
1703
+ const publicRoot = external_path_.join(packageJsonDir, 'public');
1704
+ if (isUnderDir(publicRoot, manifestPath)) {
1705
+ const fallbackSrc = external_path_.join(packageJsonDir, 'src', 'manifest.json');
1706
+ const fallbackRoot = external_path_.join(packageJsonDir, 'manifest.json');
1707
+ if (external_fs_.existsSync(fallbackSrc)) manifestPath = fallbackSrc;
1708
+ else if (external_fs_.existsSync(fallbackRoot)) manifestPath = fallbackRoot;
1709
+ else throw new Error(messages.dx(fallbackRoot));
1710
+ }
1595
1711
  }
1712
+ if (!packageJsonPath || !validatePackageJson(packageJsonPath)) return {
1713
+ manifestPath
1714
+ };
1715
+ return {
1716
+ manifestPath,
1717
+ packageJsonPath
1718
+ };
1596
1719
  }
1597
- function isUsingTypeScript(projectPath) {
1598
- const packageJsonDirectory = findNearestPackageJsonDirectory(projectPath);
1599
- const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
1600
- const packageJson = packageJsonDirectory ? (0, _lib_parse_json_safe__rspack_import_6.p)(fs__rspack_import_1.readFileSync(path__rspack_import_0.join(packageJsonDirectory, 'package.json'), 'utf8')) : void 0;
1601
- const TypeScriptAsDevDep = packageJson?.devDependencies?.typescript;
1602
- const TypeScriptAsDep = packageJson?.dependencies?.typescript;
1603
- const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
1604
- if (!hasShownUserMessage) {
1605
- if (TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles) if (tsConfigFilePath) {
1606
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`${pintor__rspack_import_2_default().brightMagenta('⏵⏵⏵ Author says')} ${_js_frameworks_lib_messages__rspack_import_3.zA('TypeScript')}`);
1607
- } else if (hasTsFiles) {
1608
- const errorMessage = '[Extension.js] Missing tsconfig.json next to package.json. Create one to use TypeScript.';
1609
- throw new Error(errorMessage);
1610
- } else {
1611
- console.log(_js_frameworks_lib_messages__rspack_import_3.LR());
1612
- writeTsConfig(projectPath);
1720
+ var config_loader = __webpack_require__("./lib/config-loader.ts");
1721
+ var package_0 = __webpack_require__("./package.json");
1722
+ function assertNoManagedDependencyConflicts(userPackageJsonPath, projectPath) {
1723
+ try {
1724
+ const raw = external_fs_.readFileSync(userPackageJsonPath, 'utf-8');
1725
+ const userPackageJson = JSON.parse(raw);
1726
+ const userDeps = Array.from(new Set([
1727
+ ...Object.keys(userPackageJson.dependencies || {}),
1728
+ ...Object.keys(userPackageJson.devDependencies || {}),
1729
+ ...Object.keys(userPackageJson.optionalDependencies || {}),
1730
+ ...Object.keys(userPackageJson.peerDependencies || {})
1731
+ ]));
1732
+ const managedDeps = new Set([
1733
+ ...Object.keys(package_0.El || {}),
1734
+ ...Object.keys(package_0.optionalDependencies || {})
1735
+ ]);
1736
+ managedDeps.delete('webpack');
1737
+ const userConfigJs = external_path_.join(projectPath, 'extension.config.js');
1738
+ const userConfigMjs = external_path_.join(projectPath, 'extension.config.mjs');
1739
+ const hasConfig = external_fs_.existsSync(userConfigJs) || external_fs_.existsSync(userConfigMjs);
1740
+ if (!hasConfig) return;
1741
+ const configPath = external_fs_.existsSync(userConfigJs) ? userConfigJs : userConfigMjs;
1742
+ const configSource = external_fs_.readFileSync(configPath, 'utf-8');
1743
+ const duplicates = userDeps.filter((d)=>managedDeps.has(d)).filter((d)=>configSource.includes(d)).sort();
1744
+ if (duplicates.length > 0) {
1745
+ console.error(messages.H3(duplicates, userPackageJsonPath));
1746
+ process.exit(1);
1613
1747
  }
1614
- hasShownUserMessage = true;
1748
+ } catch (error) {
1749
+ if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.warn(error);
1615
1750
  }
1616
- return !!tsConfigFilePath && !!(TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles);
1617
1751
  }
1618
- function defaultTypeScriptConfig(projectPath, _opts) {
1752
+ var paths = __webpack_require__("./lib/paths.ts");
1753
+ var develop_context = __webpack_require__("./lib/develop-context.ts");
1754
+ const external_child_process_namespaceObject = require("child_process");
1755
+ const package_manager_require = (0, external_module_.createRequire)(__rslib_import_meta_url__);
1756
+ function normalizePackageManager(value) {
1757
+ if (!value) return;
1758
+ const lower = value.toLowerCase().trim();
1759
+ if ('pnpm' === lower) return 'pnpm';
1760
+ if ('yarn' === lower) return 'yarn';
1761
+ if ('bun' === lower) return 'bun';
1762
+ if ('npm' === lower) return 'npm';
1763
+ }
1764
+ function inferPackageManagerFromPath(value) {
1765
+ if (!value) return;
1766
+ const lower = value.toLowerCase();
1767
+ if (lower.includes('pnpm')) return 'pnpm';
1768
+ if (lower.includes('yarn')) return 'yarn';
1769
+ if (lower.includes('bun')) return 'bun';
1770
+ if (lower.includes('npm')) return 'npm';
1771
+ }
1772
+ function getPackageManagerOverride() {
1773
+ const name = normalizePackageManager(process.env.EXTENSION_JS_PACKAGE_MANAGER);
1774
+ const execPath = process.env.EXTENSION_JS_PM_EXEC_PATH || process.env.npm_execpath || process.env.NPM_EXEC_PATH;
1775
+ if (!name && !execPath) return;
1776
+ const inferredName = name || inferPackageManagerFromPath(execPath) || 'npm';
1619
1777
  return {
1620
- compilerOptions: {
1621
- allowJs: true,
1622
- allowSyntheticDefaultImports: true,
1623
- esModuleInterop: true,
1624
- forceConsistentCasingInFileNames: true,
1625
- jsx: (0, _frameworks_lib_integrations__rspack_import_4.qQ)(projectPath) ? 'react-jsx' : 'preserve',
1626
- lib: [
1627
- 'dom',
1628
- 'dom.iterable',
1629
- 'esnext'
1630
- ],
1631
- moduleResolution: 'node',
1632
- module: 'esnext',
1633
- resolveJsonModule: true,
1634
- strict: true,
1635
- target: 'esnext',
1636
- isolatedModules: false,
1637
- skipLibCheck: true
1638
- },
1639
- exclude: [
1640
- 'node_modules',
1641
- 'dist'
1642
- ]
1778
+ name: inferredName,
1779
+ execPath
1643
1780
  };
1644
1781
  }
1645
- function getUserTypeScriptConfigFile(projectPath) {
1646
- const pkgDir = findNearestPackageJsonDirectory(projectPath);
1647
- if (pkgDir) {
1648
- const tsconfigPath = path__rspack_import_0.join(pkgDir, 'tsconfig.json');
1649
- if (fs__rspack_import_1.existsSync(tsconfigPath)) return tsconfigPath;
1782
+ function detectPackageManagerFromEnv() {
1783
+ const userAgent = process.env.npm_config_user_agent || '';
1784
+ const execPath = process.env.npm_execpath || process.env.NPM_EXEC_PATH || '';
1785
+ if (userAgent.includes('pnpm')) return {
1786
+ name: 'pnpm',
1787
+ execPath: execPath || void 0
1788
+ };
1789
+ if (userAgent.includes('yarn')) return {
1790
+ name: 'yarn',
1791
+ execPath: execPath || void 0
1792
+ };
1793
+ if (userAgent.includes('bun')) return {
1794
+ name: 'bun',
1795
+ execPath: execPath || void 0
1796
+ };
1797
+ if (userAgent.includes('npm')) return {
1798
+ name: 'npm',
1799
+ execPath: execPath || void 0
1800
+ };
1801
+ if (execPath) {
1802
+ const inferred = inferPackageManagerFromPath(execPath) || 'npm';
1803
+ return {
1804
+ name: inferred,
1805
+ execPath
1806
+ };
1650
1807
  }
1651
1808
  }
1652
- function writeTsConfig(projectPath) {
1653
- fs__rspack_import_1.writeFileSync(path__rspack_import_0.join(projectPath, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
1654
- mode: 'development'
1655
- }), null, 2));
1809
+ function resolveNpmCliFromNode(execPath) {
1810
+ const execDir = external_path_.dirname(execPath);
1811
+ const candidates = [
1812
+ external_path_.join(execDir, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
1813
+ external_path_.join(execDir, '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
1814
+ external_path_.join(execDir, '..', 'node_modules', 'npm', 'bin', 'npm-cli.js')
1815
+ ];
1816
+ for (const candidate of candidates)if (external_fs_.existsSync(candidate)) return candidate;
1656
1817
  }
1657
- },
1658
- "./plugin-playwright/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1659
- __webpack_require__.d(__webpack_exports__, {
1660
- Ih: ()=>createPlaywrightMetadataWriter,
1661
- Tb: ()=>PlaywrightPlugin
1662
- });
1663
- var fs__rspack_import_0 = __webpack_require__("fs");
1664
- var path__rspack_import_1 = __webpack_require__("path");
1665
- var _lib_paths__rspack_import_2 = __webpack_require__("./lib/paths.ts");
1666
- function _define_property(obj, key, value) {
1667
- if (key in obj) Object.defineProperty(obj, key, {
1668
- value: value,
1669
- enumerable: true,
1670
- configurable: true,
1671
- writable: true
1672
- });
1673
- else obj[key] = value;
1674
- return obj;
1818
+ function resolveBundledNpmCliPath() {
1819
+ if (process.env.EXTENSION_JS_PM_EXEC_PATH) {
1820
+ const overridePath = process.env.EXTENSION_JS_PM_EXEC_PATH;
1821
+ if (overridePath && external_fs_.existsSync(overridePath)) return overridePath;
1822
+ }
1823
+ try {
1824
+ const resolved = package_manager_require.resolve('npm/bin/npm-cli.js', {
1825
+ paths: [
1826
+ process.cwd(),
1827
+ __dirname
1828
+ ]
1829
+ });
1830
+ if (resolved && external_fs_.existsSync(resolved)) return resolved;
1831
+ } catch {}
1832
+ return resolveNpmCliFromNode(process.execPath);
1675
1833
  }
1676
- function nowISO() {
1677
- return new Date().toISOString();
1834
+ function isWindowsExecutablePath(value) {
1835
+ if (!value || 'win32' !== process.platform) return false;
1836
+ return /\.(cmd|bat|exe)$/i.test(value);
1678
1837
  }
1679
- function createRunId() {
1680
- return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
1838
+ function isNodeScriptPath(value) {
1839
+ if (!value) return false;
1840
+ return /\.(mjs|cjs|js)$/i.test(value);
1681
1841
  }
1682
- function ensureDirSync(dirPath) {
1842
+ function resolveWindowsCommandPath(command) {
1843
+ if ('win32' !== process.platform) return;
1683
1844
  try {
1684
- fs__rspack_import_0.mkdirSync(dirPath, {
1685
- recursive: true
1845
+ const systemRoot = process.env.SystemRoot || 'C:\\Windows';
1846
+ const whereExe = external_path_.join(systemRoot, 'System32', 'where.exe');
1847
+ const whereCommand = external_fs_.existsSync(whereExe) ? whereExe : 'where';
1848
+ const output = (0, external_child_process_namespaceObject.execFileSync)(whereCommand, [
1849
+ command
1850
+ ], {
1851
+ encoding: 'utf8',
1852
+ stdio: [
1853
+ 'ignore',
1854
+ 'pipe',
1855
+ 'ignore'
1856
+ ],
1857
+ windowsHide: true
1686
1858
  });
1687
- } catch {}
1859
+ const candidates = String(output).split(/\r?\n/).map((line)=>line.trim()).filter(Boolean);
1860
+ const cmdMatch = candidates.find((line)=>/\.cmd$/i.test(line));
1861
+ return cmdMatch || candidates[0];
1862
+ } catch {
1863
+ return;
1864
+ }
1688
1865
  }
1689
- function writeJsonAtomic(filePath, value) {
1866
+ function resolveUnixCommandPath(command) {
1867
+ if ('win32' === process.platform) return;
1690
1868
  try {
1691
- const tmpPath = `${filePath}.tmp-${process.pid}`;
1692
- fs__rspack_import_0.writeFileSync(tmpPath, JSON.stringify(value, null, 2) + '\n', 'utf-8');
1693
- fs__rspack_import_0.renameSync(tmpPath, filePath);
1694
- } catch {}
1869
+ const output = (0, external_child_process_namespaceObject.execFileSync)('which', [
1870
+ command
1871
+ ], {
1872
+ encoding: 'utf8',
1873
+ stdio: [
1874
+ 'ignore',
1875
+ 'pipe',
1876
+ 'ignore'
1877
+ ]
1878
+ });
1879
+ const candidate = String(output).trim();
1880
+ return candidate || void 0;
1881
+ } catch {
1882
+ return;
1883
+ }
1695
1884
  }
1696
- function getPlaywrightMetadataDir(packageJsonDir, browser) {
1697
- return (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(packageJsonDir, 'dist', 'extension-js', browser));
1885
+ function resolveCommandOnPath(command) {
1886
+ return resolveWindowsCommandPath(command) || resolveUnixCommandPath(command) || void 0;
1698
1887
  }
1699
- function createPlaywrightMetadataWriter(options) {
1700
- const metadataDir = getPlaywrightMetadataDir(options.packageJsonDir, options.browser);
1701
- const readyPath = (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(metadataDir, 'ready.json'));
1702
- const eventsPath = (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(metadataDir, 'events.ndjson'));
1703
- const base = {
1704
- command: options.command,
1705
- browser: options.browser,
1706
- runId: createRunId(),
1707
- startedAt: nowISO(),
1708
- distPath: options.distPath,
1709
- manifestPath: options.manifestPath,
1710
- port: (()=>{
1711
- if ('number' == typeof options.port && Number.isFinite(options.port)) return options.port;
1712
- if ('string' == typeof options.port) {
1713
- const parsed = parseInt(options.port, 10);
1714
- return Number.isFinite(parsed) ? parsed : null;
1715
- }
1716
- return null;
1717
- })()
1888
+ function canRunCorepack() {
1889
+ try {
1890
+ const fallback = package_manager_require('child_process');
1891
+ const spawnSync = external_child_process_namespaceObject.spawnSync?.mock !== void 0 ? external_child_process_namespaceObject.spawnSync : fallback.spawnSync || external_child_process_namespaceObject.spawnSync;
1892
+ const result = spawnSync('corepack', [
1893
+ '--version'
1894
+ ], {
1895
+ stdio: 'ignore',
1896
+ windowsHide: true
1897
+ });
1898
+ return result?.status === 0;
1899
+ } catch {
1900
+ return false;
1901
+ }
1902
+ }
1903
+ function detectByLockfile(cwd) {
1904
+ if (!cwd) return;
1905
+ const hasPnpmLock = external_fs_.existsSync(external_path_.join(cwd, 'pnpm-lock.yaml'));
1906
+ const hasYarnLock = external_fs_.existsSync(external_path_.join(cwd, 'yarn.lock'));
1907
+ const hasNpmLock = external_fs_.existsSync(external_path_.join(cwd, 'package-lock.json'));
1908
+ if (hasPnpmLock) return 'pnpm';
1909
+ if (hasYarnLock) return 'yarn';
1910
+ if (hasNpmLock) return 'npm';
1911
+ }
1912
+ function hydrateResolvedPackageManager(name) {
1913
+ const resolvedCommand = resolveCommandOnPath(name);
1914
+ if (resolvedCommand) return {
1915
+ name,
1916
+ execPath: resolvedCommand
1718
1917
  };
1719
- function writeReady(status, extra) {
1720
- ensureDirSync(metadataDir);
1721
- const payload = {
1722
- ...base,
1723
- status,
1724
- pid: process.pid,
1725
- ts: nowISO(),
1726
- compiledAt: extra?.compiledAt ?? null,
1727
- errors: Array.isArray(extra?.errors) ? extra.errors : []
1918
+ if ('npm' === name) {
1919
+ const bundledNpmCli = resolveBundledNpmCliPath();
1920
+ if (bundledNpmCli) return {
1921
+ name: 'npm',
1922
+ execPath: bundledNpmCli,
1923
+ runnerCommand: process.execPath,
1924
+ runnerArgs: [
1925
+ bundledNpmCli
1926
+ ]
1728
1927
  };
1729
- if (extra?.code) payload.code = extra.code;
1730
- if (extra?.message) payload.message = extra.message;
1731
- writeJsonAtomic(readyPath, payload);
1732
1928
  }
1733
- function appendEvent(event) {
1734
- ensureDirSync(metadataDir);
1735
- try {
1736
- fs__rspack_import_0.appendFileSync(eventsPath, `${JSON.stringify(event)}\n`, 'utf-8');
1737
- } catch {}
1929
+ }
1930
+ function resolvePackageManager(opts) {
1931
+ const lockPm = detectByLockfile(opts?.cwd);
1932
+ if (lockPm) {
1933
+ const hydrated = hydrateResolvedPackageManager(lockPm);
1934
+ if (hydrated) return hydrated;
1935
+ return {
1936
+ name: lockPm
1937
+ };
1938
+ }
1939
+ const override = getPackageManagerOverride();
1940
+ if (override) return override;
1941
+ const envPm = detectPackageManagerFromEnv();
1942
+ if (envPm) return envPm;
1943
+ const candidates = [
1944
+ 'pnpm',
1945
+ 'yarn',
1946
+ 'bun'
1947
+ ];
1948
+ for (const candidate of candidates){
1949
+ const resolved = resolveCommandOnPath(candidate);
1950
+ if (resolved) return {
1951
+ name: candidate,
1952
+ execPath: resolved
1953
+ };
1954
+ }
1955
+ const corepackPath = resolveCommandOnPath('corepack');
1956
+ if (corepackPath || canRunCorepack()) return {
1957
+ name: 'pnpm',
1958
+ runnerCommand: corepackPath || 'corepack',
1959
+ runnerArgs: [
1960
+ 'pnpm'
1961
+ ]
1962
+ };
1963
+ const bundledNpmCli = resolveBundledNpmCliPath();
1964
+ if (bundledNpmCli) return {
1965
+ name: 'npm',
1966
+ execPath: bundledNpmCli,
1967
+ runnerCommand: process.execPath,
1968
+ runnerArgs: [
1969
+ bundledNpmCli
1970
+ ]
1971
+ };
1972
+ return {
1973
+ name: 'npm'
1974
+ };
1975
+ }
1976
+ function buildExecEnv() {
1977
+ if ('win32' !== process.platform) return;
1978
+ const nodeDir = external_path_.dirname(process.execPath);
1979
+ const pathSep = external_path_.delimiter;
1980
+ const existing = process.env.PATH || process.env.Path || '';
1981
+ if (existing.includes(nodeDir)) return;
1982
+ return {
1983
+ ...process.env,
1984
+ PATH: `${nodeDir}${pathSep}${existing}`.trim(),
1985
+ Path: `${nodeDir}${pathSep}${existing}`.trim()
1986
+ };
1987
+ }
1988
+ function buildInstallCommand(pm, args) {
1989
+ if (pm.runnerCommand) return {
1990
+ command: pm.runnerCommand,
1991
+ args: [
1992
+ ...pm.runnerArgs || [],
1993
+ ...args
1994
+ ]
1995
+ };
1996
+ if (pm.execPath) {
1997
+ if (isWindowsExecutablePath(pm.execPath)) return {
1998
+ command: pm.execPath,
1999
+ args
2000
+ };
2001
+ if (isNodeScriptPath(pm.execPath)) return {
2002
+ command: process.execPath,
2003
+ args: [
2004
+ pm.execPath,
2005
+ ...args
2006
+ ]
2007
+ };
2008
+ return {
2009
+ command: pm.execPath,
2010
+ args
2011
+ };
1738
2012
  }
1739
2013
  return {
1740
- metadataDir,
1741
- readyPath,
1742
- eventsPath,
1743
- writeStarting () {
1744
- writeReady('starting');
1745
- },
1746
- writeReady (compiledAt) {
1747
- writeReady('ready', {
1748
- compiledAt: compiledAt || nowISO()
1749
- });
1750
- },
1751
- writeError (code, message, errors) {
1752
- writeReady('error', {
1753
- code,
1754
- message,
1755
- errors: Array.isArray(errors) ? errors : [],
1756
- compiledAt: null
1757
- });
1758
- },
1759
- appendEvent
2014
+ command: pm.name,
2015
+ args
1760
2016
  };
1761
2017
  }
1762
- class PlaywrightPlugin {
1763
- apply(compiler) {
1764
- this.writer.writeStarting();
1765
- compiler.hooks.compile.tap(PlaywrightPlugin.name, ()=>{
1766
- this.writer.appendEvent({
1767
- type: 'compile_start',
1768
- ts: nowISO(),
1769
- command: this.command,
1770
- browser: this.browser
1771
- });
2018
+ function buildSpawnInvocation(command, args) {
2019
+ return {
2020
+ command,
2021
+ args
2022
+ };
2023
+ }
2024
+ function execInstallCommand(command, args, options) {
2025
+ const invocation = buildSpawnInvocation(command, args);
2026
+ const env = buildExecEnv();
2027
+ const stdio = options?.stdio ?? 'ignore';
2028
+ const useShell = 'win32' === process.platform && /\.(cmd|bat)$/i.test(invocation.command);
2029
+ return new Promise((resolve, reject)=>{
2030
+ const child = (0, external_child_process_namespaceObject.spawn)(invocation.command, invocation.args, {
2031
+ cwd: options?.cwd,
2032
+ stdio,
2033
+ env: env || process.env,
2034
+ ...useShell ? {
2035
+ shell: true
2036
+ } : {}
1772
2037
  });
1773
- compiler.hooks.done.tap(PlaywrightPlugin.name, (stats)=>{
1774
- const durationMs = Number((stats?.compilation?.endTime || 0) - (stats?.compilation?.startTime || 0));
1775
- const hasErrors = Boolean(stats?.hasErrors?.());
1776
- const errorsCount = Number(Array.isArray(stats?.toJson?.({
1777
- all: false,
1778
- errors: true
1779
- })?.errors) ? stats.toJson({
1780
- all: false,
1781
- errors: true
1782
- }).errors.length : 0);
1783
- if (hasErrors) {
1784
- this.writer.appendEvent({
1785
- type: 'compile_error',
1786
- ts: nowISO(),
1787
- command: this.command,
1788
- browser: this.browser,
1789
- durationMs: Number.isFinite(durationMs) ? durationMs : void 0,
1790
- errorCount: Number.isFinite(errorsCount) ? errorsCount : 1
1791
- });
1792
- this.writer.writeError('compile_error', 'Compilation failed', [
1793
- `errors: ${String(errorsCount || 1)}`
1794
- ]);
1795
- return;
2038
+ child.on('close', (code)=>{
2039
+ if (0 !== code) reject(new Error(`Install failed with exit code ${code}`));
2040
+ else resolve();
2041
+ });
2042
+ child.on('error', (error)=>reject(error));
2043
+ });
2044
+ }
2045
+ async function ensureUserProjectDependencies(packageJsonDir) {
2046
+ if (!(0, paths.Bi)(packageJsonDir)) return;
2047
+ const pm = resolvePackageManager({
2048
+ cwd: packageJsonDir
2049
+ });
2050
+ const cmd = buildInstallCommand(pm, [
2051
+ 'install'
2052
+ ]);
2053
+ await execInstallCommand(cmd.command, cmd.args, {
2054
+ cwd: packageJsonDir,
2055
+ stdio: 'inherit'
2056
+ });
2057
+ }
2058
+ async function ensureDevelopArtifacts() {
2059
+ const developRoot = (0, develop_context.w1)();
2060
+ if (!developRoot) return;
2061
+ const requiredFiles = [
2062
+ external_path_.join(developRoot, 'dist', "ensure-hmr-for-scripts.js"),
2063
+ external_path_.join(developRoot, 'dist', "minimum-script-file.js")
2064
+ ];
2065
+ const missing = requiredFiles.filter((file)=>!external_fs_.existsSync(file));
2066
+ if (0 === missing.length) return;
2067
+ const pm = resolvePackageManager({
2068
+ cwd: developRoot
2069
+ });
2070
+ const command = buildInstallCommand(pm, [
2071
+ 'run',
2072
+ 'compile'
2073
+ ]);
2074
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2075
+ const stdio = isAuthor ? 'inherit' : 'ignore';
2076
+ if (isAuthor) console.warn(messages.TL('extension-develop build artifacts (dist missing)'));
2077
+ await execInstallCommand(command.command, command.args, {
2078
+ cwd: developRoot,
2079
+ stdio
2080
+ });
2081
+ }
2082
+ var resolve_config = __webpack_require__("./plugin-special-folders/folder-extensions/resolve-config.ts");
2083
+ var get_data = __webpack_require__("./plugin-special-folders/get-data.ts");
2084
+ async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2085
+ const require1 = (0, external_module_.createRequire)(__rslib_import_meta_url__);
2086
+ const projectStructure = await getProjectStructure(pathOrRemoteUrl);
2087
+ const isVitest = 'true' === process.env.VITEST;
2088
+ const shouldExitOnError = (buildOptions?.exitOnError ?? true) && !isVitest;
2089
+ const browser = (0, paths.YN)(buildOptions?.browser || 'chrome', buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary);
2090
+ const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
2091
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2092
+ try {
2093
+ await ensureDevelopArtifacts();
2094
+ if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
2095
+ const [{ rspack }, { merge }, { handleStatsErrors }, { default: webpackConfig }] = await Promise.all([
2096
+ Promise.resolve(require1('@rspack/core')),
2097
+ import("webpack-merge"),
2098
+ __webpack_require__.e(504).then(__webpack_require__.bind(__webpack_require__, "./lib/stats-handler.ts")),
2099
+ __webpack_require__.e(512).then(__webpack_require__.bind(__webpack_require__, "./rspack-config.ts"))
2100
+ ]);
2101
+ const debug = isAuthor;
2102
+ if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
2103
+ const commandConfig = await (0, config_loader.eY)(packageJsonDir, 'build');
2104
+ const specialFoldersData = (0, get_data.H)(packageJsonDir);
2105
+ const distPath = (0, paths.q4)(packageJsonDir, browser);
2106
+ if (debug) {
2107
+ console.log(messages.SG(manifestDir, packageJsonDir));
2108
+ console.log(messages._A(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
2109
+ console.log(messages.AC(distPath));
2110
+ }
2111
+ const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? specialFoldersData.extensions;
2112
+ const resolvedExtensionsConfig = await (0, resolve_config.R)({
2113
+ projectRoot: packageJsonDir,
2114
+ browser,
2115
+ config: mergedExtensionsConfig
2116
+ });
2117
+ const resolvedMode = buildOptions?.mode === 'development' || buildOptions?.mode === 'none' || buildOptions?.mode === 'production' ? buildOptions.mode : 'production';
2118
+ if ('development' === resolvedMode || 'production' === resolvedMode) process.env.NODE_ENV = resolvedMode;
2119
+ const baseConfig = webpackConfig(projectStructure, {
2120
+ ...commandConfig,
2121
+ ...buildOptions,
2122
+ extensions: resolvedExtensionsConfig,
2123
+ browser,
2124
+ mode: resolvedMode,
2125
+ output: {
2126
+ clean: true,
2127
+ path: distPath
1796
2128
  }
1797
- this.writer.appendEvent({
1798
- type: 'compile_success',
1799
- ts: nowISO(),
1800
- command: this.command,
1801
- browser: this.browser,
1802
- durationMs: Number.isFinite(durationMs) ? durationMs : void 0,
1803
- errorCount: 0
1804
- });
1805
- this.writer.writeReady(nowISO());
1806
2129
  });
1807
- compiler.hooks.failed.tap(PlaywrightPlugin.name, (error)=>{
1808
- this.writer.appendEvent({
1809
- type: 'compile_error',
1810
- ts: nowISO(),
1811
- command: this.command,
1812
- browser: this.browser,
1813
- errorCount: 1
1814
- });
1815
- this.writer.writeError('compile_failed', error instanceof Error ? error.message : String(error));
2130
+ const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>plugin?.constructor.name !== 'plugin-browsers');
2131
+ const userExtensionConfig = await (0, config_loader.cR)(packageJsonDir);
2132
+ const userConfig = userExtensionConfig({
2133
+ ...baseConfig,
2134
+ plugins: allPluginsButBrowserRunners
1816
2135
  });
1817
- compiler.hooks.watchClose.tap(PlaywrightPlugin.name, ()=>{
1818
- this.writer.appendEvent({
1819
- type: 'shutdown',
1820
- ts: nowISO(),
1821
- command: this.command,
1822
- browser: this.browser
2136
+ const compilerConfig = merge(userConfig);
2137
+ compilerConfig.stats = false;
2138
+ const compiler = rspack(compilerConfig);
2139
+ let summary = {
2140
+ browser,
2141
+ total_assets: 0,
2142
+ total_bytes: 0,
2143
+ largest_asset_bytes: 0,
2144
+ warnings_count: 0,
2145
+ errors_count: 0
2146
+ };
2147
+ await new Promise((resolve, reject)=>{
2148
+ compiler.run(async (err, stats)=>{
2149
+ if (err) {
2150
+ console.error(err.stack || err);
2151
+ return reject(err);
2152
+ }
2153
+ if (!stats || 'function' != typeof stats.hasErrors) return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
2154
+ if (!buildOptions?.silent && stats) console.log(messages.I(manifestDir, stats, browser));
2155
+ if (stats.hasErrors()) {
2156
+ handleStatsErrors(stats);
2157
+ if (!shouldExitOnError) return reject(new Error('Build failed with errors'));
2158
+ process.exit(1);
2159
+ } else {
2160
+ const info = stats?.toJson({
2161
+ all: false,
2162
+ assets: true,
2163
+ warnings: true,
2164
+ errors: true
2165
+ });
2166
+ summary = getBuildSummary(browser, info);
2167
+ if (summary.warnings_count > 0) {
2168
+ console.log(messages.fm(summary.warnings_count));
2169
+ const warningDetails = messages.wh(info?.warnings || []);
2170
+ if (warningDetails) console.log(`\n${warningDetails}`);
2171
+ } else console.log(messages.Cf());
2172
+ resolve();
2173
+ }
1823
2174
  });
1824
2175
  });
1825
- }
1826
- constructor(options){
1827
- _define_property(this, "writer", void 0);
1828
- _define_property(this, "command", void 0);
1829
- _define_property(this, "browser", void 0);
1830
- this.browser = String(options.browser || 'chromium');
1831
- this.command = options.command || ('development' === options.mode ? 'dev' : 'start');
1832
- this.writer = createPlaywrightMetadataWriter({
1833
- packageJsonDir: options.packageJsonDir,
1834
- browser: this.browser,
1835
- command: this.command,
1836
- distPath: options.outputPath,
1837
- manifestPath: options.manifestPath,
1838
- port: options.port
1839
- });
2176
+ return summary;
2177
+ } catch (error) {
2178
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2179
+ if (isAuthor) console.error(error);
2180
+ else console.error(messages.$3(error));
2181
+ if (!shouldExitOnError) throw error;
2182
+ process.exit(1);
1840
2183
  }
1841
2184
  }
1842
- _define_property(PlaywrightPlugin, "name", 'plugin-playwright');
1843
- },
1844
- "./plugin-special-folders/folder-extensions/resolve-config.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
1845
- __webpack_require__.d(__webpack_exports__, {
1846
- R: ()=>resolveCompanionExtensionsConfig
1847
- });
1848
- var fs__rspack_import_0 = __webpack_require__("fs");
1849
- var path__rspack_import_1 = __webpack_require__("path");
1850
- var extension_from_store__rspack_import_2 = __webpack_require__("extension-from-store");
1851
- var _utils__rspack_import_3 = __webpack_require__("./plugin-special-folders/folder-extensions/utils.ts");
1852
- function isPathLike(value) {
1853
- if (path__rspack_import_1.isAbsolute(value)) return true;
1854
- if (value.startsWith('./') || value.startsWith('../')) return true;
1855
- return value.includes('/') || value.includes('\\');
2185
+ const promises_namespaceObject = require("fs/promises");
2186
+ async function generateExtensionTypes(manifestDir, packageJsonDir) {
2187
+ const extensionEnvFile = external_path_.join(packageJsonDir, 'extension-env.d.ts');
2188
+ const typePath = 'extension';
2189
+ const fileContent = `\
2190
+ // Required Extension.js types for TypeScript projects.
2191
+ // This file is auto-generated and should not be excluded.
2192
+ // If you need additional types, consider creating a new *.d.ts file and
2193
+ // referencing it in the "include" array of your tsconfig.json file.
2194
+ // See https://www.typescriptlang.org/tsconfig#include for more information.
2195
+ /// <reference types="${typePath}/types" />
2196
+
2197
+ // Polyfill types for browser.* APIs
2198
+ /// <reference types="${typePath}/types/polyfill" />
2199
+ `;
2200
+ try {
2201
+ await promises_namespaceObject.access(extensionEnvFile);
2202
+ const existingContent = await promises_namespaceObject.readFile(extensionEnvFile, 'utf8');
2203
+ if (existingContent.includes('develop/dist/types')) await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2204
+ await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2205
+ } catch (err) {
2206
+ const manifest = require(external_path_.join(manifestDir, 'manifest.json'));
2207
+ console.log(messages.ng(manifest));
2208
+ try {
2209
+ await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2210
+ } catch (writeErr) {
2211
+ console.log(messages.v_(writeErr));
2212
+ }
2213
+ }
1856
2214
  }
1857
- function isSubpathOf(parent, child) {
1858
- const rel = path__rspack_import_1.relative(parent, child);
1859
- return '' !== rel && !rel.startsWith('..') && !path__rspack_import_1.isAbsolute(rel);
2215
+ var sanitize = __webpack_require__("./lib/sanitize.ts");
2216
+ const external_node_events_namespaceObject = require("node:events");
2217
+ var contracts = __webpack_require__("./plugin-web-extension/feature-scripts/contracts.ts");
2218
+ function _define_property(obj, key, value) {
2219
+ if (key in obj) Object.defineProperty(obj, key, {
2220
+ value: value,
2221
+ enumerable: true,
2222
+ configurable: true,
2223
+ writable: true
2224
+ });
2225
+ else obj[key] = value;
2226
+ return obj;
1860
2227
  }
1861
- function getBrowserFolder(browser) {
1862
- if ('firefox' === browser || 'gecko-based' === browser || 'firefox-based' === browser) return 'firefox';
1863
- if ('edge' === browser) return 'edge';
1864
- return 'chrome';
2228
+ class BuildEmitter extends external_node_events_namespaceObject.EventEmitter {
2229
+ constructor(){
2230
+ super();
2231
+ this.on('error', ()=>{});
2232
+ }
1865
2233
  }
1866
- function parseChromeWebStoreId(url) {
1867
- if ('chromewebstore.google.com' !== url.hostname) return null;
1868
- const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
1869
- return match ? match[1] : null;
1870
- }
1871
- function parseEdgeAddonsId(url) {
1872
- if ('microsoftedge.microsoft.com' !== url.hostname) return null;
1873
- const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
1874
- return match ? match[1] : null;
1875
- }
1876
- function parseAmoSlug(url) {
1877
- if ('addons.mozilla.org' !== url.hostname) return null;
1878
- const match = url.pathname.match(/\/addon\/([^/]+)(?:\/|$)/i);
1879
- return match ? match[1] : null;
2234
+ class BrowsersPlugin {
2235
+ apply(compiler) {
2236
+ let pendingReloadReason;
2237
+ let pendingChangedSources = [];
2238
+ compiler.hooks.watchRun.tap(BrowsersPlugin.name, ()=>{
2239
+ pendingReloadReason = void 0;
2240
+ pendingChangedSources = [];
2241
+ const modifiedFiles = compiler.modifiedFiles;
2242
+ if (!modifiedFiles || 0 === modifiedFiles.size) return;
2243
+ const contextDir = compiler.options.context || '';
2244
+ for (const file of modifiedFiles){
2245
+ const normalized = external_path_.relative(contextDir, file).replace(/\\/g, '/');
2246
+ pendingChangedSources.push(normalized);
2247
+ if (normalized.includes('manifest.json')) pendingReloadReason = 'full';
2248
+ else if (normalized.includes('_locales/')) pendingReloadReason = 'full';
2249
+ }
2250
+ });
2251
+ compiler.hooks.done.tapPromise(BrowsersPlugin.name, async (stats)=>{
2252
+ const compilation = stats.compilation;
2253
+ const hasErrors = compilation.errors && compilation.errors.length > 0;
2254
+ if (hasErrors) return void this.emitter.emit('error', {
2255
+ errors: compilation.errors.map((e)=>'string' == typeof e ? e : e.message || String(e))
2256
+ });
2257
+ const outputPath = String(compilation.options?.output?.path || '');
2258
+ const contextDir = String(compilation.options?.context || '');
2259
+ let reloadInstruction;
2260
+ if (!this.isFirstCompile && pendingReloadReason) reloadInstruction = {
2261
+ type: pendingReloadReason
2262
+ };
2263
+ else if (!this.isFirstCompile && pendingChangedSources.length > 0) {
2264
+ const isServiceWorkerSource = (rel)=>/(^|\/)background(\.|\/)/i.test(rel) || /service[-_.]?worker/i.test(rel);
2265
+ const hasServiceWorkerChange = pendingChangedSources.some(isServiceWorkerSource);
2266
+ if (hasServiceWorkerChange) reloadInstruction = {
2267
+ type: 'service-worker',
2268
+ changedAssets: pendingChangedSources
2269
+ };
2270
+ else {
2271
+ const contentScriptCount = readContentScriptCount(compilation, outputPath);
2272
+ if (contentScriptCount > 0) {
2273
+ const entries = [];
2274
+ for(let i = 0; i < contentScriptCount; i++)entries.push((0, contracts.Y0)(i));
2275
+ reloadInstruction = {
2276
+ type: "content-scripts",
2277
+ changedContentScriptEntries: entries,
2278
+ changedAssets: pendingChangedSources
2279
+ };
2280
+ }
2281
+ }
2282
+ }
2283
+ const wasFirstCompile = this.isFirstCompile;
2284
+ this.isFirstCompile = false;
2285
+ if (wasFirstCompile) try {
2286
+ this.controller = await this.options.launcher({
2287
+ ...this.options.browserOptions,
2288
+ outputPath,
2289
+ contextDir,
2290
+ extensionsToLoad: this.extensionsToLoad
2291
+ });
2292
+ const logLevel = this.options.browserOptions.logLevel || 'off';
2293
+ if ('off' !== logLevel && this.controller) await this.controller.enableUnifiedLogging({
2294
+ level: logLevel,
2295
+ contexts: this.options.browserOptions.logContexts,
2296
+ format: this.options.browserOptions.logFormat,
2297
+ timestamps: this.options.browserOptions.logTimestamps,
2298
+ color: this.options.browserOptions.logColor,
2299
+ urlFilter: this.options.browserOptions.logUrl,
2300
+ tabFilter: this.options.browserOptions.logTab
2301
+ });
2302
+ } catch (error) {
2303
+ this.emitter.emit('error', {
2304
+ errors: [
2305
+ error instanceof Error ? error.message : String(error)
2306
+ ]
2307
+ });
2308
+ }
2309
+ else if (this.controller && reloadInstruction) {
2310
+ if ('true' !== process.env.EXTENSION_NO_RELOAD) try {
2311
+ await this.controller.reload(reloadInstruction);
2312
+ } catch {}
2313
+ }
2314
+ this.emitter.emit('compiled', {
2315
+ outputPath,
2316
+ contextDir,
2317
+ isFirstCompile: wasFirstCompile,
2318
+ reloadInstruction,
2319
+ extensionsToLoad: wasFirstCompile ? this.extensionsToLoad : void 0
2320
+ });
2321
+ });
2322
+ }
2323
+ constructor(options){
2324
+ _define_property(this, "options", void 0);
2325
+ _define_property(this, "emitter", void 0);
2326
+ _define_property(this, "extensionsToLoad", void 0);
2327
+ _define_property(this, "isFirstCompile", void 0);
2328
+ _define_property(this, "controller", void 0);
2329
+ this.options = options;
2330
+ this.emitter = new BuildEmitter();
2331
+ this.extensionsToLoad = [];
2332
+ this.isFirstCompile = true;
2333
+ }
2334
+ }
2335
+ _define_property(BrowsersPlugin, "name", 'plugin-browsers');
2336
+ function readContentScriptCount(compilation, outputPath) {
2337
+ try {
2338
+ const asset = compilation.getAsset?.('manifest.json');
2339
+ if (asset?.source) {
2340
+ const manifest = JSON.parse(String(asset.source.source()));
2341
+ const list = manifest?.content_scripts;
2342
+ if (Array.isArray(list)) return list.length;
2343
+ }
2344
+ } catch {}
2345
+ try {
2346
+ const fs = __webpack_require__("fs");
2347
+ const manifestPath = external_path_.join(outputPath, 'manifest.json');
2348
+ if (fs.existsSync(manifestPath)) {
2349
+ const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
2350
+ const list = manifest?.content_scripts;
2351
+ if (Array.isArray(list)) return list.length;
2352
+ }
2353
+ } catch {}
2354
+ return 0;
1880
2355
  }
1881
- function parseStoreUrl(raw) {
1882
- let url;
2356
+ var typescript = __webpack_require__("./plugin-js-frameworks/js-tools/typescript.ts");
2357
+ async function extensionDev(pathOrRemoteUrl, devOptions) {
2358
+ let browsersPlugin;
2359
+ let emitter = new BuildEmitter();
2360
+ const projectStructure = await getProjectStructure(pathOrRemoteUrl);
1883
2361
  try {
1884
- url = new URL(raw);
1885
- } catch {
1886
- return null;
2362
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2363
+ const debug = isAuthor;
2364
+ const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
2365
+ await ensureDevelopArtifacts();
2366
+ if (false !== devOptions.install) await ensureUserProjectDependencies(packageJsonDir);
2367
+ if ((0, typescript.eE)(manifestDir)) await generateExtensionTypes(manifestDir, packageJsonDir);
2368
+ if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
2369
+ const browser = (0, paths.YN)(devOptions.browser || 'chrome', devOptions.chromiumBinary, devOptions.geckoBinary || devOptions.firefoxBinary);
2370
+ const geckoBinary = devOptions.geckoBinary || devOptions.firefoxBinary;
2371
+ if (debug) {
2372
+ console.log(messages.SG(manifestDir, packageJsonDir));
2373
+ console.log(messages._A(browser, devOptions.chromiumBinary, geckoBinary));
2374
+ }
2375
+ const browserConfig = await (0, config_loader.xY)(packageJsonDir, browser);
2376
+ const commandConfig = await (0, config_loader.eY)(packageJsonDir, 'dev');
2377
+ const merged = {
2378
+ ...(0, sanitize.a)(browserConfig),
2379
+ ...(0, sanitize.a)(commandConfig),
2380
+ ...(0, sanitize.a)(devOptions)
2381
+ };
2382
+ if (devOptions.launcher && !devOptions.noBrowser) {
2383
+ browsersPlugin = new BrowsersPlugin({
2384
+ launcher: devOptions.launcher,
2385
+ browserOptions: {
2386
+ browser,
2387
+ mode: 'development',
2388
+ enableDevtools: true,
2389
+ noOpen: merged.noOpen,
2390
+ profile: merged.profile,
2391
+ persistProfile: merged.persistProfile,
2392
+ preferences: merged.preferences,
2393
+ browserFlags: merged.browserFlags,
2394
+ excludeBrowserFlags: merged.excludeBrowserFlags,
2395
+ startingUrl: merged.startingUrl,
2396
+ chromiumBinary: merged.chromiumBinary,
2397
+ geckoBinary: merged.geckoBinary || merged.firefoxBinary,
2398
+ port: merged.port,
2399
+ source: merged.source,
2400
+ watchSource: merged.watchSource,
2401
+ sourceFormat: merged.sourceFormat,
2402
+ sourceSummary: merged.sourceSummary,
2403
+ sourceMeta: merged.sourceMeta,
2404
+ sourceProbe: merged.sourceProbe,
2405
+ sourceTree: merged.sourceTree,
2406
+ sourceConsole: merged.sourceConsole,
2407
+ sourceDom: merged.sourceDom,
2408
+ sourceMaxBytes: merged.sourceMaxBytes,
2409
+ sourceRedact: merged.sourceRedact,
2410
+ sourceIncludeShadow: merged.sourceIncludeShadow,
2411
+ sourceDiff: merged.sourceDiff,
2412
+ logLevel: merged.logLevel,
2413
+ logContexts: merged.logContexts,
2414
+ logFormat: merged.logFormat,
2415
+ logTimestamps: merged.logTimestamps,
2416
+ logColor: merged.logColor,
2417
+ logUrl: merged.logUrl,
2418
+ logTab: merged.logTab
2419
+ }
2420
+ });
2421
+ emitter = browsersPlugin.emitter;
2422
+ }
2423
+ if ('true' === process.env.EXTENSION_DEV_DRY_RUN) return emitter;
2424
+ const { devServer } = await Promise.all([
2425
+ __webpack_require__.e(512),
2426
+ __webpack_require__.e(221)
2427
+ ]).then(__webpack_require__.bind(__webpack_require__, "./dev-server/index.ts"));
2428
+ await devServer(projectStructure, {
2429
+ ...devOptions,
2430
+ mode: 'development',
2431
+ browser,
2432
+ geckoBinary,
2433
+ browsersPlugin
2434
+ });
2435
+ return emitter;
2436
+ } catch (error) {
2437
+ console.error(error);
2438
+ process.exit(1);
1887
2439
  }
1888
- const chromeId = parseChromeWebStoreId(url);
1889
- if (chromeId) return {
1890
- browser: 'chrome',
1891
- id: chromeId
1892
- };
1893
- const edgeId = parseEdgeAddonsId(url);
1894
- if (edgeId) return {
1895
- browser: 'edge',
1896
- id: edgeId
1897
- };
1898
- const amoSlug = parseAmoSlug(url);
1899
- if (amoSlug) return {
1900
- browser: 'firefox',
1901
- id: amoSlug
1902
- };
1903
- return null;
1904
2440
  }
1905
- function ensurePathsUnderExtensions(projectRoot, paths) {
1906
- const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
1907
- return paths.map((p)=>{
1908
- const abs = (0, _utils__rspack_import_3.A$)(projectRoot, p);
1909
- if (abs !== extensionsRoot && !isSubpathOf(extensionsRoot, abs) && path__rspack_import_1.resolve(abs) !== extensionsRoot) throw new Error(`Companion extensions must be inside ${extensionsRoot}.\nInvalid path: ${abs}`);
1910
- return abs;
1911
- });
1912
- }
1913
- function findExtensionRoots(dir, maxDepth = 3) {
2441
+ var plugin_playwright = __webpack_require__("./plugin-playwright/index.ts");
2442
+ var utils = __webpack_require__("./plugin-special-folders/folder-extensions/utils.ts");
2443
+ function resolveCompanionExtensionDirs(opts) {
2444
+ const { projectRoot, config } = opts;
2445
+ const normalized = (0, utils.cz)(config);
2446
+ const explicitPaths = normalized.paths;
2447
+ const scanDir = normalized.dir;
1914
2448
  const found = [];
1915
- function walk(current, depth) {
1916
- if (depth > maxDepth) return;
1917
- if (!(0, _utils__rspack_import_3.Q7)(current)) return;
1918
- if ((0, _utils__rspack_import_3.Uy)(current)) return void found.push(current);
1919
- let entries = [];
1920
- try {
1921
- entries = fs__rspack_import_0.readdirSync(current, {
1922
- withFileTypes: true
1923
- });
1924
- } catch {
1925
- return;
1926
- }
1927
- for (const ent of entries)if (ent.isDirectory()) {
1928
- if (!ent.name.startsWith('.')) walk(path__rspack_import_1.join(current, ent.name), depth + 1);
2449
+ for (const p of explicitPaths){
2450
+ const abs = (0, utils.A$)(projectRoot, p);
2451
+ if ((0, utils.Uy)(abs)) found.push(abs);
2452
+ }
2453
+ if (scanDir) {
2454
+ const absScan = (0, utils.A$)(projectRoot, scanDir);
2455
+ if ((0, utils.Q7)(absScan)) {
2456
+ let entries = [];
2457
+ try {
2458
+ entries = external_fs_.readdirSync(absScan, {
2459
+ withFileTypes: true
2460
+ });
2461
+ } catch {
2462
+ entries = [];
2463
+ }
2464
+ const scanOneLevel = (rootDir)=>{
2465
+ let dirEntries = [];
2466
+ try {
2467
+ dirEntries = external_fs_.readdirSync(rootDir, {
2468
+ withFileTypes: true
2469
+ });
2470
+ } catch {
2471
+ dirEntries = [];
2472
+ }
2473
+ for (const ent of dirEntries){
2474
+ if (!ent.isDirectory()) continue;
2475
+ if (ent.name.startsWith('.')) continue;
2476
+ const candidate = external_path_.join(rootDir, ent.name);
2477
+ if ((0, utils.Uy)(candidate)) found.push(candidate);
2478
+ }
2479
+ };
2480
+ scanOneLevel(absScan);
2481
+ if ('extensions' === external_path_.basename(absScan)) for (const ent of entries){
2482
+ if (!ent.isDirectory()) continue;
2483
+ if (ent.name.startsWith('.')) continue;
2484
+ const browserDir = external_path_.join(absScan, ent.name);
2485
+ scanOneLevel(browserDir);
2486
+ }
1929
2487
  }
1930
2488
  }
1931
- walk(dir, 0);
1932
- return found;
1933
- }
1934
- async function runExtensionFromStore(url, outDir) {
1935
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
1936
- await (0, extension_from_store__rspack_import_2.fetchExtensionFromStore)(url, {
1937
- outDir,
1938
- extract: true,
1939
- logger: isAuthor ? {
1940
- onInfo: (message)=>console.log(message),
1941
- onWarn: (message)=>console.warn(message),
1942
- onError: (message, error)=>console.error(message, error)
1943
- } : void 0
1944
- });
1945
- }
1946
- async function resolveStoreExtensionToPath(opts) {
1947
- const { projectRoot, storeUrl, browser, id } = opts;
1948
- const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
1949
- const targetRoot = path__rspack_import_1.join(extensionsRoot, browser, id);
1950
- const manifestPath = path__rspack_import_1.join(targetRoot, 'manifest.json');
1951
- if ((0, _utils__rspack_import_3.fo)(manifestPath)) return targetRoot;
1952
- await runExtensionFromStore(storeUrl, path__rspack_import_1.join(extensionsRoot, browser));
1953
- const candidates = findExtensionRoots(path__rspack_import_1.join(extensionsRoot, browser));
1954
- let selected;
1955
- if (1 === candidates.length) selected = candidates[0];
1956
- else if (candidates.length > 1) {
1957
- const directMatch = candidates.find((c)=>path__rspack_import_1.basename(c) === id);
1958
- const versionedMatch = candidates.find((c)=>path__rspack_import_1.basename(c).startsWith(`${id}@`));
1959
- if (directMatch) selected = directMatch;
1960
- else if (versionedMatch) selected = versionedMatch;
2489
+ const unique = [];
2490
+ const seen = new Set();
2491
+ for (const p of found)if (!seen.has(p)) {
2492
+ seen.add(p);
2493
+ unique.push(p);
1961
2494
  }
1962
- if (!selected) throw new Error(`Could not locate an unpacked extension from ${storeUrl}.`);
1963
- fs__rspack_import_0.mkdirSync(path__rspack_import_1.dirname(targetRoot), {
1964
- recursive: true
1965
- });
1966
- if (path__rspack_import_1.basename(selected).startsWith(`${id}@`)) fs__rspack_import_0.renameSync(selected, targetRoot);
1967
- return targetRoot;
2495
+ return unique;
1968
2496
  }
1969
- async function resolveCompanionExtensionsConfig(opts) {
1970
- const { projectRoot, browser, config } = opts;
1971
- if (!config) return;
1972
- const normalized = (0, _utils__rspack_import_3.cz)(config);
1973
- const runtimeBrowser = getBrowserFolder(browser);
1974
- const resolvedPaths = [];
1975
- const localPaths = [];
1976
- for (const entry of normalized.paths){
1977
- const parsedStore = parseStoreUrl(entry);
1978
- if (parsedStore) {
1979
- if (parsedStore.browser !== runtimeBrowser) continue;
1980
- const resolvedPath = await resolveStoreExtensionToPath({
1981
- projectRoot,
1982
- storeUrl: entry,
1983
- browser: parsedStore.browser,
1984
- id: parsedStore.id
1985
- });
1986
- resolvedPaths.push(resolvedPath);
1987
- continue;
2497
+ var extensions_to_load = __webpack_require__("./lib/extensions-to-load.ts");
2498
+ function getDarkModeDefaults(browser) {
2499
+ if ('chrome' === browser || 'edge' === browser || 'chromium' === browser || 'chromium-based' === browser) return {
2500
+ browserFlags: [
2501
+ '--force-dark-mode',
2502
+ '--enable-features=WebUIDarkMode'
2503
+ ],
2504
+ preferences: {}
2505
+ };
2506
+ if ('firefox' === browser || 'gecko-based' === browser || 'firefox-based' === browser) return {
2507
+ browserFlags: [],
2508
+ preferences: {
2509
+ 'ui.systemUsesDarkTheme': 1,
2510
+ 'layout.css.prefers-color-scheme.content-override': 2,
2511
+ 'devtools.theme': 'dark'
1988
2512
  }
1989
- if (isPathLike(entry)) localPaths.push(entry);
2513
+ };
2514
+ return {
2515
+ browserFlags: [],
2516
+ preferences: {}
2517
+ };
2518
+ }
2519
+ function withDarkMode(config) {
2520
+ const defaults = getDarkModeDefaults(config.browser);
2521
+ const existingFlags = Array.isArray(config.browserFlags) ? [
2522
+ ...config.browserFlags
2523
+ ] : [];
2524
+ const nextFlags = [
2525
+ ...existingFlags
2526
+ ];
2527
+ for (const flag of defaults.browserFlags || [])if (!nextFlags.some((f)=>String(f).trim() === flag)) nextFlags.push(flag);
2528
+ const nextPreferences = {
2529
+ ...config.preferences || {},
2530
+ ...Object.fromEntries(Object.entries(defaults.preferences || {}).filter(([k])=>!(k in (config.preferences || {}))))
2531
+ };
2532
+ return {
2533
+ ...config,
2534
+ browserFlags: nextFlags,
2535
+ preferences: nextPreferences
2536
+ };
2537
+ }
2538
+ var dev_server_messages = __webpack_require__("./dev-server/messages.ts");
2539
+ async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher) {
2540
+ const projectStructure = await getProjectStructure(pathOrRemoteUrl);
2541
+ const debug = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2542
+ const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
2543
+ if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, packageJsonDir);
2544
+ const browser = (0, paths.YN)(previewOptions.browser || 'chrome', previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary);
2545
+ const outputPath = (0, paths.u2)(projectStructure, browser, previewOptions.outputPath);
2546
+ const distPath = (0, paths.q4)(packageJsonDir, browser);
2547
+ const metadataCommand = 'start' === previewOptions.metadataCommand ? 'start' : 'preview';
2548
+ const metadata = (0, plugin_playwright.Ih)({
2549
+ packageJsonDir,
2550
+ browser: String(browser),
2551
+ command: metadataCommand,
2552
+ distPath,
2553
+ manifestPath: projectStructure.manifestPath,
2554
+ port: 'number' == typeof previewOptions.port ? previewOptions.port : 'string' == typeof previewOptions.port ? parseInt(previewOptions.port, 10) : null
2555
+ });
2556
+ metadata.writeStarting();
2557
+ if (debug) {
2558
+ console.log(messages.SG(manifestDir, packageJsonDir));
2559
+ console.log(messages._A(browser, previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary));
2560
+ console.log(messages.jV(outputPath, distPath));
1990
2561
  }
1991
- if (localPaths.length > 0) {
1992
- const absLocalPaths = ensurePathsUnderExtensions(projectRoot, localPaths);
1993
- resolvedPaths.push(...absLocalPaths);
2562
+ const manifestAtOutput = external_path_.join(outputPath, 'manifest.json');
2563
+ if (!external_fs_.existsSync(manifestAtOutput)) {
2564
+ metadata.writeError('preview_manifest_missing', `Expected manifest at ${manifestAtOutput}`);
2565
+ throw new Error(`Preview is run-only and does not compile.\nExpected an unpacked extension at:\n ${manifestAtOutput}\n\nRun \`extension build\` or \`extension dev\` first, or pass --output-path to an existing unpacked extension directory.`);
1994
2566
  }
1995
- const output = {};
1996
- if ('string' == typeof normalized.dir) {
1997
- const absDir = (0, _utils__rspack_import_3.A$)(projectRoot, normalized.dir);
1998
- const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
1999
- if (absDir !== extensionsRoot && !isSubpathOf(extensionsRoot, absDir)) throw new Error(`extensions.dir must be inside ${extensionsRoot}.\nInvalid dir: ${absDir}`);
2000
- output.dir = normalized.dir;
2567
+ const commandConfig = await (0, config_loader.eY)(packageJsonDir, metadataCommand);
2568
+ const browserConfig = await (0, config_loader.xY)(packageJsonDir, browser);
2569
+ console.log(messages.V_(browser));
2570
+ if (previewOptions.noBrowser) {
2571
+ console.log(messages.k4(browser));
2572
+ metadata.writeReady();
2573
+ console.log(dev_server_messages.tl());
2574
+ const browserLabel = String(browser || 'unknown');
2575
+ console.log(dev_server_messages.bL({
2576
+ browser: browserLabel,
2577
+ manifestPath: projectStructure.manifestPath,
2578
+ readyPath: metadata.readyPath,
2579
+ browserModeLabel: `${browserLabel.charAt(0).toUpperCase() + browserLabel.slice(1)} (no-browser mode)`
2580
+ }));
2581
+ return;
2001
2582
  }
2002
- if (resolvedPaths.length > 0) output.paths = resolvedPaths;
2003
- return output;
2583
+ const safeBrowserConfig = (0, sanitize.a)(browserConfig);
2584
+ const safeCommandConfig = (0, sanitize.a)(commandConfig);
2585
+ const safePreviewOptions = (0, sanitize.a)(previewOptions);
2586
+ const specialFoldersData = (0, get_data.H)(packageJsonDir);
2587
+ const mergedExtensionsConfig = safePreviewOptions.extensions ?? safeCommandConfig.extensions ?? safeBrowserConfig.extensions ?? specialFoldersData.extensions;
2588
+ const resolvedExtensionsConfig = await (0, resolve_config.R)({
2589
+ projectRoot: packageJsonDir,
2590
+ browser,
2591
+ config: mergedExtensionsConfig
2592
+ });
2593
+ const mergedGeckoBinary = safePreviewOptions.geckoBinary || safePreviewOptions.firefoxBinary || safeCommandConfig.geckoBinary || safeCommandConfig.firefoxBinary || safeBrowserConfig.geckoBinary || safeBrowserConfig.firefoxBinary;
2594
+ const mergedChromiumBinary = safePreviewOptions.chromiumBinary || safeCommandConfig.chromiumBinary || safeBrowserConfig.chromiumBinary;
2595
+ const merged = {
2596
+ ...safeBrowserConfig,
2597
+ ...safeCommandConfig,
2598
+ ...safePreviewOptions,
2599
+ extensions: resolvedExtensionsConfig,
2600
+ chromiumBinary: mergedChromiumBinary,
2601
+ geckoBinary: mergedGeckoBinary
2602
+ };
2603
+ const darkDefaults = withDarkMode({
2604
+ browser,
2605
+ browserFlags: merged.browserFlags,
2606
+ preferences: merged.preferences
2607
+ });
2608
+ const companionUnpackedExtensionDirs = resolveCompanionExtensionDirs({
2609
+ projectRoot: packageJsonDir,
2610
+ config: merged.extensions
2611
+ });
2612
+ const unpackedExtensionDirsToLoad = (0, extensions_to_load.n)(external_path_.resolve(__dirname, '..'), 'production', browser, outputPath, companionUnpackedExtensionDirs, projectStructure.manifestPath);
2613
+ const resolvedOpts = {
2614
+ browser,
2615
+ outPath: outputPath,
2616
+ contextDir: packageJsonDir,
2617
+ readyPath: metadata.readyPath,
2618
+ extensionsToLoad: unpackedExtensionDirsToLoad,
2619
+ noOpen: merged.noOpen,
2620
+ profile: merged.profile,
2621
+ persistProfile: merged.persistProfile,
2622
+ preferences: darkDefaults.preferences,
2623
+ browserFlags: darkDefaults.browserFlags,
2624
+ excludeBrowserFlags: merged.excludeBrowserFlags,
2625
+ startingUrl: merged.startingUrl,
2626
+ chromiumBinary: merged.chromiumBinary,
2627
+ geckoBinary: merged.geckoBinary,
2628
+ instanceId: merged.instanceId,
2629
+ port: merged.port,
2630
+ dryRun: merged.dryRun
2631
+ };
2632
+ if (!browserLauncher) throw new Error("extensionPreview requires a browserLauncher callback. The browser launch code has moved to programs/extension/browsers/.");
2633
+ await browserLauncher(resolvedOpts);
2634
+ metadata.writeReady();
2004
2635
  }
2005
2636
  },
2006
- "./plugin-special-folders/folder-extensions/utils.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2637
+ "./plugin-js-frameworks/frameworks-lib/integrations.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2007
2638
  __webpack_require__.d(__webpack_exports__, {
2008
- A$: ()=>toAbs,
2009
- Q7: ()=>isDir,
2010
- Uy: ()=>isValidExtensionRoot,
2011
- cz: ()=>normalizeCompanionConfig,
2012
- fo: ()=>isFile
2639
+ qQ: ()=>isUsingJSFramework,
2640
+ ws: ()=>_lib_has_dependency__rspack_import_0.w
2013
2641
  });
2014
- var fs__rspack_import_0 = __webpack_require__("fs");
2015
- var path__rspack_import_1 = __webpack_require__("path");
2016
- function isDir(p) {
2017
- try {
2018
- return fs__rspack_import_0.existsSync(p) && fs__rspack_import_0.statSync(p).isDirectory();
2019
- } catch {
2020
- return false;
2021
- }
2642
+ var _lib_has_dependency__rspack_import_0 = __webpack_require__("./lib/has-dependency.ts");
2643
+ __webpack_require__("./lib/develop-context.ts");
2644
+ function isUsingJSFramework(projectPath) {
2645
+ const frameworks = [
2646
+ 'react',
2647
+ 'vue',
2648
+ '@angular/core',
2649
+ 'svelte',
2650
+ 'solid-js',
2651
+ 'preact'
2652
+ ];
2653
+ return frameworks.some((fw)=>(0, _lib_has_dependency__rspack_import_0.w)(projectPath, fw));
2022
2654
  }
2023
- function isFile(p) {
2024
- try {
2025
- return fs__rspack_import_0.existsSync(p) && fs__rspack_import_0.statSync(p).isFile();
2026
- } catch {
2027
- return false;
2028
- }
2655
+ },
2656
+ "./plugin-js-frameworks/js-frameworks-lib/messages.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2657
+ __webpack_require__.d(__webpack_exports__, {
2658
+ Ei: ()=>jsFrameworksHmrSummary,
2659
+ LR: ()=>creatingTSConfig,
2660
+ MH: ()=>jsFrameworksConfigsDetected,
2661
+ Ty: ()=>isUsingCustomLoader,
2662
+ jH: ()=>jsFrameworksIntegrationsEnabled,
2663
+ zA: ()=>isUsingIntegration
2664
+ });
2665
+ var pintor__rspack_import_0 = __webpack_require__("pintor");
2666
+ var pintor__rspack_import_0_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_0);
2667
+ function isUsingIntegration(name) {
2668
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Using ${pintor__rspack_import_0_default().brightBlue(name)}...`;
2029
2669
  }
2030
- function toAbs(projectRoot, p) {
2031
- return path__rspack_import_1.isAbsolute(p) ? p : path__rspack_import_1.resolve(projectRoot, p);
2670
+ function creatingTSConfig() {
2671
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Creating default tsconfig.json...`;
2032
2672
  }
2033
- function isValidExtensionRoot(dir) {
2034
- if (!isDir(dir)) return false;
2035
- return isFile(path__rspack_import_1.join(dir, 'manifest.json'));
2673
+ function isUsingCustomLoader(loaderPath) {
2674
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} Using custom loader: ${pintor__rspack_import_0_default().yellow(loaderPath)}.`;
2036
2675
  }
2037
- function normalizeCompanionConfig(config) {
2038
- const explicitPaths = [];
2039
- let scanDir;
2040
- if (Array.isArray(config)) explicitPaths.push(...config.filter((p)=>'string' == typeof p));
2041
- else if (config && 'object' == typeof config) {
2042
- if (Array.isArray(config.paths)) explicitPaths.push(...config.paths.filter((p)=>'string' == typeof p));
2043
- if ('string' == typeof config.dir && config.dir.trim().length > 0) scanDir = config.dir.trim();
2044
- }
2045
- return {
2046
- dir: scanDir,
2047
- paths: explicitPaths
2048
- };
2676
+ function jsFrameworksIntegrationsEnabled(integrations) {
2677
+ const list = integrations.length > 0 ? integrations.map((n)=>pintor__rspack_import_0_default().yellow(n)).join(', ') : pintor__rspack_import_0_default().gray('none');
2678
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: Integrations enabled (${pintor__rspack_import_0_default().gray(String(integrations.length))}) ${list}`;
2679
+ }
2680
+ function jsFrameworksConfigsDetected(tsConfigPath, tsRoot, targets) {
2681
+ const fmt = (v)=>v ? pintor__rspack_import_0_default().underline(v) : pintor__rspack_import_0_default().gray('none');
2682
+ const tgt = targets && targets.length ? targets.map((t)=>pintor__rspack_import_0_default().gray(t)).join(', ') : pintor__rspack_import_0_default().gray('default');
2683
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: Configs\n${pintor__rspack_import_0_default().gray('TSCONFIG')} ${fmt(tsConfigPath)}\n${pintor__rspack_import_0_default().gray('TSROOT')} ${fmt(tsRoot)}\n${pintor__rspack_import_0_default().gray('SWC_TARGETS')} ${tgt}`;
2684
+ }
2685
+ function jsFrameworksHmrSummary(enabled, frameworks) {
2686
+ const list = frameworks.length > 0 ? frameworks.map((n)=>pintor__rspack_import_0_default().yellow(n)).join(', ') : pintor__rspack_import_0_default().gray('none');
2687
+ return `${pintor__rspack_import_0_default().gray('⏵⏵⏵')} JS: HMR ${enabled ? pintor__rspack_import_0_default().green('enabled') : pintor__rspack_import_0_default().gray('disabled')} for ${list}`;
2049
2688
  }
2050
2689
  },
2051
- "./plugin-special-folders/get-data.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2690
+ "./plugin-js-frameworks/js-tools/typescript.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2052
2691
  __webpack_require__.d(__webpack_exports__, {
2053
- B: ()=>getSpecialFoldersDataForCompiler,
2054
- H: ()=>getSpecialFoldersDataForProjectRoot
2692
+ eE: ()=>isUsingTypeScript,
2693
+ hB: ()=>getUserTypeScriptConfigFile
2055
2694
  });
2056
2695
  var path__rspack_import_0 = __webpack_require__("path");
2057
- var path__rspack_import_0_default = /*#__PURE__*/ __webpack_require__.n(path__rspack_import_0);
2058
- var browser_extension_manifest_fields__rspack_import_1 = __webpack_require__("browser-extension-manifest-fields");
2059
- function isUnderPublicDir(entry, projectRoot, publicDir) {
2060
- if (!entry) return false;
2061
- const normalizedEntry = String(entry);
2062
- const candidate = path__rspack_import_0_default().isAbsolute(normalizedEntry) ? normalizedEntry : path__rspack_import_0_default().join(projectRoot, normalizedEntry);
2063
- const rel = path__rspack_import_0_default().relative(publicDir, candidate);
2064
- return Boolean(rel && !rel.startsWith('..') && !path__rspack_import_0_default().isAbsolute(rel));
2065
- }
2066
- function filterPublicEntrypoints(list, projectRoot, publicDir) {
2067
- const next = {};
2068
- for (const [key, value] of Object.entries(list || {})){
2069
- if (Array.isArray(value)) {
2070
- const filtered = value.filter((entry)=>!isUnderPublicDir(String(entry), projectRoot, publicDir));
2071
- if (filtered.length > 0) next[key] = filtered;
2072
- continue;
2073
- }
2074
- if ('string' == typeof value) {
2075
- if (!isUnderPublicDir(value, projectRoot, publicDir)) next[key] = value;
2076
- continue;
2077
- }
2696
+ var fs__rspack_import_1 = __webpack_require__("fs");
2697
+ var pintor__rspack_import_2 = __webpack_require__("pintor");
2698
+ var pintor__rspack_import_2_default = /*#__PURE__*/ __webpack_require__.n(pintor__rspack_import_2);
2699
+ var _js_frameworks_lib_messages__rspack_import_3 = __webpack_require__("./plugin-js-frameworks/js-frameworks-lib/messages.ts");
2700
+ var _frameworks_lib_integrations__rspack_import_4 = __webpack_require__("./plugin-js-frameworks/frameworks-lib/integrations.ts");
2701
+ __webpack_require__("./lib/optional-deps-resolver.ts");
2702
+ var _lib_parse_json_safe__rspack_import_6 = __webpack_require__("./lib/parse-json-safe.ts");
2703
+ let hasShownUserMessage = false;
2704
+ function findNearestPackageJsonDirectory(startPath) {
2705
+ let currentDirectory = startPath;
2706
+ const maxDepth = 6;
2707
+ for(let i = 0; i < maxDepth; i++){
2708
+ const candidate = path__rspack_import_0.join(currentDirectory, 'package.json');
2709
+ if (fs__rspack_import_1.existsSync(candidate)) return currentDirectory;
2710
+ const parentDirectory = path__rspack_import_0.dirname(currentDirectory);
2711
+ if (parentDirectory === currentDirectory) break;
2712
+ currentDirectory = parentDirectory;
2078
2713
  }
2079
- return next;
2080
2714
  }
2081
- function getSpecialFoldersDataForCompiler(compiler) {
2082
- const projectRoot = compiler.options.context || '';
2083
- const publicDir = path__rspack_import_0_default().join(projectRoot, 'public');
2084
- const data = (0, browser_extension_manifest_fields__rspack_import_1.getSpecialFoldersData)({
2085
- manifestPath: path__rspack_import_0_default().join(projectRoot, 'package.json')
2086
- });
2087
- return finalizeSpecialFoldersData(data, projectRoot, publicDir);
2715
+ function hasTypeScriptSourceFiles(projectPath) {
2716
+ try {
2717
+ const entries = fs__rspack_import_1.readdirSync(projectPath, {
2718
+ withFileTypes: true
2719
+ });
2720
+ return entries.some((entry)=>{
2721
+ if (entry.isFile()) {
2722
+ const name = entry.name;
2723
+ if (!/\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
2724
+ if (/\.(d\.ts|d\.mts|d\.mtsx)$/i.test(name)) return false;
2725
+ if (/\.(spec|test)\.(ts|tsx|mts|mtsx)$/i.test(name)) return false;
2726
+ return true;
2727
+ }
2728
+ if (entry.isDirectory()) {
2729
+ if (![
2730
+ 'src',
2731
+ 'content',
2732
+ 'sidebar',
2733
+ 'background'
2734
+ ].includes(entry.name)) return false;
2735
+ const sub = path__rspack_import_0.join(projectPath, entry.name);
2736
+ return hasTypeScriptSourceFiles(sub);
2737
+ }
2738
+ return false;
2739
+ });
2740
+ } catch {
2741
+ return false;
2742
+ }
2088
2743
  }
2089
- function getSpecialFoldersDataForProjectRoot(projectRoot) {
2090
- const publicDir = path__rspack_import_0_default().join(projectRoot, 'public');
2091
- const data = (0, browser_extension_manifest_fields__rspack_import_1.getSpecialFoldersData)({
2092
- manifestPath: path__rspack_import_0_default().join(projectRoot, 'package.json')
2093
- });
2094
- return finalizeSpecialFoldersData(data, projectRoot, publicDir);
2744
+ function isUsingTypeScript(projectPath) {
2745
+ const packageJsonDirectory = findNearestPackageJsonDirectory(projectPath);
2746
+ const tsConfigFilePath = getUserTypeScriptConfigFile(projectPath);
2747
+ const packageJson = packageJsonDirectory ? (0, _lib_parse_json_safe__rspack_import_6.p)(fs__rspack_import_1.readFileSync(path__rspack_import_0.join(packageJsonDirectory, 'package.json'), 'utf8')) : void 0;
2748
+ const TypeScriptAsDevDep = packageJson?.devDependencies?.typescript;
2749
+ const TypeScriptAsDep = packageJson?.dependencies?.typescript;
2750
+ const hasTsFiles = hasTypeScriptSourceFiles(projectPath);
2751
+ if (!hasShownUserMessage) {
2752
+ if (TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles) if (tsConfigFilePath) {
2753
+ if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.log(`${pintor__rspack_import_2_default().brightMagenta('⏵⏵⏵ Author says')} ${_js_frameworks_lib_messages__rspack_import_3.zA('TypeScript')}`);
2754
+ } else if (hasTsFiles) {
2755
+ const errorMessage = '[Extension.js] Missing tsconfig.json next to package.json. Create one to use TypeScript.';
2756
+ throw new Error(errorMessage);
2757
+ } else {
2758
+ console.log(_js_frameworks_lib_messages__rspack_import_3.LR());
2759
+ writeTsConfig(projectPath);
2760
+ }
2761
+ hasShownUserMessage = true;
2762
+ }
2763
+ return !!tsConfigFilePath && !!(TypeScriptAsDevDep || TypeScriptAsDep || hasTsFiles);
2095
2764
  }
2096
- function finalizeSpecialFoldersData(data, projectRoot, publicDir) {
2765
+ function defaultTypeScriptConfig(projectPath, _opts) {
2097
2766
  return {
2098
- ...data,
2099
- pages: filterPublicEntrypoints(data.pages, projectRoot, publicDir),
2100
- scripts: filterPublicEntrypoints(data.scripts, projectRoot, publicDir),
2101
- extensions: {
2102
- dir: './extensions'
2103
- }
2767
+ compilerOptions: {
2768
+ allowJs: true,
2769
+ allowSyntheticDefaultImports: true,
2770
+ esModuleInterop: true,
2771
+ forceConsistentCasingInFileNames: true,
2772
+ jsx: (0, _frameworks_lib_integrations__rspack_import_4.qQ)(projectPath) ? 'react-jsx' : 'preserve',
2773
+ lib: [
2774
+ 'dom',
2775
+ 'dom.iterable',
2776
+ 'esnext'
2777
+ ],
2778
+ moduleResolution: 'node',
2779
+ module: 'esnext',
2780
+ resolveJsonModule: true,
2781
+ strict: true,
2782
+ target: 'esnext',
2783
+ isolatedModules: false,
2784
+ skipLibCheck: true
2785
+ },
2786
+ exclude: [
2787
+ 'node_modules',
2788
+ 'dist'
2789
+ ]
2104
2790
  };
2105
2791
  }
2792
+ function getUserTypeScriptConfigFile(projectPath) {
2793
+ const pkgDir = findNearestPackageJsonDirectory(projectPath);
2794
+ if (pkgDir) {
2795
+ const tsconfigPath = path__rspack_import_0.join(pkgDir, 'tsconfig.json');
2796
+ if (fs__rspack_import_1.existsSync(tsconfigPath)) return tsconfigPath;
2797
+ }
2798
+ }
2799
+ function writeTsConfig(projectPath) {
2800
+ fs__rspack_import_1.writeFileSync(path__rspack_import_0.join(projectPath, 'tsconfig.json'), JSON.stringify(defaultTypeScriptConfig(projectPath, {
2801
+ mode: 'development'
2802
+ }), null, 2));
2803
+ }
2106
2804
  },
2107
- "./plugin-web-extension/feature-scripts/contracts.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2805
+ "./plugin-playwright/index.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2108
2806
  __webpack_require__.d(__webpack_exports__, {
2109
- $t: ()=>EXTENSIONJS_CONTENT_SCRIPT_LAYER,
2110
- J4: ()=>getCanonicalContentScriptCssAssetName,
2111
- Y0: ()=>getCanonicalContentScriptEntryName,
2112
- es: ()=>parseCanonicalContentScriptAsset,
2113
- f6: ()=>getCanonicalContentScriptJsAssetName
2807
+ Ih: ()=>createPlaywrightMetadataWriter,
2808
+ Tb: ()=>PlaywrightPlugin
2114
2809
  });
2115
- const EXTENSIONJS_CONTENT_SCRIPT_LAYER = "extensionjs-content-script";
2116
- const CANONICAL_CONTENT_SCRIPT_ENTRY_PREFIX = "content_scripts/content-";
2117
- function getCanonicalContentScriptEntryName(index) {
2118
- return `${CANONICAL_CONTENT_SCRIPT_ENTRY_PREFIX}${index}`;
2810
+ var fs__rspack_import_0 = __webpack_require__("fs");
2811
+ var path__rspack_import_1 = __webpack_require__("path");
2812
+ var _lib_paths__rspack_import_2 = __webpack_require__("./lib/paths.ts");
2813
+ function _define_property(obj, key, value) {
2814
+ if (key in obj) Object.defineProperty(obj, key, {
2815
+ value: value,
2816
+ enumerable: true,
2817
+ configurable: true,
2818
+ writable: true
2819
+ });
2820
+ else obj[key] = value;
2821
+ return obj;
2119
2822
  }
2120
- function getCanonicalContentScriptJsAssetName(index) {
2121
- return `${getCanonicalContentScriptEntryName(index)}.js`;
2823
+ function nowISO() {
2824
+ return new Date().toISOString();
2122
2825
  }
2123
- function getCanonicalContentScriptCssAssetName(index) {
2124
- return `${getCanonicalContentScriptEntryName(index)}.css`;
2826
+ function createRunId() {
2827
+ return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
2125
2828
  }
2126
- function parseCanonicalContentScriptAsset(assetName) {
2127
- const match = /^content_scripts\/content-(\d+)(?:\.[a-f0-9]+)?\.(js|css)$/i.exec(String(assetName || ''));
2128
- if (!match) return;
2129
- const index = Number(match[1]);
2130
- if (!Number.isInteger(index)) return;
2131
- return {
2132
- index,
2133
- extension: match[2]
2134
- };
2829
+ function ensureDirSync(dirPath) {
2830
+ try {
2831
+ fs__rspack_import_0.mkdirSync(dirPath, {
2832
+ recursive: true
2833
+ });
2834
+ } catch {}
2135
2835
  }
2136
- },
2137
- "@rspack/core" (module) {
2138
- module.exports = require("@rspack/core");
2139
- },
2140
- "@rspack/dev-server" (module) {
2141
- module.exports = require("@rspack/dev-server");
2142
- },
2143
- "adm-zip" (module) {
2144
- module.exports = require("adm-zip");
2145
- },
2146
- "browser-extension-manifest-fields" (module) {
2147
- module.exports = require("browser-extension-manifest-fields");
2148
- },
2149
- "case-sensitive-paths-webpack-plugin" (module) {
2150
- module.exports = require("case-sensitive-paths-webpack-plugin");
2151
- },
2152
- "content-security-policy-parser" (module) {
2153
- module.exports = require("content-security-policy-parser");
2154
- },
2155
- crypto (module) {
2156
- module.exports = require("crypto");
2157
- },
2158
- dotenv (module) {
2159
- module.exports = require("dotenv");
2160
- },
2161
- "extension-from-store" (module) {
2162
- module.exports = require("extension-from-store");
2163
- },
2164
- fs (module) {
2165
- module.exports = require("fs");
2166
- },
2167
- ignore (module) {
2168
- module.exports = require("ignore");
2169
- },
2170
- module (module) {
2171
- module.exports = require("module");
2172
- },
2173
- net (module) {
2174
- module.exports = require("net");
2175
- },
2176
- os (module) {
2177
- module.exports = require("os");
2178
- },
2179
- "parse5-utilities" (module) {
2180
- module.exports = require("parse5-utilities");
2181
- },
2182
- path (module) {
2183
- module.exports = require("path");
2184
- },
2185
- pintor (module) {
2186
- module.exports = require("pintor");
2187
- },
2188
- stream (module) {
2189
- module.exports = require("stream");
2190
- },
2191
- "tiny-glob" (module) {
2192
- module.exports = require("tiny-glob");
2193
- },
2194
- url (module) {
2195
- module.exports = require("url");
2196
- },
2197
- vm (module) {
2198
- module.exports = require("vm");
2199
- },
2200
- "webpack-merge" (module) {
2201
- module.exports = require("webpack-merge");
2202
- },
2203
- "./package.json" (module) {
2204
- module.exports = JSON.parse('{"rE":"3.14.5","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^1.7.5","@rspack/dev-server":"^1.2.1","@rspack/plugin-preact-refresh":"1.1.4","@rspack/plugin-react-refresh":"1.6.0","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.1","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.5.1","less-loader":"12.3.0","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.6","postcss-loader":"8.2.0","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","react-refresh":"0.18.0","sass-loader":"16.0.6","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","unique-names-generator":"^4.7.1","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3"}}');
2205
- }
2206
- };
2207
- var __webpack_module_cache__ = {};
2208
- function __webpack_require__(moduleId) {
2209
- var cachedModule = __webpack_module_cache__[moduleId];
2210
- if (void 0 !== cachedModule) return cachedModule.exports;
2211
- var module = __webpack_module_cache__[moduleId] = {
2212
- exports: {}
2213
- };
2214
- __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
2215
- return module.exports;
2216
- }
2217
- __webpack_require__.m = __webpack_modules__;
2218
- (()=>{
2219
- __webpack_require__.n = (module)=>{
2220
- var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
2221
- __webpack_require__.d(getter, {
2222
- a: getter
2223
- });
2224
- return getter;
2225
- };
2226
- })();
2227
- (()=>{
2228
- __webpack_require__.d = (exports1, definition)=>{
2229
- for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
2230
- enumerable: true,
2231
- get: definition[key]
2232
- });
2233
- };
2234
- })();
2235
- (()=>{
2236
- __webpack_require__.f = {};
2237
- __webpack_require__.e = (chunkId)=>Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key)=>{
2238
- __webpack_require__.f[key](chunkId, promises);
2239
- return promises;
2240
- }, []));
2241
- })();
2242
- (()=>{
2243
- __webpack_require__.u = (chunkId)=>"" + chunkId + ".cjs";
2244
- })();
2245
- (()=>{
2246
- __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
2247
- })();
2248
- (()=>{
2249
- __webpack_require__.r = (exports1)=>{
2250
- if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
2251
- value: 'Module'
2252
- });
2253
- Object.defineProperty(exports1, '__esModule', {
2254
- value: true
2255
- });
2256
- };
2257
- })();
2258
- (()=>{
2259
- var installedChunks = {
2260
- 364: 1
2261
- };
2262
- var installChunk = (chunk)=>{
2263
- var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
2264
- for(var moduleId in moreModules)if (__webpack_require__.o(moreModules, moduleId)) __webpack_require__.m[moduleId] = moreModules[moduleId];
2265
- if (runtime) runtime(__webpack_require__);
2266
- for(var i = 0; i < chunkIds.length; i++)installedChunks[chunkIds[i]] = 1;
2267
- };
2268
- __webpack_require__.f.require = (chunkId, promises)=>{
2269
- if (!installedChunks[chunkId]) installChunk(require("./" + __webpack_require__.u(chunkId)));
2270
- };
2271
- })();
2272
- var __webpack_exports__ = {};
2273
- (()=>{
2274
- __webpack_require__.r(__webpack_exports__);
2275
- __webpack_require__.d(__webpack_exports__, {
2276
- BuildEmitter: ()=>BuildEmitter,
2277
- extensionDev: ()=>extensionDev,
2278
- extensionPreview: ()=>extensionPreview,
2279
- extensionBuild: ()=>extensionBuild
2280
- });
2281
- function getBuildSummary(browser, info) {
2282
- const assets = info?.assets || [];
2283
- return {
2284
- browser,
2285
- total_assets: assets.length,
2286
- total_bytes: assets.reduce((n, a)=>n + (a.size || 0), 0),
2287
- largest_asset_bytes: assets.reduce((m, a)=>Math.max(m, a.size || 0), 0),
2288
- warnings_count: (info?.warnings || []).length,
2289
- errors_count: (info?.errors || []).length
2290
- };
2291
- }
2292
- var external_module_ = __webpack_require__("module");
2293
- var external_path_ = __webpack_require__("path");
2294
- var external_fs_ = __webpack_require__("fs");
2295
- var messages = __webpack_require__("./lib/messages.ts");
2296
- async function findUpLocal(filename, options) {
2297
- const root = external_path_.parse(options.cwd).root;
2298
- let currentDir = options.cwd;
2299
- while(true){
2300
- const candidate = external_path_.join(currentDir, filename);
2836
+ function writeJsonAtomic(filePath, value) {
2301
2837
  try {
2302
- const stat = await external_fs_.promises.stat(candidate);
2303
- if (stat.isFile()) return candidate;
2838
+ const tmpPath = `${filePath}.tmp-${process.pid}`;
2839
+ fs__rspack_import_0.writeFileSync(tmpPath, JSON.stringify(value, null, 2) + '\n', 'utf-8');
2840
+ fs__rspack_import_0.renameSync(tmpPath, filePath);
2304
2841
  } catch {}
2305
- if (currentDir === root) return;
2306
- currentDir = external_path_.dirname(currentDir);
2307
- }
2308
- }
2309
- async function findNearestPackageJson(manifestPath) {
2310
- try {
2311
- const manifestDir = external_path_.dirname(manifestPath);
2312
- const packageJsonPath = await findUpLocal('package.json', {
2313
- cwd: manifestDir
2314
- });
2315
- return packageJsonPath || null;
2316
- } catch (error) {
2317
- console.warn('Failed to find package.json:', error);
2318
- return null;
2319
2842
  }
2320
- }
2321
- function validatePackageJson(packageJsonPath) {
2322
- try {
2323
- if (!external_fs_.existsSync(packageJsonPath)) return false;
2324
- const content = external_fs_.readFileSync(packageJsonPath, 'utf-8');
2325
- JSON.parse(content);
2326
- return true;
2327
- } catch (error) {
2328
- console.warn('Invalid package.json at:', packageJsonPath, error);
2329
- return false;
2843
+ function getPlaywrightMetadataDir(packageJsonDir, browser) {
2844
+ return (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(packageJsonDir, 'dist', 'extension-js', browser));
2330
2845
  }
2331
- }
2332
- const isUrl = (url)=>{
2333
- try {
2334
- new URL(url);
2335
- return true;
2336
- } catch (e) {
2337
- return false;
2846
+ function createPlaywrightMetadataWriter(options) {
2847
+ const metadataDir = getPlaywrightMetadataDir(options.packageJsonDir, options.browser);
2848
+ const readyPath = (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(metadataDir, 'ready.json'));
2849
+ const eventsPath = (0, _lib_paths__rspack_import_2.G6)(path__rspack_import_1.join(metadataDir, 'events.ndjson'));
2850
+ const base = {
2851
+ command: options.command,
2852
+ browser: options.browser,
2853
+ runId: createRunId(),
2854
+ startedAt: nowISO(),
2855
+ distPath: options.distPath,
2856
+ manifestPath: options.manifestPath,
2857
+ port: (()=>{
2858
+ if ('number' == typeof options.port && Number.isFinite(options.port)) return options.port;
2859
+ if ('string' == typeof options.port) {
2860
+ const parsed = parseInt(options.port, 10);
2861
+ return Number.isFinite(parsed) ? parsed : null;
2862
+ }
2863
+ return null;
2864
+ })()
2865
+ };
2866
+ function writeReady(status, extra) {
2867
+ ensureDirSync(metadataDir);
2868
+ const payload = {
2869
+ ...base,
2870
+ status,
2871
+ pid: process.pid,
2872
+ ts: nowISO(),
2873
+ compiledAt: extra?.compiledAt ?? null,
2874
+ errors: Array.isArray(extra?.errors) ? extra.errors : []
2875
+ };
2876
+ if (extra?.code) payload.code = extra.code;
2877
+ if (extra?.message) payload.message = extra.message;
2878
+ writeJsonAtomic(readyPath, payload);
2879
+ }
2880
+ function appendEvent(event) {
2881
+ ensureDirSync(metadataDir);
2882
+ try {
2883
+ fs__rspack_import_0.appendFileSync(eventsPath, `${JSON.stringify(event)}\n`, 'utf-8');
2884
+ } catch {}
2885
+ }
2886
+ return {
2887
+ metadataDir,
2888
+ readyPath,
2889
+ eventsPath,
2890
+ writeStarting () {
2891
+ writeReady('starting');
2892
+ },
2893
+ writeReady (compiledAt) {
2894
+ writeReady('ready', {
2895
+ compiledAt: compiledAt || nowISO()
2896
+ });
2897
+ },
2898
+ writeError (code, message, errors) {
2899
+ writeReady('error', {
2900
+ code,
2901
+ message,
2902
+ errors: Array.isArray(errors) ? errors : [],
2903
+ compiledAt: null
2904
+ });
2905
+ },
2906
+ appendEvent
2907
+ };
2338
2908
  }
2339
- };
2340
- async function importUrlSourceFromGithub(pathOrRemoteUrl, text) {
2341
- const cwd = process.cwd();
2342
- const url = new URL(pathOrRemoteUrl);
2343
- const segments = url.pathname.split('/').filter(Boolean);
2344
- const repoName = segments.length >= 2 ? segments[1] : segments[segments.length - 1];
2345
- const treeIndex = segments.indexOf('tree');
2346
- const expectedName = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments[segments.length - 1] : repoName;
2347
- const expectedPath = external_path_.resolve(cwd, expectedName);
2348
- if (external_fs_.existsSync(expectedPath)) try {
2349
- const entries = external_fs_.readdirSync(expectedPath);
2350
- if (0 === entries.length) external_fs_.rmSync(expectedPath, {
2351
- recursive: true,
2352
- force: true
2353
- });
2354
- else {
2355
- const hasManifest = (dir)=>{
2356
- const stack = [
2357
- dir
2358
- ];
2359
- while(stack.length){
2360
- const current = stack.pop();
2361
- const items = external_fs_.readdirSync(current, {
2362
- withFileTypes: true
2909
+ class PlaywrightPlugin {
2910
+ apply(compiler) {
2911
+ this.writer.writeStarting();
2912
+ compiler.hooks.compile.tap(PlaywrightPlugin.name, ()=>{
2913
+ this.writer.appendEvent({
2914
+ type: 'compile_start',
2915
+ ts: nowISO(),
2916
+ command: this.command,
2917
+ browser: this.browser
2918
+ });
2919
+ });
2920
+ compiler.hooks.done.tap(PlaywrightPlugin.name, (stats)=>{
2921
+ const durationMs = Number((stats?.compilation?.endTime || 0) - (stats?.compilation?.startTime || 0));
2922
+ const hasErrors = Boolean(stats?.hasErrors?.());
2923
+ const errorsCount = Number(Array.isArray(stats?.toJson?.({
2924
+ all: false,
2925
+ errors: true
2926
+ })?.errors) ? stats.toJson({
2927
+ all: false,
2928
+ errors: true
2929
+ }).errors.length : 0);
2930
+ if (hasErrors) {
2931
+ this.writer.appendEvent({
2932
+ type: 'compile_error',
2933
+ ts: nowISO(),
2934
+ command: this.command,
2935
+ browser: this.browser,
2936
+ durationMs: Number.isFinite(durationMs) ? durationMs : void 0,
2937
+ errorCount: Number.isFinite(errorsCount) ? errorsCount : 1
2363
2938
  });
2364
- for (const it of items){
2365
- if (it.isFile() && 'manifest.json' === it.name) return true;
2366
- if (it.isDirectory() && 'node_modules' !== it.name && 'dist' !== it.name && !it.name.startsWith('.')) stack.push(external_path_.join(current, it.name));
2367
- }
2939
+ this.writer.writeError('compile_error', 'Compilation failed', [
2940
+ `errors: ${String(errorsCount || 1)}`
2941
+ ]);
2942
+ return;
2368
2943
  }
2369
- return false;
2370
- };
2371
- if (hasManifest(expectedPath)) return expectedPath;
2372
- external_fs_.rmSync(expectedPath, {
2373
- recursive: true,
2374
- force: true
2944
+ this.writer.appendEvent({
2945
+ type: 'compile_success',
2946
+ ts: nowISO(),
2947
+ command: this.command,
2948
+ browser: this.browser,
2949
+ durationMs: Number.isFinite(durationMs) ? durationMs : void 0,
2950
+ errorCount: 0
2951
+ });
2952
+ this.writer.writeReady(nowISO());
2953
+ });
2954
+ compiler.hooks.failed.tap(PlaywrightPlugin.name, (error)=>{
2955
+ this.writer.appendEvent({
2956
+ type: 'compile_error',
2957
+ ts: nowISO(),
2958
+ command: this.command,
2959
+ browser: this.browser,
2960
+ errorCount: 1
2961
+ });
2962
+ this.writer.writeError('compile_failed', error instanceof Error ? error.message : String(error));
2963
+ });
2964
+ compiler.hooks.watchClose.tap(PlaywrightPlugin.name, ()=>{
2965
+ this.writer.appendEvent({
2966
+ type: 'shutdown',
2967
+ ts: nowISO(),
2968
+ command: this.command,
2969
+ browser: this.browser
2970
+ });
2375
2971
  });
2376
2972
  }
2377
- } catch {}
2378
- async function tryGitClone() {
2379
- const { default: goGitIt } = await import("go-git-it");
2380
- await goGitIt(pathOrRemoteUrl, cwd, text);
2381
- }
2382
- async function tryZipFallback() {
2383
- const branch = -1 !== treeIndex && segments.length > treeIndex + 1 ? segments[treeIndex + 1] : 'main';
2384
- const owner = segments[0];
2385
- const repo = segments[1];
2386
- const subdir = -1 !== treeIndex && segments.length > treeIndex + 2 ? segments.slice(treeIndex + 2).join('/') : '';
2387
- const zipUrl = `https://codeload.github.com/${owner}/${repo}/zip/refs/heads/${branch}`;
2388
- const extractedPath = await importUrlSourceFromZip(zipUrl);
2389
- const extractedDirs = external_fs_.readdirSync(extractedPath, {
2390
- withFileTypes: true
2391
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
2392
- const repoRootDir = extractedDirs.find((d)=>d.startsWith(`${repo}-${branch}`));
2393
- const repoRoot = repoRootDir ? external_path_.join(extractedPath, repoRootDir) : extractedPath;
2394
- return subdir ? external_path_.join(repoRoot, subdir) : repoRoot;
2395
- }
2396
- try {
2397
- await tryGitClone();
2398
- } catch {
2399
- return await tryZipFallback();
2400
- }
2401
- const candidates = [];
2402
- if (-1 !== treeIndex && segments.length > treeIndex + 2) candidates.push(segments[segments.length - 1]);
2403
- candidates.push(repoName);
2404
- for (const name of candidates){
2405
- const p = external_path_.resolve(cwd, name);
2406
- if (external_fs_.existsSync(p)) return p;
2407
- }
2408
- const dirs = external_fs_.readdirSync(cwd, {
2409
- withFileTypes: true
2410
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
2411
- for (const dir of dirs){
2412
- const manifestPath = external_path_.join(cwd, dir, 'manifest.json');
2413
- if (external_fs_.existsSync(manifestPath)) return external_path_.join(cwd, dir);
2414
- }
2415
- try {
2416
- const dirs = external_fs_.readdirSync(cwd, {
2417
- withFileTypes: true
2418
- }).filter((d)=>d.isDirectory()).map((d)=>d.name);
2419
- const ghRoot = dirs.find((d)=>/-main$|-master$/.test(d));
2420
- if (ghRoot) return external_path_.join(cwd, ghRoot);
2421
- } catch {}
2422
- throw new Error(messages.ax(cwd, candidates));
2423
- }
2424
- async function importUrlSourceFromZip(pathOrRemoteUrl) {
2425
- const cwd = process.cwd();
2426
- const { downloadAndExtractZip } = await __webpack_require__.e("893").then(__webpack_require__.bind(__webpack_require__, "./lib/zip.ts"));
2427
- const extractedPath = await downloadAndExtractZip(pathOrRemoteUrl, cwd);
2428
- return extractedPath;
2429
- }
2430
- async function getProjectPath(pathOrRemoteUrl) {
2431
- if (!pathOrRemoteUrl) return process.cwd();
2432
- if (isUrl(pathOrRemoteUrl)) {
2433
- const url = new URL(pathOrRemoteUrl);
2434
- if (url.protocol.startsWith('http')) {
2435
- const pathname = url.pathname.toLowerCase();
2436
- if (pathname.endsWith('.zip')) return await importUrlSourceFromZip(pathOrRemoteUrl);
2437
- if ('https://github.com' !== url.origin) {
2438
- const urlSource = await importUrlSourceFromZip(pathOrRemoteUrl);
2439
- return urlSource;
2973
+ constructor(options){
2974
+ _define_property(this, "writer", void 0);
2975
+ _define_property(this, "command", void 0);
2976
+ _define_property(this, "browser", void 0);
2977
+ this.browser = String(options.browser || 'chromium');
2978
+ this.command = options.command || ('development' === options.mode ? 'dev' : 'start');
2979
+ this.writer = createPlaywrightMetadataWriter({
2980
+ packageJsonDir: options.packageJsonDir,
2981
+ browser: this.browser,
2982
+ command: this.command,
2983
+ distPath: options.outputPath,
2984
+ manifestPath: options.manifestPath,
2985
+ port: options.port
2986
+ });
2987
+ }
2988
+ }
2989
+ _define_property(PlaywrightPlugin, "name", 'plugin-playwright');
2990
+ },
2991
+ "./plugin-special-folders/folder-extensions/resolve-config.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
2992
+ __webpack_require__.d(__webpack_exports__, {
2993
+ R: ()=>resolveCompanionExtensionsConfig
2994
+ });
2995
+ var fs__rspack_import_0 = __webpack_require__("fs");
2996
+ var path__rspack_import_1 = __webpack_require__("path");
2997
+ var extension_from_store__rspack_import_2 = __webpack_require__("extension-from-store");
2998
+ var _utils__rspack_import_3 = __webpack_require__("./plugin-special-folders/folder-extensions/utils.ts");
2999
+ function isPathLike(value) {
3000
+ if (path__rspack_import_1.isAbsolute(value)) return true;
3001
+ if (value.startsWith('./') || value.startsWith('../')) return true;
3002
+ return value.includes('/') || value.includes('\\');
3003
+ }
3004
+ function isSubpathOf(parent, child) {
3005
+ const rel = path__rspack_import_1.relative(parent, child);
3006
+ return '' !== rel && !rel.startsWith('..') && !path__rspack_import_1.isAbsolute(rel);
3007
+ }
3008
+ function getBrowserFolder(browser) {
3009
+ if ('firefox' === browser || 'gecko-based' === browser || 'firefox-based' === browser) return 'firefox';
3010
+ if ('edge' === browser) return 'edge';
3011
+ return 'chrome';
3012
+ }
3013
+ function parseChromeWebStoreId(url) {
3014
+ if ('chromewebstore.google.com' !== url.hostname) return null;
3015
+ const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
3016
+ return match ? match[1] : null;
3017
+ }
3018
+ function parseEdgeAddonsId(url) {
3019
+ if ('microsoftedge.microsoft.com' !== url.hostname) return null;
3020
+ const match = url.pathname.match(/\/([a-z]{32})(?:\/|$)/i);
3021
+ return match ? match[1] : null;
3022
+ }
3023
+ function parseAmoSlug(url) {
3024
+ if ('addons.mozilla.org' !== url.hostname) return null;
3025
+ const match = url.pathname.match(/\/addon\/([^/]+)(?:\/|$)/i);
3026
+ return match ? match[1] : null;
3027
+ }
3028
+ function parseStoreUrl(raw) {
3029
+ let url;
3030
+ try {
3031
+ url = new URL(raw);
3032
+ } catch {
3033
+ return null;
3034
+ }
3035
+ const chromeId = parseChromeWebStoreId(url);
3036
+ if (chromeId) return {
3037
+ browser: 'chrome',
3038
+ id: chromeId
3039
+ };
3040
+ const edgeId = parseEdgeAddonsId(url);
3041
+ if (edgeId) return {
3042
+ browser: 'edge',
3043
+ id: edgeId
3044
+ };
3045
+ const amoSlug = parseAmoSlug(url);
3046
+ if (amoSlug) return {
3047
+ browser: 'firefox',
3048
+ id: amoSlug
3049
+ };
3050
+ return null;
3051
+ }
3052
+ function ensurePathsUnderExtensions(projectRoot, paths) {
3053
+ const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
3054
+ return paths.map((p)=>{
3055
+ const abs = (0, _utils__rspack_import_3.A$)(projectRoot, p);
3056
+ if (abs !== extensionsRoot && !isSubpathOf(extensionsRoot, abs) && path__rspack_import_1.resolve(abs) !== extensionsRoot) throw new Error(`Companion extensions must be inside ${extensionsRoot}.\nInvalid path: ${abs}`);
3057
+ return abs;
3058
+ });
3059
+ }
3060
+ function findExtensionRoots(dir, maxDepth = 3) {
3061
+ const found = [];
3062
+ function walk(current, depth) {
3063
+ if (depth > maxDepth) return;
3064
+ if (!(0, _utils__rspack_import_3.Q7)(current)) return;
3065
+ if ((0, _utils__rspack_import_3.Uy)(current)) return void found.push(current);
3066
+ let entries = [];
3067
+ try {
3068
+ entries = fs__rspack_import_0.readdirSync(current, {
3069
+ withFileTypes: true
3070
+ });
3071
+ } catch {
3072
+ return;
2440
3073
  }
2441
- const urlData = url.pathname.split('/');
2442
- const owner = urlData.slice(1, 3)[0];
2443
- const project = urlData.slice(1, 3)[1];
2444
- console.log(messages.tQ(owner, project));
2445
- const projectName = external_path_.basename(url.pathname);
2446
- const urlSource = await importUrlSourceFromGithub(pathOrRemoteUrl, messages.F$(projectName));
2447
- console.log(messages.W4(url.pathname));
2448
- return urlSource;
2449
- }
2450
- }
2451
- return external_path_.resolve(process.cwd(), pathOrRemoteUrl);
2452
- }
2453
- async function getProjectStructure(pathOrRemoteUrl) {
2454
- const projectPath = await getProjectPath(pathOrRemoteUrl);
2455
- const isUnderDir = (baseDir, candidatePath)=>{
2456
- const rel = external_path_.relative(baseDir, candidatePath);
2457
- return Boolean(rel && !rel.startsWith('..') && !external_path_.isAbsolute(rel));
2458
- };
2459
- const packageJsonPathFromProject = await findNearestPackageJson(external_path_.join(projectPath, 'manifest.json'));
2460
- const packageJsonDirFromProject = packageJsonPathFromProject ? external_path_.dirname(packageJsonPathFromProject) : void 0;
2461
- const rootManifestPath = external_path_.join(projectPath, 'manifest.json');
2462
- const srcManifestPath = external_path_.join(projectPath, 'src', 'manifest.json');
2463
- let manifestPath = external_fs_.existsSync(srcManifestPath) ? srcManifestPath : rootManifestPath;
2464
- if (!external_fs_.existsSync(manifestPath)) {
2465
- if (packageJsonDirFromProject) throw new Error(messages.dx(manifestPath));
2466
- const findManifest = (dir)=>{
2467
- const files = external_fs_.readdirSync(dir, {
2468
- withFileTypes: true
2469
- });
2470
- for (const file of files){
2471
- if (file.isFile() && 'manifest.json' === file.name) return external_path_.join(dir, file.name);
2472
- if (file.isDirectory() && !file.name.startsWith('.') && 'node_modules' !== file.name && 'dist' !== file.name && 'public' !== file.name) {
2473
- const found = findManifest(external_path_.join(dir, file.name));
2474
- if (found) return found;
2475
- }
3074
+ for (const ent of entries)if (ent.isDirectory()) {
3075
+ if (!ent.name.startsWith('.')) walk(path__rspack_import_1.join(current, ent.name), depth + 1);
2476
3076
  }
2477
- return null;
2478
- };
2479
- const foundManifest = findManifest(projectPath);
2480
- if (foundManifest) manifestPath = foundManifest;
2481
- else throw new Error(messages.dx(manifestPath));
2482
- }
2483
- const packageJsonPath = await findNearestPackageJson(manifestPath);
2484
- const packageJsonDir = packageJsonPath ? external_path_.dirname(packageJsonPath) : void 0;
2485
- if (packageJsonDir) {
2486
- const publicRoot = external_path_.join(packageJsonDir, 'public');
2487
- if (isUnderDir(publicRoot, manifestPath)) {
2488
- const fallbackSrc = external_path_.join(packageJsonDir, 'src', 'manifest.json');
2489
- const fallbackRoot = external_path_.join(packageJsonDir, 'manifest.json');
2490
- if (external_fs_.existsSync(fallbackSrc)) manifestPath = fallbackSrc;
2491
- else if (external_fs_.existsSync(fallbackRoot)) manifestPath = fallbackRoot;
2492
- else throw new Error(messages.dx(fallbackRoot));
2493
- }
2494
- }
2495
- if (!packageJsonPath || !validatePackageJson(packageJsonPath)) return {
2496
- manifestPath
2497
- };
2498
- return {
2499
- manifestPath,
2500
- packageJsonPath
2501
- };
2502
- }
2503
- var config_loader = __webpack_require__("./lib/config-loader.ts");
2504
- var package_0 = __webpack_require__("./package.json");
2505
- function assertNoManagedDependencyConflicts(userPackageJsonPath, projectPath) {
2506
- try {
2507
- const raw = external_fs_.readFileSync(userPackageJsonPath, 'utf-8');
2508
- const userPackageJson = JSON.parse(raw);
2509
- const userDeps = Array.from(new Set([
2510
- ...Object.keys(userPackageJson.dependencies || {}),
2511
- ...Object.keys(userPackageJson.devDependencies || {}),
2512
- ...Object.keys(userPackageJson.optionalDependencies || {}),
2513
- ...Object.keys(userPackageJson.peerDependencies || {})
2514
- ]));
2515
- const managedDeps = new Set([
2516
- ...Object.keys(package_0.El || {}),
2517
- ...Object.keys(package_0.optionalDependencies || {})
2518
- ]);
2519
- managedDeps.delete('webpack');
2520
- const userConfigJs = external_path_.join(projectPath, 'extension.config.js');
2521
- const userConfigMjs = external_path_.join(projectPath, 'extension.config.mjs');
2522
- const hasConfig = external_fs_.existsSync(userConfigJs) || external_fs_.existsSync(userConfigMjs);
2523
- if (!hasConfig) return;
2524
- const configPath = external_fs_.existsSync(userConfigJs) ? userConfigJs : userConfigMjs;
2525
- const configSource = external_fs_.readFileSync(configPath, 'utf-8');
2526
- const duplicates = userDeps.filter((d)=>managedDeps.has(d)).filter((d)=>configSource.includes(d)).sort();
2527
- if (duplicates.length > 0) {
2528
- console.error(messages.H3(duplicates, userPackageJsonPath));
2529
- process.exit(1);
2530
3077
  }
2531
- } catch (error) {
2532
- if ('true' === process.env.EXTENSION_AUTHOR_MODE) console.warn(error);
2533
- }
2534
- }
2535
- var paths = __webpack_require__("./lib/paths.ts");
2536
- var develop_context = __webpack_require__("./lib/develop-context.ts");
2537
- const external_child_process_namespaceObject = require("child_process");
2538
- const package_manager_require = (0, external_module_.createRequire)(__rslib_import_meta_url__);
2539
- function normalizePackageManager(value) {
2540
- if (!value) return;
2541
- const lower = value.toLowerCase().trim();
2542
- if ('pnpm' === lower) return 'pnpm';
2543
- if ('yarn' === lower) return 'yarn';
2544
- if ('bun' === lower) return 'bun';
2545
- if ('npm' === lower) return 'npm';
2546
- }
2547
- function inferPackageManagerFromPath(value) {
2548
- if (!value) return;
2549
- const lower = value.toLowerCase();
2550
- if (lower.includes('pnpm')) return 'pnpm';
2551
- if (lower.includes('yarn')) return 'yarn';
2552
- if (lower.includes('bun')) return 'bun';
2553
- if (lower.includes('npm')) return 'npm';
2554
- }
2555
- function getPackageManagerOverride() {
2556
- const name = normalizePackageManager(process.env.EXTENSION_JS_PACKAGE_MANAGER);
2557
- const execPath = process.env.EXTENSION_JS_PM_EXEC_PATH || process.env.npm_execpath || process.env.NPM_EXEC_PATH;
2558
- if (!name && !execPath) return;
2559
- const inferredName = name || inferPackageManagerFromPath(execPath) || 'npm';
2560
- return {
2561
- name: inferredName,
2562
- execPath
2563
- };
2564
- }
2565
- function detectPackageManagerFromEnv() {
2566
- const userAgent = process.env.npm_config_user_agent || '';
2567
- const execPath = process.env.npm_execpath || process.env.NPM_EXEC_PATH || '';
2568
- if (userAgent.includes('pnpm')) return {
2569
- name: 'pnpm',
2570
- execPath: execPath || void 0
2571
- };
2572
- if (userAgent.includes('yarn')) return {
2573
- name: 'yarn',
2574
- execPath: execPath || void 0
2575
- };
2576
- if (userAgent.includes('bun')) return {
2577
- name: 'bun',
2578
- execPath: execPath || void 0
2579
- };
2580
- if (userAgent.includes('npm')) return {
2581
- name: 'npm',
2582
- execPath: execPath || void 0
2583
- };
2584
- if (execPath) {
2585
- const inferred = inferPackageManagerFromPath(execPath) || 'npm';
2586
- return {
2587
- name: inferred,
2588
- execPath
2589
- };
3078
+ walk(dir, 0);
3079
+ return found;
2590
3080
  }
2591
- }
2592
- function resolveNpmCliFromNode(execPath) {
2593
- const execDir = external_path_.dirname(execPath);
2594
- const candidates = [
2595
- external_path_.join(execDir, 'node_modules', 'npm', 'bin', 'npm-cli.js'),
2596
- external_path_.join(execDir, '..', 'lib', 'node_modules', 'npm', 'bin', 'npm-cli.js'),
2597
- external_path_.join(execDir, '..', 'node_modules', 'npm', 'bin', 'npm-cli.js')
2598
- ];
2599
- for (const candidate of candidates)if (external_fs_.existsSync(candidate)) return candidate;
2600
- }
2601
- function resolveBundledNpmCliPath() {
2602
- if (process.env.EXTENSION_JS_PM_EXEC_PATH) {
2603
- const overridePath = process.env.EXTENSION_JS_PM_EXEC_PATH;
2604
- if (overridePath && external_fs_.existsSync(overridePath)) return overridePath;
2605
- }
2606
- try {
2607
- const resolved = package_manager_require.resolve('npm/bin/npm-cli.js', {
2608
- paths: [
2609
- process.cwd(),
2610
- __dirname
2611
- ]
2612
- });
2613
- if (resolved && external_fs_.existsSync(resolved)) return resolved;
2614
- } catch {}
2615
- return resolveNpmCliFromNode(process.execPath);
2616
- }
2617
- function isWindowsExecutablePath(value) {
2618
- if (!value || 'win32' !== process.platform) return false;
2619
- return /\.(cmd|bat|exe)$/i.test(value);
2620
- }
2621
- function isNodeScriptPath(value) {
2622
- if (!value) return false;
2623
- return /\.(mjs|cjs|js)$/i.test(value);
2624
- }
2625
- function resolveWindowsCommandPath(command) {
2626
- if ('win32' !== process.platform) return;
2627
- try {
2628
- const systemRoot = process.env.SystemRoot || 'C:\\Windows';
2629
- const whereExe = external_path_.join(systemRoot, 'System32', 'where.exe');
2630
- const whereCommand = external_fs_.existsSync(whereExe) ? whereExe : 'where';
2631
- const output = (0, external_child_process_namespaceObject.execFileSync)(whereCommand, [
2632
- command
2633
- ], {
2634
- encoding: 'utf8',
2635
- stdio: [
2636
- 'ignore',
2637
- 'pipe',
2638
- 'ignore'
2639
- ],
2640
- windowsHide: true
3081
+ async function runExtensionFromStore(url, outDir) {
3082
+ const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
3083
+ await (0, extension_from_store__rspack_import_2.fetchExtensionFromStore)(url, {
3084
+ outDir,
3085
+ extract: true,
3086
+ logger: isAuthor ? {
3087
+ onInfo: (message)=>console.log(message),
3088
+ onWarn: (message)=>console.warn(message),
3089
+ onError: (message, error)=>console.error(message, error)
3090
+ } : void 0
2641
3091
  });
2642
- const candidates = String(output).split(/\r?\n/).map((line)=>line.trim()).filter(Boolean);
2643
- const cmdMatch = candidates.find((line)=>/\.cmd$/i.test(line));
2644
- return cmdMatch || candidates[0];
2645
- } catch {
2646
- return;
2647
3092
  }
2648
- }
2649
- function resolveUnixCommandPath(command) {
2650
- if ('win32' === process.platform) return;
2651
- try {
2652
- const output = (0, external_child_process_namespaceObject.execFileSync)('which', [
2653
- command
2654
- ], {
2655
- encoding: 'utf8',
2656
- stdio: [
2657
- 'ignore',
2658
- 'pipe',
2659
- 'ignore'
2660
- ]
3093
+ async function resolveStoreExtensionToPath(opts) {
3094
+ const { projectRoot, storeUrl, browser, id } = opts;
3095
+ const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
3096
+ const targetRoot = path__rspack_import_1.join(extensionsRoot, browser, id);
3097
+ const manifestPath = path__rspack_import_1.join(targetRoot, 'manifest.json');
3098
+ if ((0, _utils__rspack_import_3.fo)(manifestPath)) return targetRoot;
3099
+ await runExtensionFromStore(storeUrl, path__rspack_import_1.join(extensionsRoot, browser));
3100
+ const candidates = findExtensionRoots(path__rspack_import_1.join(extensionsRoot, browser));
3101
+ let selected;
3102
+ if (1 === candidates.length) selected = candidates[0];
3103
+ else if (candidates.length > 1) {
3104
+ const directMatch = candidates.find((c)=>path__rspack_import_1.basename(c) === id);
3105
+ const versionedMatch = candidates.find((c)=>path__rspack_import_1.basename(c).startsWith(`${id}@`));
3106
+ if (directMatch) selected = directMatch;
3107
+ else if (versionedMatch) selected = versionedMatch;
3108
+ }
3109
+ if (!selected) throw new Error(`Could not locate an unpacked extension from ${storeUrl}.`);
3110
+ fs__rspack_import_0.mkdirSync(path__rspack_import_1.dirname(targetRoot), {
3111
+ recursive: true
2661
3112
  });
2662
- const candidate = String(output).trim();
2663
- return candidate || void 0;
2664
- } catch {
2665
- return;
3113
+ if (path__rspack_import_1.basename(selected).startsWith(`${id}@`)) fs__rspack_import_0.renameSync(selected, targetRoot);
3114
+ return targetRoot;
2666
3115
  }
2667
- }
2668
- function resolveCommandOnPath(command) {
2669
- return resolveWindowsCommandPath(command) || resolveUnixCommandPath(command) || void 0;
2670
- }
2671
- function canRunCorepack() {
2672
- try {
2673
- const fallback = package_manager_require('child_process');
2674
- const spawnSync = external_child_process_namespaceObject.spawnSync?.mock !== void 0 ? external_child_process_namespaceObject.spawnSync : fallback.spawnSync || external_child_process_namespaceObject.spawnSync;
2675
- const result = spawnSync('corepack', [
2676
- '--version'
2677
- ], {
2678
- stdio: 'ignore',
2679
- windowsHide: true
2680
- });
2681
- return result?.status === 0;
2682
- } catch {
2683
- return false;
3116
+ async function resolveCompanionExtensionsConfig(opts) {
3117
+ const { projectRoot, browser, config } = opts;
3118
+ if (!config) return;
3119
+ const normalized = (0, _utils__rspack_import_3.cz)(config);
3120
+ const runtimeBrowser = getBrowserFolder(browser);
3121
+ const resolvedPaths = [];
3122
+ const localPaths = [];
3123
+ for (const entry of normalized.paths){
3124
+ const parsedStore = parseStoreUrl(entry);
3125
+ if (parsedStore) {
3126
+ if (parsedStore.browser !== runtimeBrowser) continue;
3127
+ const resolvedPath = await resolveStoreExtensionToPath({
3128
+ projectRoot,
3129
+ storeUrl: entry,
3130
+ browser: parsedStore.browser,
3131
+ id: parsedStore.id
3132
+ });
3133
+ resolvedPaths.push(resolvedPath);
3134
+ continue;
3135
+ }
3136
+ if (isPathLike(entry)) localPaths.push(entry);
3137
+ }
3138
+ if (localPaths.length > 0) {
3139
+ const absLocalPaths = ensurePathsUnderExtensions(projectRoot, localPaths);
3140
+ resolvedPaths.push(...absLocalPaths);
3141
+ }
3142
+ const output = {};
3143
+ if ('string' == typeof normalized.dir) {
3144
+ const absDir = (0, _utils__rspack_import_3.A$)(projectRoot, normalized.dir);
3145
+ const extensionsRoot = path__rspack_import_1.resolve(projectRoot, 'extensions');
3146
+ if (absDir !== extensionsRoot && !isSubpathOf(extensionsRoot, absDir)) throw new Error(`extensions.dir must be inside ${extensionsRoot}.\nInvalid dir: ${absDir}`);
3147
+ output.dir = normalized.dir;
3148
+ }
3149
+ if (resolvedPaths.length > 0) output.paths = resolvedPaths;
3150
+ return output;
2684
3151
  }
2685
- }
2686
- function detectByLockfile(cwd) {
2687
- if (!cwd) return;
2688
- const hasPnpmLock = external_fs_.existsSync(external_path_.join(cwd, 'pnpm-lock.yaml'));
2689
- const hasYarnLock = external_fs_.existsSync(external_path_.join(cwd, 'yarn.lock'));
2690
- const hasNpmLock = external_fs_.existsSync(external_path_.join(cwd, 'package-lock.json'));
2691
- if (hasPnpmLock) return 'pnpm';
2692
- if (hasYarnLock) return 'yarn';
2693
- if (hasNpmLock) return 'npm';
2694
- }
2695
- function hydrateResolvedPackageManager(name) {
2696
- const resolvedCommand = resolveCommandOnPath(name);
2697
- if (resolvedCommand) return {
2698
- name,
2699
- execPath: resolvedCommand
2700
- };
2701
- if ('npm' === name) {
2702
- const bundledNpmCli = resolveBundledNpmCliPath();
2703
- if (bundledNpmCli) return {
2704
- name: 'npm',
2705
- execPath: bundledNpmCli,
2706
- runnerCommand: process.execPath,
2707
- runnerArgs: [
2708
- bundledNpmCli
2709
- ]
2710
- };
3152
+ },
3153
+ "./plugin-special-folders/folder-extensions/utils.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
3154
+ __webpack_require__.d(__webpack_exports__, {
3155
+ A$: ()=>toAbs,
3156
+ Q7: ()=>isDir,
3157
+ Uy: ()=>isValidExtensionRoot,
3158
+ cz: ()=>normalizeCompanionConfig,
3159
+ fo: ()=>isFile
3160
+ });
3161
+ var fs__rspack_import_0 = __webpack_require__("fs");
3162
+ var path__rspack_import_1 = __webpack_require__("path");
3163
+ function isDir(p) {
3164
+ try {
3165
+ return fs__rspack_import_0.existsSync(p) && fs__rspack_import_0.statSync(p).isDirectory();
3166
+ } catch {
3167
+ return false;
3168
+ }
2711
3169
  }
2712
- }
2713
- function resolvePackageManager(opts) {
2714
- const lockPm = detectByLockfile(opts?.cwd);
2715
- if (lockPm) {
2716
- const hydrated = hydrateResolvedPackageManager(lockPm);
2717
- if (hydrated) return hydrated;
2718
- return {
2719
- name: lockPm
2720
- };
3170
+ function isFile(p) {
3171
+ try {
3172
+ return fs__rspack_import_0.existsSync(p) && fs__rspack_import_0.statSync(p).isFile();
3173
+ } catch {
3174
+ return false;
3175
+ }
2721
3176
  }
2722
- const override = getPackageManagerOverride();
2723
- if (override) return override;
2724
- const envPm = detectPackageManagerFromEnv();
2725
- if (envPm) return envPm;
2726
- const candidates = [
2727
- 'pnpm',
2728
- 'yarn',
2729
- 'bun'
2730
- ];
2731
- for (const candidate of candidates){
2732
- const resolved = resolveCommandOnPath(candidate);
2733
- if (resolved) return {
2734
- name: candidate,
2735
- execPath: resolved
2736
- };
3177
+ function toAbs(projectRoot, p) {
3178
+ return path__rspack_import_1.isAbsolute(p) ? p : path__rspack_import_1.resolve(projectRoot, p);
2737
3179
  }
2738
- const corepackPath = resolveCommandOnPath('corepack');
2739
- if (corepackPath || canRunCorepack()) return {
2740
- name: 'pnpm',
2741
- runnerCommand: corepackPath || 'corepack',
2742
- runnerArgs: [
2743
- 'pnpm'
2744
- ]
2745
- };
2746
- const bundledNpmCli = resolveBundledNpmCliPath();
2747
- if (bundledNpmCli) return {
2748
- name: 'npm',
2749
- execPath: bundledNpmCli,
2750
- runnerCommand: process.execPath,
2751
- runnerArgs: [
2752
- bundledNpmCli
2753
- ]
2754
- };
2755
- return {
2756
- name: 'npm'
2757
- };
2758
- }
2759
- function buildExecEnv() {
2760
- if ('win32' !== process.platform) return;
2761
- const nodeDir = external_path_.dirname(process.execPath);
2762
- const pathSep = external_path_.delimiter;
2763
- const existing = process.env.PATH || process.env.Path || '';
2764
- if (existing.includes(nodeDir)) return;
2765
- return {
2766
- ...process.env,
2767
- PATH: `${nodeDir}${pathSep}${existing}`.trim(),
2768
- Path: `${nodeDir}${pathSep}${existing}`.trim()
2769
- };
2770
- }
2771
- function buildInstallCommand(pm, args) {
2772
- if (pm.runnerCommand) return {
2773
- command: pm.runnerCommand,
2774
- args: [
2775
- ...pm.runnerArgs || [],
2776
- ...args
2777
- ]
2778
- };
2779
- if (pm.execPath) {
2780
- if (isWindowsExecutablePath(pm.execPath)) return {
2781
- command: pm.execPath,
2782
- args
2783
- };
2784
- if (isNodeScriptPath(pm.execPath)) return {
2785
- command: process.execPath,
2786
- args: [
2787
- pm.execPath,
2788
- ...args
2789
- ]
2790
- };
2791
- return {
2792
- command: pm.execPath,
2793
- args
2794
- };
3180
+ function isValidExtensionRoot(dir) {
3181
+ if (!isDir(dir)) return false;
3182
+ return isFile(path__rspack_import_1.join(dir, 'manifest.json'));
2795
3183
  }
2796
- return {
2797
- command: pm.name,
2798
- args
2799
- };
2800
- }
2801
- function buildSpawnInvocation(command, args) {
2802
- return {
2803
- command,
2804
- args
2805
- };
2806
- }
2807
- function execInstallCommand(command, args, options) {
2808
- const invocation = buildSpawnInvocation(command, args);
2809
- const env = buildExecEnv();
2810
- const stdio = options?.stdio ?? 'ignore';
2811
- const useShell = 'win32' === process.platform && /\.(cmd|bat)$/i.test(invocation.command);
2812
- return new Promise((resolve, reject)=>{
2813
- const child = (0, external_child_process_namespaceObject.spawn)(invocation.command, invocation.args, {
2814
- cwd: options?.cwd,
2815
- stdio,
2816
- env: env || process.env,
2817
- ...useShell ? {
2818
- shell: true
2819
- } : {}
2820
- });
2821
- child.on('close', (code)=>{
2822
- if (0 !== code) reject(new Error(`Install failed with exit code ${code}`));
2823
- else resolve();
2824
- });
2825
- child.on('error', (error)=>reject(error));
2826
- });
2827
- }
2828
- async function ensureUserProjectDependencies(packageJsonDir) {
2829
- if (!(0, paths.Bi)(packageJsonDir)) return;
2830
- const pm = resolvePackageManager({
2831
- cwd: packageJsonDir
2832
- });
2833
- const cmd = buildInstallCommand(pm, [
2834
- 'install'
2835
- ]);
2836
- await execInstallCommand(cmd.command, cmd.args, {
2837
- cwd: packageJsonDir,
2838
- stdio: 'inherit'
2839
- });
2840
- }
2841
- async function ensureDevelopArtifacts() {
2842
- const developRoot = (0, develop_context.w1)();
2843
- if (!developRoot) return;
2844
- const requiredFiles = [
2845
- external_path_.join(developRoot, 'dist', "ensure-hmr-for-scripts.js"),
2846
- external_path_.join(developRoot, 'dist', "minimum-script-file.js")
2847
- ];
2848
- const missing = requiredFiles.filter((file)=>!external_fs_.existsSync(file));
2849
- if (0 === missing.length) return;
2850
- const pm = resolvePackageManager({
2851
- cwd: developRoot
2852
- });
2853
- const command = buildInstallCommand(pm, [
2854
- 'run',
2855
- 'compile'
2856
- ]);
2857
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2858
- const stdio = isAuthor ? 'inherit' : 'ignore';
2859
- if (isAuthor) console.warn(messages.TL('extension-develop build artifacts (dist missing)'));
2860
- await execInstallCommand(command.command, command.args, {
2861
- cwd: developRoot,
2862
- stdio
2863
- });
2864
- }
2865
- var resolve_config = __webpack_require__("./plugin-special-folders/folder-extensions/resolve-config.ts");
2866
- var get_data = __webpack_require__("./plugin-special-folders/get-data.ts");
2867
- async function extensionBuild(pathOrRemoteUrl, buildOptions) {
2868
- const require1 = (0, external_module_.createRequire)(__rslib_import_meta_url__);
2869
- const projectStructure = await getProjectStructure(pathOrRemoteUrl);
2870
- const isVitest = 'true' === process.env.VITEST;
2871
- const shouldExitOnError = (buildOptions?.exitOnError ?? true) && !isVitest;
2872
- const browser = (0, paths.YN)(buildOptions?.browser || 'chrome', buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary);
2873
- const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
2874
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2875
- try {
2876
- await ensureDevelopArtifacts();
2877
- if (buildOptions?.install !== false) await ensureUserProjectDependencies(packageJsonDir);
2878
- const [{ rspack }, { merge }, { handleStatsErrors }, { default: webpackConfig }] = await Promise.all([
2879
- Promise.resolve(require1('@rspack/core')),
2880
- import("webpack-merge"),
2881
- __webpack_require__.e("750").then(__webpack_require__.bind(__webpack_require__, "./lib/stats-handler.ts")),
2882
- __webpack_require__.e("740").then(__webpack_require__.bind(__webpack_require__, "./rspack-config.ts"))
2883
- ]);
2884
- const debug = isAuthor;
2885
- if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
2886
- const commandConfig = await (0, config_loader.eY)(packageJsonDir, 'build');
2887
- const specialFoldersData = (0, get_data.H)(packageJsonDir);
2888
- const distPath = (0, paths.q4)(packageJsonDir, browser);
2889
- if (debug) {
2890
- console.log(messages.SG(manifestDir, packageJsonDir));
2891
- console.log(messages._A(browser, buildOptions?.chromiumBinary, buildOptions?.geckoBinary || buildOptions?.firefoxBinary));
2892
- console.log(messages.AC(distPath));
3184
+ function normalizeCompanionConfig(config) {
3185
+ const explicitPaths = [];
3186
+ let scanDir;
3187
+ if (Array.isArray(config)) explicitPaths.push(...config.filter((p)=>'string' == typeof p));
3188
+ else if (config && 'object' == typeof config) {
3189
+ if (Array.isArray(config.paths)) explicitPaths.push(...config.paths.filter((p)=>'string' == typeof p));
3190
+ if ('string' == typeof config.dir && config.dir.trim().length > 0) scanDir = config.dir.trim();
2893
3191
  }
2894
- const mergedExtensionsConfig = buildOptions?.extensions ?? commandConfig.extensions ?? specialFoldersData.extensions;
2895
- const resolvedExtensionsConfig = await (0, resolve_config.R)({
2896
- projectRoot: packageJsonDir,
2897
- browser,
2898
- config: mergedExtensionsConfig
2899
- });
2900
- const baseConfig = webpackConfig(projectStructure, {
2901
- ...commandConfig,
2902
- ...buildOptions,
2903
- extensions: resolvedExtensionsConfig,
2904
- browser,
2905
- mode: 'production',
2906
- output: {
2907
- clean: true,
2908
- path: distPath
2909
- }
2910
- });
2911
- const allPluginsButBrowserRunners = baseConfig.plugins?.filter((plugin)=>plugin?.constructor.name !== 'plugin-browsers');
2912
- const userExtensionConfig = await (0, config_loader.cR)(packageJsonDir);
2913
- const userConfig = userExtensionConfig({
2914
- ...baseConfig,
2915
- plugins: allPluginsButBrowserRunners
2916
- });
2917
- const compilerConfig = merge(userConfig);
2918
- compilerConfig.stats = false;
2919
- const compiler = rspack(compilerConfig);
2920
- let summary = {
2921
- browser,
2922
- total_assets: 0,
2923
- total_bytes: 0,
2924
- largest_asset_bytes: 0,
2925
- warnings_count: 0,
2926
- errors_count: 0
3192
+ return {
3193
+ dir: scanDir,
3194
+ paths: explicitPaths
2927
3195
  };
2928
- await new Promise((resolve, reject)=>{
2929
- compiler.run(async (err, stats)=>{
2930
- if (err) {
2931
- console.error(err.stack || err);
2932
- return reject(err);
2933
- }
2934
- if (!stats || 'function' != typeof stats.hasErrors) return reject(new Error('Build failed: bundler returned invalid stats output (no reliable compilation result).'));
2935
- if (!buildOptions?.silent && stats) console.log(messages.I(manifestDir, stats, browser));
2936
- if (stats.hasErrors()) {
2937
- handleStatsErrors(stats);
2938
- if (!shouldExitOnError) return reject(new Error('Build failed with errors'));
2939
- process.exit(1);
2940
- } else {
2941
- const info = stats?.toJson({
2942
- all: false,
2943
- assets: true,
2944
- warnings: true,
2945
- errors: true
2946
- });
2947
- summary = getBuildSummary(browser, info);
2948
- if (summary.warnings_count > 0) {
2949
- console.log(messages.fm(summary.warnings_count));
2950
- const warningDetails = messages.wh(info?.warnings || []);
2951
- if (warningDetails) console.log(`\n${warningDetails}`);
2952
- } else console.log(messages.Cf());
2953
- resolve();
2954
- }
2955
- });
2956
- });
2957
- return summary;
2958
- } catch (error) {
2959
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
2960
- if (isAuthor) console.error(error);
2961
- else console.error(messages.$3(error));
2962
- if (!shouldExitOnError) throw error;
2963
- process.exit(1);
2964
3196
  }
2965
- }
2966
- const promises_namespaceObject = require("fs/promises");
2967
- async function generateExtensionTypes(manifestDir, packageJsonDir) {
2968
- const extensionEnvFile = external_path_.join(packageJsonDir, 'extension-env.d.ts');
2969
- const typePath = 'extension';
2970
- const fileContent = `\
2971
- // Required Extension.js types for TypeScript projects.
2972
- // This file is auto-generated and should not be excluded.
2973
- // If you need additional types, consider creating a new *.d.ts file and
2974
- // referencing it in the "include" array of your tsconfig.json file.
2975
- // See https://www.typescriptlang.org/tsconfig#include for more information.
2976
- /// <reference types="${typePath}/types" />
2977
-
2978
- // Polyfill types for browser.* APIs
2979
- /// <reference types="${typePath}/types/polyfill" />
2980
- `;
2981
- try {
2982
- await promises_namespaceObject.access(extensionEnvFile);
2983
- const existingContent = await promises_namespaceObject.readFile(extensionEnvFile, 'utf8');
2984
- if (existingContent.includes('develop/dist/types')) await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2985
- await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2986
- } catch (err) {
2987
- const manifest = require(external_path_.join(manifestDir, 'manifest.json'));
2988
- console.log(messages.ng(manifest));
2989
- try {
2990
- await promises_namespaceObject.writeFile(extensionEnvFile, fileContent);
2991
- } catch (writeErr) {
2992
- console.log(messages.v_(writeErr));
2993
- }
3197
+ },
3198
+ "./plugin-special-folders/get-data.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
3199
+ __webpack_require__.d(__webpack_exports__, {
3200
+ B: ()=>getSpecialFoldersDataForCompiler,
3201
+ H: ()=>getSpecialFoldersDataForProjectRoot
3202
+ });
3203
+ var path__rspack_import_0 = __webpack_require__("path");
3204
+ var path__rspack_import_0_default = /*#__PURE__*/ __webpack_require__.n(path__rspack_import_0);
3205
+ var browser_extension_manifest_fields__rspack_import_1 = __webpack_require__("browser-extension-manifest-fields");
3206
+ function isUnderPublicDir(entry, projectRoot, publicDir) {
3207
+ if (!entry) return false;
3208
+ const normalizedEntry = String(entry);
3209
+ const candidate = path__rspack_import_0_default().isAbsolute(normalizedEntry) ? normalizedEntry : path__rspack_import_0_default().join(projectRoot, normalizedEntry);
3210
+ const rel = path__rspack_import_0_default().relative(publicDir, candidate);
3211
+ return Boolean(rel && !rel.startsWith('..') && !path__rspack_import_0_default().isAbsolute(rel));
2994
3212
  }
2995
- }
2996
- var sanitize = __webpack_require__("./lib/sanitize.ts");
2997
- const external_node_events_namespaceObject = require("node:events");
2998
- var contracts = __webpack_require__("./plugin-web-extension/feature-scripts/contracts.ts");
2999
- function _define_property(obj, key, value) {
3000
- if (key in obj) Object.defineProperty(obj, key, {
3001
- value: value,
3002
- enumerable: true,
3003
- configurable: true,
3004
- writable: true
3005
- });
3006
- else obj[key] = value;
3007
- return obj;
3008
- }
3009
- class BuildEmitter extends external_node_events_namespaceObject.EventEmitter {
3010
- }
3011
- class BrowsersPlugin {
3012
- apply(compiler) {
3013
- let pendingReloadReason;
3014
- let pendingChangedSources = [];
3015
- compiler.hooks.watchRun.tap(BrowsersPlugin.name, ()=>{
3016
- pendingReloadReason = void 0;
3017
- pendingChangedSources = [];
3018
- const modifiedFiles = compiler.modifiedFiles;
3019
- if (!modifiedFiles || 0 === modifiedFiles.size) return;
3020
- const contextDir = compiler.options.context || '';
3021
- for (const file of modifiedFiles){
3022
- const normalized = external_path_.relative(contextDir, file).replace(/\\/g, '/');
3023
- pendingChangedSources.push(normalized);
3024
- if (normalized.includes('manifest.json')) pendingReloadReason = 'full';
3025
- else if (normalized.includes('_locales/')) pendingReloadReason = 'full';
3026
- }
3027
- });
3028
- compiler.hooks.done.tapPromise(BrowsersPlugin.name, async (stats)=>{
3029
- const compilation = stats.compilation;
3030
- const hasErrors = compilation.errors && compilation.errors.length > 0;
3031
- if (hasErrors) return void this.emitter.emit('error', {
3032
- errors: compilation.errors.map((e)=>'string' == typeof e ? e : e.message || String(e))
3033
- });
3034
- const outputPath = String(compilation.options?.output?.path || '');
3035
- const contextDir = String(compilation.options?.context || '');
3036
- let reloadInstruction;
3037
- if (!this.isFirstCompile && pendingReloadReason) reloadInstruction = {
3038
- type: pendingReloadReason
3039
- };
3040
- else if (!this.isFirstCompile && pendingChangedSources.length > 0) {
3041
- const isServiceWorkerSource = (rel)=>/(^|\/)background(\.|\/)/i.test(rel) || /service[-_.]?worker/i.test(rel);
3042
- const hasServiceWorkerChange = pendingChangedSources.some(isServiceWorkerSource);
3043
- if (hasServiceWorkerChange) reloadInstruction = {
3044
- type: 'service-worker',
3045
- changedAssets: pendingChangedSources
3046
- };
3047
- else {
3048
- const contentScriptCount = readContentScriptCount(compilation, outputPath);
3049
- if (contentScriptCount > 0) {
3050
- const entries = [];
3051
- for(let i = 0; i < contentScriptCount; i++)entries.push((0, contracts.Y0)(i));
3052
- reloadInstruction = {
3053
- type: "content-scripts",
3054
- changedContentScriptEntries: entries,
3055
- changedAssets: pendingChangedSources
3056
- };
3057
- }
3058
- }
3213
+ function filterPublicEntrypoints(list, projectRoot, publicDir) {
3214
+ const next = {};
3215
+ for (const [key, value] of Object.entries(list || {})){
3216
+ if (Array.isArray(value)) {
3217
+ const filtered = value.filter((entry)=>!isUnderPublicDir(String(entry), projectRoot, publicDir));
3218
+ if (filtered.length > 0) next[key] = filtered;
3219
+ continue;
3059
3220
  }
3060
- const wasFirstCompile = this.isFirstCompile;
3061
- this.isFirstCompile = false;
3062
- if (wasFirstCompile) try {
3063
- this.controller = await this.options.launcher({
3064
- ...this.options.browserOptions,
3065
- outputPath,
3066
- contextDir,
3067
- extensionsToLoad: this.extensionsToLoad
3068
- });
3069
- const logLevel = this.options.browserOptions.logLevel || 'off';
3070
- if ('off' !== logLevel && this.controller) await this.controller.enableUnifiedLogging({
3071
- level: logLevel,
3072
- contexts: this.options.browserOptions.logContexts,
3073
- format: this.options.browserOptions.logFormat,
3074
- timestamps: this.options.browserOptions.logTimestamps,
3075
- color: this.options.browserOptions.logColor,
3076
- urlFilter: this.options.browserOptions.logUrl,
3077
- tabFilter: this.options.browserOptions.logTab
3078
- });
3079
- } catch (error) {
3080
- this.emitter.emit('error', {
3081
- errors: [
3082
- error instanceof Error ? error.message : String(error)
3083
- ]
3084
- });
3221
+ if ('string' == typeof value) {
3222
+ if (!isUnderPublicDir(value, projectRoot, publicDir)) next[key] = value;
3223
+ continue;
3085
3224
  }
3086
- else if (this.controller && reloadInstruction) try {
3087
- await this.controller.reload(reloadInstruction);
3088
- } catch {}
3089
- this.emitter.emit('compiled', {
3090
- outputPath,
3091
- contextDir,
3092
- isFirstCompile: wasFirstCompile,
3093
- reloadInstruction,
3094
- extensionsToLoad: wasFirstCompile ? this.extensionsToLoad : void 0
3095
- });
3096
- });
3225
+ }
3226
+ return next;
3097
3227
  }
3098
- constructor(options){
3099
- _define_property(this, "options", void 0);
3100
- _define_property(this, "emitter", void 0);
3101
- _define_property(this, "extensionsToLoad", void 0);
3102
- _define_property(this, "isFirstCompile", void 0);
3103
- _define_property(this, "controller", void 0);
3104
- this.options = options;
3105
- this.emitter = new BuildEmitter();
3106
- this.extensionsToLoad = [];
3107
- this.isFirstCompile = true;
3228
+ function getSpecialFoldersDataForCompiler(compiler) {
3229
+ const projectRoot = compiler.options.context || '';
3230
+ const publicDir = path__rspack_import_0_default().join(projectRoot, 'public');
3231
+ const data = (0, browser_extension_manifest_fields__rspack_import_1.getSpecialFoldersData)({
3232
+ manifestPath: path__rspack_import_0_default().join(projectRoot, 'package.json')
3233
+ });
3234
+ return finalizeSpecialFoldersData(data, projectRoot, publicDir);
3108
3235
  }
3109
- }
3110
- _define_property(BrowsersPlugin, "name", 'plugin-browsers');
3111
- function readContentScriptCount(compilation, outputPath) {
3112
- try {
3113
- const asset = compilation.getAsset?.('manifest.json');
3114
- if (asset?.source) {
3115
- const manifest = JSON.parse(String(asset.source.source()));
3116
- const list = manifest?.content_scripts;
3117
- if (Array.isArray(list)) return list.length;
3118
- }
3119
- } catch {}
3120
- try {
3121
- const fs = __webpack_require__("fs");
3122
- const manifestPath = external_path_.join(outputPath, 'manifest.json');
3123
- if (fs.existsSync(manifestPath)) {
3124
- const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
3125
- const list = manifest?.content_scripts;
3126
- if (Array.isArray(list)) return list.length;
3127
- }
3128
- } catch {}
3129
- return 0;
3130
- }
3131
- var typescript = __webpack_require__("./plugin-js-frameworks/js-tools/typescript.ts");
3132
- async function extensionDev(pathOrRemoteUrl, devOptions) {
3133
- let browsersPlugin;
3134
- let emitter = new BuildEmitter();
3135
- const projectStructure = await getProjectStructure(pathOrRemoteUrl);
3136
- try {
3137
- const isAuthor = 'true' === process.env.EXTENSION_AUTHOR_MODE;
3138
- const debug = isAuthor;
3139
- const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
3140
- await ensureDevelopArtifacts();
3141
- if (false !== devOptions.install) await ensureUserProjectDependencies(packageJsonDir);
3142
- if ((0, typescript.eE)(manifestDir)) await generateExtensionTypes(manifestDir, packageJsonDir);
3143
- if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, manifestDir);
3144
- const browser = (0, paths.YN)(devOptions.browser || 'chrome', devOptions.chromiumBinary, devOptions.geckoBinary || devOptions.firefoxBinary);
3145
- const geckoBinary = devOptions.geckoBinary || devOptions.firefoxBinary;
3146
- if (debug) {
3147
- console.log(messages.SG(manifestDir, packageJsonDir));
3148
- console.log(messages._A(browser, devOptions.chromiumBinary, geckoBinary));
3149
- }
3150
- const browserConfig = await (0, config_loader.xY)(packageJsonDir, browser);
3151
- const commandConfig = await (0, config_loader.eY)(packageJsonDir, 'dev');
3152
- const merged = {
3153
- ...(0, sanitize.a)(browserConfig),
3154
- ...(0, sanitize.a)(commandConfig),
3155
- ...(0, sanitize.a)(devOptions)
3156
- };
3157
- if (devOptions.launcher && !devOptions.noBrowser) {
3158
- browsersPlugin = new BrowsersPlugin({
3159
- launcher: devOptions.launcher,
3160
- browserOptions: {
3161
- browser,
3162
- mode: 'development',
3163
- enableDevtools: true,
3164
- noOpen: merged.noOpen,
3165
- profile: merged.profile,
3166
- persistProfile: merged.persistProfile,
3167
- preferences: merged.preferences,
3168
- browserFlags: merged.browserFlags,
3169
- excludeBrowserFlags: merged.excludeBrowserFlags,
3170
- startingUrl: merged.startingUrl,
3171
- chromiumBinary: merged.chromiumBinary,
3172
- geckoBinary: merged.geckoBinary || merged.firefoxBinary,
3173
- port: merged.port,
3174
- source: merged.source,
3175
- watchSource: merged.watchSource,
3176
- sourceFormat: merged.sourceFormat,
3177
- sourceSummary: merged.sourceSummary,
3178
- sourceMeta: merged.sourceMeta,
3179
- sourceProbe: merged.sourceProbe,
3180
- sourceTree: merged.sourceTree,
3181
- sourceConsole: merged.sourceConsole,
3182
- sourceDom: merged.sourceDom,
3183
- sourceMaxBytes: merged.sourceMaxBytes,
3184
- sourceRedact: merged.sourceRedact,
3185
- sourceIncludeShadow: merged.sourceIncludeShadow,
3186
- sourceDiff: merged.sourceDiff,
3187
- logLevel: merged.logLevel,
3188
- logContexts: merged.logContexts,
3189
- logFormat: merged.logFormat,
3190
- logTimestamps: merged.logTimestamps,
3191
- logColor: merged.logColor,
3192
- logUrl: merged.logUrl,
3193
- logTab: merged.logTab
3194
- }
3195
- });
3196
- emitter = browsersPlugin.emitter;
3197
- }
3198
- if ('true' === process.env.EXTENSION_DEV_DRY_RUN) return emitter;
3199
- const { devServer } = await Promise.all([
3200
- __webpack_require__.e("740"),
3201
- __webpack_require__.e("481")
3202
- ]).then(__webpack_require__.bind(__webpack_require__, "./dev-server/index.ts"));
3203
- await devServer(projectStructure, {
3204
- ...devOptions,
3205
- mode: 'development',
3206
- browser,
3207
- geckoBinary,
3208
- browsersPlugin
3236
+ function getSpecialFoldersDataForProjectRoot(projectRoot) {
3237
+ const publicDir = path__rspack_import_0_default().join(projectRoot, 'public');
3238
+ const data = (0, browser_extension_manifest_fields__rspack_import_1.getSpecialFoldersData)({
3239
+ manifestPath: path__rspack_import_0_default().join(projectRoot, 'package.json')
3209
3240
  });
3210
- return emitter;
3211
- } catch (error) {
3212
- console.error(error);
3213
- process.exit(1);
3241
+ return finalizeSpecialFoldersData(data, projectRoot, publicDir);
3214
3242
  }
3215
- }
3216
- var plugin_playwright = __webpack_require__("./plugin-playwright/index.ts");
3217
- var utils = __webpack_require__("./plugin-special-folders/folder-extensions/utils.ts");
3218
- function resolveCompanionExtensionDirs(opts) {
3219
- const { projectRoot, config } = opts;
3220
- const normalized = (0, utils.cz)(config);
3221
- const explicitPaths = normalized.paths;
3222
- const scanDir = normalized.dir;
3223
- const found = [];
3224
- for (const p of explicitPaths){
3225
- const abs = (0, utils.A$)(projectRoot, p);
3226
- if ((0, utils.Uy)(abs)) found.push(abs);
3227
- }
3228
- if (scanDir) {
3229
- const absScan = (0, utils.A$)(projectRoot, scanDir);
3230
- if ((0, utils.Q7)(absScan)) {
3231
- let entries = [];
3232
- try {
3233
- entries = external_fs_.readdirSync(absScan, {
3234
- withFileTypes: true
3235
- });
3236
- } catch {
3237
- entries = [];
3238
- }
3239
- const scanOneLevel = (rootDir)=>{
3240
- let dirEntries = [];
3241
- try {
3242
- dirEntries = external_fs_.readdirSync(rootDir, {
3243
- withFileTypes: true
3244
- });
3245
- } catch {
3246
- dirEntries = [];
3247
- }
3248
- for (const ent of dirEntries){
3249
- if (!ent.isDirectory()) continue;
3250
- if (ent.name.startsWith('.')) continue;
3251
- const candidate = external_path_.join(rootDir, ent.name);
3252
- if ((0, utils.Uy)(candidate)) found.push(candidate);
3253
- }
3254
- };
3255
- scanOneLevel(absScan);
3256
- if ('extensions' === external_path_.basename(absScan)) for (const ent of entries){
3257
- if (!ent.isDirectory()) continue;
3258
- if (ent.name.startsWith('.')) continue;
3259
- const browserDir = external_path_.join(absScan, ent.name);
3260
- scanOneLevel(browserDir);
3243
+ function finalizeSpecialFoldersData(data, projectRoot, publicDir) {
3244
+ return {
3245
+ ...data,
3246
+ pages: filterPublicEntrypoints(data.pages, projectRoot, publicDir),
3247
+ scripts: filterPublicEntrypoints(data.scripts, projectRoot, publicDir),
3248
+ extensions: {
3249
+ dir: './extensions'
3261
3250
  }
3262
- }
3251
+ };
3252
+ }
3253
+ },
3254
+ "./plugin-web-extension/feature-scripts/contracts.ts" (__unused_rspack_module, __webpack_exports__, __webpack_require__) {
3255
+ __webpack_require__.d(__webpack_exports__, {
3256
+ $t: ()=>EXTENSIONJS_CONTENT_SCRIPT_LAYER,
3257
+ J4: ()=>getCanonicalContentScriptCssAssetName,
3258
+ Y0: ()=>getCanonicalContentScriptEntryName,
3259
+ es: ()=>parseCanonicalContentScriptAsset,
3260
+ f6: ()=>getCanonicalContentScriptJsAssetName
3261
+ });
3262
+ const EXTENSIONJS_CONTENT_SCRIPT_LAYER = "extensionjs-content-script";
3263
+ const CANONICAL_CONTENT_SCRIPT_ENTRY_PREFIX = "content_scripts/content-";
3264
+ function getCanonicalContentScriptEntryName(index) {
3265
+ return `${CANONICAL_CONTENT_SCRIPT_ENTRY_PREFIX}${index}`;
3263
3266
  }
3264
- const unique = [];
3265
- const seen = new Set();
3266
- for (const p of found)if (!seen.has(p)) {
3267
- seen.add(p);
3268
- unique.push(p);
3267
+ function getCanonicalContentScriptJsAssetName(index) {
3268
+ return `${getCanonicalContentScriptEntryName(index)}.js`;
3269
3269
  }
3270
- return unique;
3271
- }
3272
- var extensions_to_load = __webpack_require__("./lib/extensions-to-load.ts");
3273
- function getDarkModeDefaults(browser) {
3274
- if ('chrome' === browser || 'edge' === browser || 'chromium' === browser || 'chromium-based' === browser) return {
3275
- browserFlags: [
3276
- '--force-dark-mode',
3277
- '--enable-features=WebUIDarkMode'
3278
- ],
3279
- preferences: {}
3280
- };
3281
- if ('firefox' === browser || 'gecko-based' === browser || 'firefox-based' === browser) return {
3282
- browserFlags: [],
3283
- preferences: {
3284
- 'ui.systemUsesDarkTheme': 1,
3285
- 'layout.css.prefers-color-scheme.content-override': 2,
3286
- 'devtools.theme': 'dark'
3287
- }
3288
- };
3289
- return {
3290
- browserFlags: [],
3291
- preferences: {}
3292
- };
3293
- }
3294
- function withDarkMode(config) {
3295
- const defaults = getDarkModeDefaults(config.browser);
3296
- const existingFlags = Array.isArray(config.browserFlags) ? [
3297
- ...config.browserFlags
3298
- ] : [];
3299
- const nextFlags = [
3300
- ...existingFlags
3301
- ];
3302
- for (const flag of defaults.browserFlags || [])if (!nextFlags.some((f)=>String(f).trim() === flag)) nextFlags.push(flag);
3303
- const nextPreferences = {
3304
- ...config.preferences || {},
3305
- ...Object.fromEntries(Object.entries(defaults.preferences || {}).filter(([k])=>!(k in (config.preferences || {}))))
3306
- };
3307
- return {
3308
- ...config,
3309
- browserFlags: nextFlags,
3310
- preferences: nextPreferences
3311
- };
3270
+ function getCanonicalContentScriptCssAssetName(index) {
3271
+ return `${getCanonicalContentScriptEntryName(index)}.css`;
3272
+ }
3273
+ function parseCanonicalContentScriptAsset(assetName) {
3274
+ const match = /^content_scripts\/content-(\d+)(?:\.[a-f0-9]+)?\.(js|css)$/i.exec(String(assetName || ''));
3275
+ if (!match) return;
3276
+ const index = Number(match[1]);
3277
+ if (!Number.isInteger(index)) return;
3278
+ return {
3279
+ index,
3280
+ extension: match[2]
3281
+ };
3282
+ }
3283
+ },
3284
+ "@rspack/core" (module) {
3285
+ module.exports = require("@rspack/core");
3286
+ },
3287
+ "@rspack/dev-server" (module) {
3288
+ module.exports = require("@rspack/dev-server");
3289
+ },
3290
+ "adm-zip" (module) {
3291
+ module.exports = require("adm-zip");
3292
+ },
3293
+ "browser-extension-manifest-fields" (module) {
3294
+ module.exports = require("browser-extension-manifest-fields");
3295
+ },
3296
+ "case-sensitive-paths-webpack-plugin" (module) {
3297
+ module.exports = require("case-sensitive-paths-webpack-plugin");
3298
+ },
3299
+ "content-security-policy-parser" (module) {
3300
+ module.exports = require("content-security-policy-parser");
3301
+ },
3302
+ crypto (module) {
3303
+ module.exports = require("crypto");
3304
+ },
3305
+ dotenv (module) {
3306
+ module.exports = require("dotenv");
3307
+ },
3308
+ "extension-from-store" (module) {
3309
+ module.exports = require("extension-from-store");
3310
+ },
3311
+ fs (module) {
3312
+ module.exports = require("fs");
3313
+ },
3314
+ ignore (module) {
3315
+ module.exports = require("ignore");
3316
+ },
3317
+ module (module) {
3318
+ module.exports = require("module");
3319
+ },
3320
+ net (module) {
3321
+ module.exports = require("net");
3322
+ },
3323
+ os (module) {
3324
+ module.exports = require("os");
3325
+ },
3326
+ "parse5-utilities" (module) {
3327
+ module.exports = require("parse5-utilities");
3328
+ },
3329
+ path (module) {
3330
+ module.exports = require("path");
3331
+ },
3332
+ pintor (module) {
3333
+ module.exports = require("pintor");
3334
+ },
3335
+ stream (module) {
3336
+ module.exports = require("stream");
3337
+ },
3338
+ "tiny-glob" (module) {
3339
+ module.exports = require("tiny-glob");
3340
+ },
3341
+ url (module) {
3342
+ module.exports = require("url");
3343
+ },
3344
+ vm (module) {
3345
+ module.exports = require("vm");
3346
+ },
3347
+ "webpack-merge" (module) {
3348
+ module.exports = require("webpack-merge");
3349
+ },
3350
+ "./package.json" (module) {
3351
+ module.exports = JSON.parse('{"rE":"3.15.0-next.1","El":{"@prefresh/core":"1.5.9","@prefresh/utils":"1.2.1","@rspack/core":"^2.0.1","@rspack/dev-server":"^2.0.1","@rspack/plugin-preact-refresh":"1.1.5","@rspack/plugin-react-refresh":"1.6.2","@swc/core":"^1.15.8","@swc/helpers":"^0.5.18","@vue/compiler-sfc":"3.5.26","adm-zip":"^0.5.16","browser-extension-manifest-fields":"^2.2.1","case-sensitive-paths-webpack-plugin":"^2.4.0","content-security-policy-parser":"^0.6.0","cross-spawn":"^7.0.6","dotenv":"^17.2.3","extension-from-store":"^0.1.1","go-git-it":"^5.1.5","ignore":"^7.0.5","less":"4.5.1","less-loader":"12.3.2","loader-utils":"^3.3.1","magic-string":"^0.30.21","parse5-utilities":"^1.0.0","pintor":"0.3.0","postcss":"8.5.10","postcss-loader":"8.2.1","postcss-preset-env":"11.1.1","postcss-scss":"4.0.9","preact":"10.27.3","react-refresh":"0.18.0","sass-loader":"16.0.7","schema-utils":"^4.3.3","svelte-loader":"3.2.4","tiny-glob":"^0.2.9","typescript":"5.9.3","unique-names-generator":"^4.7.1","vue":"3.5.26","vue-loader":"17.4.2","webextension-polyfill":"^0.12.0","webpack-merge":"^6.0.1","webpack-target-webextension":"^2.1.3"}}');
3312
3352
  }
3313
- var dev_server_messages = __webpack_require__("./dev-server/messages.ts");
3314
- async function extensionPreview(pathOrRemoteUrl, previewOptions, browserLauncher) {
3315
- const projectStructure = await getProjectStructure(pathOrRemoteUrl);
3316
- const debug = 'true' === process.env.EXTENSION_AUTHOR_MODE;
3317
- const { manifestDir, packageJsonDir } = (0, paths.fu)(projectStructure);
3318
- if (projectStructure.packageJsonPath) assertNoManagedDependencyConflicts(projectStructure.packageJsonPath, packageJsonDir);
3319
- const browser = (0, paths.YN)(previewOptions.browser || 'chrome', previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary);
3320
- const outputPath = (0, paths.u2)(projectStructure, browser, previewOptions.outputPath);
3321
- const distPath = (0, paths.q4)(packageJsonDir, browser);
3322
- const metadataCommand = 'start' === previewOptions.metadataCommand ? 'start' : 'preview';
3323
- const metadata = (0, plugin_playwright.Ih)({
3324
- packageJsonDir,
3325
- browser: String(browser),
3326
- command: metadataCommand,
3327
- distPath,
3328
- manifestPath: projectStructure.manifestPath,
3329
- port: 'number' == typeof previewOptions.port ? previewOptions.port : 'string' == typeof previewOptions.port ? parseInt(previewOptions.port, 10) : null
3353
+ };
3354
+ var __webpack_module_cache__ = {};
3355
+ function __webpack_require__(moduleId) {
3356
+ var cachedModule = __webpack_module_cache__[moduleId];
3357
+ if (void 0 !== cachedModule) return cachedModule.exports;
3358
+ var module = __webpack_module_cache__[moduleId] = {
3359
+ exports: {}
3360
+ };
3361
+ __webpack_modules__[moduleId](module, module.exports, __webpack_require__);
3362
+ return module.exports;
3363
+ }
3364
+ __webpack_require__.m = __webpack_modules__;
3365
+ (()=>{
3366
+ __webpack_require__.n = (module)=>{
3367
+ var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
3368
+ __webpack_require__.d(getter, {
3369
+ a: getter
3330
3370
  });
3331
- metadata.writeStarting();
3332
- if (debug) {
3333
- console.log(messages.SG(manifestDir, packageJsonDir));
3334
- console.log(messages._A(browser, previewOptions.chromiumBinary, previewOptions.geckoBinary || previewOptions.firefoxBinary));
3335
- console.log(messages.jV(outputPath, distPath));
3336
- }
3337
- const manifestAtOutput = external_path_.join(outputPath, 'manifest.json');
3338
- if (!external_fs_.existsSync(manifestAtOutput)) {
3339
- metadata.writeError('preview_manifest_missing', `Expected manifest at ${manifestAtOutput}`);
3340
- throw new Error(`Preview is run-only and does not compile.\nExpected an unpacked extension at:\n ${manifestAtOutput}\n\nRun \`extension build\` or \`extension dev\` first, or pass --output-path to an existing unpacked extension directory.`);
3341
- }
3342
- const commandConfig = await (0, config_loader.eY)(packageJsonDir, metadataCommand);
3343
- const browserConfig = await (0, config_loader.xY)(packageJsonDir, browser);
3344
- console.log(messages.V_(browser));
3345
- if (previewOptions.noBrowser) {
3346
- console.log(messages.k4(browser));
3347
- metadata.writeReady();
3348
- console.log(dev_server_messages.tl());
3349
- const browserLabel = String(browser || 'unknown');
3350
- console.log(dev_server_messages.bL({
3351
- browser: browserLabel,
3352
- manifestPath: projectStructure.manifestPath,
3353
- readyPath: metadata.readyPath,
3354
- browserModeLabel: `${browserLabel.charAt(0).toUpperCase() + browserLabel.slice(1)} (no-browser mode)`
3355
- }));
3356
- return;
3357
- }
3358
- const safeBrowserConfig = (0, sanitize.a)(browserConfig);
3359
- const safeCommandConfig = (0, sanitize.a)(commandConfig);
3360
- const safePreviewOptions = (0, sanitize.a)(previewOptions);
3361
- const specialFoldersData = (0, get_data.H)(packageJsonDir);
3362
- const mergedExtensionsConfig = safePreviewOptions.extensions ?? safeCommandConfig.extensions ?? safeBrowserConfig.extensions ?? specialFoldersData.extensions;
3363
- const resolvedExtensionsConfig = await (0, resolve_config.R)({
3364
- projectRoot: packageJsonDir,
3365
- browser,
3366
- config: mergedExtensionsConfig
3371
+ return getter;
3372
+ };
3373
+ })();
3374
+ (()=>{
3375
+ __webpack_require__.d = (exports1, definition)=>{
3376
+ for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
3377
+ enumerable: true,
3378
+ get: definition[key]
3367
3379
  });
3368
- const mergedGeckoBinary = safePreviewOptions.geckoBinary || safePreviewOptions.firefoxBinary || safeCommandConfig.geckoBinary || safeCommandConfig.firefoxBinary || safeBrowserConfig.geckoBinary || safeBrowserConfig.firefoxBinary;
3369
- const mergedChromiumBinary = safePreviewOptions.chromiumBinary || safeCommandConfig.chromiumBinary || safeBrowserConfig.chromiumBinary;
3370
- const merged = {
3371
- ...safeBrowserConfig,
3372
- ...safeCommandConfig,
3373
- ...safePreviewOptions,
3374
- extensions: resolvedExtensionsConfig,
3375
- chromiumBinary: mergedChromiumBinary,
3376
- geckoBinary: mergedGeckoBinary
3377
- };
3378
- const darkDefaults = withDarkMode({
3379
- browser,
3380
- browserFlags: merged.browserFlags,
3381
- preferences: merged.preferences
3380
+ };
3381
+ })();
3382
+ (()=>{
3383
+ __webpack_require__.f = {};
3384
+ __webpack_require__.e = (chunkId)=>Promise.all(Object.keys(__webpack_require__.f).reduce((promises, key)=>{
3385
+ __webpack_require__.f[key](chunkId, promises);
3386
+ return promises;
3387
+ }, []));
3388
+ })();
3389
+ (()=>{
3390
+ __webpack_require__.u = (chunkId)=>"" + chunkId + ".cjs";
3391
+ })();
3392
+ (()=>{
3393
+ __webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
3394
+ })();
3395
+ (()=>{
3396
+ __webpack_require__.r = (exports1)=>{
3397
+ if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
3398
+ value: 'Module'
3382
3399
  });
3383
- const companionUnpackedExtensionDirs = resolveCompanionExtensionDirs({
3384
- projectRoot: packageJsonDir,
3385
- config: merged.extensions
3400
+ Object.defineProperty(exports1, '__esModule', {
3401
+ value: true
3386
3402
  });
3387
- const unpackedExtensionDirsToLoad = (0, extensions_to_load.n)(external_path_.resolve(__dirname, '..'), 'production', browser, outputPath, companionUnpackedExtensionDirs, projectStructure.manifestPath);
3388
- const resolvedOpts = {
3389
- browser,
3390
- outPath: outputPath,
3391
- contextDir: packageJsonDir,
3392
- readyPath: metadata.readyPath,
3393
- extensionsToLoad: unpackedExtensionDirsToLoad,
3394
- noOpen: merged.noOpen,
3395
- profile: merged.profile,
3396
- persistProfile: merged.persistProfile,
3397
- preferences: darkDefaults.preferences,
3398
- browserFlags: darkDefaults.browserFlags,
3399
- excludeBrowserFlags: merged.excludeBrowserFlags,
3400
- startingUrl: merged.startingUrl,
3401
- chromiumBinary: merged.chromiumBinary,
3402
- geckoBinary: merged.geckoBinary,
3403
- instanceId: merged.instanceId,
3404
- port: merged.port,
3405
- dryRun: merged.dryRun
3406
- };
3407
- if (!browserLauncher) throw new Error("extensionPreview requires a browserLauncher callback. The browser launch code has moved to programs/extension/browsers/.");
3408
- await browserLauncher(resolvedOpts);
3409
- metadata.writeReady();
3410
- }
3403
+ };
3404
+ })();
3405
+ (()=>{
3406
+ var installedChunks = {
3407
+ 364: 1
3408
+ };
3409
+ var installChunk = (chunk)=>{
3410
+ var moreModules = chunk.modules, chunkIds = chunk.ids, runtime = chunk.runtime;
3411
+ for(var moduleId in moreModules)if (__webpack_require__.o(moreModules, moduleId)) __webpack_require__.m[moduleId] = moreModules[moduleId];
3412
+ if (runtime) runtime(__webpack_require__);
3413
+ for(var i = 0; i < chunkIds.length; i++)installedChunks[chunkIds[i]] = 1;
3414
+ };
3415
+ __webpack_require__.f.require = (chunkId, promises)=>{
3416
+ if (!installedChunks[chunkId]) installChunk(require("./" + __webpack_require__.u(chunkId)));
3417
+ };
3411
3418
  })();
3419
+ var __webpack_exports__ = __webpack_require__("./module.ts");
3412
3420
  exports.BuildEmitter = __webpack_exports__.BuildEmitter;
3413
3421
  exports.extensionBuild = __webpack_exports__.extensionBuild;
3414
3422
  exports.extensionDev = __webpack_exports__.extensionDev;