extension-create 3.5.0-next.2 → 3.5.0-next.21

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.
@@ -0,0 +1,10 @@
1
+ type InstallResult = {
2
+ code: number | null;
3
+ stderr: string;
4
+ stdout: string;
5
+ };
6
+ export declare function runInstall(command: string, args: string[], opts: {
7
+ cwd: string;
8
+ stdio: 'inherit' | 'ignore' | 'pipe';
9
+ }): Promise<InstallResult>;
10
+ export {};
@@ -16,6 +16,9 @@ export declare function initializingGitForRepositoryFailed(gitCommand: string, g
16
16
  export declare function initializingGitForRepositoryProcessError(projectName: string, error: any): string;
17
17
  export declare function initializingGitForRepositoryError(projectName: string, error: any): string;
18
18
  export declare function installingDependencies(): string;
19
+ export declare function installingBuildDependencies(dependencies: string[]): string;
20
+ export declare function foundSpecializedDependencies(count: number): string;
21
+ export declare function installingProjectIntegrations(integrations: string[]): string[];
19
22
  export declare function installingDependenciesFailed(gitCommand: string, gitArgs: string[], code: number | null): string;
20
23
  export declare function installingDependenciesProcessError(projectName: string, error: any): string;
21
24
  export declare function cantInstallDependencies(projectName: string, error: any): string;
@@ -2,6 +2,7 @@ type ProgressOptions = {
2
2
  enabled?: boolean;
3
3
  intervalMs?: number;
4
4
  width?: number;
5
+ persistLabel?: boolean;
5
6
  };
6
7
  type ProgressHandle = {
7
8
  stop: () => void;
package/dist/module.cjs CHANGED
@@ -143,6 +143,30 @@ function initializingGitForRepositoryProcessError(projectName, error) {
143
143
  function initializingGitForRepositoryError(projectName, error) {
144
144
  return `${external_pintor_default().red('Error')} Couldn't initialize ${external_pintor_default().yellow('git')} for ${external_pintor_default().blue(projectName)}.\n${external_pintor_default().red(String(error?.message || error))}\n${external_pintor_default().red('Next step: retry initialization or create the repository manually.')}`;
145
145
  }
146
+ function installingDependencies() {
147
+ return `${statusPrefix} Installing project-specific dependencies...`;
148
+ }
149
+ function installingBuildDependencies(dependencies) {
150
+ return `${statusPrefix} Installing general build dependencies...`;
151
+ }
152
+ function foundSpecializedDependencies(count) {
153
+ return `${statusPrefix} Found ${external_pintor_default().yellow(String(count))} specialized integration${1 === count ? '' : 's'} needing installation...`;
154
+ }
155
+ function installingProjectIntegrations(integrations) {
156
+ if (0 === integrations.length) return [
157
+ `${statusPrefix} Installing specialized dependencies for ${external_pintor_default().gray('project tooling')}...`
158
+ ];
159
+ return integrations.map((integration)=>`${statusPrefix} Installing specialized dependencies for ${external_pintor_default().yellow(integration)}...`);
160
+ }
161
+ function installingDependenciesFailed(gitCommand, gitArgs, code) {
162
+ return `${external_pintor_default().red('Error')} Command ${external_pintor_default().yellow(gitCommand)} ${external_pintor_default().yellow(gitArgs.join(' '))} failed.\n${external_pintor_default().red(`Exit code: ${external_pintor_default().yellow(String(code))}`)}\n${external_pintor_default().red('Next step: run the command manually to inspect the error.')}`;
163
+ }
164
+ function installingDependenciesProcessError(projectName, error) {
165
+ return `${external_pintor_default().red('Error')} Child process failed while installing dependencies for ${external_pintor_default().blue(projectName)}.\n${external_pintor_default().red(String(error))}\n${external_pintor_default().red('Next step: run the install command manually to inspect the error.')}`;
166
+ }
167
+ function cantInstallDependencies(projectName, error) {
168
+ return `${external_pintor_default().red('Error')} Couldn't install dependencies for ${external_pintor_default().blue(projectName)}.\n${external_pintor_default().red(String(error?.message || error))}\n${external_pintor_default().red('Next step: check your package manager settings, then try again.')}`;
169
+ }
146
170
  function writingPackageJsonMetadata() {
147
171
  return `${statusPrefix} Writing ${external_pintor_default().yellow('package.json')}...`;
148
172
  }
@@ -330,7 +354,7 @@ async function importExternalTemplate(projectPath, projectName, template) {
330
354
  if (!line) return false;
331
355
  const trimmed = line.trim();
332
356
  if (!trimmed) return false;
333
- if (/Using git version/i.test(line) || /GitHub API rate limit reached, continuing without connectivity check/i.test(line) || /\[go-git-it\] An error occurred: Error: Failed to download release asset: HTTP 404/i.test(line) || /^Downloading extension\b/i.test(trimmed) || /^URL https?:\/\/codeload\.github\.com\/extension-js\/examples\/zip\/refs\/heads\/main\b/i.test(trimmed) || /^\[[=\s]+\]\s*\d+%/i.test(trimmed)) {
357
+ if (/Using git version/i.test(line) || /GitHub API rate limit reached, continuing without connectivity check/i.test(line) || /^Downloading extension\b/i.test(trimmed) || /^URL https?:\/\/codeload\.github\.com\/extension-js\/examples\/zip\/refs\/heads\/main\b/i.test(trimmed) || /^\[[=\s]+\]\s*\d+%/i.test(trimmed)) {
334
358
  suppressGoGitItStack = true;
335
359
  return true;
336
360
  }
@@ -478,6 +502,194 @@ async function overridePackageJson(projectPath, projectName, { template: _templa
478
502
  throw error;
479
503
  }
480
504
  }
505
+ function stripAnsi(input) {
506
+ return input.replace(/\x1b\[[0-9;]*m/g, '');
507
+ }
508
+ function shouldShowProgress() {
509
+ return Boolean(process.stdout.isTTY) && !process.env.CI;
510
+ }
511
+ function startProgressBar(label, options) {
512
+ const enabled = (options?.enabled ?? true) && shouldShowProgress();
513
+ if (!enabled) return {
514
+ stop: ()=>void 0
515
+ };
516
+ const width = Math.max(10, options?.width ?? 24);
517
+ const intervalMs = Math.max(50, options?.intervalMs ?? 90);
518
+ let tick = 0;
519
+ let lastVisibleLength = 0;
520
+ const render = ()=>{
521
+ const filled = tick % (width + 1);
522
+ const empty = width - filled;
523
+ const bar = `[${'='.repeat(filled)}${' '.repeat(empty)}]`;
524
+ const line = `${label} ${bar}`;
525
+ lastVisibleLength = stripAnsi(line).length;
526
+ process.stdout.write(`\r${line}`);
527
+ tick = (tick + 1) % (width + 1);
528
+ };
529
+ render();
530
+ const timer = setInterval(render, intervalMs);
531
+ return {
532
+ stop: ()=>{
533
+ clearInterval(timer);
534
+ if (process.stdout.isTTY) {
535
+ process.stdout.write(`\r${' '.repeat(lastVisibleLength)}\r`);
536
+ if (options?.persistLabel) process.stdout.write(`${label}\n`);
537
+ }
538
+ }
539
+ };
540
+ }
541
+ const external_cross_spawn_namespaceObject = require("cross-spawn");
542
+ function resolveWindowsCmdExe() {
543
+ const comspec = process.env.ComSpec;
544
+ if (comspec) return comspec;
545
+ const systemRoot = process.env.SystemRoot || 'C:\\Windows';
546
+ return external_path_namespaceObject.join(systemRoot, 'System32', 'cmd.exe');
547
+ }
548
+ function resolveInstallInvocation(command, args) {
549
+ if ('win32' !== process.platform) return {
550
+ command,
551
+ args
552
+ };
553
+ return {
554
+ command: resolveWindowsCmdExe(),
555
+ args: [
556
+ '/d',
557
+ '/s',
558
+ '/c',
559
+ command,
560
+ ...args
561
+ ]
562
+ };
563
+ }
564
+ function buildExecEnv() {
565
+ if ('win32' !== process.platform) return;
566
+ const nodeDir = external_path_namespaceObject.dirname(process.execPath);
567
+ const pathSep = external_path_namespaceObject.delimiter;
568
+ const existing = process.env.PATH || process.env.Path || '';
569
+ if (existing.includes(nodeDir)) return;
570
+ return {
571
+ ...process.env,
572
+ PATH: `${nodeDir}${pathSep}${existing}`.trim(),
573
+ Path: `${nodeDir}${pathSep}${existing}`.trim()
574
+ };
575
+ }
576
+ async function runInstall(command, args, opts) {
577
+ const invocation = resolveInstallInvocation(command, args);
578
+ const env = buildExecEnv();
579
+ const child = (0, external_cross_spawn_namespaceObject.spawn)(invocation.command, invocation.args, {
580
+ stdio: opts.stdio,
581
+ cwd: opts.cwd,
582
+ env: env || process.env
583
+ });
584
+ let stdout = '';
585
+ let stderr = '';
586
+ if (child.stdout) child.stdout.on('data', (chunk)=>{
587
+ stdout += chunk.toString();
588
+ });
589
+ if (child.stderr) child.stderr.on('data', (chunk)=>{
590
+ stderr += chunk.toString();
591
+ });
592
+ return new Promise((resolve, reject)=>{
593
+ child.on('close', (code)=>{
594
+ resolve({
595
+ code,
596
+ stderr,
597
+ stdout
598
+ });
599
+ });
600
+ child.on('error', (error)=>{
601
+ reject(error);
602
+ });
603
+ });
604
+ }
605
+ function getInstallArgs() {
606
+ return [
607
+ 'install',
608
+ '--silent'
609
+ ];
610
+ }
611
+ function getTagFallback(version) {
612
+ if ('*' === version || 'latest' === version || 'next' === version) return null;
613
+ const cleaned = version.replace(/^[~^]/, '');
614
+ return cleaned.includes('-') ? 'next' : 'latest';
615
+ }
616
+ async function updateExtensionDependencyTag(projectPath, projectName) {
617
+ const packageJsonPath = external_path_namespaceObject.join(projectPath, 'package.json');
618
+ try {
619
+ const raw = await external_fs_namespaceObject.promises.readFile(packageJsonPath, 'utf8');
620
+ const packageJson = JSON.parse(raw);
621
+ const currentVersion = packageJson?.devDependencies?.extension;
622
+ if ('string' != typeof currentVersion) return false;
623
+ const tag = getTagFallback(currentVersion);
624
+ if (!tag || currentVersion === tag) return false;
625
+ packageJson.devDependencies = {
626
+ ...packageJson.devDependencies || {},
627
+ extension: tag
628
+ };
629
+ await external_fs_namespaceObject.promises.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n');
630
+ return true;
631
+ } catch (error) {
632
+ console.error(cantInstallDependencies(projectName, error));
633
+ return false;
634
+ }
635
+ }
636
+ function shouldRetryWithTagFallback(output) {
637
+ const text = output.toLowerCase();
638
+ return text.includes('no matching version found for extension@') || text.includes('notarget') || text.includes('etarget');
639
+ }
640
+ async function install_dependencies_runInstall(command, args, cwd, stdio) {
641
+ return runInstall(command, args, {
642
+ cwd,
643
+ stdio
644
+ });
645
+ }
646
+ async function installDependencies(projectPath, projectName) {
647
+ const nodeModulesPath = external_path_namespaceObject.join(projectPath, 'node_modules');
648
+ const command = await getInstallCommand();
649
+ const dependenciesArgs = getInstallArgs();
650
+ const installMessage = installingDependencies();
651
+ const progressEnabled = shouldShowProgress();
652
+ const progress = startProgressBar(installMessage, {
653
+ enabled: progressEnabled,
654
+ persistLabel: true
655
+ });
656
+ if (!progressEnabled) console.log(installMessage);
657
+ try {
658
+ await external_fs_namespaceObject.promises.mkdir(nodeModulesPath, {
659
+ recursive: true
660
+ });
661
+ const stdio = 'development' === process.env.EXTENSION_ENV ? 'inherit' : 'pipe';
662
+ let firstRun;
663
+ try {
664
+ firstRun = await install_dependencies_runInstall(command, dependenciesArgs, projectPath, stdio);
665
+ } finally{
666
+ progress.stop();
667
+ }
668
+ if (0 !== firstRun.code) {
669
+ const output = `${firstRun.stdout}\n${firstRun.stderr}`;
670
+ const shouldRetry = shouldRetryWithTagFallback(output);
671
+ const didUpdate = shouldRetry ? await updateExtensionDependencyTag(projectPath, projectName) : false;
672
+ if (didUpdate) {
673
+ const retryProgress = startProgressBar(installMessage, {
674
+ enabled: progressEnabled,
675
+ persistLabel: true
676
+ });
677
+ let retryRun;
678
+ try {
679
+ retryRun = await install_dependencies_runInstall(command, dependenciesArgs, projectPath, stdio);
680
+ } finally{
681
+ retryProgress.stop();
682
+ }
683
+ if (0 === retryRun.code) return;
684
+ }
685
+ throw new Error(installingDependenciesFailed(command, dependenciesArgs, firstRun.code));
686
+ }
687
+ } catch (error) {
688
+ console.error(installingDependenciesProcessError(projectName, error));
689
+ console.error(cantInstallDependencies(projectName, error));
690
+ throw error;
691
+ }
692
+ }
481
693
  const manifestSearchMaxDepth = 3;
482
694
  const ignoredManifestDirs = new Set([
483
695
  'node_modules',
@@ -703,7 +915,6 @@ async function writeGitignore(projectPath) {
703
915
  throw err;
704
916
  });
705
917
  }
706
- const external_cross_spawn_namespaceObject = require("cross-spawn");
707
918
  async function initializeGitRepository(projectPath, projectName) {
708
919
  const gitCommand = 'git';
709
920
  const gitArgs = [
@@ -741,7 +952,298 @@ async function setupBuiltInTests(projectPath, projectName) {
741
952
  throw error;
742
953
  }
743
954
  }
744
- async function extensionCreate(projectNameInput, { cliVersion, template = 'init', install: _install = false }) {
955
+ const external_module_namespaceObject = require("module");
956
+ const requireFromCreate = (0, external_module_namespaceObject.createRequire)(__rslib_import_meta_url__);
957
+ function resolveDevelopRoot(projectPath) {
958
+ const override = process.env.EXTENSION_CREATE_DEVELOP_ROOT;
959
+ if (override) return override;
960
+ try {
961
+ const localPkgPath = external_path_namespaceObject.join(projectPath, 'node_modules', 'extension-develop', 'package.json');
962
+ if (external_fs_namespaceObject.existsSync(localPkgPath)) return external_path_namespaceObject.dirname(localPkgPath);
963
+ const pkgPath = requireFromCreate.resolve('extension-develop/package.json', {
964
+ paths: [
965
+ projectPath,
966
+ process.cwd(),
967
+ __dirname
968
+ ]
969
+ });
970
+ return external_path_namespaceObject.dirname(pkgPath);
971
+ } catch {
972
+ return null;
973
+ }
974
+ }
975
+ function resolveBuildDepsPath(developRoot) {
976
+ return external_path_namespaceObject.join(developRoot, 'webpack', 'webpack-lib', 'build-dependencies.json');
977
+ }
978
+ function loadBuildDependencies(developRoot) {
979
+ const metadataPath = resolveBuildDepsPath(developRoot);
980
+ if (!external_fs_namespaceObject.existsSync(metadataPath)) {
981
+ console.warn(`${installingBuildDependencies([])} (build-dependencies.json missing; skipping build deps install)`);
982
+ return {};
983
+ }
984
+ return JSON.parse(external_fs_namespaceObject.readFileSync(metadataPath, 'utf8'));
985
+ }
986
+ function readPackageJson(projectPath) {
987
+ try {
988
+ const raw = external_fs_namespaceObject.readFileSync(external_path_namespaceObject.join(projectPath, 'package.json'), 'utf8');
989
+ return JSON.parse(raw);
990
+ } catch {
991
+ return {};
992
+ }
993
+ }
994
+ function hasDependency(pkg, name) {
995
+ return Boolean(pkg.dependencies?.[name] || pkg.devDependencies?.[name]);
996
+ }
997
+ function canResolve(dependency, paths) {
998
+ try {
999
+ requireFromCreate.resolve(dependency, {
1000
+ paths
1001
+ });
1002
+ return true;
1003
+ } catch {
1004
+ return false;
1005
+ }
1006
+ }
1007
+ function findConfigFile(projectPath, candidates) {
1008
+ return candidates.some((file)=>external_fs_namespaceObject.existsSync(external_path_namespaceObject.join(projectPath, file)));
1009
+ }
1010
+ function detectOptionalDependencies(projectPath) {
1011
+ const pkg = readPackageJson(projectPath);
1012
+ const usesReact = hasDependency(pkg, 'react') || hasDependency(pkg, 'react-dom');
1013
+ const usesPreact = hasDependency(pkg, 'preact');
1014
+ const usesVue = hasDependency(pkg, 'vue');
1015
+ const usesSvelte = hasDependency(pkg, 'svelte');
1016
+ const hasTsConfig = external_fs_namespaceObject.existsSync(external_path_namespaceObject.join(projectPath, 'tsconfig.json'));
1017
+ const usesTypeScript = hasDependency(pkg, "typescript") || hasTsConfig;
1018
+ const usesSass = hasDependency(pkg, 'sass') || hasDependency(pkg, 'sass-loader');
1019
+ const usesLess = hasDependency(pkg, 'less') || hasDependency(pkg, 'less-loader');
1020
+ const postCssConfigFiles = [
1021
+ '.postcssrc',
1022
+ '.postcssrc.json',
1023
+ '.postcssrc.yaml',
1024
+ '.postcssrc.yml',
1025
+ 'postcss.config.mjs',
1026
+ '.postcssrc.js',
1027
+ '.postcssrc.cjs',
1028
+ 'postcss.config.js',
1029
+ 'postcss.config.cjs'
1030
+ ];
1031
+ const tailwindConfigFiles = [
1032
+ 'tailwind.config.mjs',
1033
+ 'tailwind.config.cjs',
1034
+ 'tailwind.config.js'
1035
+ ];
1036
+ const usesPostCss = hasDependency(pkg, 'postcss') || hasDependency(pkg, 'postcss-loader') || findConfigFile(projectPath, postCssConfigFiles) || hasDependency(pkg, 'tailwindcss') || hasDependency(pkg, '@tailwindcss/postcss') || findConfigFile(projectPath, tailwindConfigFiles);
1037
+ const integrations = [];
1038
+ const dependenciesByIntegration = {};
1039
+ const deps = new Set();
1040
+ const addIntegration = (name, depsForIntegration)=>{
1041
+ if (!integrations.includes(name)) integrations.push(name);
1042
+ if (!dependenciesByIntegration[name]) dependenciesByIntegration[name] = [];
1043
+ for (const dep of depsForIntegration){
1044
+ if (!dependenciesByIntegration[name].includes(dep)) dependenciesByIntegration[name].push(dep);
1045
+ deps.add(dep);
1046
+ }
1047
+ };
1048
+ if (usesTypeScript) addIntegration('TypeScript', [
1049
+ "typescript"
1050
+ ]);
1051
+ if (usesReact) addIntegration('React', [
1052
+ 'react-refresh',
1053
+ '@rspack/plugin-react-refresh'
1054
+ ]);
1055
+ if (usesPreact) addIntegration('Preact', [
1056
+ '@prefresh/core',
1057
+ '@prefresh/utils',
1058
+ '@rspack/plugin-preact-refresh',
1059
+ 'preact'
1060
+ ]);
1061
+ if (usesVue) addIntegration('Vue', [
1062
+ 'vue-loader',
1063
+ '@vue/compiler-sfc'
1064
+ ]);
1065
+ if (usesSvelte) addIntegration('Svelte', [
1066
+ 'svelte-loader',
1067
+ "typescript"
1068
+ ]);
1069
+ if (usesSass) addIntegration('Sass', [
1070
+ 'sass-loader',
1071
+ 'postcss-loader',
1072
+ 'postcss-scss',
1073
+ 'postcss-preset-env'
1074
+ ]);
1075
+ if (usesLess) addIntegration('Less', [
1076
+ 'less',
1077
+ 'less-loader'
1078
+ ]);
1079
+ if (!usesPostCss || usesSass || usesLess) {
1080
+ if (usesPostCss) addIntegration('PostCSS', []);
1081
+ } else addIntegration('PostCSS', [
1082
+ 'postcss',
1083
+ 'postcss-loader'
1084
+ ]);
1085
+ return {
1086
+ integrations,
1087
+ dependencies: Array.from(deps),
1088
+ dependenciesByIntegration
1089
+ };
1090
+ }
1091
+ function buildOptionalInstallArgs(pm, dependencies, installDir) {
1092
+ if ('yarn' === pm) return [
1093
+ 'add',
1094
+ ...dependencies,
1095
+ '--cwd',
1096
+ installDir,
1097
+ '--optional'
1098
+ ];
1099
+ if ('pnpm' === pm) return [
1100
+ 'add',
1101
+ ...dependencies,
1102
+ '--dir',
1103
+ installDir,
1104
+ '--save-optional'
1105
+ ];
1106
+ if ('bun' === pm) return [
1107
+ 'add',
1108
+ ...dependencies,
1109
+ '--cwd',
1110
+ installDir,
1111
+ '--optional'
1112
+ ];
1113
+ return [
1114
+ 'install',
1115
+ ...dependencies,
1116
+ '--prefix',
1117
+ installDir,
1118
+ '--save-optional'
1119
+ ];
1120
+ }
1121
+ function buildBuildInstallArgs(pm, dependencies, dependencyMap) {
1122
+ const depsWithVersions = dependencies.map((dep)=>`${dep}@${dependencyMap[dep]}`);
1123
+ if ('yarn' === pm) return [
1124
+ 'add',
1125
+ ...depsWithVersions
1126
+ ];
1127
+ if ('pnpm' === pm) return [
1128
+ 'add',
1129
+ '--save',
1130
+ ...depsWithVersions
1131
+ ];
1132
+ if ('bun' === pm) return [
1133
+ 'add',
1134
+ ...depsWithVersions
1135
+ ];
1136
+ return [
1137
+ 'install',
1138
+ '--save',
1139
+ ...depsWithVersions
1140
+ ];
1141
+ }
1142
+ function resolveMissingBuildDeps(developRoot) {
1143
+ const dependencyMap = loadBuildDependencies(developRoot);
1144
+ const candidates = Object.keys(dependencyMap);
1145
+ const missing = candidates.filter((dep)=>!canResolve(dep, [
1146
+ developRoot,
1147
+ process.cwd()
1148
+ ]));
1149
+ return {
1150
+ dependencies: missing,
1151
+ dependencyMap
1152
+ };
1153
+ }
1154
+ function resolveMissingOptionalDeps(developRoot, projectPath) {
1155
+ const plan = detectOptionalDependencies(projectPath);
1156
+ const dependenciesByIntegration = {};
1157
+ const integrations = [];
1158
+ const missing = new Set();
1159
+ for (const integration of plan.integrations){
1160
+ const depsForIntegration = plan.dependenciesByIntegration[integration] || [];
1161
+ const missingForIntegration = depsForIntegration.filter((dep)=>!canResolve(dep, [
1162
+ developRoot,
1163
+ projectPath,
1164
+ process.cwd()
1165
+ ]));
1166
+ if (0 !== missingForIntegration.length) {
1167
+ integrations.push(integration);
1168
+ dependenciesByIntegration[integration] = missingForIntegration;
1169
+ missingForIntegration.forEach((dep)=>missing.add(dep));
1170
+ }
1171
+ }
1172
+ return {
1173
+ integrations,
1174
+ dependencies: Array.from(missing),
1175
+ dependenciesByIntegration
1176
+ };
1177
+ }
1178
+ async function installBuildDependencies(developRoot, plan) {
1179
+ if (0 === plan.dependencies.length) return;
1180
+ const pm = detectPackageManagerFromEnv();
1181
+ const installMessage = installingBuildDependencies(plan.dependencies);
1182
+ const progressEnabled = shouldShowProgress();
1183
+ const progress = startProgressBar(installMessage, {
1184
+ enabled: progressEnabled,
1185
+ persistLabel: true
1186
+ });
1187
+ if (!progressEnabled) console.log(installMessage);
1188
+ try {
1189
+ const args = buildBuildInstallArgs(pm, plan.dependencies, plan.dependencyMap);
1190
+ const stdio = 'development' === process.env.EXTENSION_ENV ? 'inherit' : 'ignore';
1191
+ const result = await runInstall(pm, args, {
1192
+ cwd: developRoot,
1193
+ stdio
1194
+ });
1195
+ if (0 !== result.code) throw new Error(installingDependenciesFailed(pm, args, result.code));
1196
+ } finally{
1197
+ progress.stop();
1198
+ }
1199
+ }
1200
+ async function installOptionalDependencies(developRoot, projectPath, plan) {
1201
+ if (0 === plan.dependencies.length) return;
1202
+ const pm = detectPackageManagerFromEnv();
1203
+ const stdio = 'development' === process.env.EXTENSION_ENV ? 'inherit' : 'ignore';
1204
+ const progressEnabled = shouldShowProgress();
1205
+ console.log(foundSpecializedDependencies(plan.integrations.length));
1206
+ for (const [index, integration] of plan.integrations.entries()){
1207
+ const missingDeps = plan.dependenciesByIntegration[integration] || [];
1208
+ const [baseMessage] = installingProjectIntegrations([
1209
+ integration
1210
+ ]);
1211
+ const installMessage = baseMessage.replace('►►► ', `►►► [${index + 1}/${plan.integrations.length}] `);
1212
+ const progress = startProgressBar(installMessage, {
1213
+ enabled: progressEnabled,
1214
+ persistLabel: true
1215
+ });
1216
+ if (!progressEnabled) console.log(installMessage);
1217
+ try {
1218
+ if (0 === missingDeps.length) continue;
1219
+ for (const dep of missingDeps){
1220
+ const args = buildOptionalInstallArgs(pm, [
1221
+ dep
1222
+ ], developRoot);
1223
+ const result = await runInstall(pm, args, {
1224
+ cwd: developRoot,
1225
+ stdio
1226
+ });
1227
+ if (0 !== result.code) throw new Error(installingDependenciesFailed(pm, args, result.code));
1228
+ }
1229
+ } finally{
1230
+ progress.stop();
1231
+ }
1232
+ }
1233
+ }
1234
+ async function installInternalDependencies(projectPath) {
1235
+ if ('test' === process.env.EXTENSION_ENV || 'true' === process.env.EXTENSION_SKIP_INTERNAL_INSTALL) return;
1236
+ const developRoot = resolveDevelopRoot(projectPath);
1237
+ if (!developRoot) return;
1238
+ const buildPlan = resolveMissingBuildDeps(developRoot);
1239
+ if (0 === buildPlan.dependencies.length) console.log(installingBuildDependencies(buildPlan.dependencies));
1240
+ else await installBuildDependencies(developRoot, buildPlan);
1241
+ const optionalPlan = resolveMissingOptionalDeps(developRoot, projectPath);
1242
+ if (0 === optionalPlan.dependencies.length) {
1243
+ if (optionalPlan.integrations.length > 0) installingProjectIntegrations(optionalPlan.integrations).forEach((message)=>console.log(message));
1244
+ } else await installOptionalDependencies(developRoot, projectPath, optionalPlan);
1245
+ }
1246
+ async function extensionCreate(projectNameInput, { cliVersion, template = 'init', install = false }) {
745
1247
  if (!projectNameInput) throw new Error(noProjectName());
746
1248
  if (projectNameInput.startsWith('http')) throw new Error(noUrlAllowed());
747
1249
  const projectPath = external_path_namespaceObject.isAbsolute(projectNameInput) ? projectNameInput : external_path_namespaceObject.join(process.cwd(), projectNameInput);
@@ -753,13 +1255,17 @@ async function extensionCreate(projectNameInput, { cliVersion, template = 'init'
753
1255
  template,
754
1256
  cliVersion
755
1257
  });
1258
+ if (install) {
1259
+ await installDependencies(projectPath, projectName);
1260
+ await installInternalDependencies(projectPath);
1261
+ }
756
1262
  await writeReadmeFile(projectPath, projectName);
757
1263
  await writeManifestJson(projectPath, projectName);
758
1264
  await initializeGitRepository(projectPath, projectName);
759
1265
  await writeGitignore(projectPath);
760
1266
  await setupBuiltInTests(projectPath, projectName);
761
1267
  if (isTypeScriptTemplate(template)) await generateExtensionTypes(projectPath, projectName);
762
- const successfulInstall = await successfullInstall(projectPath, projectName, false);
1268
+ const successfulInstall = await successfullInstall(projectPath, projectName, Boolean(install));
763
1269
  console.log(successfulInstall);
764
1270
  } catch (error) {
765
1271
  throw error;
package/dist/module.d.ts CHANGED
@@ -3,4 +3,4 @@ export interface CreateOptions {
3
3
  install?: boolean;
4
4
  cliVersion?: string;
5
5
  }
6
- export declare function extensionCreate(projectNameInput: string | undefined, { cliVersion, template, install: _install }: CreateOptions): Promise<void>;
6
+ export declare function extensionCreate(projectNameInput: string | undefined, { cliVersion, template, install }: CreateOptions): Promise<void>;
@@ -0,0 +1,21 @@
1
+ type OptionalDepsPlan = {
2
+ integrations: string[];
3
+ dependencies: string[];
4
+ dependenciesByIntegration: Record<string, string[]>;
5
+ };
6
+ type BuildDepsPlan = {
7
+ dependencies: string[];
8
+ dependencyMap: Record<string, string>;
9
+ };
10
+ declare function resolveDevelopRoot(projectPath: string): string | null;
11
+ declare function detectOptionalDependencies(projectPath: string): OptionalDepsPlan;
12
+ declare function resolveMissingBuildDeps(developRoot: string): BuildDepsPlan;
13
+ declare function resolveMissingOptionalDeps(developRoot: string, projectPath: string): OptionalDepsPlan;
14
+ export declare function installInternalDependencies(projectPath: string): Promise<void>;
15
+ export declare const __testing__: {
16
+ resolveDevelopRoot: typeof resolveDevelopRoot;
17
+ resolveMissingBuildDeps: typeof resolveMissingBuildDeps;
18
+ resolveMissingOptionalDeps: typeof resolveMissingOptionalDeps;
19
+ detectOptionalDependencies: typeof detectOptionalDependencies;
20
+ };
21
+ export {};
package/package.json CHANGED
@@ -23,7 +23,7 @@
23
23
  "dist"
24
24
  ],
25
25
  "name": "extension-create",
26
- "version": "3.5.0-next.2",
26
+ "version": "3.5.0-next.21",
27
27
  "description": "The standalone extension creation engine for Extension.js",
28
28
  "author": {
29
29
  "name": "Cezar Augusto",
@@ -81,15 +81,15 @@
81
81
  "devDependencies": {
82
82
  "@changesets/cli": "^2.29.8",
83
83
  "@eslint/js": "^9.39.2",
84
- "@rslib/core": "^0.19.2",
84
+ "@rslib/core": "^0.19.4",
85
85
  "@types/adm-zip": "^0.5.7",
86
86
  "@types/chrome": "^0.1.33",
87
87
  "@types/cross-spawn": "^6.0.6",
88
- "@types/node": "^25.0.9",
88
+ "@types/node": "^25.2.0",
89
89
  "@types/webextension-polyfill": "0.12.4",
90
90
  "@vitest/coverage-v8": "^4.0.17",
91
91
  "eslint": "^9.39.2",
92
- "globals": "^17.0.0",
92
+ "globals": "^17.3.0",
93
93
  "prettier": "^3.8.0",
94
94
  "tsconfig": "*",
95
95
  "typescript": "5.9.3",