stackkit 0.1.5 → 0.1.7

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/dist/cli/add.js CHANGED
@@ -17,7 +17,6 @@ const logger_1 = require("../lib/ui/logger");
17
17
  const package_manager_1 = require("../lib/pm/package-manager");
18
18
  const package_root_1 = require("../lib/utils/package-root");
19
19
  const framework_utils_1 = require("../lib/framework/framework-utils");
20
- const generator_utils_1 = require("../lib/generation/generator-utils");
21
20
  async function addCommand(module, options) {
22
21
  try {
23
22
  const projectRoot = process.cwd();
@@ -29,10 +28,6 @@ async function addCommand(module, options) {
29
28
  logger_1.logger.newLine();
30
29
  logger_1.logger.success(`Added ${chalk_1.default.bold(config.displayName)}`);
31
30
  logger_1.logger.newLine();
32
- if (config.metadata.envVars && config.metadata.envVars.length > 0) {
33
- logger_1.logger.log("Next: Fill in environment variables in .env");
34
- }
35
- logger_1.logger.newLine();
36
31
  }
37
32
  catch (error) {
38
33
  logger_1.logger.error(`Failed to add module: ${error.message}`);
@@ -44,88 +39,59 @@ async function addCommand(module, options) {
44
39
  }
45
40
  async function getAddConfig(module, options, projectInfo) {
46
41
  const modulesDir = path_1.default.join((0, package_root_1.getPackageRoot)(), "modules");
47
- const argv = process.argv.slice(2);
48
- const addIndex = argv.indexOf("add");
49
- const argsAfterAdd = addIndex >= 0 ? argv.slice(addIndex + 1) : [];
50
- const flagsProvided = argsAfterAdd.some((arg) => arg.startsWith("-"));
51
- const optionsProvided = flagsProvided ||
52
- !!(options && (options.yes || options.provider || options.force || options.dryRun));
53
- if (optionsProvided) {
54
- if (!module) {
55
- throw new Error("Module name is required when using flags");
56
- }
57
- if (module === "database" || module === "auth") {
42
+ // If no module provided, go interactive
43
+ if (!module) {
44
+ return await getInteractiveConfig(modulesDir, projectInfo);
45
+ }
46
+ // Only allow: no-arg interactive, or explicit category + --provider.
47
+ // Disallow positional provider names like `npx stackkit add better-auth` or
48
+ // `npx stackkit add auth prisma-postgresql` — require `--provider` flag.
49
+ if (module === "database" || module === "auth") {
50
+ if (!options?.provider) {
58
51
  if (module === "database") {
59
- if (!options?.provider) {
60
- throw new Error("Provider is required for database. Use --provider <provider>");
61
- }
62
- let baseProvider = options.provider;
63
- let adapterProvider = options.provider;
64
- if (options.provider.includes("-")) {
65
- const parts = options.provider.split("-");
66
- baseProvider = parts[0]; // e.g., "prisma"
67
- adapterProvider = options.provider; // e.g., "prisma-postgresql"
68
- }
69
- const moduleMetadata = await loadModuleMetadata(modulesDir, baseProvider, baseProvider);
70
- if (!moduleMetadata) {
71
- throw new Error(`Database provider "${baseProvider}" not found`);
72
- }
73
- return {
74
- module: "database",
75
- provider: adapterProvider,
76
- displayName: `${moduleMetadata.displayName} (${adapterProvider.split("-")[1] || adapterProvider})`,
77
- metadata: moduleMetadata,
78
- };
52
+ throw new Error("Provider is required for database. Use: `npx stackkit add database --provider <provider>`");
79
53
  }
80
- else if (module === "auth") {
81
- const provider = options?.provider || "better-auth";
82
- const moduleMetadata = await loadModuleMetadata(modulesDir, provider, provider);
83
- if (!moduleMetadata) {
84
- throw new Error(`Auth provider "${provider}" not found`);
85
- }
86
- return {
87
- module: "auth",
88
- provider,
89
- displayName: moduleMetadata.displayName,
90
- metadata: moduleMetadata,
91
- };
54
+ else {
55
+ throw new Error("Provider is required for auth. Use: `npx stackkit add auth --provider <provider>`");
92
56
  }
93
57
  }
94
- const moduleMetadata = await loadModuleMetadata(modulesDir, module, options?.provider);
95
- if (!moduleMetadata) {
96
- throw new Error(`Module "${module}" not found`);
97
- }
98
- let selectedProvider = options?.provider;
99
- if (!selectedProvider && moduleMetadata.category !== module) {
100
- selectedProvider = module;
101
- }
102
- if (moduleMetadata.category === "database" && !selectedProvider) {
103
- if (typeof moduleMetadata.dependencies === "object" &&
104
- "providers" in moduleMetadata.dependencies) {
105
- const providers = Object.keys(moduleMetadata.dependencies.providers || {});
106
- if (providers.length > 0) {
107
- const { provider } = await inquirer_1.default.prompt([
108
- {
109
- type: "list",
110
- name: "provider",
111
- message: "Select database provider:",
112
- choices: providers.map((p) => ({ name: p, value: p })),
113
- },
114
- ]);
115
- selectedProvider = provider;
116
- }
58
+ if (module === "database") {
59
+ let baseProvider = options.provider;
60
+ let adapterProvider = options.provider;
61
+ if (options.provider.includes("-")) {
62
+ const parts = options.provider.split("-");
63
+ baseProvider = parts[0]; // e.g., "prisma"
64
+ adapterProvider = options.provider; // e.g., "prisma-postgresql"
65
+ }
66
+ const moduleMetadata = await loadModuleMetadata(modulesDir, baseProvider, baseProvider);
67
+ if (!moduleMetadata) {
68
+ throw new Error(`Database provider "${baseProvider}" not found`);
117
69
  }
70
+ return {
71
+ module: "database",
72
+ provider: adapterProvider,
73
+ displayName: `${moduleMetadata.displayName} (${adapterProvider.split("-")[1] || adapterProvider})`,
74
+ metadata: moduleMetadata,
75
+ };
118
76
  }
119
- if (projectInfo && !moduleMetadata.supportedFrameworks.includes(projectInfo.framework)) {
120
- throw new Error(`Module "${module}" does not support ${projectInfo.framework}. Supported: ${moduleMetadata.supportedFrameworks.join(", ")}`);
77
+ else if (module === "auth") {
78
+ const provider = options.provider;
79
+ const moduleMetadata = await loadModuleMetadata(modulesDir, provider, provider);
80
+ if (!moduleMetadata) {
81
+ throw new Error(`Auth provider "${provider}" not found`);
82
+ }
83
+ return {
84
+ module: "auth",
85
+ provider,
86
+ displayName: moduleMetadata.displayName,
87
+ metadata: moduleMetadata,
88
+ };
121
89
  }
122
- return {
123
- module,
124
- provider: selectedProvider,
125
- displayName: moduleMetadata.displayName,
126
- metadata: moduleMetadata,
127
- };
128
90
  }
91
+ // Unknown module type
92
+ throw new Error(`Unknown module type "${module}". Use "database" or "auth", or specify a provider directly.`);
93
+ }
94
+ async function getInteractiveConfig(modulesDir, projectInfo) {
129
95
  const answers = await inquirer_1.default.prompt([
130
96
  {
131
97
  type: "list",
@@ -133,7 +99,7 @@ async function getAddConfig(module, options, projectInfo) {
133
99
  message: "What would you like to add?",
134
100
  choices: [
135
101
  { name: "Database", value: "database" },
136
- { name: "Authentication", value: "auth" },
102
+ { name: "Auth", value: "auth" },
137
103
  ],
138
104
  },
139
105
  ]);
@@ -167,7 +133,7 @@ async function getAddConfig(module, options, projectInfo) {
167
133
  ]);
168
134
  return {
169
135
  module: "database",
170
- provider: "prisma",
136
+ provider: `prisma-${providerAnswers.provider}`,
171
137
  displayName: `Prisma (${providerAnswers.provider})`,
172
138
  metadata: (await loadModuleMetadata(modulesDir, "prisma", "prisma")),
173
139
  };
@@ -210,6 +176,55 @@ async function getAddConfig(module, options, projectInfo) {
210
176
  }
211
177
  throw new Error("Invalid selection");
212
178
  }
179
+ async function getProviderConfig(modulesDir, provider, projectInfo) {
180
+ if (provider.includes("-")) {
181
+ const parts = provider.split("-");
182
+ const baseProvider = parts[0];
183
+ const specificProvider = provider;
184
+ if (baseProvider === "prisma") {
185
+ const metadata = await loadModuleMetadata(modulesDir, "database", baseProvider);
186
+ if (!metadata) {
187
+ throw new Error(`Database provider "${baseProvider}" not found`);
188
+ }
189
+ return {
190
+ module: "database",
191
+ provider: specificProvider,
192
+ displayName: `Prisma (${parts[1]})`,
193
+ metadata,
194
+ };
195
+ }
196
+ }
197
+ else {
198
+ if (provider === "mongoose") {
199
+ const metadata = await loadModuleMetadata(modulesDir, "database", "mongoose");
200
+ if (!metadata) {
201
+ throw new Error(`Database provider "${provider}" not found`);
202
+ }
203
+ return {
204
+ module: "database",
205
+ provider: "mongoose",
206
+ displayName: "Mongoose",
207
+ metadata,
208
+ };
209
+ }
210
+ else if (provider === "better-auth" || provider === "authjs") {
211
+ const metadata = await loadModuleMetadata(modulesDir, provider, provider);
212
+ if (!metadata) {
213
+ throw new Error(`Auth provider "${provider}" not found`);
214
+ }
215
+ if (projectInfo && !metadata.supportedFrameworks.includes(projectInfo.framework)) {
216
+ throw new Error(`Auth provider "${provider}" does not support ${projectInfo.framework}`);
217
+ }
218
+ return {
219
+ module: "auth",
220
+ provider,
221
+ displayName: provider === "better-auth" ? "Better Auth" : "Auth.js",
222
+ metadata,
223
+ };
224
+ }
225
+ }
226
+ throw new Error(`Unknown provider "${provider}". Available providers: better-auth, authjs, mongoose, prisma-postgresql, prisma-mongodb, prisma-mysql, prisma-sqlite`);
227
+ }
213
228
  async function addModuleToProject(projectRoot, projectInfo, config, options) {
214
229
  const moduleMetadata = config.metadata;
215
230
  const selectedProvider = config.provider;
@@ -228,6 +243,21 @@ async function addModuleToProject(projectRoot, projectInfo, config, options) {
228
243
  return;
229
244
  }
230
245
  }
246
+ if (config.module === "database" && projectInfo.hasDatabase && !options?.force) {
247
+ logger_1.logger.warn("Database library already detected in this project");
248
+ const { proceed } = await inquirer_1.default.prompt([
249
+ {
250
+ type: "confirm",
251
+ name: "proceed",
252
+ message: "Continue anyway? (use --force to skip this prompt)",
253
+ default: false,
254
+ },
255
+ ]);
256
+ if (!proceed) {
257
+ logger_1.logger.info("Cancelled");
258
+ return;
259
+ }
260
+ }
231
261
  if (options?.dryRun) {
232
262
  logger_1.logger.warn("Dry run mode - no changes will be made");
233
263
  logger_1.logger.newLine();
@@ -413,10 +443,10 @@ async function loadModuleMetadata(modulesDir, moduleName, provider) {
413
443
  if (await fs_extra_1.default.pathExists(metadataPath)) {
414
444
  const metadata = await fs_extra_1.default.readJSON(metadataPath);
415
445
  if (provider && moduleDir === provider) {
416
- return await (0, generator_utils_1.mergeGeneratorIntoModuleMetadata)(metadata, modulePath);
446
+ return metadata;
417
447
  }
418
448
  if (!provider && (metadata.category === moduleName || moduleDir === moduleName)) {
419
- return await (0, generator_utils_1.mergeGeneratorIntoModuleMetadata)(metadata, modulePath);
449
+ return metadata;
420
450
  }
421
451
  }
422
452
  }
@@ -306,7 +306,8 @@ async function processGeneratorEnvVars(config, targetDir) {
306
306
  const generator = await fs_extra_1.default.readJson(dbGeneratorPath);
307
307
  if (generator.operations) {
308
308
  for (const operation of generator.operations) {
309
- if (operation.type === "add-env" && (!operation.condition || checkCondition(operation.condition, config))) {
309
+ if (operation.type === "add-env" &&
310
+ (!operation.condition || checkCondition(operation.condition, config))) {
310
311
  for (const [key, value] of Object.entries(operation.envVars)) {
311
312
  envVars.push({
312
313
  key,
@@ -326,7 +327,8 @@ async function processGeneratorEnvVars(config, targetDir) {
326
327
  const generator = await fs_extra_1.default.readJson(authGeneratorPath);
327
328
  if (generator.operations) {
328
329
  for (const operation of generator.operations) {
329
- if (operation.type === "add-env" && (!operation.condition || checkCondition(operation.condition, config))) {
330
+ if (operation.type === "add-env" &&
331
+ (!operation.condition || checkCondition(operation.condition, config))) {
330
332
  for (const [key, value] of Object.entries(operation.envVars)) {
331
333
  envVars.push({
332
334
  key,
@@ -137,7 +137,7 @@ async function runDoctorChecks() {
137
137
  summary: {
138
138
  errors: checks.filter((c) => c.status === "error").length,
139
139
  warnings: checks.filter((c) => c.status === "warning").length,
140
- suggestions: generateSuggestions(),
140
+ suggestions: generateSuggestions(authModules, databaseModules),
141
141
  },
142
142
  };
143
143
  return report;
@@ -261,6 +261,7 @@ async function checkAuthRoutesExist(projectRoot, projectType) {
261
261
  if (projectType !== "nextjs")
262
262
  return true; // Skip for non-Next.js
263
263
  const possiblePaths = [
264
+ // NextAuth routes
264
265
  "app/api/auth/[...nextauth]/route.ts",
265
266
  "app/api/auth/[...nextauth]/route.js",
266
267
  "src/app/api/auth/[...nextauth]/route.ts",
@@ -269,6 +270,11 @@ async function checkAuthRoutesExist(projectRoot, projectType) {
269
270
  "pages/api/auth/[...nextauth].js",
270
271
  "src/pages/api/auth/[...nextauth].ts",
271
272
  "src/pages/api/auth/[...nextauth].js",
273
+ // Better Auth routes
274
+ "app/api/auth/[...all]/route.ts",
275
+ "app/api/auth/[...all]/route.js",
276
+ "src/app/api/auth/[...all]/route.ts",
277
+ "src/app/api/auth/[...all]/route.js",
272
278
  ];
273
279
  for (const routePath of possiblePaths) {
274
280
  if (await fs_extra_1.default.pathExists(path_1.default.join(projectRoot, routePath))) {
@@ -372,8 +378,10 @@ async function checkDependencies(packageJson) {
372
378
  const deps = { ...packageJson.dependencies, ...packageJson.devDependencies };
373
379
  for (const [name, version] of Object.entries(deps || {})) {
374
380
  if (typeof version === "string" && (version.startsWith("^") || version.startsWith("~"))) {
381
+ // Assume up to date if using flexible versioning
375
382
  }
376
383
  else {
384
+ // Assume outdated if using exact versions (simplified check)
377
385
  outdated.push(name);
378
386
  }
379
387
  }
@@ -406,11 +414,16 @@ async function checkEslintConfigExists(projectRoot) {
406
414
  }
407
415
  return false;
408
416
  }
409
- function generateSuggestions() {
417
+ function generateSuggestions(authModules, databaseModules) {
410
418
  const suggestions = [];
419
+ // Show suggestions based on what's missing
420
+ if (authModules.length === 0) {
421
+ suggestions.push("stackkit add auth - Add authentication module");
422
+ }
423
+ if (databaseModules.length === 0) {
424
+ suggestions.push("stackkit add db - Add database module");
425
+ }
411
426
  // Always show available commands
412
- suggestions.push("stackkit add auth - Add authentication module");
413
- suggestions.push("stackkit add db - Add database module");
414
427
  suggestions.push("stackkit list - View available modules");
415
428
  return suggestions;
416
429
  }
package/dist/index.js CHANGED
@@ -7,11 +7,14 @@ const add_1 = require("./cli/add");
7
7
  const doctor_1 = require("./cli/doctor");
8
8
  const list_1 = require("./cli/list");
9
9
  const logger_1 = require("./lib/ui/logger");
10
+ const fs_1 = require("fs");
11
+ const path_1 = require("path");
12
+ const packageJson = JSON.parse((0, fs_1.readFileSync)((0, path_1.join)(__dirname, "../package.json"), "utf-8"));
10
13
  const program = new commander_1.Command();
11
14
  program
12
15
  .name("stackkit")
13
16
  .description("CLI for creating and managing StackKit projects")
14
- .version("0.1.5")
17
+ .version(packageJson.version)
15
18
  .configureHelp({
16
19
  subcommandTerm: (cmd) => {
17
20
  const name = cmd.name();
@@ -175,7 +175,7 @@ class AdvancedCodeGenerator {
175
175
  conditionMet = typeof actualVal === "string" && actualVal.endsWith(cleanExpectedVal);
176
176
  break;
177
177
  }
178
- const contentToProcess = conditionMet ? blockContent : (elseContent || "");
178
+ const contentToProcess = conditionMet ? blockContent : elseContent || "";
179
179
  return this.processTemplateRecursive(contentToProcess, context)
180
180
  .replace(/^\n+/, "")
181
181
  .replace(/\n+$/, "");
@@ -185,7 +185,7 @@ class AdvancedCodeGenerator {
185
185
  const conditionParts = condition.split("==");
186
186
  if (conditionParts.length === 2) {
187
187
  const [varName, expectedValue] = conditionParts.map((s) => s.trim().replace(/['"]/g, ""));
188
- const contentToProcess = context[varName] === expectedValue ? blockContent : (elseContent || "");
188
+ const contentToProcess = context[varName] === expectedValue ? blockContent : elseContent || "";
189
189
  return this.processTemplateRecursive(contentToProcess, context)
190
190
  .replace(/^\n+/, "")
191
191
  .replace(/\n+$/, "");
@@ -195,7 +195,7 @@ class AdvancedCodeGenerator {
195
195
  const [arrayName, item] = conditionFunc[0].split("(");
196
196
  const itemValue = item.replace(")", "").replace(/['"]/g, "");
197
197
  const array = context[arrayName] || [];
198
- const contentToProcess = Array.isArray(array) && array.includes(itemValue) ? blockContent : (elseContent || "");
198
+ const contentToProcess = Array.isArray(array) && array.includes(itemValue) ? blockContent : elseContent || "";
199
199
  return this.processTemplateRecursive(contentToProcess, context)
200
200
  .replace(/^\n+/, "")
201
201
  .replace(/\n+$/, "");
@@ -74,15 +74,20 @@ async function mergeGeneratorIntoModuleMetadata(metadata, modulePath) {
74
74
  if (await fs.pathExists(generatorPath)) {
75
75
  try {
76
76
  const generator = await fs.readJson(generatorPath);
77
- if (generator.envVars) {
78
- metadata.envVars = metadata.envVars || [];
79
- for (const [key, value] of Object.entries(generator.envVars)) {
80
- metadata.envVars.push({
81
- key,
82
- value: value,
83
- description: `Environment variable for ${key}`,
84
- required: true,
85
- });
77
+ // Process add-env operations to extract envVars
78
+ if (generator.operations && Array.isArray(generator.operations)) {
79
+ for (const operation of generator.operations) {
80
+ if (operation.type === "add-env" && operation.envVars) {
81
+ metadata.envVars = metadata.envVars || [];
82
+ for (const [key, value] of Object.entries(operation.envVars)) {
83
+ metadata.envVars.push({
84
+ key,
85
+ value: value,
86
+ description: `Environment variable for ${key}`,
87
+ required: true,
88
+ });
89
+ }
90
+ }
86
91
  }
87
92
  }
88
93
  if (generator.dependencies) {
@@ -1,6 +1,2 @@
1
- import NextAuth from "next-auth";
2
- import { authOptions } from "@/lib/auth";
3
-
4
- const handler = NextAuth(authOptions);
5
-
6
- export { handler as GET, handler as POST };
1
+ import { handlers } from "@/auth"
2
+ export const { GET, POST } = handlers
@@ -1,36 +1,22 @@
1
- import { NextAuthOptions } from "next-auth";
2
- import { PrismaAdapter } from "@auth/prisma-adapter";
3
- import { prisma } from "@/lib/prisma";
4
- import GoogleProvider from "next-auth/providers/google";
1
+ import NextAuth from "next-auth"
2
+ import { PrismaAdapter } from "@auth/prisma-adapter"
3
+ import prisma from "@/lib/prisma"
4
+ import Google from "next-auth/providers/google"
5
+ import { encode, decode } from 'next-auth/jwt';
5
6
 
6
- export const authOptions: NextAuthOptions = {
7
+ export const { handlers, signIn, signOut, auth } = NextAuth({
7
8
  adapter: PrismaAdapter(prisma),
8
9
  providers: [
9
- GoogleProvider({
10
- clientId: process.env.GOOGLE_CLIENT_ID!,
11
- clientSecret: process.env.GOOGLE_CLIENT_SECRET!,
10
+ Google({
11
+ clientId: process.env.AUTH_GOOGLE_ID,
12
+ clientSecret: process.env.AUTH_GOOGLE_SECRET,
12
13
  }),
13
14
  ],
14
- session: {
15
- strategy: "jwt",
16
- },
17
- callbacks: {
18
- async jwt({ token, user }) {
19
- if (user) {
20
- token.id = user.id;
21
- }
22
- return token;
23
- },
24
- async session({ session, token }) {
25
- if (token) {
26
- session.user.id = token.id as string;
27
- }
28
- return session;
29
- },
30
- },
15
+ session: { strategy: "jwt" },
16
+ secret: process.env.AUTH_SECRET,
17
+ jwt: { encode, decode },
31
18
  pages: {
32
- signIn: "/auth/signin",
33
- signOut: "/auth/signout",
34
- error: "/auth/error",
19
+ signIn: '/sign-in',
20
+ error: '/error',
35
21
  },
36
- };
22
+ })
@@ -1,10 +1,10 @@
1
-
1
+ {{#var defaultId = {{#if prismaProvider == "mongodb"}}@default(auto()) @map("_id") @db.ObjectId{{else}}@default(cuid()){{/if}}}}
2
2
  model Account {
3
- id String @id {{idDefault}}
4
- userId String {{userIdType}}
3
+ id String @id {{defaultId}}
4
+ userId String @map("user_id")
5
5
  type String
6
6
  provider String
7
- providerAccountId String
7
+ providerAccountId String @map("provider_account_id")
8
8
  refresh_token String? @db.Text
9
9
  access_token String? @db.Text
10
10
  expires_at Int?
@@ -16,30 +16,36 @@ model Account {
16
16
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
17
17
 
18
18
  @@unique([provider, providerAccountId])
19
+ @@map("accounts")
19
20
  }
20
21
 
21
22
  model Session {
22
- id String @id {{idDefault}}
23
- sessionToken String @unique
24
- userId String {{userIdType}}
23
+ id String @id {{defaultId}}
24
+ sessionToken String @unique @map("session_token")
25
+ userId String {{#if prismaProvider == "mongodb"}} @db.ObjectId{{/if}} @map("user_id")
25
26
  expires DateTime
26
27
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
28
+
29
+ @@map("sessions")
27
30
  }
28
31
 
29
32
  model User {
30
- id String @id {{idDefault}}
33
+ id String @id {{defaultId}}
31
34
  name String?
32
- email String @unique
33
- emailVerified DateTime?
35
+ email String? @unique
36
+ emailVerified DateTime? @map("email_verified")
34
37
  image String?
35
38
  accounts Account[]
36
39
  sessions Session[]
40
+
41
+ @@map("users")
37
42
  }
38
43
 
39
44
  model VerificationToken {
40
45
  identifier String
41
- token String @unique
46
+ token String
42
47
  expires DateTime
43
48
 
44
49
  @@unique([identifier, token])
50
+ @@map("verification_tokens")
45
51
  }
@@ -2,9 +2,53 @@
2
2
  "name": "authjs",
3
3
  "type": "auth",
4
4
  "priority": 10,
5
- "operations": [],
6
- "dependencies": {},
5
+ "operations": [
6
+ {
7
+ "type": "create-file",
8
+ "source": "lib/auth.ts",
9
+ "destination": "lib/auth.ts"
10
+ },
11
+ {
12
+ "type": "create-file",
13
+ "source": "api/auth/[...nextauth]/route.ts",
14
+ "destination": "app/api/auth/[...nextauth]/route.ts"
15
+ },
16
+ {
17
+ "type": "create-file",
18
+ "destination": "proxy.ts",
19
+ "content": "export { auth as middleware } from \"@/auth\""
20
+ },
21
+ {
22
+ "type": "patch-file",
23
+ "destination": "prisma/schema.prisma",
24
+ "condition": { "database": "prisma" },
25
+ "operations": [
26
+ {
27
+ "type": "add-to-bottom",
28
+ "source": "prisma/schema.prisma"
29
+ }
30
+ ]
31
+ },
32
+ {
33
+ "type": "add-dependency",
34
+ "condition": { "database": "prisma" },
35
+ "dependencies": {
36
+ "@auth/prisma-adapter": "^0.5.0"
37
+ },
38
+ "devDependencies": {}
39
+ },
40
+ {
41
+ "type": "add-env",
42
+ "envVars": {
43
+ "AUTH_SECRET": "",
44
+ "AUTH_GOOGLE_ID": "",
45
+ "AUTH_GOOGLE_SECRET": ""
46
+ }
47
+ }
48
+ ],
49
+ "dependencies": {
50
+ "next-auth": "^5.0.0-beta.30"
51
+ },
7
52
  "devDependencies": {},
8
- "scripts": {},
9
- "envVars": {}
53
+ "scripts": {}
10
54
  }
@@ -1,4 +1,4 @@
1
- {{#var defaultId = {{#if prismaProvider == mongodb}}@default(auto()) @map("_id") @db.ObjectId{{else}}@default(cuid()){{/if}}}}
1
+ {{#var defaultId = {{#if prismaProvider == "mongodb"}}@default(auto()) @map("_id") @db.ObjectId{{else}}@default(cuid()){{/if}}}}
2
2
  model User {
3
3
  id String @id {{defaultId}}
4
4
  name String
@@ -23,7 +23,7 @@ model Session {
23
23
  updatedAt DateTime @updatedAt
24
24
  ipAddress String?
25
25
  userAgent String?
26
- userId String {{#if prismaProvider == mongodb}} @db.ObjectId{{/if}}
26
+ userId String {{#if prismaProvider == "mongodb"}} @db.ObjectId{{/if}}
27
27
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
28
28
 
29
29
  @@index([userId])
@@ -34,7 +34,7 @@ model Account {
34
34
  id String @id {{defaultId}}
35
35
  accountId String
36
36
  providerId String
37
- userId String {{#if prismaProvider == mongodb}} @db.ObjectId{{/if}}
37
+ userId String {{#if prismaProvider == "mongodb"}} @db.ObjectId{{/if}}
38
38
  user User @relation(fields: [userId], references: [id], onDelete: Cascade)
39
39
  accessToken String?
40
40
  refreshToken String?
@@ -6,7 +6,7 @@ const globalForPrisma = globalThis as unknown as {
6
6
  }
7
7
 
8
8
  {{#switch prismaProvider}}
9
- {{#case postgresql}}
9
+ {{#case "postgresql"}}
10
10
  import { PrismaPg } from '@prisma/adapter-pg'
11
11
 
12
12
  const connectionString = `${process.env.DATABASE_URL}`
@@ -16,13 +16,13 @@ const prisma = new PrismaClient({ adapter })
16
16
 
17
17
  export { prisma }
18
18
  {{/case}}
19
- {{#case mongodb}}
19
+ {{#case "mongodb"}}
20
20
 
21
21
  const prisma = new PrismaClient()
22
22
 
23
23
  export { prisma }
24
24
  {{/case}}
25
- {{#case mysql}}
25
+ {{#case "mysql"}}
26
26
  import { PrismaMariaDb } from '@prisma/adapter-mariadb';
27
27
 
28
28
  const adapter = new PrismaMariaDb({
@@ -36,7 +36,7 @@ const prisma = new PrismaClient({ adapter });
36
36
 
37
37
  export { prisma }
38
38
  {{/case}}
39
- {{#case sqlite}}
39
+ {{#case "sqlite"}}
40
40
  import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
41
41
 
42
42
  const connectionString = `${process.env.DATABASE_URL}`;
@@ -1,6 +1,6 @@
1
1
  import "dotenv/config";
2
2
  {{#switch prismaProvider}}
3
- {{#case mongodb}}
3
+ {{#case "mongodb"}}
4
4
  import { defineConfig, env } from "prisma/config";
5
5
  {{/case}}
6
6
  {{#case default}}
@@ -14,7 +14,7 @@ export default defineConfig({
14
14
  path: "prisma/migrations",
15
15
  },
16
16
  {{#switch prismaProvider}}
17
- {{#case mongodb}}
17
+ {{#case "mongodb"}}
18
18
  engine: "classic",
19
19
  datasource: {
20
20
  url: env('DATABASE_URL'),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stackkit",
3
- "version": "0.1.5",
3
+ "version": "0.1.7",
4
4
  "description": "Production-ready CLI to create and extend JavaScript or TypeScript apps with modular stacks.",
5
5
  "main": "dist/index.js",
6
6
  "bin": {
@@ -28,6 +28,8 @@
28
28
  "copy-assets": "cp -r ../../templates . && cp -r ../../modules .",
29
29
  "clean": "rm -rf dist templates modules",
30
30
  "typecheck": "tsc --noEmit",
31
+ "lint": "eslint src --ext .ts",
32
+ "lint:fix": "eslint src --ext .ts --fix",
31
33
  "prepublishOnly": "npm run build"
32
34
  },
33
35
  "keywords": [
@@ -1,11 +0,0 @@
1
- import { getServerSession } from "next-auth/next";
2
- import { authOptions } from "@/lib/auth";
3
-
4
- export async function getSession() {
5
- return await getServerSession(authOptions);
6
- }
7
-
8
- export async function getCurrentUser() {
9
- const session = await getSession();
10
- return session?.user;
11
- }