stackkit-cli 0.3.0 → 0.4.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/README.md +25 -17
- package/dist/commands/add.d.ts +0 -1
- package/dist/commands/add.js +12 -5
- package/dist/commands/init.d.ts +0 -1
- package/dist/commands/init.js +0 -1
- package/dist/commands/list.d.ts +0 -1
- package/dist/commands/list.js +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +1 -2
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +0 -1
- package/dist/utils/code-inject.d.ts +0 -1
- package/dist/utils/code-inject.js +1 -2
- package/dist/utils/detect.d.ts +0 -1
- package/dist/utils/detect.js +45 -17
- package/dist/utils/env-editor.d.ts +0 -1
- package/dist/utils/env-editor.js +2 -3
- package/dist/utils/files.d.ts +0 -1
- package/dist/utils/files.js +1 -2
- package/dist/utils/json-editor.d.ts +0 -1
- package/dist/utils/json-editor.js +0 -1
- package/dist/utils/logger.d.ts +0 -1
- package/dist/utils/logger.js +3 -2
- package/dist/utils/package-manager.d.ts +0 -1
- package/dist/utils/package-manager.js +0 -1
- package/modules/auth/authjs-express/files/lib/auth.ts +40 -0
- package/modules/auth/authjs-express/files/routes/auth.ts +12 -0
- package/modules/auth/authjs-express/module.json +39 -0
- package/modules/auth/authjs-nextjs/files/lib/auth.ts +43 -0
- package/modules/auth/authjs-nextjs/module.json +38 -0
- package/modules/auth/better-auth-express/files/lib/auth.ts +16 -0
- package/modules/auth/better-auth-express/files/routes/auth.ts +12 -0
- package/modules/auth/better-auth-express/module.json +38 -0
- package/{templates/auth/better-auth-nextjs/app → modules/auth/better-auth-nextjs/files}/api/auth/[...all]/route.ts +1 -0
- package/modules/auth/better-auth-nextjs/files/lib/auth.ts +26 -0
- package/modules/auth/better-auth-nextjs/module.json +41 -0
- package/modules/auth/better-auth-react/files/lib/auth-client.ts +9 -0
- package/modules/auth/better-auth-react/module.json +26 -0
- package/modules/auth/clerk-express/files/lib/auth.ts +7 -0
- package/modules/auth/clerk-express/module.json +19 -0
- package/modules/auth/clerk-nextjs/files/lib/auth-provider.tsx +5 -0
- package/modules/auth/clerk-nextjs/files/middleware.ts +9 -0
- package/modules/auth/clerk-nextjs/module.json +27 -0
- package/modules/auth/clerk-react/files/lib/auth-provider.tsx +15 -0
- package/modules/auth/clerk-react/module.json +18 -0
- package/modules/database/drizzle-postgresql/files/drizzle.config.ts +10 -0
- package/modules/database/drizzle-postgresql/files/lib/db.ts +7 -0
- package/modules/database/drizzle-postgresql/files/lib/schema.ts +8 -0
- package/modules/database/drizzle-postgresql/module.json +34 -0
- package/modules/database/mongoose-mongodb/files/lib/db.ts +40 -0
- package/modules/database/mongoose-mongodb/module.json +17 -0
- package/{templates/databases/prisma-mongodb → modules/database/prisma-mongodb/files}/lib/db.ts +2 -6
- package/{templates/databases/prisma-mongodb → modules/database/prisma-mongodb/files}/prisma/schema.prisma +1 -0
- package/modules/database/prisma-mongodb/module.json +36 -0
- package/{templates/databases/prisma-postgresql → modules/database/prisma-postgresql/files}/lib/db.ts +2 -6
- package/{templates/databases/prisma-postgresql → modules/database/prisma-postgresql/files}/prisma/schema.prisma +1 -0
- package/modules/database/prisma-postgresql/module.json +36 -0
- package/package.json +4 -3
- package/templates/bases/nextjs-base/README.md +36 -0
- package/templates/bases/nextjs-base/app/favicon.ico +0 -0
- package/templates/bases/nextjs-base/app/globals.css +26 -3
- package/templates/bases/nextjs-base/app/layout.tsx +21 -6
- package/templates/bases/nextjs-base/app/page.tsx +61 -4
- package/templates/bases/nextjs-base/eslint.config.mjs +18 -0
- package/templates/bases/nextjs-base/next.config.ts +4 -2
- package/templates/bases/nextjs-base/package-lock.json +6538 -0
- package/templates/bases/nextjs-base/package.json +12 -10
- package/templates/bases/nextjs-base/postcss.config.mjs +7 -0
- package/templates/bases/nextjs-base/public/file.svg +1 -0
- package/templates/bases/nextjs-base/public/globe.svg +1 -0
- package/templates/bases/nextjs-base/public/next.svg +1 -0
- package/templates/bases/nextjs-base/public/vercel.svg +1 -0
- package/templates/bases/nextjs-base/public/window.svg +1 -0
- package/templates/bases/nextjs-base/template.json +12 -1
- package/templates/bases/nextjs-base/tsconfig.json +9 -2
- package/templates/bases/react-vite-base/index.html +13 -0
- package/templates/bases/react-vite-base/package.json +27 -0
- package/templates/bases/react-vite-base/src/App.css +14 -0
- package/templates/bases/react-vite-base/src/App.tsx +23 -0
- package/templates/bases/react-vite-base/src/index.css +68 -0
- package/templates/bases/react-vite-base/src/main.tsx +10 -0
- package/templates/bases/react-vite-base/src/vite-env.d.ts +1 -0
- package/templates/bases/react-vite-base/template.json +5 -0
- package/templates/bases/react-vite-base/tsconfig.json +21 -0
- package/templates/bases/react-vite-base/vite.config.ts +7 -0
- package/dist/commands/add.d.ts.map +0 -1
- package/dist/commands/add.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list.d.ts.map +0 -1
- package/dist/commands/list.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/types/index.d.ts.map +0 -1
- package/dist/types/index.js.map +0 -1
- package/dist/utils/code-inject.d.ts.map +0 -1
- package/dist/utils/code-inject.js.map +0 -1
- package/dist/utils/detect.d.ts.map +0 -1
- package/dist/utils/detect.js.map +0 -1
- package/dist/utils/env-editor.d.ts.map +0 -1
- package/dist/utils/env-editor.js.map +0 -1
- package/dist/utils/files.d.ts.map +0 -1
- package/dist/utils/files.js.map +0 -1
- package/dist/utils/json-editor.d.ts.map +0 -1
- package/dist/utils/json-editor.js.map +0 -1
- package/dist/utils/logger.d.ts.map +0 -1
- package/dist/utils/logger.js.map +0 -1
- package/dist/utils/package-manager.d.ts.map +0 -1
- package/dist/utils/package-manager.js.map +0 -1
- package/templates/auth/better-auth-express/config.json +0 -18
- package/templates/auth/better-auth-express/src/lib/auth.ts +0 -12
- package/templates/auth/better-auth-express/src/routes/auth.ts +0 -10
- package/templates/auth/better-auth-nextjs/config.json +0 -18
- package/templates/auth/better-auth-nextjs/lib/auth.ts +0 -14
- package/templates/auth/nextauth/config.json +0 -18
- package/templates/auth/nextauth/lib/auth.ts +0 -31
- package/templates/bases/nextjs-base/.eslintrc.json +0 -3
- package/templates/databases/prisma-mongodb/config.json +0 -21
- package/templates/databases/prisma-postgresql/config.json +0 -22
- package/templates/next-prisma-postgres-shadcn/.env.example +0 -5
- package/templates/next-prisma-postgres-shadcn/.eslintrc.json +0 -7
- package/templates/next-prisma-postgres-shadcn/.prettierrc +0 -8
- package/templates/next-prisma-postgres-shadcn/README.md +0 -85
- package/templates/next-prisma-postgres-shadcn/app/api/health/route.ts +0 -25
- package/templates/next-prisma-postgres-shadcn/app/globals.css +0 -1
- package/templates/next-prisma-postgres-shadcn/app/layout.tsx +0 -22
- package/templates/next-prisma-postgres-shadcn/app/page.tsx +0 -29
- package/templates/next-prisma-postgres-shadcn/lib/db.ts +0 -14
- package/templates/next-prisma-postgres-shadcn/lib/env.ts +0 -15
- package/templates/next-prisma-postgres-shadcn/next.config.ts +0 -7
- package/templates/next-prisma-postgres-shadcn/package.json +0 -32
- package/templates/next-prisma-postgres-shadcn/prisma/schema.prisma +0 -20
- package/templates/next-prisma-postgres-shadcn/public/.gitkeep +0 -1
- package/templates/next-prisma-postgres-shadcn/template.json +0 -18
- package/templates/next-prisma-postgres-shadcn/tsconfig.json +0 -32
- /package/{templates/auth/nextauth/app → modules/auth/authjs-nextjs/files}/api/auth/[...nextauth]/route.ts +0 -0
package/README.md
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
# stackkit-cli
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Add modules to existing projects.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
## Installation
|
|
5
|
+
## Usage
|
|
8
6
|
|
|
9
7
|
```bash
|
|
10
|
-
#
|
|
11
|
-
|
|
8
|
+
# Add authentication
|
|
9
|
+
npx stackkit-cli add auth
|
|
12
10
|
|
|
13
|
-
#
|
|
14
|
-
npx stackkit-cli
|
|
11
|
+
# Add database
|
|
12
|
+
npx stackkit-cli add database --provider prisma-postgresql
|
|
13
|
+
|
|
14
|
+
# List available modules
|
|
15
|
+
npx stackkit-cli list
|
|
15
16
|
```
|
|
16
17
|
|
|
17
|
-
##
|
|
18
|
+
## Commands
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
20
|
+
- `add <module>` - Add module to your project
|
|
21
|
+
- `list` - List available modules
|
|
22
|
+
- `init` - Create new project (same as create-stackkit-app)
|
|
22
23
|
|
|
23
|
-
|
|
24
|
-
npx stackkit-cli list
|
|
24
|
+
## Development
|
|
25
25
|
|
|
26
|
-
|
|
27
|
-
|
|
26
|
+
```bash
|
|
27
|
+
pnpm install
|
|
28
|
+
pnpm build
|
|
29
|
+
npx . add auth
|
|
28
30
|
```
|
|
29
31
|
|
|
30
|
-
|
|
32
|
+
See [main README](../../README.md) for full documentation.
|
|
31
33
|
|
|
32
34
|
### `init [project-name]`
|
|
33
35
|
|
|
34
36
|
Create a new project from a template.
|
|
35
37
|
|
|
36
38
|
**Options:**
|
|
39
|
+
|
|
37
40
|
- `--template <name>` - Template to use
|
|
38
41
|
- `--pm <npm|yarn|pnpm>` - Package manager (default: auto-detect)
|
|
39
42
|
- `--no-install` - Skip dependency installation
|
|
@@ -41,6 +44,7 @@ Create a new project from a template.
|
|
|
41
44
|
- `--yes` - Skip all prompts
|
|
42
45
|
|
|
43
46
|
**Examples:**
|
|
47
|
+
|
|
44
48
|
```bash
|
|
45
49
|
npx stackkit-cli init my-app
|
|
46
50
|
npx stackkit-cli init my-app --template next-prisma-postgres-shadcn --pm pnpm
|
|
@@ -52,10 +56,12 @@ npx stackkit-cli init my-app --no-install --no-git --yes
|
|
|
52
56
|
List available templates and modules.
|
|
53
57
|
|
|
54
58
|
**Options:**
|
|
59
|
+
|
|
55
60
|
- `--templates` - Show templates only
|
|
56
61
|
- `--modules` - Show modules only
|
|
57
62
|
|
|
58
63
|
**Examples:**
|
|
64
|
+
|
|
59
65
|
```bash
|
|
60
66
|
npx stackkit-cli list
|
|
61
67
|
npx stackkit-cli list --templates
|
|
@@ -67,11 +73,13 @@ npx stackkit-cli list --modules
|
|
|
67
73
|
Add a module to your existing project.
|
|
68
74
|
|
|
69
75
|
**Options:**
|
|
76
|
+
|
|
70
77
|
- `--dry-run` - Preview changes without applying
|
|
71
78
|
- `--force` - Overwrite existing files
|
|
72
79
|
- `--no-install` - Skip dependency installation
|
|
73
80
|
|
|
74
81
|
**Examples:**
|
|
82
|
+
|
|
75
83
|
```bash
|
|
76
84
|
npx stackkit-cli add auth
|
|
77
85
|
npx stackkit-cli add auth --dry-run
|
package/dist/commands/add.d.ts
CHANGED
package/dist/commands/add.js
CHANGED
|
@@ -123,8 +123,12 @@ async function loadModuleMetadata(modulesDir, moduleName, provider) {
|
|
|
123
123
|
const metadataPath = path_1.default.join(modulePath, 'module.json');
|
|
124
124
|
if (await fs_extra_1.default.pathExists(metadataPath)) {
|
|
125
125
|
const metadata = await fs_extra_1.default.readJSON(metadataPath);
|
|
126
|
-
//
|
|
127
|
-
if (
|
|
126
|
+
// If provider is specified, match by directory name (exact match)
|
|
127
|
+
if (provider && moduleDir === provider) {
|
|
128
|
+
return metadata;
|
|
129
|
+
}
|
|
130
|
+
// Otherwise, match by module name (category)
|
|
131
|
+
if (!provider && metadata.name === moduleName) {
|
|
128
132
|
return metadata;
|
|
129
133
|
}
|
|
130
134
|
}
|
|
@@ -189,8 +193,12 @@ async function findModulePath(modulesDir, moduleName, provider) {
|
|
|
189
193
|
const metadataPath = path_1.default.join(modulePath, 'module.json');
|
|
190
194
|
if (await fs_extra_1.default.pathExists(metadataPath)) {
|
|
191
195
|
const metadata = await fs_extra_1.default.readJSON(metadataPath);
|
|
192
|
-
//
|
|
193
|
-
if (
|
|
196
|
+
// If provider is specified, match by directory name (exact match)
|
|
197
|
+
if (provider && moduleDir === provider) {
|
|
198
|
+
return modulePath;
|
|
199
|
+
}
|
|
200
|
+
// Otherwise, match by module name (category)
|
|
201
|
+
if (!provider && metadata.name === moduleName) {
|
|
194
202
|
return modulePath;
|
|
195
203
|
}
|
|
196
204
|
}
|
|
@@ -198,4 +206,3 @@ async function findModulePath(modulesDir, moduleName, provider) {
|
|
|
198
206
|
}
|
|
199
207
|
return null;
|
|
200
208
|
}
|
|
201
|
-
//# sourceMappingURL=add.js.map
|
package/dist/commands/init.d.ts
CHANGED
package/dist/commands/init.js
CHANGED
package/dist/commands/list.d.ts
CHANGED
package/dist/commands/list.js
CHANGED
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ const program = new commander_1.Command();
|
|
|
13
13
|
program
|
|
14
14
|
.name('stackkit')
|
|
15
15
|
.description('Production-ready project generator and module CLI')
|
|
16
|
-
.version('0.
|
|
16
|
+
.version('0.3.2');
|
|
17
17
|
// Init command
|
|
18
18
|
program
|
|
19
19
|
.command('init [project-name]')
|
|
@@ -47,4 +47,3 @@ program.on('command:*', () => {
|
|
|
47
47
|
process.exit(1);
|
|
48
48
|
});
|
|
49
49
|
program.parse();
|
|
50
|
-
//# sourceMappingURL=index.js.map
|
package/dist/types/index.d.ts
CHANGED
|
@@ -47,12 +47,13 @@ export interface ModifyJsonPatch extends ModulePatch {
|
|
|
47
47
|
}[];
|
|
48
48
|
}
|
|
49
49
|
export interface ProjectInfo {
|
|
50
|
-
framework: 'nextjs' | 'unknown';
|
|
50
|
+
framework: 'nextjs' | 'express' | 'react' | 'react-vite' | 'unknown';
|
|
51
51
|
router: 'app' | 'pages' | 'unknown';
|
|
52
52
|
language: 'ts' | 'js';
|
|
53
53
|
packageManager: 'npm' | 'yarn' | 'pnpm';
|
|
54
54
|
hasAuth: boolean;
|
|
55
55
|
hasPrisma: boolean;
|
|
56
|
+
hasDatabase: boolean;
|
|
56
57
|
rootDir: string;
|
|
57
58
|
}
|
|
58
59
|
export interface CLIOptions {
|
|
@@ -62,4 +63,3 @@ export interface CLIOptions {
|
|
|
62
63
|
noInstall?: boolean;
|
|
63
64
|
pm?: 'npm' | 'yarn' | 'pnpm';
|
|
64
65
|
}
|
|
65
|
-
//# sourceMappingURL=index.d.ts.map
|
package/dist/types/index.js
CHANGED
|
@@ -12,4 +12,3 @@ export declare function injectCode(filePath: string, injection: CodeInjection, p
|
|
|
12
12
|
}): Promise<void>;
|
|
13
13
|
export declare function removeInjection(content: string, id: string): string;
|
|
14
14
|
export declare function hasInjection(content: string, id: string): boolean;
|
|
15
|
-
//# sourceMappingURL=code-inject.d.ts.map
|
|
@@ -10,7 +10,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
10
10
|
const CODE_MARKER_START = (id) => `// StackKit:${id}:start`;
|
|
11
11
|
const CODE_MARKER_END = (id) => `// StackKit:${id}:end`;
|
|
12
12
|
async function injectCode(filePath, injection, position, options = {}) {
|
|
13
|
-
if (!await fs_extra_1.default.pathExists(filePath)) {
|
|
13
|
+
if (!(await fs_extra_1.default.pathExists(filePath))) {
|
|
14
14
|
throw new Error(`File not found: ${filePath}`);
|
|
15
15
|
}
|
|
16
16
|
let content = await fs_extra_1.default.readFile(filePath, 'utf-8');
|
|
@@ -68,4 +68,3 @@ function removeInjection(content, id) {
|
|
|
68
68
|
function hasInjection(content, id) {
|
|
69
69
|
return content.includes(CODE_MARKER_START(id));
|
|
70
70
|
}
|
|
71
|
-
//# sourceMappingURL=code-inject.js.map
|
package/dist/utils/detect.d.ts
CHANGED
|
@@ -2,4 +2,3 @@ import { ProjectInfo } from '../types';
|
|
|
2
2
|
export declare function detectProjectInfo(targetDir: string): Promise<ProjectInfo>;
|
|
3
3
|
export declare function getRouterBasePath(projectInfo: ProjectInfo): string;
|
|
4
4
|
export declare function getLibPath(projectInfo: ProjectInfo): string;
|
|
5
|
-
//# sourceMappingURL=detect.d.ts.map
|
package/dist/utils/detect.js
CHANGED
|
@@ -10,27 +10,47 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
10
10
|
const path_1 = __importDefault(require("path"));
|
|
11
11
|
async function detectProjectInfo(targetDir) {
|
|
12
12
|
const packageJsonPath = path_1.default.join(targetDir, 'package.json');
|
|
13
|
-
if (!await fs_extra_1.default.pathExists(packageJsonPath)) {
|
|
13
|
+
if (!(await fs_extra_1.default.pathExists(packageJsonPath))) {
|
|
14
14
|
throw new Error('No package.json found. This does not appear to be a Node.js project.');
|
|
15
15
|
}
|
|
16
16
|
const packageJson = await fs_extra_1.default.readJSON(packageJsonPath);
|
|
17
17
|
// Detect framework
|
|
18
18
|
const isNextJs = packageJson.dependencies?.next || packageJson.devDependencies?.next;
|
|
19
|
-
const
|
|
19
|
+
const isExpress = packageJson.dependencies?.express || packageJson.devDependencies?.express;
|
|
20
|
+
const isReact = packageJson.dependencies?.react || packageJson.devDependencies?.react;
|
|
21
|
+
const isVite = packageJson.dependencies?.vite || packageJson.devDependencies?.vite;
|
|
22
|
+
let framework;
|
|
23
|
+
if (isNextJs) {
|
|
24
|
+
framework = 'nextjs';
|
|
25
|
+
}
|
|
26
|
+
else if (isExpress) {
|
|
27
|
+
framework = 'express';
|
|
28
|
+
}
|
|
29
|
+
else if (isReact && isVite) {
|
|
30
|
+
framework = 'react-vite';
|
|
31
|
+
}
|
|
32
|
+
else if (isReact) {
|
|
33
|
+
framework = 'react';
|
|
34
|
+
}
|
|
35
|
+
else {
|
|
36
|
+
framework = 'unknown';
|
|
37
|
+
}
|
|
20
38
|
if (framework === 'unknown') {
|
|
21
|
-
throw new Error('Only Next.js projects are currently supported.');
|
|
39
|
+
throw new Error('Only Next.js, Express, and React projects are currently supported.');
|
|
22
40
|
}
|
|
23
|
-
// Detect router type
|
|
24
|
-
const appDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'app'));
|
|
25
|
-
const pagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pages'));
|
|
26
|
-
const srcAppDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'app'));
|
|
27
|
-
const srcPagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'pages'));
|
|
41
|
+
// Detect router type (only for Next.js)
|
|
28
42
|
let router = 'unknown';
|
|
29
|
-
if (
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
43
|
+
if (framework === 'nextjs') {
|
|
44
|
+
const appDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'app'));
|
|
45
|
+
const pagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'pages'));
|
|
46
|
+
const srcAppDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'app'));
|
|
47
|
+
const srcPagesDirExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'src', 'pages'));
|
|
48
|
+
if (appDirExists || srcAppDirExists) {
|
|
49
|
+
router = 'app';
|
|
50
|
+
}
|
|
51
|
+
else if (pagesDirExists || srcPagesDirExists) {
|
|
52
|
+
router = 'pages';
|
|
53
|
+
}
|
|
34
54
|
}
|
|
35
55
|
// Detect TypeScript vs JavaScript
|
|
36
56
|
const tsconfigExists = await fs_extra_1.default.pathExists(path_1.default.join(targetDir, 'tsconfig.json'));
|
|
@@ -47,11 +67,16 @@ async function detectProjectInfo(targetDir) {
|
|
|
47
67
|
}
|
|
48
68
|
// Check for existing integrations
|
|
49
69
|
const hasAuth = !!(packageJson.dependencies?.['next-auth'] ||
|
|
70
|
+
packageJson.dependencies?.['better-auth'] ||
|
|
50
71
|
packageJson.dependencies?.['@auth/core'] ||
|
|
51
72
|
packageJson.dependencies?.['@clerk/nextjs'] ||
|
|
52
|
-
packageJson.dependencies?.['@kinde-oss/kinde-auth-nextjs']
|
|
53
|
-
|
|
54
|
-
|
|
73
|
+
packageJson.dependencies?.['@kinde-oss/kinde-auth-nextjs'] ||
|
|
74
|
+
packageJson.dependencies?.['passport']);
|
|
75
|
+
const hasPrisma = !!(packageJson.dependencies?.['@prisma/client'] || packageJson.devDependencies?.['prisma']);
|
|
76
|
+
const hasDatabase = hasPrisma ||
|
|
77
|
+
!!(packageJson.dependencies?.['mongoose'] ||
|
|
78
|
+
packageJson.dependencies?.['typeorm'] ||
|
|
79
|
+
packageJson.dependencies?.['drizzle-orm']);
|
|
55
80
|
return {
|
|
56
81
|
framework,
|
|
57
82
|
router,
|
|
@@ -59,6 +84,7 @@ async function detectProjectInfo(targetDir) {
|
|
|
59
84
|
packageManager,
|
|
60
85
|
hasAuth,
|
|
61
86
|
hasPrisma,
|
|
87
|
+
hasDatabase,
|
|
62
88
|
rootDir: targetDir,
|
|
63
89
|
};
|
|
64
90
|
}
|
|
@@ -73,7 +99,9 @@ function getRouterBasePath(projectInfo) {
|
|
|
73
99
|
throw new Error('Unknown router type');
|
|
74
100
|
}
|
|
75
101
|
function getLibPath(projectInfo) {
|
|
102
|
+
if (projectInfo.framework === 'express') {
|
|
103
|
+
return 'src/lib';
|
|
104
|
+
}
|
|
76
105
|
const srcExists = fs_extra_1.default.existsSync(path_1.default.join(projectInfo.rootDir, 'src'));
|
|
77
106
|
return srcExists ? 'src/lib' : 'lib';
|
|
78
107
|
}
|
|
79
|
-
//# sourceMappingURL=detect.js.map
|
package/dist/utils/env-editor.js
CHANGED
|
@@ -59,7 +59,7 @@ async function appendToEnvFile(filePath, variables, fileType, options = {}) {
|
|
|
59
59
|
if (variable.description) {
|
|
60
60
|
content += `# ${variable.description}\n`;
|
|
61
61
|
}
|
|
62
|
-
const value = fileType === 'example' ?
|
|
62
|
+
const value = fileType === 'example' ? variable.value || '' : variable.value || '';
|
|
63
63
|
content += `${variable.key}=${value}\n`;
|
|
64
64
|
}
|
|
65
65
|
content += `${ENV_MARKER_END}\n`;
|
|
@@ -74,7 +74,7 @@ async function removeEnvVariables(projectRoot, keys) {
|
|
|
74
74
|
}
|
|
75
75
|
}
|
|
76
76
|
async function removeFromEnvFile(filePath, keys) {
|
|
77
|
-
if (!await fs_extra_1.default.pathExists(filePath)) {
|
|
77
|
+
if (!(await fs_extra_1.default.pathExists(filePath))) {
|
|
78
78
|
return;
|
|
79
79
|
}
|
|
80
80
|
let content = await fs_extra_1.default.readFile(filePath, 'utf-8');
|
|
@@ -89,4 +89,3 @@ async function removeFromEnvFile(filePath, keys) {
|
|
|
89
89
|
}
|
|
90
90
|
await fs_extra_1.default.writeFile(filePath, newLines.join('\n'), 'utf-8');
|
|
91
91
|
}
|
|
92
|
-
//# sourceMappingURL=env-editor.js.map
|
package/dist/utils/files.d.ts
CHANGED
|
@@ -4,4 +4,3 @@ export declare function createFile(targetPath: string, content: string, options?
|
|
|
4
4
|
}): Promise<void>;
|
|
5
5
|
export declare function readFile(filePath: string): Promise<string>;
|
|
6
6
|
export declare function fileExists(filePath: string): Promise<boolean>;
|
|
7
|
-
//# sourceMappingURL=files.d.ts.map
|
package/dist/utils/files.js
CHANGED
|
@@ -11,7 +11,7 @@ const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const logger_1 = require("./logger");
|
|
13
13
|
async function copyTemplate(templatePath, targetPath, projectName) {
|
|
14
|
-
if (!await fs_extra_1.default.pathExists(templatePath)) {
|
|
14
|
+
if (!(await fs_extra_1.default.pathExists(templatePath))) {
|
|
15
15
|
throw new Error(`Template not found: ${templatePath}`);
|
|
16
16
|
}
|
|
17
17
|
// Create target directory
|
|
@@ -48,4 +48,3 @@ async function readFile(filePath) {
|
|
|
48
48
|
async function fileExists(filePath) {
|
|
49
49
|
return fs_extra_1.default.pathExists(filePath);
|
|
50
50
|
}
|
|
51
|
-
//# sourceMappingURL=files.js.map
|
package/dist/utils/logger.d.ts
CHANGED
package/dist/utils/logger.js
CHANGED
|
@@ -7,7 +7,9 @@ exports.logger = exports.Logger = void 0;
|
|
|
7
7
|
const chalk_1 = __importDefault(require("chalk"));
|
|
8
8
|
const ora_1 = __importDefault(require("ora"));
|
|
9
9
|
class Logger {
|
|
10
|
-
|
|
10
|
+
constructor() {
|
|
11
|
+
this.spinner = null;
|
|
12
|
+
}
|
|
11
13
|
info(message) {
|
|
12
14
|
console.log(chalk_1.default.blue('ℹ'), message);
|
|
13
15
|
}
|
|
@@ -55,4 +57,3 @@ class Logger {
|
|
|
55
57
|
}
|
|
56
58
|
exports.Logger = Logger;
|
|
57
59
|
exports.logger = new Logger();
|
|
58
|
-
//# sourceMappingURL=logger.js.map
|
|
@@ -3,4 +3,3 @@ export declare function detectPackageManager(cwd: string): Promise<PackageManage
|
|
|
3
3
|
export declare function installDependencies(cwd: string, pm: PackageManager, dev?: boolean): Promise<void>;
|
|
4
4
|
export declare function addDependencies(cwd: string, pm: PackageManager, packages: string[], dev?: boolean): Promise<void>;
|
|
5
5
|
export declare function initGit(cwd: string): Promise<void>;
|
|
6
|
-
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import Credentials from '@auth/core/providers/credentials';
|
|
2
|
+
|
|
3
|
+
export const authConfig = {
|
|
4
|
+
secret: process.env.AUTH_SECRET,
|
|
5
|
+
trustHost: true,
|
|
6
|
+
providers: [
|
|
7
|
+
// GitHub OAuth Provider
|
|
8
|
+
// Uncomment and add GITHUB_ID and GITHUB_SECRET to .env
|
|
9
|
+
// GitHub({
|
|
10
|
+
// clientId: process.env.GITHUB_ID!,
|
|
11
|
+
// clientSecret: process.env.GITHUB_SECRET!,
|
|
12
|
+
// }),
|
|
13
|
+
|
|
14
|
+
// Google OAuth Provider
|
|
15
|
+
// Uncomment and add GOOGLE_ID and GOOGLE_SECRET to .env
|
|
16
|
+
// Google({
|
|
17
|
+
// clientId: process.env.GOOGLE_ID!,
|
|
18
|
+
// clientSecret: process.env.GOOGLE_SECRET!,
|
|
19
|
+
// }),
|
|
20
|
+
|
|
21
|
+
// Credentials Provider (email/password)
|
|
22
|
+
Credentials({
|
|
23
|
+
credentials: {
|
|
24
|
+
email: { label: 'Email', type: 'email' },
|
|
25
|
+
password: { label: 'Password', type: 'password' },
|
|
26
|
+
},
|
|
27
|
+
authorize: async (credentials) => {
|
|
28
|
+
// Add your own authentication logic here
|
|
29
|
+
if (credentials?.email === 'demo@example.com' && credentials?.password === 'demo') {
|
|
30
|
+
return {
|
|
31
|
+
id: '1',
|
|
32
|
+
name: 'Demo User',
|
|
33
|
+
email: 'demo@example.com',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Auth } from '@auth/core';
|
|
2
|
+
import { Router } from 'express';
|
|
3
|
+
import { authConfig } from '../lib/auth';
|
|
4
|
+
|
|
5
|
+
const router = Router();
|
|
6
|
+
|
|
7
|
+
router.all('/auth/*', async (req, res) => {
|
|
8
|
+
const response = await Auth(req, authConfig);
|
|
9
|
+
return res.status(response.status).json(response.body);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default router;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "auth",
|
|
3
|
+
"displayName": "Auth.js (Express)",
|
|
4
|
+
"description": "Authentication with Auth.js for Express",
|
|
5
|
+
"category": "auth",
|
|
6
|
+
"supportedFrameworks": ["express"],
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"@auth/express": "^0.7.6",
|
|
9
|
+
"@auth/core": "^0.37.4"
|
|
10
|
+
},
|
|
11
|
+
"envVars": [
|
|
12
|
+
{
|
|
13
|
+
"key": "AUTH_SECRET",
|
|
14
|
+
"value": "",
|
|
15
|
+
"description": "Secret for encrypting tokens. Generate with: openssl rand -base64 32",
|
|
16
|
+
"required": true
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"key": "AUTH_TRUST_HOST",
|
|
20
|
+
"value": "true",
|
|
21
|
+
"description": "Trust the host header (required for Express)",
|
|
22
|
+
"required": true
|
|
23
|
+
}
|
|
24
|
+
],
|
|
25
|
+
"patches": [
|
|
26
|
+
{
|
|
27
|
+
"type": "create-file",
|
|
28
|
+
"description": "Create Auth.js configuration",
|
|
29
|
+
"source": "lib/auth.ts",
|
|
30
|
+
"destination": "src/lib/auth.ts"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"type": "create-file",
|
|
34
|
+
"description": "Create auth routes",
|
|
35
|
+
"source": "routes/auth.ts",
|
|
36
|
+
"destination": "src/routes/auth.ts"
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import NextAuth from 'next-auth';
|
|
2
|
+
import Credentials from 'next-auth/providers/credentials';
|
|
3
|
+
|
|
4
|
+
export const { handlers, signIn, signOut, auth } = NextAuth({
|
|
5
|
+
providers: [
|
|
6
|
+
// GitHub OAuth Provider
|
|
7
|
+
// Uncomment and add GITHUB_ID and GITHUB_SECRET to .env
|
|
8
|
+
// GitHub({
|
|
9
|
+
// clientId: process.env.GITHUB_ID!,
|
|
10
|
+
// clientSecret: process.env.GITHUB_SECRET!,
|
|
11
|
+
// }),
|
|
12
|
+
|
|
13
|
+
// Google OAuth Provider
|
|
14
|
+
// Uncomment and add GOOGLE_ID and GOOGLE_SECRET to .env
|
|
15
|
+
// Google({
|
|
16
|
+
// clientId: process.env.GOOGLE_ID!,
|
|
17
|
+
// clientSecret: process.env.GOOGLE_SECRET!,
|
|
18
|
+
// }),
|
|
19
|
+
|
|
20
|
+
// Credentials Provider (email/password)
|
|
21
|
+
Credentials({
|
|
22
|
+
credentials: {
|
|
23
|
+
email: { label: 'Email', type: 'email' },
|
|
24
|
+
password: { label: 'Password', type: 'password' },
|
|
25
|
+
},
|
|
26
|
+
authorize: async (credentials) => {
|
|
27
|
+
// Add your own authentication logic here
|
|
28
|
+
// This is just a demo - DO NOT use in production
|
|
29
|
+
if (credentials?.email === 'demo@example.com' && credentials?.password === 'demo') {
|
|
30
|
+
return {
|
|
31
|
+
id: '1',
|
|
32
|
+
name: 'Demo User',
|
|
33
|
+
email: 'demo@example.com',
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
return null;
|
|
37
|
+
},
|
|
38
|
+
}),
|
|
39
|
+
],
|
|
40
|
+
pages: {
|
|
41
|
+
signIn: '/auth/signin',
|
|
42
|
+
},
|
|
43
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "auth",
|
|
3
|
+
"displayName": "Auth.js v5 (Next.js)",
|
|
4
|
+
"description": "Modern authentication with Auth.js v5 (NextAuth successor)",
|
|
5
|
+
"category": "auth",
|
|
6
|
+
"supportedFrameworks": ["nextjs"],
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"next-auth": "^5.0.0-beta.25"
|
|
9
|
+
},
|
|
10
|
+
"envVars": [
|
|
11
|
+
{
|
|
12
|
+
"key": "AUTH_SECRET",
|
|
13
|
+
"value": "",
|
|
14
|
+
"description": "Secret for encrypting tokens. Generate with: openssl rand -base64 32",
|
|
15
|
+
"required": true
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
"key": "AUTH_URL",
|
|
19
|
+
"value": "http://localhost:3000",
|
|
20
|
+
"description": "Canonical URL of your site (change in production)",
|
|
21
|
+
"required": false
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"patches": [
|
|
25
|
+
{
|
|
26
|
+
"type": "create-file",
|
|
27
|
+
"description": "Create Auth.js configuration",
|
|
28
|
+
"source": "lib/auth.ts",
|
|
29
|
+
"destination": "{{lib}}/auth.ts"
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
"type": "create-file",
|
|
33
|
+
"description": "Create Auth.js API route",
|
|
34
|
+
"source": "api/auth/[...nextauth]/route.ts",
|
|
35
|
+
"destination": "{{router}}/api/auth/[...nextauth]/route.ts"
|
|
36
|
+
}
|
|
37
|
+
]
|
|
38
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { betterAuth } from 'better-auth';
|
|
2
|
+
|
|
3
|
+
export const auth = betterAuth({
|
|
4
|
+
secret: process.env.BETTER_AUTH_SECRET!,
|
|
5
|
+
baseURL: process.env.BETTER_AUTH_URL!,
|
|
6
|
+
|
|
7
|
+
emailAndPassword: {
|
|
8
|
+
enabled: true,
|
|
9
|
+
},
|
|
10
|
+
|
|
11
|
+
// Uncomment to add database adapter
|
|
12
|
+
// database: {
|
|
13
|
+
// provider: "pg", // or "mongodb", "mysql"
|
|
14
|
+
// url: process.env.DATABASE_URL!,
|
|
15
|
+
// },
|
|
16
|
+
});
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { Router } from 'express';
|
|
2
|
+
import { auth } from '../lib/auth';
|
|
3
|
+
|
|
4
|
+
const router = Router();
|
|
5
|
+
|
|
6
|
+
// Mount Better Auth handlers
|
|
7
|
+
router.all('/auth/*', async (req, res) => {
|
|
8
|
+
const response = await auth.handler(req);
|
|
9
|
+
return res.status(response.status).json(response.body);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
export default router;
|