oxc-configs 0.0.3 → 0.0.4

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 (4) hide show
  1. package/README.md +1 -1
  2. package/index.ts +47 -12
  3. package/package.json +6 -5
  4. package/utils.ts +106 -0
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # oxc-configs
2
2
 
3
- OXC toolset pre-made configs + fetch CLI.
3
+ OXC toolset pre-made/opinioated configs + setup and fetch CLI.
4
4
 
5
5
  ## Prerequisites
6
6
 
package/index.ts CHANGED
@@ -1,9 +1,11 @@
1
1
  #! /usr/bin/env bun
2
2
 
3
- import { cancel, intro, isCancel, log, outro, select, spinner } from '@clack/prompts';
3
+ import { cancel, confirm, intro, isCancel, log, outro, select, spinner } from '@clack/prompts';
4
4
  import { $ } from 'bun';
5
5
  import { bold, green, yellow } from 'picocolors';
6
6
 
7
+ import { detectPackageManager, hasGlobalInstallation, installDependencies } from './utils';
8
+
7
9
  enum Template {
8
10
  ReactTypeScript = 'react-typescript',
9
11
  TypeScript = 'typescript',
@@ -14,7 +16,7 @@ async function main() {
14
16
  const argv = process.argv.slice(2);
15
17
  let template: string | symbol | undefined = argv[0];
16
18
 
17
- intro(yellow(`@simek/oxc-configs`));
19
+ intro(yellow(`oxc-configs`));
18
20
 
19
21
  if (!template) {
20
22
  template = await select({
@@ -46,6 +48,43 @@ async function main() {
46
48
  process.exit(1);
47
49
  }
48
50
 
51
+ const installDeps = await confirm({
52
+ message: 'Do you want to install or update OXC dependencies?',
53
+ });
54
+
55
+ if (isCancel(installDeps)) {
56
+ cancel('Dependencies installation process has been cancelled.');
57
+ process.exit(0);
58
+ }
59
+
60
+ if (installDeps) {
61
+ const pm = await detectPackageManager();
62
+
63
+ if (!(await hasGlobalInstallation(pm))) {
64
+ cancel(`The ${pm} lock has been detected but package manager seems to not be installed.`);
65
+ process.exit(1);
66
+ }
67
+
68
+ if ((template as Template) !== Template.JavaScript) {
69
+ const typeAware = await confirm({
70
+ message: 'Do you want to enable type aware linting?',
71
+ });
72
+
73
+ if (isCancel(typeAware)) {
74
+ cancel('OXC dependencies setup process has been cancelled.');
75
+ process.exit(0);
76
+ }
77
+
78
+ if (typeAware) {
79
+ await installDependencies(pm, ['oxlint', 'oxfmt', 'oxlint-tsgolint']);
80
+ } else {
81
+ await installDependencies(pm, ['oxlint', 'oxfmt']);
82
+ }
83
+ } else {
84
+ await installDependencies(pm, ['oxlint', 'oxfmt']);
85
+ }
86
+ }
87
+
49
88
  await fetchConfigsFromRepo(template, '.oxfmtrc.json');
50
89
  await fetchConfigsFromRepo(template, '.oxlintrc.json');
51
90
 
@@ -54,16 +93,12 @@ async function main() {
54
93
  outro(green('All done!'));
55
94
  }
56
95
 
57
- export async function fetchConfigsFromRepo(template: string, fileName: string) {
58
- let replaceFile: 'yes' | 'no' | symbol = 'yes';
96
+ async function fetchConfigsFromRepo(template: string, fileName: string) {
97
+ let replaceFile: boolean | symbol = true;
59
98
 
60
99
  if (await Bun.file(fileName).exists()) {
61
- replaceFile = await select({
100
+ replaceFile = await confirm({
62
101
  message: `${bold(fileName)} already exists. Do you want to replace its content with the template?`,
63
- options: [
64
- { value: 'no', label: 'No' },
65
- { value: 'yes', label: 'Yes' },
66
- ],
67
102
  });
68
103
 
69
104
  if (isCancel(replaceFile)) {
@@ -72,8 +107,8 @@ export async function fetchConfigsFromRepo(template: string, fileName: string) {
72
107
  }
73
108
  }
74
109
 
75
- if (replaceFile === 'no') {
76
- log.info(`Ignoring ${bold(fileName)} config file.`);
110
+ if (!replaceFile) {
111
+ log.info(`Skipping ${bold(fileName)} config file.`);
77
112
  } else {
78
113
  const progress = spinner();
79
114
  progress.start(`Fetching ${bold(fileName)} config file...`);
@@ -85,7 +120,7 @@ export async function fetchConfigsFromRepo(template: string, fileName: string) {
85
120
  const config = await configContent.json();
86
121
  await Bun.write(fileName, JSON.stringify(config));
87
122
 
88
- progress.stop(`${bold(fileName)} fetched and written`);
123
+ progress.stop(`${bold(fileName)} fetched and written.`);
89
124
  }
90
125
  }
91
126
 
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "oxc-configs",
3
- "description": "OXC toolset pre-made configs.",
4
- "version": "0.0.3",
3
+ "description": "OXC toolset pre-made/opinioated configs + setup and fetch CLI",
4
+ "version": "0.0.4",
5
5
  "bugs": {
6
6
  "url": "https://github.com/simek/oxc-configs/issues"
7
7
  },
@@ -11,7 +11,8 @@
11
11
  "oxc-configs": "index.ts"
12
12
  },
13
13
  "files": [
14
- "index.ts"
14
+ "index.ts",
15
+ "utils.ts"
15
16
  ],
16
17
  "type": "module",
17
18
  "module": "index.ts",
@@ -24,10 +25,10 @@
24
25
  "picocolors": "^1.1.1"
25
26
  },
26
27
  "devDependencies": {
27
- "@types/bun": "^1.3.7",
28
+ "@types/bun": "^1.3.8",
28
29
  "oxfmt": "^0.27.0",
29
30
  "oxlint": "^1.42.0",
30
- "oxlint-tsgolint": "^0.11.3",
31
+ "oxlint-tsgolint": "^0.11.4",
31
32
  "typescript": "^5.9.3"
32
33
  },
33
34
  "engines": {
package/utils.ts ADDED
@@ -0,0 +1,106 @@
1
+ import { cancel, log } from '@clack/prompts';
2
+ import { $, file } from 'bun';
3
+ import { bold } from 'picocolors';
4
+
5
+ type PM = 'npm' | 'yarn' | 'pnpm' | 'bun';
6
+
7
+ export type CommandToRun = {
8
+ exe: PM;
9
+ args: string[];
10
+ };
11
+
12
+ export async function hasGlobalInstallation(pm: PM | null | undefined): Promise<boolean> {
13
+ if (!pm) {
14
+ return false;
15
+ }
16
+ try {
17
+ await $`${pm} --version`.quiet();
18
+ return true;
19
+ } catch {
20
+ return false;
21
+ }
22
+ }
23
+
24
+ async function getTypeofLockFile(): Promise<PM | null> {
25
+ const [isYarn, isPnpm, isBun, isBunBinary, isNpm] = await Promise.all([
26
+ file('yarn.lock').exists(),
27
+ file('pnpm-lock.yaml').exists(),
28
+ file('bun.lock').exists(),
29
+ file('bun.lockb').exists(),
30
+ file('package-lock.json').exists(),
31
+ ]);
32
+
33
+ if (isYarn) {
34
+ return 'yarn';
35
+ } else if (isPnpm) {
36
+ return 'pnpm';
37
+ } else if (isBun || isBunBinary) {
38
+ return 'bun';
39
+ }
40
+ if (isNpm) {
41
+ return 'npm';
42
+ }
43
+
44
+ return null;
45
+ }
46
+
47
+ export async function detectPackageManager(): Promise<PM | null> {
48
+ const type = await getTypeofLockFile();
49
+
50
+ if (type) {
51
+ return type;
52
+ }
53
+ const [hasYarn, hasPnpm, hasBun, hasNpm] = await Promise.all([
54
+ hasGlobalInstallation('yarn'),
55
+ hasGlobalInstallation('pnpm'),
56
+ hasGlobalInstallation('bun'),
57
+ hasGlobalInstallation('npm'),
58
+ ]);
59
+ if (hasYarn) {
60
+ return 'yarn';
61
+ } else if (hasPnpm) {
62
+ return 'pnpm';
63
+ } else if (hasBun) {
64
+ return 'bun';
65
+ } else if (hasNpm) {
66
+ return 'npm';
67
+ }
68
+ return null;
69
+ }
70
+
71
+ export function getCommandToRun(packages: string[], preferredManager: PM, version?: string): CommandToRun {
72
+ const args: string[] = [];
73
+
74
+ switch (preferredManager) {
75
+ case 'bun':
76
+ case 'pnpm':
77
+ case 'yarn':
78
+ args.push('add', '-D');
79
+ break;
80
+ default:
81
+ args.push('install', '-D');
82
+ break;
83
+ }
84
+
85
+ return {
86
+ exe: preferredManager,
87
+ args: [
88
+ ...args,
89
+ ...packages
90
+ .map(p => p.trim())
91
+ .filter(Boolean)
92
+ .map(p => (version ? `${p}@${version}` : p)),
93
+ ],
94
+ };
95
+ }
96
+
97
+ export async function installDependencies(pm: PM, deps: string[]) {
98
+ log.info(`Installing ${bold(deps.join(', '))} packages using ${bold(pm)}.`);
99
+ try {
100
+ const { exe, args } = getCommandToRun(deps, pm, 'latest');
101
+ await $`${exe} ${args}`.quiet();
102
+ } catch (error) {
103
+ cancel(`OXC dependencies cannot be installed. ${error}`);
104
+ process.exit(0);
105
+ }
106
+ }