create-stackkit-app 0.4.2 → 0.4.4
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 +1 -0
- package/bin/create-stackkit.js +10 -1
- package/dist/index.js +2 -1
- package/dist/lib/create-project.js +138 -412
- package/dist/lib/utils/config-utils.d.ts +2 -0
- package/dist/lib/utils/config-utils.js +33 -0
- package/dist/lib/utils/file-utils.d.ts +8 -0
- package/dist/lib/utils/file-utils.js +75 -0
- package/dist/lib/utils/git-utils.d.ts +1 -0
- package/dist/lib/utils/git-utils.js +9 -0
- package/dist/lib/utils/js-conversion.d.ts +1 -0
- package/dist/lib/utils/js-conversion.js +244 -0
- package/dist/lib/utils/module-utils.d.ts +2 -0
- package/dist/lib/utils/module-utils.js +311 -0
- package/dist/lib/utils/package-utils.d.ts +1 -0
- package/dist/lib/utils/package-utils.js +39 -0
- package/modules/auth/better-auth/files/api/auth/[...all]/route.ts +4 -0
- package/modules/auth/better-auth/files/lib/auth.ts +13 -0
- package/modules/auth/better-auth/files/schemas/prisma-schema.prisma +63 -0
- package/modules/auth/better-auth/module.json +54 -0
- package/modules/auth/{clerk-express/files/lib → clerk/files/express}/auth.ts +1 -1
- package/modules/auth/{clerk-nextjs/files/lib → clerk/files/nextjs}/auth-provider.tsx +1 -1
- package/modules/auth/clerk/files/nextjs/middleware.ts +9 -0
- package/modules/auth/{clerk-react/files/lib → clerk/files/react}/auth-provider.tsx +2 -2
- package/modules/auth/clerk/module.json +115 -0
- package/modules/database/mongoose-mongodb/files/lib/db.ts +45 -7
- package/modules/database/mongoose-mongodb/files/models/User.ts +39 -0
- package/modules/database/mongoose-mongodb/module.json +27 -12
- package/modules/database/prisma/files/lib/prisma.ts +6 -0
- package/modules/database/prisma/files/prisma/schema.prisma +8 -0
- package/modules/database/prisma/files/prisma.config.ts +12 -0
- package/modules/database/prisma/module.json +140 -0
- package/package.json +12 -3
- package/templates/express/.env.example +2 -10
- package/templates/express/package.json +13 -18
- package/templates/express/src/app.ts +21 -39
- package/templates/express/src/config/env.ts +6 -17
- package/templates/express/src/features/auth/auth.controller.ts +48 -0
- package/templates/express/src/features/auth/auth.route.ts +10 -0
- package/templates/express/src/features/auth/auth.service.ts +21 -0
- package/templates/express/src/middlewares/error.middleware.ts +5 -5
- package/templates/express/src/server.ts +3 -3
- package/templates/express/template.json +34 -1
- package/templates/express/tsconfig.json +17 -1
- package/templates/nextjs/app/layout.tsx +1 -5
- package/templates/nextjs/app/page.tsx +26 -34
- package/templates/nextjs/package.json +2 -1
- package/templates/nextjs/template.json +13 -1
- package/templates/react-vite/eslint.config.js +9 -9
- package/templates/react-vite/package.json +1 -2
- package/templates/react-vite/src/api/client.ts +16 -16
- package/templates/react-vite/src/api/services/user.service.ts +2 -10
- package/templates/react-vite/src/components/ErrorBoundary.tsx +4 -4
- package/templates/react-vite/src/components/Layout.tsx +1 -1
- package/templates/react-vite/src/components/Loading.tsx +1 -1
- package/templates/react-vite/src/components/SEO.tsx +5 -5
- package/templates/react-vite/src/config/constants.ts +3 -3
- package/templates/react-vite/src/hooks/index.ts +5 -5
- package/templates/react-vite/src/lib/queryClient.ts +2 -2
- package/templates/react-vite/src/main.tsx +12 -12
- package/templates/react-vite/src/pages/About.tsx +6 -2
- package/templates/react-vite/src/pages/Home.tsx +8 -4
- package/templates/react-vite/src/pages/NotFound.tsx +2 -2
- package/templates/react-vite/src/pages/UserProfile.tsx +6 -6
- package/templates/react-vite/src/router.tsx +13 -13
- package/templates/react-vite/src/types/{api.ts → api.d.ts} +6 -6
- package/templates/react-vite/src/types/user.d.ts +6 -0
- package/templates/react-vite/src/utils/helpers.ts +11 -11
- package/templates/react-vite/src/utils/storage.ts +4 -4
- package/templates/react-vite/template.json +26 -0
- package/templates/react-vite/tsconfig.json +1 -4
- package/templates/react-vite/vite.config.ts +5 -5
- package/dist/lib/template-composer.d.ts +0 -16
- package/dist/lib/template-composer.js +0 -197
- package/modules/auth/better-auth-express/adapters/mongoose-mongodb.ts +0 -13
- package/modules/auth/better-auth-express/adapters/prisma-mongodb.ts +0 -15
- package/modules/auth/better-auth-express/adapters/prisma-postgresql.ts +0 -15
- package/modules/auth/better-auth-express/files/lib/auth.ts +0 -16
- package/modules/auth/better-auth-express/files/routes/auth.ts +0 -12
- package/modules/auth/better-auth-express/files/schemas/prisma-mongodb-schema.prisma +0 -72
- package/modules/auth/better-auth-express/files/schemas/prisma-postgresql-schema.prisma +0 -72
- package/modules/auth/better-auth-express/module.json +0 -61
- package/modules/auth/better-auth-nextjs/adapters/mongoose-mongodb.ts +0 -24
- package/modules/auth/better-auth-nextjs/adapters/prisma-mongodb.ts +0 -26
- package/modules/auth/better-auth-nextjs/adapters/prisma-postgresql.ts +0 -26
- package/modules/auth/better-auth-nextjs/files/api/auth/[...all]/route.ts +0 -5
- package/modules/auth/better-auth-nextjs/files/lib/auth.ts +0 -26
- package/modules/auth/better-auth-nextjs/files/schemas/prisma-mongodb-schema.prisma +0 -72
- package/modules/auth/better-auth-nextjs/files/schemas/prisma-postgresql-schema.prisma +0 -72
- package/modules/auth/better-auth-nextjs/module.json +0 -62
- package/modules/auth/better-auth-react/files/lib/auth-client.ts +0 -9
- package/modules/auth/better-auth-react/module.json +0 -28
- package/modules/auth/clerk-express/module.json +0 -34
- package/modules/auth/clerk-nextjs/files/middleware.ts +0 -9
- package/modules/auth/clerk-nextjs/module.json +0 -64
- package/modules/auth/clerk-react/module.json +0 -28
- package/modules/database/prisma-mongodb/files/lib/db.ts +0 -9
- package/modules/database/prisma-mongodb/files/prisma/schema.prisma +0 -17
- package/modules/database/prisma-mongodb/module.json +0 -60
- package/modules/database/prisma-postgresql/files/lib/db.ts +0 -9
- package/modules/database/prisma-postgresql/files/prisma/schema.prisma +0 -17
- package/modules/database/prisma-postgresql/module.json +0 -60
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
36
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.mergeDatabaseConfig = mergeDatabaseConfig;
|
|
40
|
+
exports.mergeAuthConfig = mergeAuthConfig;
|
|
41
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
42
|
+
const path_1 = __importStar(require("path"));
|
|
43
|
+
const config_utils_1 = require("./config-utils");
|
|
44
|
+
const file_utils_1 = require("./file-utils");
|
|
45
|
+
async function mergeDatabaseConfig(templatesDir, targetDir, database, framework, dbProvider) {
|
|
46
|
+
const modulesDir = (0, path_1.join)(templatesDir, "..", "modules");
|
|
47
|
+
const dbModulePath = (0, path_1.join)(modulesDir, "database", database);
|
|
48
|
+
if (!(await fs_extra_1.default.pathExists(dbModulePath))) {
|
|
49
|
+
// eslint-disable-next-line no-console
|
|
50
|
+
console.warn(`Database module not found: ${database}`);
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
// Read module.json
|
|
54
|
+
const moduleJsonPath = (0, path_1.join)(dbModulePath, "module.json");
|
|
55
|
+
if (!(await fs_extra_1.default.pathExists(moduleJsonPath))) {
|
|
56
|
+
return [];
|
|
57
|
+
}
|
|
58
|
+
const moduleData = await fs_extra_1.default.readJson(moduleJsonPath);
|
|
59
|
+
const variables = {};
|
|
60
|
+
if (dbProvider) {
|
|
61
|
+
variables.provider = dbProvider;
|
|
62
|
+
if (dbProvider === "postgresql") {
|
|
63
|
+
variables.connectionString = "postgresql://user:password@localhost:5432/mydb?schema=public";
|
|
64
|
+
variables.prismaClientInit = `
|
|
65
|
+
import { PrismaPg } from "@prisma/adapter-pg";
|
|
66
|
+
|
|
67
|
+
const globalForPrisma = global as unknown as {
|
|
68
|
+
prisma: PrismaClient | undefined;
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
const adapter = new PrismaPg({
|
|
72
|
+
connectionString: process.env.DATABASE_URL!,
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
const prisma = globalForPrisma.prisma ?? new PrismaClient({
|
|
76
|
+
adapter,
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
if (process.env.NODE_ENV !== "production") globalForPrisma.prisma = prisma;
|
|
80
|
+
`;
|
|
81
|
+
}
|
|
82
|
+
else if (dbProvider === "mongodb") {
|
|
83
|
+
variables.connectionString = "mongodb+srv://username:password@cluster.mongodb.net/mydb";
|
|
84
|
+
variables.prismaClientInit = `
|
|
85
|
+
const prisma = new PrismaClient()
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
else if (dbProvider === "mysql") {
|
|
89
|
+
variables.connectionString = "mysql://user:password@localhost:3306/mydb";
|
|
90
|
+
variables.prismaClientInit = `
|
|
91
|
+
import { PrismaMariaDb } from '@prisma/adapter-mariadb';
|
|
92
|
+
|
|
93
|
+
const adapter = new PrismaMariaDb({
|
|
94
|
+
host: process.env.DATABASE_HOST,
|
|
95
|
+
user: process.env.DATABASE_USER,
|
|
96
|
+
password: process.env.DATABASE_PASSWORD,
|
|
97
|
+
database: process.env.DATABASE_NAME,
|
|
98
|
+
connectionLimit: 5
|
|
99
|
+
});
|
|
100
|
+
const prisma = new PrismaClient({ adapter });
|
|
101
|
+
`;
|
|
102
|
+
}
|
|
103
|
+
else if (dbProvider === "sqlite") {
|
|
104
|
+
variables.connectionString = "file:./dev.db";
|
|
105
|
+
variables.prismaClientInit = `
|
|
106
|
+
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
|
|
107
|
+
|
|
108
|
+
const adapter = new PrismaBetterSqlite3({ url: process.env.DATABASE_URL });
|
|
109
|
+
const prisma = new PrismaClient({ adapter });
|
|
110
|
+
`;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
const filesDir = (0, path_1.join)(dbModulePath, "files");
|
|
114
|
+
if (await fs_extra_1.default.pathExists(filesDir)) {
|
|
115
|
+
const libDir = framework === "nextjs" ? "lib" : "src";
|
|
116
|
+
for (const patch of moduleData.patches || []) {
|
|
117
|
+
if (patch.type === "create-file") {
|
|
118
|
+
const sourceFile = (0, path_1.join)(filesDir, patch.source);
|
|
119
|
+
let destFile = (0, path_1.join)(targetDir, patch.destination);
|
|
120
|
+
destFile = destFile
|
|
121
|
+
.replace("{{lib}}", libDir)
|
|
122
|
+
.replace("{{src}}", "src")
|
|
123
|
+
.replace("{{models}}", framework === "nextjs" ? "models" : "src/models");
|
|
124
|
+
if (await fs_extra_1.default.pathExists(sourceFile)) {
|
|
125
|
+
await fs_extra_1.default.ensureDir((0, path_1.join)(destFile, ".."));
|
|
126
|
+
// Check if text file
|
|
127
|
+
const ext = path_1.default.extname(sourceFile);
|
|
128
|
+
if ([".ts", ".js", ".prisma", ".json"].includes(ext)) {
|
|
129
|
+
let content = await fs_extra_1.default.readFile(sourceFile, "utf-8");
|
|
130
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
131
|
+
content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
132
|
+
}
|
|
133
|
+
await fs_extra_1.default.writeFile(destFile, content);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
await fs_extra_1.default.copy(sourceFile, destFile, { overwrite: false });
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const dependencies = {
|
|
143
|
+
...moduleData.dependencies.common,
|
|
144
|
+
...(dbProvider ? moduleData.dependencies.providers[dbProvider] : {}),
|
|
145
|
+
};
|
|
146
|
+
const devDependencies = {
|
|
147
|
+
...moduleData.devDependencies.common,
|
|
148
|
+
...(dbProvider ? moduleData.devDependencies.providers[dbProvider] : {}),
|
|
149
|
+
};
|
|
150
|
+
await (0, file_utils_1.mergePackageJson)(targetDir, {
|
|
151
|
+
dependencies,
|
|
152
|
+
devDependencies,
|
|
153
|
+
});
|
|
154
|
+
const envVars = {};
|
|
155
|
+
const commonEnvVars = Array.isArray(moduleData.envVars) ? moduleData.envVars : moduleData.envVars?.common || [];
|
|
156
|
+
const providerEnvVars = dbProvider && moduleData.envVars?.providers?.[dbProvider] ? moduleData.envVars.providers[dbProvider] : [];
|
|
157
|
+
const allEnvVars = [...commonEnvVars, ...providerEnvVars];
|
|
158
|
+
for (const envVar of allEnvVars) {
|
|
159
|
+
let value = envVar.value;
|
|
160
|
+
for (const [key, val] of Object.entries(variables)) {
|
|
161
|
+
value = value.replace(new RegExp(`{{${key}}}`, "g"), val);
|
|
162
|
+
}
|
|
163
|
+
envVars[envVar.key] = value;
|
|
164
|
+
}
|
|
165
|
+
await (0, file_utils_1.mergeEnvFile)(targetDir, envVars);
|
|
166
|
+
if (moduleData.frameworkPatches) {
|
|
167
|
+
const frameworkKey = framework === "react-vite" ? "react" : framework;
|
|
168
|
+
const patches = moduleData.frameworkPatches[frameworkKey];
|
|
169
|
+
if (patches) {
|
|
170
|
+
await (0, config_utils_1.applyFrameworkPatches)(targetDir, patches);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
return moduleData.postInstall || [];
|
|
174
|
+
}
|
|
175
|
+
async function mergeAuthConfig(templatesDir, targetDir, framework, auth, database = "none", dbProvider) {
|
|
176
|
+
const modulesDir = (0, path_1.join)(templatesDir, "..", "modules");
|
|
177
|
+
const authKey = auth;
|
|
178
|
+
const authModulePath = (0, path_1.join)(modulesDir, "auth", authKey);
|
|
179
|
+
if (!(await fs_extra_1.default.pathExists(authModulePath))) {
|
|
180
|
+
// eslint-disable-next-line no-console
|
|
181
|
+
console.warn(`Auth module not found: ${authKey}`);
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
// Read module.json
|
|
185
|
+
const moduleJsonPath = (0, path_1.join)(authModulePath, "module.json");
|
|
186
|
+
if (!(await fs_extra_1.default.pathExists(moduleJsonPath))) {
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
const moduleData = await fs_extra_1.default.readJson(moduleJsonPath);
|
|
190
|
+
if (moduleData.supportedFrameworks && !moduleData.supportedFrameworks.includes(framework)) {
|
|
191
|
+
// eslint-disable-next-line no-console
|
|
192
|
+
console.warn(`Auth ${authKey} does not support framework ${framework}`);
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
let frameworkConfig = null;
|
|
196
|
+
if (moduleData.frameworkConfigs) {
|
|
197
|
+
frameworkConfig = moduleData.frameworkConfigs[framework];
|
|
198
|
+
if (!frameworkConfig) {
|
|
199
|
+
// eslint-disable-next-line no-console
|
|
200
|
+
console.warn(`No config for framework ${framework} in ${authKey}`);
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const variables = {};
|
|
205
|
+
if (framework === "nextjs") {
|
|
206
|
+
variables.dbImport = "@/lib/db";
|
|
207
|
+
}
|
|
208
|
+
else if (framework === "express") {
|
|
209
|
+
variables.dbImport = "../db";
|
|
210
|
+
}
|
|
211
|
+
else {
|
|
212
|
+
variables.dbImport = "../db";
|
|
213
|
+
}
|
|
214
|
+
const filesDir = (0, path_1.join)(authModulePath, "files");
|
|
215
|
+
if (await fs_extra_1.default.pathExists(filesDir)) {
|
|
216
|
+
const getReplacements = () => {
|
|
217
|
+
if (framework === "nextjs") {
|
|
218
|
+
return { lib: "lib", router: "app" };
|
|
219
|
+
}
|
|
220
|
+
else if (framework === "express") {
|
|
221
|
+
return { lib: "src", router: "src" };
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
return { lib: "src", router: "src" };
|
|
225
|
+
}
|
|
226
|
+
};
|
|
227
|
+
const replacements = getReplacements();
|
|
228
|
+
const patches = frameworkConfig?.patches || moduleData.patches || [];
|
|
229
|
+
for (const patch of patches) {
|
|
230
|
+
if (patch.type === "create-file") {
|
|
231
|
+
const sourceFile = (0, path_1.join)(filesDir, patch.source);
|
|
232
|
+
let destFile = (0, path_1.join)(targetDir, patch.destination);
|
|
233
|
+
destFile = destFile
|
|
234
|
+
.replace("{{lib}}", replacements.lib)
|
|
235
|
+
.replace("{{router}}", replacements.router);
|
|
236
|
+
if (await fs_extra_1.default.pathExists(sourceFile)) {
|
|
237
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(destFile));
|
|
238
|
+
// Check if text file
|
|
239
|
+
const ext = path_1.default.extname(sourceFile);
|
|
240
|
+
if ([".ts", ".js", ".json"].includes(ext)) {
|
|
241
|
+
let content = await fs_extra_1.default.readFile(sourceFile, "utf-8");
|
|
242
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
243
|
+
content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
244
|
+
}
|
|
245
|
+
await fs_extra_1.default.writeFile(destFile, content);
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
await fs_extra_1.default.copy(sourceFile, destFile, { overwrite: false });
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
// Add framework-specific patches
|
|
255
|
+
if (framework === "nextjs") {
|
|
256
|
+
const apiSource = (0, path_1.join)(filesDir, "api/auth/[...all]/route.ts");
|
|
257
|
+
const apiDest = (0, path_1.join)(targetDir, "app/api/auth/[...all]/route.ts");
|
|
258
|
+
if (await fs_extra_1.default.pathExists(apiSource)) {
|
|
259
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(apiDest));
|
|
260
|
+
await fs_extra_1.default.copy(apiSource, apiDest, { overwrite: false });
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
if (database !== "none" && moduleData.databaseAdapters) {
|
|
264
|
+
let adapterKey = database;
|
|
265
|
+
if (database === "prisma" && dbProvider) {
|
|
266
|
+
adapterKey = `prisma-${dbProvider}`;
|
|
267
|
+
}
|
|
268
|
+
const adapterConfig = moduleData.databaseAdapters[adapterKey];
|
|
269
|
+
if (adapterConfig) {
|
|
270
|
+
variables.databaseAdapter = adapterConfig.adapterCode;
|
|
271
|
+
if (adapterConfig.schema && adapterConfig.schemaDestination) {
|
|
272
|
+
const schemaSource = (0, path_1.join)(authModulePath, adapterConfig.schema);
|
|
273
|
+
const schemaDest = (0, path_1.join)(targetDir, adapterConfig.schemaDestination);
|
|
274
|
+
if (await fs_extra_1.default.pathExists(schemaSource)) {
|
|
275
|
+
await fs_extra_1.default.ensureDir(path_1.default.dirname(schemaDest));
|
|
276
|
+
let content = await fs_extra_1.default.readFile(schemaSource, "utf-8");
|
|
277
|
+
// Set schema variables
|
|
278
|
+
if (dbProvider === "postgresql") {
|
|
279
|
+
variables.provider = "postgresql";
|
|
280
|
+
variables.idDefault = "@default(cuid())";
|
|
281
|
+
variables.userIdType = "";
|
|
282
|
+
}
|
|
283
|
+
else if (dbProvider === "mongodb") {
|
|
284
|
+
variables.provider = "mongodb";
|
|
285
|
+
variables.idDefault = '@default(auto()) @map("_id") @db.ObjectId';
|
|
286
|
+
variables.userIdType = "@db.ObjectId";
|
|
287
|
+
}
|
|
288
|
+
for (const [key, value] of Object.entries(variables)) {
|
|
289
|
+
content = content.replace(new RegExp(`{{${key}}}`, "g"), value);
|
|
290
|
+
}
|
|
291
|
+
await fs_extra_1.default.writeFile(schemaDest, content, { flag: "a" }); // append
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
if (adapterConfig.dependencies) {
|
|
295
|
+
await (0, file_utils_1.mergePackageJson)(targetDir, {
|
|
296
|
+
dependencies: adapterConfig.dependencies,
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
await (0, file_utils_1.mergePackageJson)(targetDir, {
|
|
302
|
+
dependencies: frameworkConfig?.dependencies || moduleData.dependencies,
|
|
303
|
+
devDependencies: frameworkConfig?.devDependencies || moduleData.devDependencies,
|
|
304
|
+
});
|
|
305
|
+
const envVars = {};
|
|
306
|
+
const envVarList = frameworkConfig?.envVars || moduleData.envVars || [];
|
|
307
|
+
for (const envVar of envVarList) {
|
|
308
|
+
envVars[envVar.key] = envVar.value;
|
|
309
|
+
}
|
|
310
|
+
await (0, file_utils_1.mergeEnvFile)(targetDir, envVars);
|
|
311
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function installDependencies(cwd: string, packageManager: string): Promise<void>;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.installDependencies = installDependencies;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
async function installDependencies(cwd, packageManager) {
|
|
6
|
+
const commands = {
|
|
7
|
+
npm: "npm install",
|
|
8
|
+
yarn: "yarn install",
|
|
9
|
+
pnpm: "pnpm install",
|
|
10
|
+
bun: "bun install",
|
|
11
|
+
};
|
|
12
|
+
const isAvailable = (cmd) => {
|
|
13
|
+
try {
|
|
14
|
+
(0, child_process_1.execSync)(`command -v ${cmd}`, { stdio: "ignore" });
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
catch {
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
let chosen = packageManager;
|
|
22
|
+
if (!isAvailable(chosen)) {
|
|
23
|
+
const fallbacks = ["pnpm", "npm", "yarn", "bun"];
|
|
24
|
+
const found = fallbacks.find((p) => isAvailable(p));
|
|
25
|
+
if (found) {
|
|
26
|
+
// eslint-disable-next-line no-console
|
|
27
|
+
console.warn(`Selected package manager '${chosen}' was not found. Falling back to '${found}'.`);
|
|
28
|
+
chosen = found;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
throw new Error(`Selected package manager '${packageManager}' was not found and no fallback package manager is available. Please install '${packageManager}' or use a different package manager.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
const command = commands[chosen];
|
|
35
|
+
(0, child_process_1.execSync)(command, {
|
|
36
|
+
cwd,
|
|
37
|
+
stdio: "pipe",
|
|
38
|
+
});
|
|
39
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
|
|
3
|
+
{{databaseAdapter}}
|
|
4
|
+
emailAndPassword: {
|
|
5
|
+
enabled: true,
|
|
6
|
+
},
|
|
7
|
+
socialProviders: {
|
|
8
|
+
google: {
|
|
9
|
+
clientId: process.env.GOOGLE_CLIENT_ID!,
|
|
10
|
+
clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
});
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Better Auth models
|
|
2
|
+
model User {
|
|
3
|
+
id String @id {{idDefault}}
|
|
4
|
+
name String
|
|
5
|
+
email String
|
|
6
|
+
emailVerified Boolean @default(false)
|
|
7
|
+
image String?
|
|
8
|
+
createdAt DateTime @default(now())
|
|
9
|
+
updatedAt DateTime @updatedAt
|
|
10
|
+
sessions Session[]
|
|
11
|
+
accounts Account[]
|
|
12
|
+
role String @default("USER")
|
|
13
|
+
|
|
14
|
+
@@unique([email])
|
|
15
|
+
@@map("user")
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
model Session {
|
|
19
|
+
id String @id {{idDefault}}
|
|
20
|
+
expiresAt DateTime
|
|
21
|
+
token String @unique
|
|
22
|
+
createdAt DateTime @default(now())
|
|
23
|
+
updatedAt DateTime @updatedAt
|
|
24
|
+
ipAddress String?
|
|
25
|
+
userAgent String?
|
|
26
|
+
userId String {{userIdType}}
|
|
27
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
28
|
+
|
|
29
|
+
@@index([userId])
|
|
30
|
+
@@map("session")
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
model Account {
|
|
34
|
+
id String @id {{idDefault}}
|
|
35
|
+
accountId String
|
|
36
|
+
providerId String
|
|
37
|
+
userId String {{userIdType}}
|
|
38
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
39
|
+
accessToken String?
|
|
40
|
+
refreshToken String?
|
|
41
|
+
idToken String?
|
|
42
|
+
accessTokenExpiresAt DateTime?
|
|
43
|
+
refreshTokenExpiresAt DateTime?
|
|
44
|
+
scope String?
|
|
45
|
+
password String?
|
|
46
|
+
createdAt DateTime @default(now())
|
|
47
|
+
updatedAt DateTime @updatedAt
|
|
48
|
+
|
|
49
|
+
@@index([userId])
|
|
50
|
+
@@map("account")
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
model Verification {
|
|
54
|
+
id String @id {{idDefault}}
|
|
55
|
+
identifier String
|
|
56
|
+
value String
|
|
57
|
+
expiresAt DateTime
|
|
58
|
+
createdAt DateTime @default(now())
|
|
59
|
+
updatedAt DateTime @updatedAt
|
|
60
|
+
|
|
61
|
+
@@index([identifier])
|
|
62
|
+
@@map("verification")
|
|
63
|
+
}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "better-auth",
|
|
3
|
+
"displayName": "Better Auth",
|
|
4
|
+
"description": "Modern authentication with Better Auth",
|
|
5
|
+
"category": "auth",
|
|
6
|
+
"provider": "better-auth",
|
|
7
|
+
"supportedFrameworks": ["nextjs", "express", "react-vite"],
|
|
8
|
+
"databaseAdapters": {
|
|
9
|
+
"prisma-postgresql": {
|
|
10
|
+
"adapterCode": "import { prisma } from \"{{dbImport}}\";\nimport { prismaAdapter } from \"@better-auth/prisma\";\n\nexport const auth = betterAuth({\n database: prismaAdapter(prisma, {\n provider: \"postgresql\",\n }),",
|
|
11
|
+
"schema": "files/schemas/prisma-schema.prisma",
|
|
12
|
+
"schemaDestination": "prisma/schema.prisma",
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"better-auth": "^1.1.4"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"prisma-mongodb": {
|
|
18
|
+
"adapterCode": "import { prisma } from \"{{dbImport}}\";\nimport { prismaAdapter } from \"@better-auth/prisma\";\n\nexport const auth = betterAuth({\n database: prismaAdapter(prisma, {\n provider: \"mongodb\",\n }),",
|
|
19
|
+
"schema": "files/schemas/prisma-schema.prisma",
|
|
20
|
+
"schemaDestination": "prisma/schema.prisma",
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"better-auth": "^1.1.4"
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"mongoose-mongodb": {
|
|
26
|
+
"adapterCode": "import { client } from \"{{dbImport}}\";\nimport { mongodbAdapter } from \"better-auth/adapters/mongodb\";\n\nexport const auth = betterAuth({\n database: mongodbAdapter(client),",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"better-auth": "^1.1.4"
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"envVars": [
|
|
33
|
+
{
|
|
34
|
+
"key": "BETTER_AUTH_SECRET",
|
|
35
|
+
"value": "",
|
|
36
|
+
"description": "Secret key for Better Auth. Generate with: openssl rand -base64 32",
|
|
37
|
+
"required": true
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
"key": "BETTER_AUTH_URL",
|
|
41
|
+
"value": "http://localhost:3000",
|
|
42
|
+
"description": "Base URL of your application (change in production)",
|
|
43
|
+
"required": true
|
|
44
|
+
}
|
|
45
|
+
],
|
|
46
|
+
"patches": [
|
|
47
|
+
{
|
|
48
|
+
"type": "create-file",
|
|
49
|
+
"description": "Create Better Auth configuration",
|
|
50
|
+
"source": "files/lib/auth.ts",
|
|
51
|
+
"destination": "{{lib}}/auth.ts"
|
|
52
|
+
}
|
|
53
|
+
]
|
|
54
|
+
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { ClerkProvider } from
|
|
1
|
+
import { ClerkProvider } from "@clerk/clerk-react";
|
|
2
2
|
|
|
3
3
|
const publishableKey = import.meta.env.VITE_CLERK_PUBLISHABLE_KEY;
|
|
4
4
|
|
|
5
5
|
if (!publishableKey) {
|
|
6
|
-
throw new Error(
|
|
6
|
+
throw new Error("Missing Publishable Key");
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
export function AuthProvider({ children }: { children: React.ReactNode }) {
|
|
@@ -0,0 +1,115 @@
|
|
|
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
|
+
}
|