create-alistt69-kit 0.1.11 → 0.1.13
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/LICENSE +20 -20
- package/README.md +123 -123
- package/bin/index.js +24 -24
- package/package.json +44 -44
- package/src/core/apply-features.js +14 -14
- package/src/core/collect-project-info.js +170 -170
- package/src/core/copy-base-template.js +11 -11
- package/src/core/create-project.js +99 -99
- package/src/core/install-dependencies.js +27 -27
- package/src/core/parse-cli-args.js +122 -122
- package/src/core/prepare-target-directory.js +69 -69
- package/src/core/render-project-readme.js +188 -188
- package/src/core/replace-tokens.js +45 -45
- package/src/core/restore-special-files.js +18 -18
- package/src/features/autoprefixer/files/postcss.config.cjs +4 -4
- package/src/features/autoprefixer/index.js +18 -18
- package/src/features/define-feature.js +32 -32
- package/src/features/eslint/files/eslint.config.mjs +133 -133
- package/src/features/eslint/index.js +29 -29
- package/src/features/index.js +24 -24
- package/src/features/react-router/files/src/app/App.tsx +20 -20
- package/src/features/react-router/files/src/app/layouts/app/index.tsx +36 -36
- package/src/features/react-router/files/src/app/providers/router/config/router.tsx +13 -13
- package/src/features/react-router/files/src/pages/error/index.ts +1 -1
- package/src/features/react-router/files/src/pages/error/lazy.ts +3 -3
- package/src/features/react-router/files/src/pages/error/page.tsx +7 -7
- package/src/features/react-router/files/src/pages/main/index.ts +1 -1
- package/src/features/react-router/files/src/pages/main/lazy.ts +3 -3
- package/src/features/react-router/files/src/pages/main/page.tsx +7 -7
- package/src/features/react-router/index.js +18 -18
- package/src/features/stylelint/files/stylelint.config.mjs +13 -13
- package/src/features/stylelint/index.js +23 -23
- package/src/templates/base/.editorconfig +11 -11
- package/src/templates/base/README.md +2 -2
- package/src/templates/base/babel.config.json +12 -12
- package/src/templates/base/gitignore +27 -27
- package/src/templates/base/package.json +48 -48
- package/src/templates/base/public/index.html +12 -12
- package/src/templates/base/src/app/App.tsx +17 -17
- package/src/templates/base/src/index.tsx +16 -16
- package/src/templates/base/src/styles/index.scss +13 -13
- package/src/templates/base/tsconfig.json +25 -25
- package/src/utils/console-format.js +11 -11
- package/src/utils/package-json.js +96 -96
- package/src/utils/package-manager.js +22 -22
|
@@ -1,123 +1,123 @@
|
|
|
1
|
-
import { allowedPackageManagers } from '../utils/package-manager.js';
|
|
2
|
-
|
|
3
|
-
function readOptionValue(args, currentIndex, optionName) {
|
|
4
|
-
const currentArg = args[currentIndex];
|
|
5
|
-
|
|
6
|
-
if (currentArg.includes('=')) {
|
|
7
|
-
return {
|
|
8
|
-
value: currentArg.slice(currentArg.indexOf('=') + 1),
|
|
9
|
-
nextIndex: currentIndex,
|
|
10
|
-
};
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const nextArg = args[currentIndex + 1];
|
|
14
|
-
|
|
15
|
-
if (!nextArg || nextArg.startsWith('-')) {
|
|
16
|
-
throw new Error(`Option ${optionName} requires a value`);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
value: nextArg,
|
|
21
|
-
nextIndex: currentIndex + 1,
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export function formatHelpMessage() {
|
|
26
|
-
return [
|
|
27
|
-
'Usage:',
|
|
28
|
-
' create-alistt69-kit <project-name> [options]',
|
|
29
|
-
'',
|
|
30
|
-
'Options:',
|
|
31
|
-
' -def, --defaults Skip prompts and use defaults',
|
|
32
|
-
' --overwrite Overwrite target directory if it exists',
|
|
33
|
-
' --no-install Do not install dependencies',
|
|
34
|
-
' --features <comma-list> Example: eslint,stylelint,react-router',
|
|
35
|
-
' --features all Enable all features',
|
|
36
|
-
' --pm <npm|pnpm|yarn> Package manager',
|
|
37
|
-
' -h, --help Show help',
|
|
38
|
-
'',
|
|
39
|
-
'Defaults:',
|
|
40
|
-
' All features are enabled by default',
|
|
41
|
-
' Package manager: npm',
|
|
42
|
-
' Install dependencies: yes',
|
|
43
|
-
'',
|
|
44
|
-
'Examples:',
|
|
45
|
-
' create-alistt69-kit my-app',
|
|
46
|
-
' create-alistt69-kit my-app --features=all',
|
|
47
|
-
' create-alistt69-kit my-app --pm pnpm --no-install',
|
|
48
|
-
' create-alistt69-kit my-app --defaults',
|
|
49
|
-
' create-alistt69-kit my-app --defaults --overwrite',
|
|
50
|
-
].join('\n');
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function parseCliArgs(argv) {
|
|
54
|
-
const result = {
|
|
55
|
-
projectName: undefined,
|
|
56
|
-
selectedFeatureIds: undefined,
|
|
57
|
-
shouldInstallDependencies: undefined,
|
|
58
|
-
packageManager: undefined,
|
|
59
|
-
defaults: false,
|
|
60
|
-
overwrite: false,
|
|
61
|
-
showHelp: false,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
for (let index = 0; index < argv.length; index += 1) {
|
|
65
|
-
const arg = argv[index];
|
|
66
|
-
|
|
67
|
-
if (arg === '-h' || arg === '--help') {
|
|
68
|
-
result.showHelp = true;
|
|
69
|
-
continue;
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
if (arg === '-def' || arg === '--defaults') {
|
|
73
|
-
result.defaults = true;
|
|
74
|
-
continue;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
if (arg === '--overwrite') {
|
|
78
|
-
result.overwrite = true;
|
|
79
|
-
continue;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
if (arg === '--no-install') {
|
|
83
|
-
result.shouldInstallDependencies = false;
|
|
84
|
-
continue;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
if (arg.startsWith('--features')) {
|
|
88
|
-
const { value, nextIndex } = readOptionValue(argv, index, '--features');
|
|
89
|
-
index = nextIndex;
|
|
90
|
-
|
|
91
|
-
result.selectedFeatureIds = value
|
|
92
|
-
? value.split(',').map((item) => item.trim()).filter(Boolean)
|
|
93
|
-
: [];
|
|
94
|
-
|
|
95
|
-
continue;
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if (arg.startsWith('--pm')) {
|
|
99
|
-
const { value, nextIndex } = readOptionValue(argv, index, '--pm');
|
|
100
|
-
index = nextIndex;
|
|
101
|
-
|
|
102
|
-
if (!allowedPackageManagers.includes(value)) {
|
|
103
|
-
throw new Error(`Unknown package manager: ${value}`);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
result.packageManager = value;
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if (arg.startsWith('-')) {
|
|
111
|
-
throw new Error(`Unknown option: ${arg}`);
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
if (!result.projectName) {
|
|
115
|
-
result.projectName = arg;
|
|
116
|
-
continue;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
throw new Error(`Unexpected argument: ${arg}`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
return result;
|
|
1
|
+
import { allowedPackageManagers } from '../utils/package-manager.js';
|
|
2
|
+
|
|
3
|
+
function readOptionValue(args, currentIndex, optionName) {
|
|
4
|
+
const currentArg = args[currentIndex];
|
|
5
|
+
|
|
6
|
+
if (currentArg.includes('=')) {
|
|
7
|
+
return {
|
|
8
|
+
value: currentArg.slice(currentArg.indexOf('=') + 1),
|
|
9
|
+
nextIndex: currentIndex,
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const nextArg = args[currentIndex + 1];
|
|
14
|
+
|
|
15
|
+
if (!nextArg || nextArg.startsWith('-')) {
|
|
16
|
+
throw new Error(`Option ${optionName} requires a value`);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
return {
|
|
20
|
+
value: nextArg,
|
|
21
|
+
nextIndex: currentIndex + 1,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export function formatHelpMessage() {
|
|
26
|
+
return [
|
|
27
|
+
'Usage:',
|
|
28
|
+
' create-alistt69-kit <project-name> [options]',
|
|
29
|
+
'',
|
|
30
|
+
'Options:',
|
|
31
|
+
' -def, --defaults Skip prompts and use defaults',
|
|
32
|
+
' --overwrite Overwrite target directory if it exists',
|
|
33
|
+
' --no-install Do not install dependencies',
|
|
34
|
+
' --features <comma-list> Example: eslint,stylelint,react-router',
|
|
35
|
+
' --features all Enable all features',
|
|
36
|
+
' --pm <npm|pnpm|yarn> Package manager',
|
|
37
|
+
' -h, --help Show help',
|
|
38
|
+
'',
|
|
39
|
+
'Defaults:',
|
|
40
|
+
' All features are enabled by default',
|
|
41
|
+
' Package manager: npm',
|
|
42
|
+
' Install dependencies: yes',
|
|
43
|
+
'',
|
|
44
|
+
'Examples:',
|
|
45
|
+
' create-alistt69-kit my-app',
|
|
46
|
+
' create-alistt69-kit my-app --features=all',
|
|
47
|
+
' create-alistt69-kit my-app --pm pnpm --no-install',
|
|
48
|
+
' create-alistt69-kit my-app --defaults',
|
|
49
|
+
' create-alistt69-kit my-app --defaults --overwrite',
|
|
50
|
+
].join('\n');
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export function parseCliArgs(argv) {
|
|
54
|
+
const result = {
|
|
55
|
+
projectName: undefined,
|
|
56
|
+
selectedFeatureIds: undefined,
|
|
57
|
+
shouldInstallDependencies: undefined,
|
|
58
|
+
packageManager: undefined,
|
|
59
|
+
defaults: false,
|
|
60
|
+
overwrite: false,
|
|
61
|
+
showHelp: false,
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
for (let index = 0; index < argv.length; index += 1) {
|
|
65
|
+
const arg = argv[index];
|
|
66
|
+
|
|
67
|
+
if (arg === '-h' || arg === '--help') {
|
|
68
|
+
result.showHelp = true;
|
|
69
|
+
continue;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (arg === '-def' || arg === '--defaults') {
|
|
73
|
+
result.defaults = true;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
if (arg === '--overwrite') {
|
|
78
|
+
result.overwrite = true;
|
|
79
|
+
continue;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (arg === '--no-install') {
|
|
83
|
+
result.shouldInstallDependencies = false;
|
|
84
|
+
continue;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (arg.startsWith('--features')) {
|
|
88
|
+
const { value, nextIndex } = readOptionValue(argv, index, '--features');
|
|
89
|
+
index = nextIndex;
|
|
90
|
+
|
|
91
|
+
result.selectedFeatureIds = value
|
|
92
|
+
? value.split(',').map((item) => item.trim()).filter(Boolean)
|
|
93
|
+
: [];
|
|
94
|
+
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
if (arg.startsWith('--pm')) {
|
|
99
|
+
const { value, nextIndex } = readOptionValue(argv, index, '--pm');
|
|
100
|
+
index = nextIndex;
|
|
101
|
+
|
|
102
|
+
if (!allowedPackageManagers.includes(value)) {
|
|
103
|
+
throw new Error(`Unknown package manager: ${value}`);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
result.packageManager = value;
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (arg.startsWith('-')) {
|
|
111
|
+
throw new Error(`Unknown option: ${arg}`);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!result.projectName) {
|
|
115
|
+
result.projectName = arg;
|
|
116
|
+
continue;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
throw new Error(`Unexpected argument: ${arg}`);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
return result;
|
|
123
123
|
}
|
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
import { confirm, isCancel } from '@clack/prompts';
|
|
2
|
-
import { access, readdir, rm } from 'node:fs/promises';
|
|
3
|
-
import process from 'node:process';
|
|
4
|
-
import { resolve } from 'node:path';
|
|
5
|
-
|
|
6
|
-
async function pathExists(targetDirPath) {
|
|
7
|
-
try {
|
|
8
|
-
await access(targetDirPath);
|
|
9
|
-
return true;
|
|
10
|
-
} catch {
|
|
11
|
-
return false;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
export async function prepareTargetDirectory({
|
|
16
|
-
projectName,
|
|
17
|
-
overwrite = false,
|
|
18
|
-
defaults = false,
|
|
19
|
-
}) {
|
|
20
|
-
const targetDirPath = resolve(process.cwd(), projectName);
|
|
21
|
-
const exists = await pathExists(targetDirPath);
|
|
22
|
-
|
|
23
|
-
if (!exists) {
|
|
24
|
-
return {
|
|
25
|
-
targetDirPath,
|
|
26
|
-
wasOverwritten: false,
|
|
27
|
-
};
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
const directoryEntries = await readdir(targetDirPath);
|
|
31
|
-
const isEmpty = directoryEntries.length === 0;
|
|
32
|
-
|
|
33
|
-
if (isEmpty) {
|
|
34
|
-
return {
|
|
35
|
-
targetDirPath,
|
|
36
|
-
wasOverwritten: false,
|
|
37
|
-
};
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
if (overwrite) {
|
|
41
|
-
await rm(targetDirPath, { recursive: true, overwrite: true });
|
|
42
|
-
|
|
43
|
-
return {
|
|
44
|
-
targetDirPath,
|
|
45
|
-
wasOverwritten: true,
|
|
46
|
-
};
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
if (defaults) {
|
|
50
|
-
throw new Error(
|
|
51
|
-
`Directory already exists and is not empty: ${targetDirPath}. Use --overwrite to overwrite it.`,
|
|
52
|
-
);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
const overwriteAnswer = await confirm({
|
|
56
|
-
message: `Directory "${projectName}" already exists and will be overwritten. Continue?`,
|
|
57
|
-
initialValue: false,
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
if (isCancel(overwriteAnswer) || !overwriteAnswer) {
|
|
61
|
-
process.exit(0);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
await rm(targetDirPath, { recursive: true, overwrite: true });
|
|
65
|
-
|
|
66
|
-
return {
|
|
67
|
-
targetDirPath,
|
|
68
|
-
wasOverwritten: true,
|
|
69
|
-
};
|
|
1
|
+
import { confirm, isCancel } from '@clack/prompts';
|
|
2
|
+
import { access, readdir, rm } from 'node:fs/promises';
|
|
3
|
+
import process from 'node:process';
|
|
4
|
+
import { resolve } from 'node:path';
|
|
5
|
+
|
|
6
|
+
async function pathExists(targetDirPath) {
|
|
7
|
+
try {
|
|
8
|
+
await access(targetDirPath);
|
|
9
|
+
return true;
|
|
10
|
+
} catch {
|
|
11
|
+
return false;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export async function prepareTargetDirectory({
|
|
16
|
+
projectName,
|
|
17
|
+
overwrite = false,
|
|
18
|
+
defaults = false,
|
|
19
|
+
}) {
|
|
20
|
+
const targetDirPath = resolve(process.cwd(), projectName);
|
|
21
|
+
const exists = await pathExists(targetDirPath);
|
|
22
|
+
|
|
23
|
+
if (!exists) {
|
|
24
|
+
return {
|
|
25
|
+
targetDirPath,
|
|
26
|
+
wasOverwritten: false,
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const directoryEntries = await readdir(targetDirPath);
|
|
31
|
+
const isEmpty = directoryEntries.length === 0;
|
|
32
|
+
|
|
33
|
+
if (isEmpty) {
|
|
34
|
+
return {
|
|
35
|
+
targetDirPath,
|
|
36
|
+
wasOverwritten: false,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (overwrite) {
|
|
41
|
+
await rm(targetDirPath, { recursive: true, overwrite: true });
|
|
42
|
+
|
|
43
|
+
return {
|
|
44
|
+
targetDirPath,
|
|
45
|
+
wasOverwritten: true,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (defaults) {
|
|
50
|
+
throw new Error(
|
|
51
|
+
`Directory already exists and is not empty: ${targetDirPath}. Use --overwrite to overwrite it.`,
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const overwriteAnswer = await confirm({
|
|
56
|
+
message: `Directory "${projectName}" already exists and will be overwritten. Continue?`,
|
|
57
|
+
initialValue: false,
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
if (isCancel(overwriteAnswer) || !overwriteAnswer) {
|
|
61
|
+
process.exit(0);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
await rm(targetDirPath, { recursive: true, overwrite: true });
|
|
65
|
+
|
|
66
|
+
return {
|
|
67
|
+
targetDirPath,
|
|
68
|
+
wasOverwritten: true,
|
|
69
|
+
};
|
|
70
70
|
}
|