@shivasankaran18/stackd 1.2.5 → 1.3.0
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/apps/cli/src/cli.ts +2 -28
- package/apps/cli/src/commands/create.ts +0 -30
- package/apps/cli/src/scripts/ui/shadcn.ts +10 -4
- package/apps/web/app/scaffold/page.tsx +1 -1
- package/apps/web/package.json +2 -1
- package/package.json +22 -19
- package/packages/ui/eslint.config.mjs +4 -0
- package/packages/ui/package.json +27 -0
- package/packages/ui/src/button.tsx +20 -0
- package/packages/ui/src/card.tsx +27 -0
- package/packages/ui/src/code.tsx +11 -0
- package/packages/ui/tsconfig.json +8 -0
- package/packages/ui/turbo/generators/config.ts +30 -0
- package/packages/ui/turbo/generators/templates/component.hbs +8 -0
- package/stackd.ts +0 -0
- package/apps/cli/src/scripts/ui/tailwind.ts +0 -39
package/apps/cli/src/cli.ts
CHANGED
@@ -15,7 +15,6 @@ export interface ProjectConfig {
|
|
15
15
|
orm: string;
|
16
16
|
auth: string;
|
17
17
|
dbUrl: string;
|
18
|
-
ui: string;
|
19
18
|
}
|
20
19
|
|
21
20
|
interface Answers {
|
@@ -28,8 +27,7 @@ interface Answers {
|
|
28
27
|
orm: string;
|
29
28
|
auth: string;
|
30
29
|
dbUrl: string;
|
31
|
-
projectName:
|
32
|
-
ui: string;
|
30
|
+
projectName:string;
|
33
31
|
}
|
34
32
|
|
35
33
|
const showBanner = () => {
|
@@ -69,9 +67,7 @@ const CHOICES = {
|
|
69
67
|
MONGOOSE: 'Mongoose',
|
70
68
|
JWT: 'JWT',
|
71
69
|
NEXTAUTH: 'NextAuth',
|
72
|
-
PASSPORT: 'Passport'
|
73
|
-
TAILWIND: 'Tailwind CSS',
|
74
|
-
SHADCN: 'shadcn/ui + Tailwind'
|
70
|
+
PASSPORT: 'Passport'
|
75
71
|
};
|
76
72
|
|
77
73
|
program
|
@@ -128,27 +124,6 @@ program
|
|
128
124
|
}
|
129
125
|
]);
|
130
126
|
|
131
|
-
// Add UI framework selection after frontend
|
132
|
-
let uiChoice = { ui: CHOICES.NONE };
|
133
|
-
if (frontendChoice.frontend !== chalk.green(CHOICES.DJANGO_TEMPLATES) &&
|
134
|
-
frontendChoice.frontend !== CHOICES.SKIP) {
|
135
|
-
uiChoice = await inquirer.prompt([
|
136
|
-
{
|
137
|
-
type: 'list',
|
138
|
-
name: 'ui',
|
139
|
-
message: chalk.magenta.bold('🎨 Choose a UI framework:'),
|
140
|
-
choices: (answers) => {
|
141
|
-
const isReact = frontendChoice.frontend.includes('React');
|
142
|
-
return [
|
143
|
-
chalk.blue(CHOICES.TAILWIND),
|
144
|
-
...(isReact ? [chalk.cyan(CHOICES.SHADCN)] : []),
|
145
|
-
CHOICES.NONE
|
146
|
-
];
|
147
|
-
},
|
148
|
-
default: CHOICES.NONE,
|
149
|
-
}
|
150
|
-
]);
|
151
|
-
}
|
152
127
|
|
153
128
|
const backendChoice = await inquirer.prompt([
|
154
129
|
{
|
@@ -235,7 +210,6 @@ program
|
|
235
210
|
const answers = {
|
236
211
|
...projectSettings,
|
237
212
|
...frontendChoice,
|
238
|
-
...uiChoice,
|
239
213
|
...backendChoice,
|
240
214
|
...databaseChoice,
|
241
215
|
...ormChoice,
|
@@ -16,8 +16,6 @@ import chalk from 'chalk';
|
|
16
16
|
import ora from 'ora';
|
17
17
|
import { mkdir } from 'fs/promises';
|
18
18
|
import { ProjectConfig } from '../cli.js';
|
19
|
-
import { setupShadcn } from '../scripts/ui/shadcn.js';
|
20
|
-
import { setupTailwindCSS } from '../scripts/ui/tailwindcss.js';
|
21
19
|
|
22
20
|
const emitLog = (message: string): void => {
|
23
21
|
console.log(`[Emit Logs]: ${message}`);
|
@@ -66,24 +64,6 @@ export async function createProject(projectName: string, options: ProjectConfig)
|
|
66
64
|
break;
|
67
65
|
}
|
68
66
|
|
69
|
-
// UI Framework setup
|
70
|
-
if (options.ui !== 'None' && options.frontend !== 'Django Templates' && options.frontend !== 'Skip') {
|
71
|
-
spinner.text = 'Setting up UI framework...';
|
72
|
-
switch(options.ui) {
|
73
|
-
case 'Tailwind CSS':
|
74
|
-
await setupTailwindCSS(config, projectDir, emitLog);
|
75
|
-
break;
|
76
|
-
case 'shadcn/ui + Tailwind':
|
77
|
-
await setupTailwindCSS(config, projectDir, emitLog);
|
78
|
-
// @ts-ignore
|
79
|
-
await setupShadcn(config, projectDir, emitLog);
|
80
|
-
break;
|
81
|
-
default:
|
82
|
-
emitLog('Unknown UI framework choice');
|
83
|
-
break;
|
84
|
-
}
|
85
|
-
}
|
86
|
-
|
87
67
|
// Backend setup
|
88
68
|
spinner.text = 'Setting up backend...';
|
89
69
|
switch(options.backend) {
|
@@ -163,16 +143,6 @@ export async function createProject(projectName: string, options: ProjectConfig)
|
|
163
143
|
}
|
164
144
|
}
|
165
145
|
|
166
|
-
// Add UI-specific instructions
|
167
|
-
if (options.ui !== 'None') {
|
168
|
-
console.log(chalk.yellow('\nUI Framework Setup:'));
|
169
|
-
if (options.ui === 'Tailwind CSS') {
|
170
|
-
console.log(chalk.cyan(' Tailwind CSS is ready to use'));
|
171
|
-
} else if (options.ui === 'shadcn/ui + Tailwind') {
|
172
|
-
console.log(chalk.cyan(' Run `npx shadcn-ui@latest init` to complete shadcn/ui setup'));
|
173
|
-
}
|
174
|
-
}
|
175
|
-
|
176
146
|
// Add database specific instructions
|
177
147
|
if (options.database !== 'Skip') {
|
178
148
|
console.log(chalk.yellow('\nDatabase Setup:'));
|
@@ -2,9 +2,12 @@ import { writeFile, mkdir } from 'fs/promises';
|
|
2
2
|
import { join } from 'path';
|
3
3
|
import { execSync } from 'child_process';
|
4
4
|
import { existsSync } from 'fs';
|
5
|
-
import { ProjectConfig } from '../../cli.js';
|
6
5
|
|
7
|
-
export async function setupShadcn(
|
6
|
+
export async function setupShadcn(
|
7
|
+
config: any,
|
8
|
+
projectDir: string,
|
9
|
+
emitLog: (log: string) => void
|
10
|
+
) {
|
8
11
|
try {
|
9
12
|
const frontendDir = join(projectDir, 'frontend');
|
10
13
|
emitLog('📦 Setting up shadcn/ui...');
|
@@ -14,7 +17,10 @@ export async function setupShadcn(config: ProjectConfig, projectDir: string, emi
|
|
14
17
|
|
15
18
|
// Install shadcn/ui dependencies
|
16
19
|
emitLog('Installing shadcn/ui dependencies...');
|
17
|
-
execSync('npm install @shadcn/ui', {
|
20
|
+
execSync('npm install @shadcn/ui class-variance-authority clsx tailwind-merge lucide-react', {
|
21
|
+
cwd: frontendDir,
|
22
|
+
stdio: 'inherit'
|
23
|
+
});
|
18
24
|
|
19
25
|
// Create components.json configuration
|
20
26
|
const componentsConfig = {
|
@@ -60,7 +66,7 @@ export function cn(...inputs: ClassValue[]) {
|
|
60
66
|
|
61
67
|
emitLog('✅ shadcn/ui setup completed successfully!');
|
62
68
|
} catch (error) {
|
63
|
-
emitLog(
|
69
|
+
emitLog(`❌ Error setting up shadcn/ui: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
64
70
|
throw error;
|
65
71
|
}
|
66
72
|
}
|
@@ -49,7 +49,7 @@ const Navbar = () => (
|
|
49
49
|
</div>
|
50
50
|
|
51
51
|
<a
|
52
|
-
href="https://github.com/
|
52
|
+
href="https://github.com/ShyamSunder06/STACKD"
|
53
53
|
target="_blank"
|
54
54
|
rel="noopener noreferrer"
|
55
55
|
className="absolute right-8 text-muted-foreground hover:text-foreground"
|
package/apps/web/package.json
CHANGED
@@ -16,6 +16,7 @@
|
|
16
16
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
17
17
|
"@radix-ui/react-slot": "^1.1.2",
|
18
18
|
"@radix-ui/react-switch": "^1.1.3",
|
19
|
+
"@repo/ui": "*",
|
19
20
|
"axios": "^1.7.9",
|
20
21
|
"class-variance-authority": "^0.7.1",
|
21
22
|
"clsx": "^2.1.1",
|
@@ -37,7 +38,7 @@
|
|
37
38
|
},
|
38
39
|
"devDependencies": {
|
39
40
|
"@repo/eslint-config": "*",
|
40
|
-
|
41
|
+
"@repo/typescript-config": "*",
|
41
42
|
"@types/d3": "^7.4.3",
|
42
43
|
"@types/node": "^20.0.0",
|
43
44
|
"@types/react": "19.0.8",
|
package/package.json
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
{
|
2
2
|
"name": "@shivasankaran18/stackd",
|
3
|
-
"version": "1.
|
3
|
+
"version": "1.3.0",
|
4
4
|
"bin": {
|
5
|
-
"stackd": "stackd.
|
5
|
+
"stackd": "dist/stackd.js",
|
6
6
|
"pre-install": "npm install"
|
7
7
|
},
|
8
|
+
"main": "dist/stackd.js",
|
8
9
|
"type": "module",
|
9
10
|
"scripts": {
|
10
11
|
"build": "turbo run build",
|
@@ -12,6 +13,7 @@
|
|
12
13
|
"lint": "turbo run lint",
|
13
14
|
"format": "prettier --write \"**/*.{ts,tsx,md}\"",
|
14
15
|
"check-types": "turbo run check-types",
|
16
|
+
"prepare": "husky install",
|
15
17
|
"setup": "sh start-web.sh",
|
16
18
|
"@types/node": "^22.13.5",
|
17
19
|
"chalk": "4",
|
@@ -22,7 +24,7 @@
|
|
22
24
|
"ora": "^8.2.0",
|
23
25
|
"path": "^0.12.7",
|
24
26
|
"ts-node": "^10.9.2",
|
25
|
-
"create":
|
27
|
+
"create":"node dist/stackd.js init"
|
26
28
|
},
|
27
29
|
"devDependencies": {
|
28
30
|
"@types/chalk": "^2.2.4",
|
@@ -44,42 +46,43 @@
|
|
44
46
|
],
|
45
47
|
"dependencies": {
|
46
48
|
"@octokit/rest": "^21.1.1",
|
49
|
+
"chalk": "^4.1.2",
|
50
|
+
"framer-motion": "^12.4.7",
|
51
|
+
"fs": "^0.0.1-security",
|
52
|
+
"simple-git": "^3.27.0",
|
53
|
+
"ts-node": "^10.9.2",
|
54
|
+
"tsx": "^4.19.3",
|
55
|
+
"@types/chalk": "^2.2.4",
|
56
|
+
"@types/commander": "^2.12.5",
|
57
|
+
"@types/node": "^22.13.5",
|
58
|
+
"commander": "^13.1.0",
|
59
|
+
"gradient-string": "^3.0.0",
|
60
|
+
"inquirer": "^12.4.2",
|
61
|
+
"ora": "^8.2.0",
|
62
|
+
|
47
63
|
"@radix-ui/react-dropdown-menu": "^2.1.6",
|
48
64
|
"@radix-ui/react-label": "^2.1.2",
|
49
65
|
"@radix-ui/react-scroll-area": "^1.2.3",
|
50
66
|
"@radix-ui/react-slot": "^1.1.2",
|
51
67
|
"@radix-ui/react-switch": "^1.1.3",
|
52
|
-
"@
|
53
|
-
"@types/commander": "^2.12.5",
|
54
|
-
"@types/node": "^22.13.5",
|
55
|
-
"@types/react": "^19.0.10",
|
68
|
+
"@repo/ui": "*",
|
56
69
|
"axios": "^1.7.9",
|
57
|
-
"chalk": "^4.1.2",
|
58
70
|
"class-variance-authority": "^0.7.1",
|
59
71
|
"clsx": "^2.1.1",
|
60
|
-
"commander": "^13.1.0",
|
61
72
|
"d3": "^7.9.0",
|
62
73
|
"date-fns": "^4.1.0",
|
63
|
-
|
64
|
-
"framer-motion": "^12.4.7",
|
65
|
-
"fs": "^0.0.1-security",
|
66
|
-
"gradient-string": "^3.0.0",
|
67
|
-
"inquirer": "^12.4.2",
|
74
|
+
|
68
75
|
"lucide-react": "^0.475.0",
|
69
76
|
"next": "^15.1.6",
|
70
77
|
"next-auth": "^4.24.11",
|
71
78
|
"next-themes": "^0.4.4",
|
72
|
-
"ora": "^8.2.0",
|
73
79
|
"path": "^0.12.7",
|
74
80
|
"prisma": "^6.4.0",
|
75
81
|
"react": "^19.0.0",
|
76
82
|
"react-dom": "^19.0.0",
|
77
83
|
"redis": "^4.7.0",
|
78
|
-
"simple-git": "^3.27.0",
|
79
84
|
"sonner": "^2.0.1",
|
80
85
|
"tailwind-merge": "^3.0.1",
|
81
|
-
"tailwindcss-animate": "^1.0.7"
|
82
|
-
"ts-node": "^10.9.2",
|
83
|
-
"tsx": "^4.19.3"
|
86
|
+
"tailwindcss-animate": "^1.0.7"
|
84
87
|
}
|
85
88
|
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
{
|
2
|
+
"name": "@repo/ui",
|
3
|
+
"version": "0.0.0",
|
4
|
+
"private": true,
|
5
|
+
"exports": {
|
6
|
+
"./*": "./src/*.tsx"
|
7
|
+
},
|
8
|
+
"scripts": {
|
9
|
+
"lint": "eslint . --max-warnings 0",
|
10
|
+
"generate:component": "turbo gen react-component",
|
11
|
+
"check-types": "tsc --noEmit"
|
12
|
+
},
|
13
|
+
"devDependencies": {
|
14
|
+
"@repo/eslint-config": "*",
|
15
|
+
"@repo/typescript-config": "*",
|
16
|
+
"@turbo/gen": "^2.4.0",
|
17
|
+
"@types/node": "^22.13.0",
|
18
|
+
"@types/react": "19.0.8",
|
19
|
+
"@types/react-dom": "19.0.3",
|
20
|
+
"eslint": "^9.20.0",
|
21
|
+
"typescript": "5.7.3"
|
22
|
+
},
|
23
|
+
"dependencies": {
|
24
|
+
"react": "^19.0.0",
|
25
|
+
"react-dom": "^19.0.0"
|
26
|
+
}
|
27
|
+
}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
"use client";
|
2
|
+
|
3
|
+
import { ReactNode } from "react";
|
4
|
+
|
5
|
+
interface ButtonProps {
|
6
|
+
children: ReactNode;
|
7
|
+
className?: string;
|
8
|
+
appName: string;
|
9
|
+
}
|
10
|
+
|
11
|
+
export const Button = ({ children, className, appName }: ButtonProps) => {
|
12
|
+
return (
|
13
|
+
<button
|
14
|
+
className={className}
|
15
|
+
onClick={() => alert(`Hello from your ${appName} app!`)}
|
16
|
+
>
|
17
|
+
{children}
|
18
|
+
</button>
|
19
|
+
);
|
20
|
+
};
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { type JSX } from "react";
|
2
|
+
|
3
|
+
export function Card({
|
4
|
+
className,
|
5
|
+
title,
|
6
|
+
children,
|
7
|
+
href,
|
8
|
+
}: {
|
9
|
+
className?: string;
|
10
|
+
title: string;
|
11
|
+
children: React.ReactNode;
|
12
|
+
href: string;
|
13
|
+
}): JSX.Element {
|
14
|
+
return (
|
15
|
+
<a
|
16
|
+
className={className}
|
17
|
+
href={`${href}?utm_source=create-turbo&utm_medium=basic&utm_campaign=create-turbo"`}
|
18
|
+
rel="noopener noreferrer"
|
19
|
+
target="_blank"
|
20
|
+
>
|
21
|
+
<h2>
|
22
|
+
{title} <span>-></span>
|
23
|
+
</h2>
|
24
|
+
<p>{children}</p>
|
25
|
+
</a>
|
26
|
+
);
|
27
|
+
}
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import type { PlopTypes } from "@turbo/gen";
|
2
|
+
|
3
|
+
// Learn more about Turborepo Generators at https://turbo.build/repo/docs/core-concepts/monorepos/code-generation
|
4
|
+
|
5
|
+
export default function generator(plop: PlopTypes.NodePlopAPI): void {
|
6
|
+
// A simple generator to add a new React component to the internal UI library
|
7
|
+
plop.setGenerator("react-component", {
|
8
|
+
description: "Adds a new react component",
|
9
|
+
prompts: [
|
10
|
+
{
|
11
|
+
type: "input",
|
12
|
+
name: "name",
|
13
|
+
message: "What is the name of the component?",
|
14
|
+
},
|
15
|
+
],
|
16
|
+
actions: [
|
17
|
+
{
|
18
|
+
type: "add",
|
19
|
+
path: "src/{{kebabCase name}}.tsx",
|
20
|
+
templateFile: "templates/component.hbs",
|
21
|
+
},
|
22
|
+
{
|
23
|
+
type: "append",
|
24
|
+
path: "package.json",
|
25
|
+
pattern: /"exports": {(?<insertion>)/g,
|
26
|
+
template: ' "./{{kebabCase name}}": "./src/{{kebabCase name}}.tsx",',
|
27
|
+
},
|
28
|
+
],
|
29
|
+
});
|
30
|
+
}
|
package/stackd.ts
CHANGED
File without changes
|
@@ -1,39 +0,0 @@
|
|
1
|
-
import { execSync } from 'child_process';
|
2
|
-
import { writeFile } from 'fs/promises';
|
3
|
-
import { join } from 'path';
|
4
|
-
import { ProjectConfig } from '../../cli.js';
|
5
|
-
|
6
|
-
export async function setupTailwind(config: ProjectConfig, projectDir: string, emitLog: (message: string) => void) {
|
7
|
-
try {
|
8
|
-
emitLog('Installing Tailwind CSS...');
|
9
|
-
execSync('npm install -D tailwindcss postcss autoprefixer', { cwd: projectDir });
|
10
|
-
execSync('npx tailwindcss init -p', { cwd: projectDir });
|
11
|
-
|
12
|
-
// Add Tailwind configuration
|
13
|
-
const tailwindConfig = `
|
14
|
-
module.exports = {
|
15
|
-
content: [
|
16
|
-
"./src/**/*.{js,jsx,ts,tsx}",
|
17
|
-
],
|
18
|
-
theme: {
|
19
|
-
extend: {},
|
20
|
-
},
|
21
|
-
plugins: [],
|
22
|
-
}`;
|
23
|
-
|
24
|
-
await writeFile(join(projectDir, 'tailwind.config.js'), tailwindConfig);
|
25
|
-
|
26
|
-
// Add Tailwind directives to CSS
|
27
|
-
const cssContent = `
|
28
|
-
@tailwind base;
|
29
|
-
@tailwind components;
|
30
|
-
@tailwind utilities;`;
|
31
|
-
|
32
|
-
await writeFile(join(projectDir, 'src/index.css'), cssContent);
|
33
|
-
|
34
|
-
emitLog('Tailwind CSS setup completed');
|
35
|
-
} catch (error) {
|
36
|
-
emitLog('Failed to setup Tailwind CSS');
|
37
|
-
throw error;
|
38
|
-
}
|
39
|
-
}
|