@aex.is/zero 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -22,7 +22,7 @@ zero
22
22
 
23
23
  ## Requirements
24
24
 
25
- - Bun installed and available on PATH.
25
+ - One package manager installed: npm, pnpm, yarn, or bun.
26
26
 
27
27
  ## Generated starters
28
28
 
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -13,7 +13,6 @@ export const frameworks = [
13
13
  '@radix-ui/react-slot'
14
14
  ],
15
15
  scaffold: {
16
- command: 'bunx',
17
16
  packageName: 'create-next-app@latest',
18
17
  argSets: [
19
18
  [
@@ -25,7 +24,6 @@ export const frameworks = [
25
24
  '--no-src-dir',
26
25
  '--import-alias',
27
26
  '@/*',
28
- '--use-bun',
29
27
  '--skip-install'
30
28
  ],
31
29
  [
@@ -37,7 +35,6 @@ export const frameworks = [
37
35
  '--no-src-dir',
38
36
  '--import-alias',
39
37
  '@/*',
40
- '--use-bun'
41
38
  ],
42
39
  [
43
40
  '--ts',
@@ -77,7 +74,6 @@ export const frameworks = [
77
74
  'react-native-svg'
78
75
  ],
79
76
  scaffold: {
80
- command: 'bunx',
81
77
  packageName: 'create-expo-app',
82
78
  argSets: [
83
79
  ['--template', 'expo-router', '--yes', '--no-install'],
@@ -0,0 +1,41 @@
1
+ export const packageManagers = [
2
+ {
3
+ id: 'npm',
4
+ label: 'npm',
5
+ runner: { command: 'npx', args: [] },
6
+ install: ['npm', 'install'],
7
+ add: ['npm', 'install'],
8
+ dev: ['npm', 'run', 'dev']
9
+ },
10
+ {
11
+ id: 'pnpm',
12
+ label: 'pnpm',
13
+ runner: { command: 'pnpm', args: ['dlx'] },
14
+ install: ['pnpm', 'install'],
15
+ add: ['pnpm', 'add'],
16
+ dev: ['pnpm', 'dev']
17
+ },
18
+ {
19
+ id: 'yarn',
20
+ label: 'yarn',
21
+ runner: { command: 'yarn', args: ['dlx'] },
22
+ install: ['yarn', 'install'],
23
+ add: ['yarn', 'add'],
24
+ dev: ['yarn', 'dev']
25
+ },
26
+ {
27
+ id: 'bun',
28
+ label: 'bun',
29
+ runner: { command: 'bunx', args: [] },
30
+ install: ['bun', 'install'],
31
+ add: ['bun', 'add'],
32
+ dev: ['bun', 'run', 'dev']
33
+ }
34
+ ];
35
+ export function getPackageManagerDefinition(id) {
36
+ const manager = packageManagers.find((item) => item.id === id);
37
+ if (!manager) {
38
+ throw new Error(`Unknown package manager: ${id}`);
39
+ }
40
+ return manager;
41
+ }
@@ -1,13 +1,15 @@
1
1
  import { execa } from 'execa';
2
2
  import { getModulePackages } from '../config/modules.js';
3
+ import { getPackageManagerDefinition } from '../config/package-managers.js';
3
4
  const baseEnv = {
4
5
  ...process.env,
5
6
  CI: '1'
6
7
  };
7
- export async function installBaseDependencies(targetDir, extraPackages = []) {
8
+ export async function installBaseDependencies(targetDir, packageManager, extraPackages = []) {
9
+ const manager = getPackageManagerDefinition(packageManager);
8
10
  if (extraPackages.length > 0) {
9
11
  const packages = Array.from(new Set(extraPackages)).sort();
10
- await execa('bun', ['add', ...packages], {
12
+ await execa(manager.add[0], [...manager.add.slice(1), ...packages], {
11
13
  cwd: targetDir,
12
14
  stdio: 'inherit',
13
15
  env: baseEnv,
@@ -15,19 +17,20 @@ export async function installBaseDependencies(targetDir, extraPackages = []) {
15
17
  });
16
18
  return;
17
19
  }
18
- await execa('bun', ['install'], {
20
+ await execa(manager.install[0], manager.install.slice(1), {
19
21
  cwd: targetDir,
20
22
  stdio: 'inherit',
21
23
  env: baseEnv,
22
24
  shell: false
23
25
  });
24
26
  }
25
- export async function installModulePackages(framework, moduleIds, targetDir) {
27
+ export async function installModulePackages(framework, moduleIds, targetDir, packageManager) {
26
28
  const packages = getModulePackages(moduleIds, framework);
27
29
  if (packages.length === 0) {
28
30
  return;
29
31
  }
30
- await execa('bun', ['add', ...packages], {
32
+ const manager = getPackageManagerDefinition(packageManager);
33
+ await execa(manager.add[0], [...manager.add.slice(1), ...packages], {
31
34
  cwd: targetDir,
32
35
  stdio: 'inherit',
33
36
  env: baseEnv,
@@ -8,6 +8,7 @@ import { installBaseDependencies, installModulePackages } from './installers.js'
8
8
  import { writeEnvExample } from './env.js';
9
9
  import { assertAssetSources, generateExpoAssets, generateNextAssets, resolveAssetSources } from './assets.js';
10
10
  import { buildNextTemplateFiles, buildExpoTemplateFiles, componentsJsonTemplate } from './templates.js';
11
+ import { getPackageManagerDefinition } from '../config/package-managers.js';
11
12
  const baseEnv = {
12
13
  ...process.env,
13
14
  CI: '1'
@@ -17,10 +18,12 @@ export async function scaffoldProject(config) {
17
18
  const targetDir = path.resolve(process.cwd(), directoryInput);
18
19
  await ensureEmptyTargetDir(targetDir);
19
20
  const framework = getFrameworkDefinition(config.framework);
21
+ const packageManager = getPackageManagerDefinition(config.packageManager);
20
22
  const sources = resolveAssetSources();
21
23
  await assertAssetSources(sources);
22
24
  console.log(`Scaffolding ${framework.label}...`);
23
- await runScaffoldCommand(framework.scaffold.command, framework.scaffold.packageName, directoryInput, framework.scaffold.argSets);
25
+ const argSets = buildScaffoldArgs(framework, config.packageManager);
26
+ await runScaffoldCommand(packageManager.runner, framework.scaffold.packageName, directoryInput, argSets);
24
27
  console.log('Applying framework templates...');
25
28
  if (config.framework === 'nextjs') {
26
29
  await applyNextTemplates(config, targetDir);
@@ -45,15 +48,16 @@ export async function scaffoldProject(config) {
45
48
  assetsDir: path.join(targetDir, 'assets')
46
49
  });
47
50
  }
48
- console.log('Installing base dependencies with Bun...');
49
- await installBaseDependencies(targetDir, framework.packages);
51
+ console.log(`Installing base dependencies with ${packageManager.label}...`);
52
+ await installBaseDependencies(targetDir, config.packageManager, framework.packages);
50
53
  console.log('Installing module packages...');
51
- await installModulePackages(config.framework, config.modules, targetDir);
54
+ await installModulePackages(config.framework, config.modules, targetDir, config.packageManager);
52
55
  console.log('Generating .env.example...');
53
56
  await writeEnvExample(config.modules, config.framework, targetDir);
54
57
  console.log('Scaffold complete.');
55
58
  const cdTarget = directoryInput === '.' ? '.' : directoryInput.includes(' ') ? `"${directoryInput}"` : directoryInput;
56
- console.log(`\nNext steps:\n 1) cd ${cdTarget}\n 2) bun run dev`);
59
+ const devCommand = packageManager.dev.join(' ');
60
+ console.log(`\nNext steps:\n 1) cd ${cdTarget}\n 2) ${devCommand}`);
57
61
  }
58
62
  async function ensureEmptyTargetDir(targetDir) {
59
63
  try {
@@ -75,12 +79,12 @@ async function ensureEmptyTargetDir(targetDir) {
75
79
  throw error;
76
80
  }
77
81
  }
78
- async function runScaffoldCommand(command, packageName, directoryInput, argSets) {
82
+ async function runScaffoldCommand(runner, packageName, directoryInput, argSets) {
79
83
  const errors = [];
80
84
  const targetArg = directoryInput === '.' ? '.' : directoryInput;
81
85
  for (const args of argSets) {
82
86
  try {
83
- await execa(command, [packageName, targetArg, ...args], {
87
+ await execa(runner.command, [...runner.args, packageName, targetArg, ...args], {
84
88
  stdio: 'inherit',
85
89
  env: baseEnv,
86
90
  shell: false
@@ -96,6 +100,31 @@ async function runScaffoldCommand(command, packageName, directoryInput, argSets)
96
100
  : 'Scaffold failed for unknown reasons.';
97
101
  throw new Error(message);
98
102
  }
103
+ function buildScaffoldArgs(framework, packageManager) {
104
+ if (framework.id !== 'nextjs') {
105
+ return framework.scaffold.argSets;
106
+ }
107
+ const flag = resolveNextPackageManagerFlag(packageManager);
108
+ if (!flag) {
109
+ return framework.scaffold.argSets;
110
+ }
111
+ const withFlag = framework.scaffold.argSets.map((args) => [...args, flag]);
112
+ return [...withFlag, ...framework.scaffold.argSets];
113
+ }
114
+ function resolveNextPackageManagerFlag(packageManager) {
115
+ switch (packageManager) {
116
+ case 'npm':
117
+ return '--use-npm';
118
+ case 'pnpm':
119
+ return '--use-pnpm';
120
+ case 'yarn':
121
+ return '--use-yarn';
122
+ case 'bun':
123
+ return '--use-bun';
124
+ default:
125
+ return null;
126
+ }
127
+ }
99
128
  async function applyNextTemplates(config, targetDir) {
100
129
  const srcAppDir = path.join(targetDir, 'src', 'app');
101
130
  const usesSrcDir = await pathExists(srcAppDir);
@@ -1,4 +1,5 @@
1
1
  import which from 'which';
2
+ import { getPackageManagerDefinition } from '../config/package-managers.js';
2
3
  export function detectPlatform() {
3
4
  switch (process.platform) {
4
5
  case 'darwin':
@@ -14,23 +15,22 @@ export function detectPlatform() {
14
15
  export function detectShell(platform = detectPlatform()) {
15
16
  return platform === 'windows' ? 'powershell' : 'posix';
16
17
  }
17
- export async function isBunAvailable() {
18
+ export async function isCommandAvailable(command) {
18
19
  try {
19
- await which('bun');
20
+ await which(command);
20
21
  return true;
21
22
  }
22
23
  catch {
23
24
  return false;
24
25
  }
25
26
  }
26
- export async function assertBunAvailable() {
27
- const available = await isBunAvailable();
27
+ export async function assertPackageManagerAvailable(packageManager) {
28
+ const manager = getPackageManagerDefinition(packageManager);
29
+ const command = manager.install[0];
30
+ const available = await isCommandAvailable(command);
28
31
  if (!available) {
29
32
  const platform = detectPlatform();
30
33
  const shell = detectShell(platform);
31
- const hint = platform === 'windows'
32
- ? 'Install Bun for Windows and reopen PowerShell.'
33
- : 'Install Bun and ensure it is on your PATH.';
34
- throw new Error(`Bun is required but was not found in PATH. (${platform}/${shell}) ${hint}`);
34
+ throw new Error(`${manager.label} is required but was not found in PATH. (${platform}/${shell}) Install ${manager.label} and retry.`);
35
35
  }
36
36
  }
package/dist/index.js CHANGED
@@ -1,10 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { runWizard } from './cli/bubbletea.js';
3
- import { assertBunAvailable } from './env/detect.js';
3
+ import { assertPackageManagerAvailable } from './env/detect.js';
4
4
  import { scaffoldProject } from './engine/scaffold.js';
5
5
  async function main() {
6
+ const config = await runWizard();
7
+ if (!config) {
8
+ return;
9
+ }
6
10
  try {
7
- await assertBunAvailable();
11
+ await assertPackageManagerAvailable(config.packageManager);
8
12
  }
9
13
  catch (error) {
10
14
  const message = error instanceof Error ? error.message : String(error);
@@ -12,10 +16,6 @@ async function main() {
12
16
  process.exitCode = 1;
13
17
  return;
14
18
  }
15
- const config = await runWizard();
16
- if (!config) {
17
- return;
18
- }
19
19
  try {
20
20
  await scaffoldProject(config);
21
21
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aex.is/zero",
3
- "version": "0.1.8",
3
+ "version": "0.1.9",
4
4
  "description": "Aexis Zero scaffolding CLI",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",