create-bunli 0.7.0 → 0.8.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.
- package/README.md +18 -6
- package/dist/cli.d.ts +1 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +372 -195
- package/dist/create-project.d.ts +5 -4
- package/dist/create-project.d.ts.map +1 -0
- package/dist/create.d.ts +4 -3
- package/dist/create.d.ts.map +1 -0
- package/dist/index.d.ts +6 -3
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +344 -187
- package/dist/steps.d.ts +36 -0
- package/dist/steps.d.ts.map +1 -0
- package/dist/template-engine.d.ts +3 -2
- package/dist/template-engine.d.ts.map +1 -0
- package/dist/templates/advanced/README.md +8 -4
- package/dist/templates/advanced/bunli.config.ts +19 -19
- package/dist/templates/advanced/package.json +9 -4
- package/dist/templates/advanced/src/commands/config.ts +129 -118
- package/dist/templates/advanced/src/commands/init.ts +53 -59
- package/dist/templates/advanced/src/commands/serve.ts +77 -82
- package/dist/templates/advanced/src/commands/validate.ts +58 -64
- package/dist/templates/advanced/src/index.ts +30 -29
- package/dist/templates/advanced/src/utils/config.ts +48 -47
- package/dist/templates/advanced/src/utils/constants.ts +6 -6
- package/dist/templates/advanced/src/utils/glob.ts +29 -28
- package/dist/templates/advanced/src/utils/validator.ts +60 -61
- package/dist/templates/advanced/template.json +2 -6
- package/dist/templates/advanced/tsconfig.json +1 -1
- package/dist/templates/basic/README.md +1 -1
- package/dist/templates/basic/bunli.config.ts +17 -17
- package/dist/templates/basic/package.json +4 -3
- package/dist/templates/basic/src/commands/hello.ts +20 -25
- package/dist/templates/basic/src/index.ts +9 -8
- package/dist/templates/basic/template.json +2 -6
- package/dist/templates/basic/tsconfig.json +1 -1
- package/dist/templates/monorepo/README.md +1 -1
- package/dist/templates/monorepo/bunli.config.ts +21 -21
- package/dist/templates/monorepo/package.json +3 -2
- package/dist/templates/monorepo/packages/cli/package.json +10 -5
- package/dist/templates/monorepo/packages/cli/src/index.ts +13 -13
- package/dist/templates/monorepo/packages/cli/tsconfig.json +3 -6
- package/dist/templates/monorepo/packages/core/package.json +6 -5
- package/dist/templates/monorepo/packages/core/scripts/build.ts +10 -10
- package/dist/templates/monorepo/packages/core/src/commands/analyze.ts +58 -56
- package/dist/templates/monorepo/packages/core/src/commands/process.ts +39 -46
- package/dist/templates/monorepo/packages/core/src/index.ts +3 -3
- package/dist/templates/monorepo/packages/core/src/types.ts +15 -15
- package/dist/templates/monorepo/packages/core/tsconfig.json +3 -5
- package/dist/templates/monorepo/packages/utils/package.json +6 -5
- package/dist/templates/monorepo/packages/utils/scripts/build.ts +10 -10
- package/dist/templates/monorepo/packages/utils/src/format.ts +19 -19
- package/dist/templates/monorepo/packages/utils/src/index.ts +3 -3
- package/dist/templates/monorepo/packages/utils/src/json.ts +4 -4
- package/dist/templates/monorepo/packages/utils/src/logger.ts +9 -9
- package/dist/templates/monorepo/packages/utils/tsconfig.json +2 -2
- package/dist/templates/monorepo/template.json +2 -6
- package/dist/templates/monorepo/tsconfig.json +1 -1
- package/dist/templates/monorepo/turbo.json +1 -1
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -0
- package/package.json +35 -34
- package/templates/advanced/README.md +8 -4
- package/templates/advanced/bunli.config.ts +19 -19
- package/templates/advanced/package.json +9 -4
- package/templates/advanced/src/commands/config.ts +129 -118
- package/templates/advanced/src/commands/init.ts +53 -59
- package/templates/advanced/src/commands/serve.ts +77 -82
- package/templates/advanced/src/commands/validate.ts +58 -64
- package/templates/advanced/src/index.ts +30 -29
- package/templates/advanced/src/utils/config.ts +48 -47
- package/templates/advanced/src/utils/constants.ts +6 -6
- package/templates/advanced/src/utils/glob.ts +29 -28
- package/templates/advanced/src/utils/validator.ts +60 -61
- package/templates/advanced/template.json +2 -6
- package/templates/advanced/tsconfig.json +1 -1
- package/templates/basic/README.md +1 -1
- package/templates/basic/bunli.config.ts +17 -17
- package/templates/basic/package.json +4 -3
- package/templates/basic/src/commands/hello.ts +20 -25
- package/templates/basic/src/index.ts +9 -8
- package/templates/basic/template.json +2 -6
- package/templates/basic/tsconfig.json +1 -1
- package/templates/monorepo/README.md +1 -1
- package/templates/monorepo/bunli.config.ts +21 -21
- package/templates/monorepo/package.json +3 -2
- package/templates/monorepo/packages/cli/package.json +10 -5
- package/templates/monorepo/packages/cli/src/index.ts +13 -13
- package/templates/monorepo/packages/cli/tsconfig.json +3 -6
- package/templates/monorepo/packages/core/package.json +6 -5
- package/templates/monorepo/packages/core/scripts/build.ts +10 -10
- package/templates/monorepo/packages/core/src/commands/analyze.ts +58 -56
- package/templates/monorepo/packages/core/src/commands/process.ts +39 -46
- package/templates/monorepo/packages/core/src/index.ts +3 -3
- package/templates/monorepo/packages/core/src/types.ts +15 -15
- package/templates/monorepo/packages/core/tsconfig.json +3 -5
- package/templates/monorepo/packages/utils/package.json +6 -5
- package/templates/monorepo/packages/utils/scripts/build.ts +10 -10
- package/templates/monorepo/packages/utils/src/format.ts +19 -19
- package/templates/monorepo/packages/utils/src/index.ts +3 -3
- package/templates/monorepo/packages/utils/src/json.ts +4 -4
- package/templates/monorepo/packages/utils/src/logger.ts +9 -9
- package/templates/monorepo/packages/utils/tsconfig.json +2 -2
- package/templates/monorepo/template.json +2 -6
- package/templates/monorepo/tsconfig.json +1 -1
- package/templates/monorepo/turbo.json +1 -1
|
@@ -1,33 +1,33 @@
|
|
|
1
|
-
import { defineConfig } from
|
|
1
|
+
import { defineConfig } from "@bunli/core";
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
|
-
name:
|
|
5
|
-
version:
|
|
6
|
-
description:
|
|
7
|
-
|
|
4
|
+
name: "{{name}}",
|
|
5
|
+
version: "{{version}}",
|
|
6
|
+
description: "{{description}}",
|
|
7
|
+
|
|
8
8
|
commands: {
|
|
9
|
-
directory:
|
|
9
|
+
directory: "./src/commands",
|
|
10
10
|
},
|
|
11
|
-
|
|
11
|
+
|
|
12
12
|
plugins: [],
|
|
13
|
-
|
|
13
|
+
|
|
14
14
|
build: {
|
|
15
|
-
entry:
|
|
16
|
-
outdir:
|
|
17
|
-
targets: [
|
|
15
|
+
entry: "./src/index.ts",
|
|
16
|
+
outdir: "./dist",
|
|
17
|
+
targets: ["darwin-arm64", "darwin-x64", "linux-x64", "windows-x64"],
|
|
18
18
|
minify: true,
|
|
19
19
|
sourcemap: true,
|
|
20
|
-
compress: true
|
|
20
|
+
compress: true,
|
|
21
21
|
},
|
|
22
|
-
|
|
22
|
+
|
|
23
23
|
dev: {
|
|
24
24
|
watch: true,
|
|
25
|
-
inspect: false
|
|
25
|
+
inspect: false,
|
|
26
26
|
},
|
|
27
|
-
|
|
27
|
+
|
|
28
28
|
test: {
|
|
29
|
-
pattern: [
|
|
29
|
+
pattern: ["**/*.test.ts", "**/*.spec.ts"],
|
|
30
30
|
coverage: true,
|
|
31
|
-
watch: false
|
|
32
|
-
}
|
|
33
|
-
})
|
|
31
|
+
watch: false,
|
|
32
|
+
},
|
|
33
|
+
});
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "{{name}}",
|
|
3
3
|
"version": "0.1.0",
|
|
4
|
-
"type": "module",
|
|
5
4
|
"description": "{{description}}",
|
|
6
|
-
"author": "{{author}}",
|
|
7
5
|
"license": "{{license}}",
|
|
6
|
+
"author": "{{author}}",
|
|
8
7
|
"bin": {
|
|
9
8
|
"{{name}}": "./dist/index.js"
|
|
10
9
|
},
|
|
10
|
+
"type": "module",
|
|
11
11
|
"scripts": {
|
|
12
12
|
"postinstall": "bunli generate",
|
|
13
13
|
"dev": "bun run src/index.ts",
|
|
14
14
|
"build": "bunli build",
|
|
15
15
|
"test": "bun test",
|
|
16
16
|
"test:watch": "bun test --watch",
|
|
17
|
-
"typecheck": "
|
|
17
|
+
"typecheck": "tsgo --noEmit",
|
|
18
18
|
"lint": "tsc --noEmit",
|
|
19
19
|
"prepare": "bun run build"
|
|
20
20
|
},
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
28
|
"@bunli/test": "latest",
|
|
29
|
+
"@tsconfig/bun": "catalog:",
|
|
29
30
|
"@types/bun": "latest",
|
|
30
31
|
"bunli": "latest",
|
|
31
32
|
"typescript": "^5.0.0"
|
|
@@ -33,6 +34,10 @@
|
|
|
33
34
|
"bunli": {
|
|
34
35
|
"entry": "./src/index.ts",
|
|
35
36
|
"outDir": "./dist",
|
|
36
|
-
"external": [
|
|
37
|
+
"external": [
|
|
38
|
+
"@bunli/core",
|
|
39
|
+
"@bunli/utils",
|
|
40
|
+
"zod"
|
|
41
|
+
]
|
|
37
42
|
}
|
|
38
43
|
}
|
|
@@ -1,229 +1,240 @@
|
|
|
1
|
-
import { defineCommand, option } from
|
|
2
|
-
import { Result, TaggedError } from
|
|
3
|
-
import { z } from
|
|
4
|
-
|
|
5
|
-
import {
|
|
1
|
+
import { defineCommand, option } from "@bunli/core";
|
|
2
|
+
import { Result, TaggedError } from "better-result";
|
|
3
|
+
import { z } from "zod";
|
|
4
|
+
|
|
5
|
+
import { loadConfig, saveConfig, getConfigPath } from "../utils/config.js";
|
|
6
|
+
import { DEFAULT_CONFIG } from "../utils/constants.js";
|
|
6
7
|
|
|
7
8
|
const toErrorMessage = (error: unknown): string =>
|
|
8
|
-
error instanceof Error ? error.message : String(error)
|
|
9
|
+
error instanceof Error ? error.message : String(error);
|
|
9
10
|
|
|
10
|
-
class ConfigCommandError extends TaggedError(
|
|
11
|
-
message: string
|
|
12
|
-
cause?: unknown
|
|
11
|
+
class ConfigCommandError extends TaggedError("ConfigCommandError")<{
|
|
12
|
+
message: string;
|
|
13
|
+
cause?: unknown;
|
|
13
14
|
}>() {
|
|
14
15
|
constructor(message: string, cause?: unknown) {
|
|
15
|
-
super(cause === undefined ? { message } : { message, cause })
|
|
16
|
+
super(cause === undefined ? { message } : { message, cause });
|
|
16
17
|
}
|
|
17
18
|
}
|
|
18
19
|
|
|
19
20
|
const configCommand = defineCommand({
|
|
20
|
-
name:
|
|
21
|
-
description:
|
|
21
|
+
name: "config",
|
|
22
|
+
description: "Manage configuration",
|
|
22
23
|
commands: [
|
|
23
24
|
defineCommand({
|
|
24
|
-
name:
|
|
25
|
-
description:
|
|
25
|
+
name: "get",
|
|
26
|
+
description: "Get a config value",
|
|
26
27
|
handler: async ({ positional, colors }) => {
|
|
27
|
-
const key = positional[0]
|
|
28
|
+
const key = positional[0];
|
|
28
29
|
if (!key) {
|
|
29
|
-
console.error(colors.red(
|
|
30
|
-
process.exitCode = 1
|
|
31
|
-
return
|
|
30
|
+
console.error(colors.red("Usage: config get <key>"));
|
|
31
|
+
process.exitCode = 1;
|
|
32
|
+
return;
|
|
32
33
|
}
|
|
33
34
|
|
|
34
35
|
const configResult = await Result.tryPromise({
|
|
35
36
|
try: () => loadConfig(),
|
|
36
|
-
catch: (cause) =>
|
|
37
|
-
|
|
37
|
+
catch: (cause) =>
|
|
38
|
+
new ConfigCommandError(`Failed to load config: ${toErrorMessage(cause)}`, cause),
|
|
39
|
+
});
|
|
38
40
|
|
|
39
41
|
if (Result.isError(configResult)) {
|
|
40
|
-
console.error(colors.red(configResult.error.message))
|
|
41
|
-
process.exitCode = 1
|
|
42
|
-
return
|
|
42
|
+
console.error(colors.red(configResult.error.message));
|
|
43
|
+
process.exitCode = 1;
|
|
44
|
+
return;
|
|
43
45
|
}
|
|
44
46
|
|
|
45
|
-
const value = getNestedValue(configResult.value as Record<string, unknown>, key)
|
|
47
|
+
const value = getNestedValue(configResult.value as Record<string, unknown>, key);
|
|
46
48
|
|
|
47
49
|
if (value === undefined) {
|
|
48
|
-
console.log(colors.yellow(`Config key '${key}' not found`))
|
|
50
|
+
console.log(colors.yellow(`Config key '${key}' not found`));
|
|
49
51
|
} else {
|
|
50
|
-
console.log(JSON.stringify(value, null, 2))
|
|
52
|
+
console.log(JSON.stringify(value, null, 2));
|
|
51
53
|
}
|
|
52
|
-
}
|
|
54
|
+
},
|
|
53
55
|
}),
|
|
54
56
|
|
|
55
57
|
defineCommand({
|
|
56
|
-
name:
|
|
57
|
-
description:
|
|
58
|
+
name: "set",
|
|
59
|
+
description: "Set a config value",
|
|
58
60
|
handler: async ({ positional, colors, spinner }) => {
|
|
59
|
-
const key = positional[0]
|
|
60
|
-
const rawValue = positional[1]
|
|
61
|
+
const key = positional[0];
|
|
62
|
+
const rawValue = positional[1];
|
|
61
63
|
|
|
62
64
|
if (!key || rawValue === undefined) {
|
|
63
|
-
console.error(colors.red(
|
|
64
|
-
process.exitCode = 1
|
|
65
|
-
return
|
|
65
|
+
console.error(colors.red("Usage: config set <key> <json-value>"));
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
return;
|
|
66
68
|
}
|
|
67
69
|
|
|
68
|
-
const spin = spinner(
|
|
69
|
-
spin.start()
|
|
70
|
+
const spin = spinner("Updating config...");
|
|
71
|
+
spin.start();
|
|
70
72
|
|
|
71
73
|
const configResult = await Result.tryPromise({
|
|
72
74
|
try: () => loadConfig(),
|
|
73
|
-
catch: (cause) =>
|
|
74
|
-
|
|
75
|
+
catch: (cause) =>
|
|
76
|
+
new ConfigCommandError(`Failed to load config: ${toErrorMessage(cause)}`, cause),
|
|
77
|
+
});
|
|
75
78
|
|
|
76
79
|
if (Result.isError(configResult)) {
|
|
77
|
-
spin.fail(
|
|
78
|
-
console.error(colors.red(configResult.error.message))
|
|
79
|
-
process.exitCode = 1
|
|
80
|
-
return
|
|
80
|
+
spin.fail("Failed to update config");
|
|
81
|
+
console.error(colors.red(configResult.error.message));
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
return;
|
|
81
84
|
}
|
|
82
85
|
|
|
83
86
|
const parsedValue = Result.try({
|
|
84
87
|
try: () => JSON.parse(rawValue),
|
|
85
88
|
catch: (cause) =>
|
|
86
|
-
new ConfigCommandError(
|
|
87
|
-
|
|
89
|
+
new ConfigCommandError(
|
|
90
|
+
`Failed to parse value as JSON: ${toErrorMessage(cause)}`,
|
|
91
|
+
cause,
|
|
92
|
+
),
|
|
93
|
+
});
|
|
88
94
|
|
|
89
95
|
if (Result.isError(parsedValue)) {
|
|
90
|
-
spin.fail(
|
|
91
|
-
console.error(colors.red(parsedValue.error.message))
|
|
92
|
-
process.exitCode = 1
|
|
93
|
-
return
|
|
96
|
+
spin.fail("Failed to update config");
|
|
97
|
+
console.error(colors.red(parsedValue.error.message));
|
|
98
|
+
process.exitCode = 1;
|
|
99
|
+
return;
|
|
94
100
|
}
|
|
95
101
|
|
|
96
|
-
const nextConfig = configResult.value as Record<string, unknown
|
|
97
|
-
setNestedValue(nextConfig, key, parsedValue.value)
|
|
102
|
+
const nextConfig = configResult.value as Record<string, unknown>;
|
|
103
|
+
setNestedValue(nextConfig, key, parsedValue.value);
|
|
98
104
|
|
|
99
105
|
const saveResult = await Result.tryPromise({
|
|
100
106
|
try: () => saveConfig(nextConfig),
|
|
101
|
-
catch: (cause) =>
|
|
102
|
-
|
|
107
|
+
catch: (cause) =>
|
|
108
|
+
new ConfigCommandError(`Failed to save config: ${toErrorMessage(cause)}`, cause),
|
|
109
|
+
});
|
|
103
110
|
|
|
104
111
|
if (Result.isError(saveResult)) {
|
|
105
|
-
spin.fail(
|
|
106
|
-
console.error(colors.red(saveResult.error.message))
|
|
107
|
-
process.exitCode = 1
|
|
108
|
-
return
|
|
112
|
+
spin.fail("Failed to update config");
|
|
113
|
+
console.error(colors.red(saveResult.error.message));
|
|
114
|
+
process.exitCode = 1;
|
|
115
|
+
return;
|
|
109
116
|
}
|
|
110
117
|
|
|
111
|
-
spin.succeed(`Config '${key}' updated`)
|
|
112
|
-
}
|
|
118
|
+
spin.succeed(`Config '${key}' updated`);
|
|
119
|
+
},
|
|
113
120
|
}),
|
|
114
121
|
|
|
115
122
|
defineCommand({
|
|
116
|
-
name:
|
|
117
|
-
description:
|
|
123
|
+
name: "list",
|
|
124
|
+
description: "List all config values",
|
|
118
125
|
handler: async ({ colors }) => {
|
|
119
126
|
const configResult = await Result.tryPromise({
|
|
120
127
|
try: () => loadConfig(),
|
|
121
|
-
catch: (cause) =>
|
|
122
|
-
|
|
128
|
+
catch: (cause) =>
|
|
129
|
+
new ConfigCommandError(`Failed to load config: ${toErrorMessage(cause)}`, cause),
|
|
130
|
+
});
|
|
123
131
|
|
|
124
132
|
if (Result.isError(configResult)) {
|
|
125
|
-
console.error(colors.red(configResult.error.message))
|
|
126
|
-
process.exitCode = 1
|
|
127
|
-
return
|
|
133
|
+
console.error(colors.red(configResult.error.message));
|
|
134
|
+
process.exitCode = 1;
|
|
135
|
+
return;
|
|
128
136
|
}
|
|
129
137
|
|
|
130
138
|
const configPathResult = await Result.tryPromise({
|
|
131
139
|
try: () => getConfigPath(),
|
|
132
|
-
catch: (cause) =>
|
|
133
|
-
|
|
140
|
+
catch: (cause) =>
|
|
141
|
+
new ConfigCommandError(
|
|
142
|
+
`Failed to resolve config path: ${toErrorMessage(cause)}`,
|
|
143
|
+
cause,
|
|
144
|
+
),
|
|
145
|
+
});
|
|
134
146
|
|
|
135
147
|
if (Result.isError(configPathResult)) {
|
|
136
|
-
console.error(colors.red(configPathResult.error.message))
|
|
137
|
-
process.exitCode = 1
|
|
138
|
-
return
|
|
148
|
+
console.error(colors.red(configPathResult.error.message));
|
|
149
|
+
process.exitCode = 1;
|
|
150
|
+
return;
|
|
139
151
|
}
|
|
140
152
|
|
|
141
|
-
console.log(colors.bold(
|
|
142
|
-
console.log(colors.dim(` File: ${configPathResult.value}`))
|
|
143
|
-
console.log()
|
|
144
|
-
console.log(JSON.stringify(configResult.value, null, 2))
|
|
145
|
-
}
|
|
153
|
+
console.log(colors.bold("Configuration:"));
|
|
154
|
+
console.log(colors.dim(` File: ${configPathResult.value}`));
|
|
155
|
+
console.log();
|
|
156
|
+
console.log(JSON.stringify(configResult.value, null, 2));
|
|
157
|
+
},
|
|
146
158
|
}),
|
|
147
159
|
|
|
148
160
|
defineCommand({
|
|
149
|
-
name:
|
|
150
|
-
description:
|
|
161
|
+
name: "reset",
|
|
162
|
+
description: "Reset config to defaults",
|
|
151
163
|
options: {
|
|
152
|
-
force: option(
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
}
|
|
158
|
-
)
|
|
164
|
+
force: option(z.boolean().default(false), {
|
|
165
|
+
short: "f",
|
|
166
|
+
description: "Skip confirmation",
|
|
167
|
+
argumentKind: "flag",
|
|
168
|
+
}),
|
|
159
169
|
},
|
|
160
170
|
handler: async ({ flags, colors, prompt, spinner }) => {
|
|
161
171
|
if (!flags.force) {
|
|
162
172
|
const confirmed = await prompt.confirm(
|
|
163
|
-
|
|
164
|
-
{ default: false }
|
|
165
|
-
)
|
|
173
|
+
"This will reset all config to defaults. Continue?",
|
|
174
|
+
{ default: false },
|
|
175
|
+
);
|
|
166
176
|
|
|
167
177
|
if (!confirmed) {
|
|
168
|
-
console.log(colors.yellow(
|
|
169
|
-
return
|
|
178
|
+
console.log(colors.yellow("Reset cancelled"));
|
|
179
|
+
return;
|
|
170
180
|
}
|
|
171
181
|
}
|
|
172
182
|
|
|
173
|
-
const spin = spinner(
|
|
174
|
-
spin.start()
|
|
183
|
+
const spin = spinner("Resetting config...");
|
|
184
|
+
spin.start();
|
|
175
185
|
|
|
176
186
|
const saveResult = await Result.tryPromise({
|
|
177
187
|
try: () => saveConfig(DEFAULT_CONFIG),
|
|
178
|
-
catch: (cause) =>
|
|
179
|
-
|
|
188
|
+
catch: (cause) =>
|
|
189
|
+
new ConfigCommandError(`Failed to save config: ${toErrorMessage(cause)}`, cause),
|
|
190
|
+
});
|
|
180
191
|
|
|
181
192
|
if (Result.isError(saveResult)) {
|
|
182
|
-
spin.fail(
|
|
183
|
-
console.error(colors.red(saveResult.error.message))
|
|
184
|
-
process.exitCode = 1
|
|
185
|
-
return
|
|
193
|
+
spin.fail("Failed to reset config");
|
|
194
|
+
console.error(colors.red(saveResult.error.message));
|
|
195
|
+
process.exitCode = 1;
|
|
196
|
+
return;
|
|
186
197
|
}
|
|
187
198
|
|
|
188
|
-
spin.succeed(
|
|
189
|
-
}
|
|
190
|
-
})
|
|
191
|
-
]
|
|
192
|
-
})
|
|
199
|
+
spin.succeed("Config reset to defaults");
|
|
200
|
+
},
|
|
201
|
+
}),
|
|
202
|
+
],
|
|
203
|
+
});
|
|
193
204
|
|
|
194
205
|
function getNestedValue(obj: Record<string, unknown>, path: string): unknown {
|
|
195
|
-
const keys = path.split(
|
|
196
|
-
let current: unknown = obj
|
|
206
|
+
const keys = path.split(".");
|
|
207
|
+
let current: unknown = obj;
|
|
197
208
|
|
|
198
209
|
for (const key of keys) {
|
|
199
|
-
if (!current || typeof current !==
|
|
200
|
-
return undefined
|
|
210
|
+
if (!current || typeof current !== "object") {
|
|
211
|
+
return undefined;
|
|
201
212
|
}
|
|
202
213
|
|
|
203
|
-
current = (current as Record<string, unknown>)[key]
|
|
214
|
+
current = (current as Record<string, unknown>)[key];
|
|
204
215
|
}
|
|
205
216
|
|
|
206
|
-
return current
|
|
217
|
+
return current;
|
|
207
218
|
}
|
|
208
219
|
|
|
209
220
|
function setNestedValue(obj: Record<string, unknown>, path: string, value: unknown): void {
|
|
210
|
-
const keys = path.split(
|
|
211
|
-
const lastKey = keys.pop()
|
|
221
|
+
const keys = path.split(".");
|
|
222
|
+
const lastKey = keys.pop();
|
|
212
223
|
if (!lastKey) {
|
|
213
|
-
return
|
|
224
|
+
return;
|
|
214
225
|
}
|
|
215
226
|
|
|
216
|
-
let current: Record<string, unknown> = obj
|
|
227
|
+
let current: Record<string, unknown> = obj;
|
|
217
228
|
|
|
218
229
|
for (const key of keys) {
|
|
219
|
-
const next = current[key]
|
|
220
|
-
if (!next || typeof next !==
|
|
221
|
-
current[key] = {}
|
|
230
|
+
const next = current[key];
|
|
231
|
+
if (!next || typeof next !== "object" || Array.isArray(next)) {
|
|
232
|
+
current[key] = {};
|
|
222
233
|
}
|
|
223
|
-
current = current[key] as Record<string, unknown
|
|
234
|
+
current = current[key] as Record<string, unknown>;
|
|
224
235
|
}
|
|
225
236
|
|
|
226
|
-
current[lastKey] = value
|
|
237
|
+
current[lastKey] = value;
|
|
227
238
|
}
|
|
228
239
|
|
|
229
|
-
export default configCommand
|
|
240
|
+
export default configCommand;
|
|
@@ -1,74 +1,68 @@
|
|
|
1
|
-
import { defineCommand, option } from
|
|
2
|
-
import { z } from
|
|
3
|
-
|
|
1
|
+
import { defineCommand, option } from "@bunli/core";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
|
|
4
|
+
import { CONFIG_FILE_NAME, DEFAULT_CONFIG } from "../utils/constants.js";
|
|
4
5
|
|
|
5
6
|
const initCommand = defineCommand({
|
|
6
|
-
name:
|
|
7
|
-
description:
|
|
7
|
+
name: "init",
|
|
8
|
+
description: "Initialize a new configuration file",
|
|
8
9
|
options: {
|
|
9
|
-
force: option(
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
{
|
|
19
|
-
short: 't',
|
|
20
|
-
description: 'Config template to use'
|
|
21
|
-
}
|
|
22
|
-
)
|
|
10
|
+
force: option(z.boolean().default(false), {
|
|
11
|
+
short: "f",
|
|
12
|
+
description: "Overwrite existing config",
|
|
13
|
+
argumentKind: "flag",
|
|
14
|
+
}),
|
|
15
|
+
template: option(z.enum(["minimal", "default", "full"]).default("default"), {
|
|
16
|
+
short: "t",
|
|
17
|
+
description: "Config template to use",
|
|
18
|
+
}),
|
|
23
19
|
},
|
|
24
20
|
handler: async ({ flags, colors, prompt, spinner }) => {
|
|
25
|
-
const configPath = `${process.cwd()}/${CONFIG_FILE_NAME}
|
|
26
|
-
|
|
21
|
+
const configPath = `${process.cwd()}/${CONFIG_FILE_NAME}`;
|
|
22
|
+
|
|
27
23
|
// Check if config already exists
|
|
28
|
-
const configFile = Bun.file(configPath)
|
|
29
|
-
if (await configFile.exists() && !flags.force) {
|
|
30
|
-
const overwrite = await prompt.confirm(
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
24
|
+
const configFile = Bun.file(configPath);
|
|
25
|
+
if ((await configFile.exists()) && !flags.force) {
|
|
26
|
+
const overwrite = await prompt.confirm(`Config file already exists. Overwrite?`, {
|
|
27
|
+
default: false,
|
|
28
|
+
});
|
|
29
|
+
|
|
35
30
|
if (!overwrite) {
|
|
36
|
-
console.log(colors.yellow(
|
|
37
|
-
return
|
|
31
|
+
console.log(colors.yellow("Init cancelled"));
|
|
32
|
+
return;
|
|
38
33
|
}
|
|
39
34
|
}
|
|
40
|
-
|
|
41
|
-
const spin = spinner(
|
|
42
|
-
spin.start()
|
|
43
|
-
|
|
35
|
+
|
|
36
|
+
const spin = spinner("Creating config file...");
|
|
37
|
+
spin.start();
|
|
38
|
+
|
|
44
39
|
try {
|
|
45
40
|
// Get template content
|
|
46
|
-
const configContent = getConfigTemplate(flags.template)
|
|
47
|
-
|
|
41
|
+
const configContent = getConfigTemplate(flags.template);
|
|
42
|
+
|
|
48
43
|
// Write config file
|
|
49
|
-
await Bun.write(configPath, configContent)
|
|
50
|
-
|
|
51
|
-
spin.succeed(
|
|
52
|
-
console.log(colors.dim(` ${CONFIG_FILE_NAME}`))
|
|
53
|
-
|
|
44
|
+
await Bun.write(configPath, configContent);
|
|
45
|
+
|
|
46
|
+
spin.succeed("Config file created");
|
|
47
|
+
console.log(colors.dim(` ${CONFIG_FILE_NAME}`));
|
|
48
|
+
|
|
54
49
|
// Next steps
|
|
55
|
-
console.log()
|
|
56
|
-
console.log(
|
|
57
|
-
console.log(colors.gray(` 1. Edit ${CONFIG_FILE_NAME} to customize your configuration`))
|
|
58
|
-
console.log(colors.gray(` 2. Run '{{name}} validate' to check your files`))
|
|
59
|
-
|
|
50
|
+
console.log();
|
|
51
|
+
console.log("Next steps:");
|
|
52
|
+
console.log(colors.gray(` 1. Edit ${CONFIG_FILE_NAME} to customize your configuration`));
|
|
53
|
+
console.log(colors.gray(` 2. Run '{{name}} validate' to check your files`));
|
|
60
54
|
} catch (error) {
|
|
61
|
-
spin.fail(
|
|
62
|
-
console.error(colors.red(String(error)))
|
|
63
|
-
process.exit(1)
|
|
55
|
+
spin.fail("Failed to create config file");
|
|
56
|
+
console.error(colors.red(String(error)));
|
|
57
|
+
process.exit(1);
|
|
64
58
|
}
|
|
65
|
-
}
|
|
66
|
-
})
|
|
59
|
+
},
|
|
60
|
+
});
|
|
67
61
|
|
|
68
|
-
function getConfigTemplate(template:
|
|
62
|
+
function getConfigTemplate(template: "minimal" | "default" | "full"): string {
|
|
69
63
|
const templates = {
|
|
70
64
|
minimal: `export default ${JSON.stringify(DEFAULT_CONFIG, null, 2)}`,
|
|
71
|
-
|
|
65
|
+
|
|
72
66
|
default: `export default {
|
|
73
67
|
// Validation rules
|
|
74
68
|
rules: {
|
|
@@ -88,7 +82,7 @@ function getConfigTemplate(template: 'minimal' | 'default' | 'full'): string {
|
|
|
88
82
|
include: ['src/**/*.{js,ts}'],
|
|
89
83
|
exclude: ['node_modules', 'dist', 'test'],
|
|
90
84
|
}`,
|
|
91
|
-
|
|
85
|
+
|
|
92
86
|
full: `import { defineConfig } from '{{name}}'
|
|
93
87
|
|
|
94
88
|
export default defineConfig({
|
|
@@ -146,10 +140,10 @@ export default defineConfig({
|
|
|
146
140
|
console.log(\`Found \${results.errors} errors and \${results.warnings} warnings\`)
|
|
147
141
|
},
|
|
148
142
|
},
|
|
149
|
-
})
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
return templates[template]
|
|
143
|
+
})`,
|
|
144
|
+
};
|
|
145
|
+
|
|
146
|
+
return templates[template];
|
|
153
147
|
}
|
|
154
148
|
|
|
155
|
-
export default initCommand
|
|
149
|
+
export default initCommand;
|