Skip to content

Commit 17c322b

Browse files
committed
Half working
0 parents  commit 17c322b

17 files changed

+606
-0
lines changed

.editorconfig

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[*]
2+
indent_style = space
3+
indent_size = 4
4+
end_of_line = lf
5+
charset = utf-8

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
node_modules
2+
my-app
3+
bun.lockb
4+
package-lock.json
5+
dist

.prettierrc.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"printWidth": 120,
3+
"tabWidth": 4,
4+
"useTabs": false,
5+
"semi": true,
6+
"singleQuote": true,
7+
"jsxSingleQuote": true,
8+
"endOfLine": "lf",
9+
"plugins": [
10+
"@ianvs/prettier-plugin-sort-imports",
11+
"prettier-plugin-css-order",
12+
"prettier-plugin-organize-attributes",
13+
"prettier-plugin-tailwindcss"
14+
]
15+
}

bin/create-dokez-app.ts

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#!/usr/bin/env bun
2+
import { help } from '../src/commands/help.js';
3+
import { init } from '../src/commands/init.js';
4+
import { version } from '../src/commands/version.js';
5+
6+
const command = process.argv[2];
7+
8+
switch (command) {
9+
case 'init':
10+
init();
11+
break;
12+
case '--help':
13+
case '-h':
14+
help();
15+
break;
16+
case '--version':
17+
case '-v':
18+
version();
19+
break;
20+
default:
21+
console.error('Unknown command. Use "init" or "--help"');
22+
process.exit(1);
23+
}

package.json

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"name": "create-dokez-app",
3+
"version": "1.0.0",
4+
"description": "CLI tool to create a new Dokez app",
5+
"main": "index.js",
6+
"type": "module",
7+
"bin": {
8+
"create-dokez-app": "./dist/bin/create-dokez-app.js"
9+
},
10+
"dependencies": {
11+
"@radix-ui/react-icons": "^1.3.0",
12+
"class-variance-authority": "^0.7.0",
13+
"clsx": "^2.1.1",
14+
"detect-package-manager": "^3.0.2",
15+
"execa": "^9.4.1",
16+
"fs-extra": "^11.2.0",
17+
"lucide-react": "^0.453.0",
18+
"prompts": "^2.4.2",
19+
"tailwind-merge": "^2.5.4",
20+
"tailwindcss-animate": "^1.0.7"
21+
},
22+
"devDependencies": {
23+
"@types/prompts": "^2.4.9",
24+
"prettier": "^3.3.3",
25+
"typescript": "^5.6.3",
26+
"@types/node": "^22.7.7",
27+
"@types/fs-extra": "^11.0.4"
28+
},
29+
"scripts": {
30+
"build": "tsc"
31+
},
32+
"author": "konyogony",
33+
"license": "MIT"
34+
}

src/commands/help.ts

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const help = () => {
2+
console.log(`Usage: create-dokez-app [command]\n`);
3+
console.log(`Create an app with Dokez configuration.\n`);
4+
console.log('Commands:');
5+
console.log(' init\t\tCreate a new app');
6+
console.log(' --help, -h\tShow help');
7+
console.log(' --version, -v\tShow version');
8+
};

src/commands/init.ts

+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import process from 'process';
2+
import { configureNextjs } from '../config/configure-nextjs.js';
3+
import { configurePrettier } from '../config/configure-prettier.js';
4+
import { configureShadcn } from '../config/configure-shadcn.js';
5+
import { getPmInfo } from '../utils/get-pm-info.js';
6+
import { getResponse } from '../utils/get-response.js';
7+
import { errorText, isNextJsProject, successText } from '../utils/utils.js';
8+
9+
export const init = async () => {
10+
// Get user response
11+
const response = await getResponse();
12+
13+
// Check if the directory is already a Next.js project
14+
if (isNextJsProject(`./${response['app-name']}`)) {
15+
console.error(errorText('This directory is already a Next.js project.'));
16+
process.exit(1);
17+
}
18+
19+
// Get package manager info
20+
const { pm, pmx, pmi } = await getPmInfo();
21+
22+
// Configure Next.js
23+
await configureNextjs(response, pmx);
24+
25+
// Configure shadcn
26+
await configureShadcn(response, pmx, pmi);
27+
28+
// Configure Prettier
29+
await configurePrettier(response, pmi, pm);
30+
31+
console.log('\n' + successText('Installation of project successful!'));
32+
};

src/commands/version.ts

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import packageJson from '../../package.json';
2+
3+
export const version = () => {
4+
console.log(`${packageJson.name} - ${packageJson.version}, by ${packageJson.author}`);
5+
};

src/config/configure-nextjs.ts

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import { execa } from 'execa';
2+
import { responseT } from '../utils/types.js';
3+
import { blueText, infoText, successText } from '../utils/utils.js';
4+
5+
export const configureNextjs = async (response: responseT, pmx: string[]) => {
6+
try {
7+
console.log('\n' + infoText('Installing Next.js...'));
8+
9+
await execa(
10+
pmx[0],
11+
[
12+
pmx[1],
13+
'create-next-app@canary',
14+
response['app-name'],
15+
'--ts',
16+
'--tailwind',
17+
'--app',
18+
'--no-src-dir',
19+
response['eslint'] ? '--eslint' : '--no-eslint',
20+
response['turbopack'] ? '--turbo' : '--no-turbo',
21+
'--no-import-alias',
22+
].filter((str) => str !== '' && str !== undefined),
23+
{ stdio: 'ignore' },
24+
);
25+
console.log(successText(`Created app with the following options:`));
26+
console.log(`- Name: ${blueText(response['app-name'])}`);
27+
console.log(`- ESLint: ${response['eslint'] ? blueText('Enabled') : blueText('Disabled')}`);
28+
console.log(`- Turbopack: ${response['turbopack'] ? blueText('Enabled') : blueText('Disabled')}`);
29+
console.log(`- Prettier: ${response['prettier'] ? blueText('Enabled') : blueText('Disabled')}`);
30+
console.log(`- Shadcn style: ${blueText(response['shadcn-style'])}`);
31+
console.log(`- Base color: ${blueText(response['base-color'])}`);
32+
console.log(`- Additional options: ${blueText('Typescript, Tailwind, App Router, no Source Directory')}`);
33+
process.chdir(response['app-name']);
34+
35+
console.log(successText('Next.js installed successfully!'));
36+
} catch (error) {
37+
console.error(error);
38+
process.exit(1);
39+
}
40+
};

src/config/configure-prettier.ts

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
import { execa } from 'execa';
2+
import fs from 'fs-extra';
3+
import { responseT } from '../utils/types.js';
4+
import { errorText, successText } from '../utils/utils.js';
5+
6+
export const configurePrettier = async (response: responseT, pmi: string[], pm: string) => {
7+
try {
8+
await execa(
9+
pmi[0],
10+
[
11+
pmi[1],
12+
'--save-dev',
13+
'prettier',
14+
'@ianvs/prettier-plugin-sort-imports',
15+
'prettier-plugin-css-order',
16+
'prettier-plugin-organize-attributes',
17+
'prettier-plugin-tailwindcss',
18+
].filter((str) => str !== ''),
19+
{ stdio: 'ignore' },
20+
);
21+
22+
const prettierConfigContent = `{
23+
"printWidth": 120,
24+
"tabWidth": 4,
25+
"useTabs": false,
26+
"semi": true,
27+
"singleQuote": true,
28+
"jsxSingleQuote": true,
29+
"endOfLine": "lf",
30+
"plugins": [
31+
"@ianvs/prettier-plugin-sort-imports",
32+
"prettier-plugin-css-order",
33+
"prettier-plugin-organize-attributes",
34+
"prettier-plugin-tailwindcss"
35+
]
36+
}
37+
`;
38+
39+
try {
40+
await fs.writeFile('./.prettierrc.json', prettierConfigContent);
41+
} catch (error) {
42+
console.error(errorText(`Error creating ${'.prettierrc.json'} file:`), error);
43+
process.exit(1);
44+
}
45+
46+
await execa(pm, ['run', 'prettier', '.', '-w'], { stdio: 'ignore' });
47+
48+
if (!response['prettier']) {
49+
await execa(
50+
pm,
51+
[
52+
'remove',
53+
'prettier',
54+
'@ianvs/prettier-plugin-sort-imports',
55+
'prettier-plugin-css-order',
56+
'prettier-plugin-organize-attributes',
57+
'prettier-plugin-tailwindcss',
58+
],
59+
{ stdio: 'ignore' },
60+
);
61+
try {
62+
await fs.remove('./.prettierrc.json');
63+
} catch (error) {
64+
console.error(errorText(`Error removing ${'.prettierrc.json'} file:`), error);
65+
process.exit(1);
66+
}
67+
} else {
68+
console.log(successText('Prettier installed successfully!'));
69+
}
70+
} catch (error) {
71+
console.error(error);
72+
process.exit(1);
73+
}
74+
};

0 commit comments

Comments
 (0)