stackkit-cli 0.4.4 → 0.4.5
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 +26 -2
- package/bin/stackkit.js +1 -1
- package/dist/commands/add.js +20 -39
- package/dist/commands/doctor.d.ts +11 -0
- package/dist/commands/doctor.js +483 -0
- package/dist/commands/list.d.ts +1 -1
- package/dist/commands/list.js +59 -38
- package/dist/index.js +11 -13
- package/dist/types/index.d.ts +15 -0
- package/dist/utils/config-utils.d.ts +2 -0
- package/dist/utils/config-utils.js +88 -0
- package/dist/utils/detect.js +12 -2
- package/dist/utils/env-editor.d.ts +0 -1
- package/dist/utils/env-editor.js +50 -25
- package/dist/utils/files.d.ts +8 -0
- package/dist/utils/files.js +51 -0
- package/dist/utils/js-conversion.d.ts +1 -0
- package/dist/utils/js-conversion.js +244 -0
- package/dist/utils/module-utils.d.ts +2 -0
- package/dist/utils/module-utils.js +461 -0
- package/dist/utils/package-manager.js +15 -31
- package/modules/auth/authjs/files/api/auth/[...nextauth]/route.ts +6 -0
- package/modules/auth/authjs/files/lib/auth-client.ts +11 -0
- package/modules/auth/authjs/files/lib/auth.ts +41 -0
- package/modules/auth/authjs/files/schemas/prisma-schema.prisma +45 -0
- package/modules/auth/authjs/module.json +95 -0
- package/modules/auth/better-auth/files/lib/auth-client.ts +7 -0
- package/modules/auth/better-auth/files/lib/auth.ts +62 -0
- package/modules/auth/better-auth/files/lib/email-service.ts +34 -0
- package/modules/auth/better-auth/files/lib/email-templates.ts +89 -0
- package/modules/auth/better-auth/files/schemas/prisma-schema.prisma +1 -1
- package/modules/auth/better-auth/module.json +164 -27
- package/modules/database/mongoose/files/lib/db.ts +68 -0
- package/modules/database/{mongoose-mongodb → mongoose}/files/models/User.ts +0 -5
- package/modules/database/{mongoose-mongodb → mongoose}/module.json +9 -24
- package/modules/database/prisma/files/lib/prisma.ts +1 -3
- package/modules/database/prisma/files/prisma/schema.prisma +1 -1
- package/modules/database/prisma/files/prisma.config.ts +2 -2
- package/modules/database/prisma/module.json +5 -23
- package/package.json +1 -1
- package/templates/express/.env.example +0 -1
- package/templates/express/package.json +4 -4
- package/templates/express/src/app.ts +2 -2
- package/templates/express/src/features/health/health.controller.ts +18 -0
- package/templates/express/src/features/health/health.route.ts +9 -0
- package/templates/express/src/features/health/health.service.ts +6 -0
- package/templates/nextjs/lib/env.ts +8 -0
- package/templates/nextjs/package.json +7 -7
- package/templates/react-vite/.env.example +1 -2
- package/templates/react-vite/.prettierignore +4 -0
- package/templates/react-vite/.prettierrc +9 -0
- package/templates/react-vite/README.md +22 -0
- package/templates/react-vite/package.json +16 -16
- package/templates/react-vite/src/router.tsx +0 -12
- package/templates/react-vite/vite.config.ts +0 -6
- package/dist/commands/init.d.ts +0 -10
- package/dist/commands/init.js +0 -157
- package/dist/utils/code-inject.d.ts +0 -14
- package/dist/utils/code-inject.js +0 -70
- package/dist/utils/json-editor.d.ts +0 -8
- package/dist/utils/json-editor.js +0 -45
- package/modules/auth/clerk/files/express/auth.ts +0 -7
- package/modules/auth/clerk/files/nextjs/auth-provider.tsx +0 -5
- package/modules/auth/clerk/files/nextjs/middleware.ts +0 -9
- package/modules/auth/clerk/files/react/auth-provider.tsx +0 -15
- package/modules/auth/clerk/module.json +0 -115
- package/modules/database/mongoose-mongodb/files/lib/db.ts +0 -78
- package/templates/express/src/features/auth/auth.controller.ts +0 -48
- package/templates/express/src/features/auth/auth.route.ts +0 -10
- package/templates/express/src/features/auth/auth.service.ts +0 -21
- package/templates/react-vite/src/api/services/user.service.ts +0 -18
- package/templates/react-vite/src/pages/UserProfile.tsx +0 -40
- package/templates/react-vite/src/types/user.d.ts +0 -6
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
-
};
|
|
5
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.modifyJson = modifyJson;
|
|
7
|
-
exports.addToPackageJson = addToPackageJson;
|
|
8
|
-
exports.setJsonValue = setJsonValue;
|
|
9
|
-
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
-
async function modifyJson(filePath, modifier, options = {}) {
|
|
11
|
-
const exists = await fs_extra_1.default.pathExists(filePath);
|
|
12
|
-
if (!exists && !options.create) {
|
|
13
|
-
throw new Error(`File not found: ${filePath}`);
|
|
14
|
-
}
|
|
15
|
-
const modified = modifier(exists ? await fs_extra_1.default.readJSON(filePath) : {});
|
|
16
|
-
await fs_extra_1.default.writeJSON(filePath, modified, { spaces: 2 });
|
|
17
|
-
}
|
|
18
|
-
async function addToPackageJson(filePath, section, additions) {
|
|
19
|
-
await modifyJson(filePath, (_json) => {
|
|
20
|
-
_json[section] = _json[section] || {};
|
|
21
|
-
Object.assign(_json[section], additions);
|
|
22
|
-
return _json;
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
async function setJsonValue(filePath, path, value, options = {}) {
|
|
26
|
-
await modifyJson(filePath, (_json) => {
|
|
27
|
-
const keys = path.split(".");
|
|
28
|
-
let current = _json;
|
|
29
|
-
for (let i = 0; i < keys.length - 1; i++) {
|
|
30
|
-
const key = keys[i];
|
|
31
|
-
if (!current[key]) {
|
|
32
|
-
current[key] = {};
|
|
33
|
-
}
|
|
34
|
-
current = current[key];
|
|
35
|
-
}
|
|
36
|
-
const lastKey = keys[keys.length - 1];
|
|
37
|
-
if (options.merge && typeof current[lastKey] === "object" && typeof value === "object") {
|
|
38
|
-
current[lastKey] = { ...current[lastKey], ...value };
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
current[lastKey] = value;
|
|
42
|
-
}
|
|
43
|
-
return _json;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { ClerkProvider } from "@clerk/clerk-react";
|
|
2
|
-
|
|
3
|
-
const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
|
|
4
|
-
|
|
5
|
-
if (!publishableKey) {
|
|
6
|
-
throw new Error("Missing Publishable Key");
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
10
|
-
return (
|
|
11
|
-
<ClerkProvider publishableKey={publishableKey} afterSignOutUrl="/">
|
|
12
|
-
{children}
|
|
13
|
-
</ClerkProvider>
|
|
14
|
-
);
|
|
15
|
-
}
|
|
@@ -1,115 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "clerk",
|
|
3
|
-
"displayName": "Clerk",
|
|
4
|
-
"description": "Clerk Authentication",
|
|
5
|
-
"category": "auth",
|
|
6
|
-
"provider": "clerk",
|
|
7
|
-
"supportedFrameworks": ["nextjs", "express", "react-vite"],
|
|
8
|
-
"frameworkConfigs": {
|
|
9
|
-
"nextjs": {
|
|
10
|
-
"dependencies": {
|
|
11
|
-
"@clerk/nextjs": "^6.10.2"
|
|
12
|
-
},
|
|
13
|
-
"envVars": [
|
|
14
|
-
{
|
|
15
|
-
"key": "NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY",
|
|
16
|
-
"value": "",
|
|
17
|
-
"description": "Clerk publishable key (from Clerk dashboard)",
|
|
18
|
-
"required": true
|
|
19
|
-
},
|
|
20
|
-
{
|
|
21
|
-
"key": "CLERK_SECRET_KEY",
|
|
22
|
-
"value": "",
|
|
23
|
-
"description": "Clerk secret key (from Clerk dashboard)",
|
|
24
|
-
"required": true
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
"key": "NEXT_PUBLIC_CLERK_SIGN_IN_URL",
|
|
28
|
-
"value": "/sign-in",
|
|
29
|
-
"description": "Sign in page URL",
|
|
30
|
-
"required": true
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
"key": "NEXT_PUBLIC_CLERK_SIGN_UP_URL",
|
|
34
|
-
"value": "/sign-up",
|
|
35
|
-
"description": "Sign up page URL",
|
|
36
|
-
"required": true
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
"key": "NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL",
|
|
40
|
-
"value": "/",
|
|
41
|
-
"description": "Redirect URL after sign in",
|
|
42
|
-
"required": true
|
|
43
|
-
},
|
|
44
|
-
{
|
|
45
|
-
"key": "NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL",
|
|
46
|
-
"value": "/",
|
|
47
|
-
"description": "Redirect URL after sign up",
|
|
48
|
-
"required": true
|
|
49
|
-
}
|
|
50
|
-
],
|
|
51
|
-
"patches": [
|
|
52
|
-
{
|
|
53
|
-
"type": "create-file",
|
|
54
|
-
"description": "Create Clerk auth provider",
|
|
55
|
-
"source": "nextjs/auth-provider.tsx",
|
|
56
|
-
"destination": "{{lib}}/auth-provider.tsx"
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"type": "create-file",
|
|
60
|
-
"description": "Create Clerk middleware",
|
|
61
|
-
"source": "nextjs/middleware.ts",
|
|
62
|
-
"destination": "middleware.ts"
|
|
63
|
-
}
|
|
64
|
-
]
|
|
65
|
-
},
|
|
66
|
-
"express": {
|
|
67
|
-
"dependencies": {
|
|
68
|
-
"@clerk/express": "^1.3.0"
|
|
69
|
-
},
|
|
70
|
-
"envVars": [
|
|
71
|
-
{
|
|
72
|
-
"key": "CLERK_PUBLISHABLE_KEY",
|
|
73
|
-
"value": "",
|
|
74
|
-
"description": "Clerk publishable key (from Clerk dashboard)",
|
|
75
|
-
"required": true
|
|
76
|
-
},
|
|
77
|
-
{
|
|
78
|
-
"key": "CLERK_SECRET_KEY",
|
|
79
|
-
"value": "",
|
|
80
|
-
"description": "Clerk secret key (from Clerk dashboard)",
|
|
81
|
-
"required": true
|
|
82
|
-
}
|
|
83
|
-
],
|
|
84
|
-
"patches": [
|
|
85
|
-
{
|
|
86
|
-
"type": "create-file",
|
|
87
|
-
"description": "Create Clerk auth utilities",
|
|
88
|
-
"source": "express/auth.ts",
|
|
89
|
-
"destination": "{{lib}}/auth.ts"
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
},
|
|
93
|
-
"react-vite": {
|
|
94
|
-
"dependencies": {
|
|
95
|
-
"@clerk/clerk-react": "^5.15.0"
|
|
96
|
-
},
|
|
97
|
-
"envVars": [
|
|
98
|
-
{
|
|
99
|
-
"key": "VITE_CLERK_PUBLISHABLE_KEY",
|
|
100
|
-
"value": "",
|
|
101
|
-
"description": "Clerk publishable key (from Clerk dashboard)",
|
|
102
|
-
"required": true
|
|
103
|
-
}
|
|
104
|
-
],
|
|
105
|
-
"patches": [
|
|
106
|
-
{
|
|
107
|
-
"type": "create-file",
|
|
108
|
-
"description": "Create Clerk auth provider",
|
|
109
|
-
"source": "react/auth-provider.tsx",
|
|
110
|
-
"destination": "{{lib}}/auth-provider.tsx"
|
|
111
|
-
}
|
|
112
|
-
]
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import "dotenv/config";
|
|
2
|
-
import mongoose from "mongoose";
|
|
3
|
-
|
|
4
|
-
const MONGODB_URI = process.env.DATABASE_URL || "mongodb://localhost:27017/myapp";
|
|
5
|
-
|
|
6
|
-
if (!MONGODB_URI) {
|
|
7
|
-
throw new Error("Please define the DATABASE_URL environment variable");
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
interface MongooseCache {
|
|
11
|
-
conn: typeof mongoose | null;
|
|
12
|
-
promise: Promise<typeof mongoose> | null;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
declare global {
|
|
16
|
-
var mongoose: MongooseCache | undefined;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
const cached: MongooseCache = global.mongoose || { conn: null, promise: null };
|
|
20
|
-
|
|
21
|
-
if (!global.mongoose) {
|
|
22
|
-
global.mongoose = cached;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
async function connectDB(): Promise<typeof mongoose> {
|
|
26
|
-
if (cached.conn) {
|
|
27
|
-
console.log("Using existing MongoDB connection");
|
|
28
|
-
return cached.conn;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
if (!cached.promise) {
|
|
32
|
-
const opts = {
|
|
33
|
-
bufferCommands: false,
|
|
34
|
-
maxPoolSize: 10, // Maintain up to 10 socket connections
|
|
35
|
-
serverSelectionTimeoutMS: 5000, // Keep trying to send operations for 5 seconds
|
|
36
|
-
socketTimeoutMS: 45000, // Close sockets after 45 seconds of inactivity
|
|
37
|
-
family: 4, // Use IPv4, skip trying IPv6
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
console.log("Creating new MongoDB connection");
|
|
41
|
-
cached.promise = mongoose.connect(MONGODB_URI, opts).then((mongoose) => {
|
|
42
|
-
console.log("MongoDB connected successfully");
|
|
43
|
-
return mongoose;
|
|
44
|
-
});
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
try {
|
|
48
|
-
cached.conn = await cached.promise;
|
|
49
|
-
} catch (e) {
|
|
50
|
-
cached.promise = null;
|
|
51
|
-
console.error("MongoDB connection error:", e);
|
|
52
|
-
throw e;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return cached.conn;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
// Handle connection events
|
|
59
|
-
mongoose.connection.on("connected", () => {
|
|
60
|
-
console.log("Mongoose connected to MongoDB");
|
|
61
|
-
});
|
|
62
|
-
|
|
63
|
-
mongoose.connection.on("error", (err) => {
|
|
64
|
-
console.error("Mongoose connection error:", err);
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
mongoose.connection.on("disconnected", () => {
|
|
68
|
-
console.log("Mongoose disconnected");
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
// Close connection on app termination
|
|
72
|
-
process.on("SIGINT", async () => {
|
|
73
|
-
await mongoose.connection.close();
|
|
74
|
-
console.log("MongoDB connection closed due to app termination");
|
|
75
|
-
process.exit(0);
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
export default connectDB;
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import { NextFunction, Request, Response } from "express";
|
|
2
|
-
import { authServices } from "./auth.service";
|
|
3
|
-
|
|
4
|
-
const signup = async (req: Request, res: Response, next: NextFunction) => {
|
|
5
|
-
try {
|
|
6
|
-
const result = await authServices.signup(req.body);
|
|
7
|
-
|
|
8
|
-
res.status(201).json({
|
|
9
|
-
success: true,
|
|
10
|
-
message: "User registered successfully",
|
|
11
|
-
data: result,
|
|
12
|
-
});
|
|
13
|
-
} catch (error) {
|
|
14
|
-
next(error);
|
|
15
|
-
}
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
const signin = async (req: Request, res: Response, next: NextFunction) => {
|
|
19
|
-
try {
|
|
20
|
-
const { email, password } = req.body;
|
|
21
|
-
|
|
22
|
-
const result = await authServices.signin(email, password);
|
|
23
|
-
|
|
24
|
-
if (!result) {
|
|
25
|
-
res.status(401).json({
|
|
26
|
-
success: false,
|
|
27
|
-
message: "Invalid email or password",
|
|
28
|
-
});
|
|
29
|
-
return;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
res.status(200).json({
|
|
33
|
-
success: true,
|
|
34
|
-
message: "Login successful",
|
|
35
|
-
data: {
|
|
36
|
-
token: result.token,
|
|
37
|
-
user: result.user,
|
|
38
|
-
},
|
|
39
|
-
});
|
|
40
|
-
} catch (error) {
|
|
41
|
-
next(error);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
export const authController = {
|
|
46
|
-
signup,
|
|
47
|
-
signin,
|
|
48
|
-
};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { Router } from "express";
|
|
2
|
-
import { authController } from "./auth.controller";
|
|
3
|
-
|
|
4
|
-
const router = Router();
|
|
5
|
-
|
|
6
|
-
// routes
|
|
7
|
-
router.post("/signup", authController.signup);
|
|
8
|
-
router.post("/signin", authController.signin);
|
|
9
|
-
|
|
10
|
-
export const authRoutes = router;
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
// @ts-nocheck
|
|
2
|
-
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
3
|
-
|
|
4
|
-
const signup = async (payload: Record<string, unknown>) => {
|
|
5
|
-
// your logic here
|
|
6
|
-
};
|
|
7
|
-
|
|
8
|
-
const signin = async (
|
|
9
|
-
email: string,
|
|
10
|
-
password: string,
|
|
11
|
-
): Promise<{ token: string; user: any } | null> => {
|
|
12
|
-
// your logic here
|
|
13
|
-
return null;
|
|
14
|
-
};
|
|
15
|
-
|
|
16
|
-
export const authServices = {
|
|
17
|
-
signup,
|
|
18
|
-
signin,
|
|
19
|
-
};
|
|
20
|
-
|
|
21
|
-
export type { User };
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import api from "../client";
|
|
2
|
-
|
|
3
|
-
export const userService = {
|
|
4
|
-
getUser: async (id: string): Promise<User> => {
|
|
5
|
-
const response = await api.get<ApiResponse<User>>(`/users/${id}`);
|
|
6
|
-
return response.data.data;
|
|
7
|
-
},
|
|
8
|
-
|
|
9
|
-
getCurrentUser: async (): Promise<User> => {
|
|
10
|
-
const response = await api.get<ApiResponse<User>>("/users/me");
|
|
11
|
-
return response.data.data;
|
|
12
|
-
},
|
|
13
|
-
|
|
14
|
-
updateUser: async (id: string, data: Partial<User>): Promise<User> => {
|
|
15
|
-
const response = await api.patch<ApiResponse<User>>(`/users/${id}`, data);
|
|
16
|
-
return response.data.data;
|
|
17
|
-
},
|
|
18
|
-
};
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { useQuery } from "@tanstack/react-query";
|
|
2
|
-
import { useLoaderData, useParams } from "react-router";
|
|
3
|
-
import { userService } from "../api/services/user.service";
|
|
4
|
-
|
|
5
|
-
type User = { id?: string; name?: string; email?: string; avatar?: string; [key: string]: any };
|
|
6
|
-
|
|
7
|
-
export default function UserProfile() {
|
|
8
|
-
const loaderUser = useLoaderData() as User | undefined;
|
|
9
|
-
const { userId } = useParams();
|
|
10
|
-
|
|
11
|
-
const { data: user = loaderUser ?? {} } = useQuery({
|
|
12
|
-
queryKey: ["user", userId],
|
|
13
|
-
queryFn: async () => {
|
|
14
|
-
if (!userId) throw new Error("Missing user id");
|
|
15
|
-
return await userService.getUser(userId);
|
|
16
|
-
},
|
|
17
|
-
initialData: loaderUser,
|
|
18
|
-
staleTime: 1000 * 60,
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
return (
|
|
22
|
-
<div className="min-h-screen bg-black text-white flex items-center justify-center">
|
|
23
|
-
<div className="max-w-xl p-8 bg-zinc-900 rounded-md shadow">
|
|
24
|
-
<div className="flex items-center gap-4">
|
|
25
|
-
{user.avatar ? (
|
|
26
|
-
<img src={user.avatar} alt={user.name} className="w-16 h-16 rounded-full" />
|
|
27
|
-
) : (
|
|
28
|
-
<div className="w-16 h-16 rounded-full bg-zinc-700 flex items-center justify-center text-xl">
|
|
29
|
-
{user.name?.[0] ?? "U"}
|
|
30
|
-
</div>
|
|
31
|
-
)}
|
|
32
|
-
<div>
|
|
33
|
-
<h2 className="text-2xl font-semibold">{user.name}</h2>
|
|
34
|
-
<p className="text-sm text-zinc-400">{user.email}</p>
|
|
35
|
-
</div>
|
|
36
|
-
</div>
|
|
37
|
-
</div>
|
|
38
|
-
</div>
|
|
39
|
-
);
|
|
40
|
-
}
|