create-pba 1.0.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/.env.example +18 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +124 -0
- package/dist/cli.js.map +1 -0
- package/dist/lib/auth.d.ts +12 -0
- package/dist/lib/auth.d.ts.map +1 -0
- package/dist/lib/auth.js +23 -0
- package/dist/lib/auth.js.map +1 -0
- package/dist/server.d.ts +2 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +31 -0
- package/dist/server.js.map +1 -0
- package/package.json +43 -0
- package/prisma/migrations/20260310075315_better_auth_setup/migration.sql +105 -0
- package/prisma/migrations/migration_lock.toml +3 -0
- package/prisma/schema.prisma +73 -0
- package/prisma.config.ts +14 -0
- package/src/cli.ts +136 -0
- package/src/lib/auth.ts +22 -0
- package/src/server.ts +40 -0
- package/tsconfig.json +49 -0
package/.env.example
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
BETTER_AUTH_SECRET="mehul"
|
|
2
|
+
BETTER_AUTH_URL=`http://localhost:${PORT}` # Base URL of your app
|
|
3
|
+
GITHUB_CLIENT_ID=
|
|
4
|
+
GITHUB_CLIENT_SECRET=
|
|
5
|
+
PORT=3005
|
|
6
|
+
# This was inserted by `prisma init`:
|
|
7
|
+
# Environment variables declared in this file are NOT automatically loaded by Prisma.
|
|
8
|
+
# Please add `import "dotenv/config";` to your `prisma.config.ts` file, or use the Prisma CLI with Bun
|
|
9
|
+
# to load environment variables from .env files: https://pris.ly/prisma-config-env-vars.
|
|
10
|
+
|
|
11
|
+
# Prisma supports the native connection string format for PostgreSQL, MySQL, SQLite, SQL Server, MongoDB and CockroachDB.
|
|
12
|
+
# See the documentation for all the connection string options: https://pris.ly/d/connection-strings
|
|
13
|
+
|
|
14
|
+
# The following `prisma+postgres` URL is similar to the URL produced by running a local Prisma Postgres
|
|
15
|
+
# server with the `prisma dev` CLI command, when not choosing any non-default ports or settings. The API key, unlike the
|
|
16
|
+
# one found in a remote Prisma Postgres URL, does not contain any sensitive information.
|
|
17
|
+
|
|
18
|
+
DATABASE_URL=""
|
package/dist/cli.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":""}
|
package/dist/cli.js
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const child_process_1 = require("child_process");
|
|
8
|
+
const fs_1 = __importDefault(require("fs"));
|
|
9
|
+
const path_1 = __importDefault(require("path"));
|
|
10
|
+
const readline_1 = __importDefault(require("readline"));
|
|
11
|
+
const rl = readline_1.default.createInterface({
|
|
12
|
+
input: process.stdin,
|
|
13
|
+
output: process.stdout
|
|
14
|
+
});
|
|
15
|
+
const ask = (query) => new Promise((resolve) => rl.question(query, resolve));
|
|
16
|
+
async function main() {
|
|
17
|
+
const args = process.argv.slice(2);
|
|
18
|
+
let projectName = "";
|
|
19
|
+
// Parse arguments
|
|
20
|
+
for (let i = 0; i < args.length; i++) {
|
|
21
|
+
if (args[i] === "--name" || args[i] === "-n") {
|
|
22
|
+
projectName = args[i + 1] || "";
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
// If no name found via flag, check positional argument
|
|
27
|
+
if (!projectName && args[0] && !args[0].startsWith("-")) {
|
|
28
|
+
projectName = args[0];
|
|
29
|
+
}
|
|
30
|
+
// If still no name, prompt the user
|
|
31
|
+
if (!projectName) {
|
|
32
|
+
projectName = await ask("📁 Enter project name (default: my-pba-app): ");
|
|
33
|
+
projectName = projectName.trim() || "my-pba-app";
|
|
34
|
+
}
|
|
35
|
+
const templateDir = path_1.default.resolve(__dirname, "..");
|
|
36
|
+
console.log(`🚀 Creating a new Prisma Better Auth project in: ${projectName}`);
|
|
37
|
+
if (fs_1.default.existsSync(projectName)) {
|
|
38
|
+
console.error(`❌ Error: Directory "${projectName}" already exists.`);
|
|
39
|
+
rl.close();
|
|
40
|
+
process.exit(1);
|
|
41
|
+
}
|
|
42
|
+
// 1. Create project directory
|
|
43
|
+
fs_1.default.mkdirSync(projectName);
|
|
44
|
+
process.chdir(projectName);
|
|
45
|
+
// 2. Initialize npm
|
|
46
|
+
console.log("📦 Initializing project...");
|
|
47
|
+
(0, child_process_1.execSync)("npm init -y", { stdio: "inherit" });
|
|
48
|
+
// 3. Copy files from template
|
|
49
|
+
console.log("📂 Copying template files...");
|
|
50
|
+
const itemsToCopy = [
|
|
51
|
+
"src",
|
|
52
|
+
"prisma",
|
|
53
|
+
"tsconfig.json",
|
|
54
|
+
"prisma.config.ts",
|
|
55
|
+
".env.example",
|
|
56
|
+
".gitignore"
|
|
57
|
+
];
|
|
58
|
+
itemsToCopy.forEach((item) => {
|
|
59
|
+
const srcPath = path_1.default.join(templateDir, item);
|
|
60
|
+
const destPath = path_1.default.join(process.cwd(), item);
|
|
61
|
+
if (fs_1.default.existsSync(srcPath)) {
|
|
62
|
+
if (item === "src") {
|
|
63
|
+
// Copy src while excluding cli.ts
|
|
64
|
+
if (!fs_1.default.existsSync(destPath))
|
|
65
|
+
fs_1.default.mkdirSync(destPath, { recursive: true });
|
|
66
|
+
const files = fs_1.default.readdirSync(srcPath);
|
|
67
|
+
files.forEach(file => {
|
|
68
|
+
if (file !== "cli.ts") {
|
|
69
|
+
fs_1.default.cpSync(path_1.default.join(srcPath, file), path_1.default.join(destPath, file), { recursive: true });
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
fs_1.default.cpSync(srcPath, destPath, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
// 4. Ask to install dependencies
|
|
79
|
+
const installDeps = await ask("📥 Do you want to install dependencies now? (y/n): ");
|
|
80
|
+
rl.close();
|
|
81
|
+
if (installDeps.toLowerCase() === "y" || installDeps.toLowerCase() === "yes") {
|
|
82
|
+
console.log("📥 Installing dependencies...");
|
|
83
|
+
const deps = [
|
|
84
|
+
"express",
|
|
85
|
+
"prisma",
|
|
86
|
+
"better-auth",
|
|
87
|
+
"@prisma/client",
|
|
88
|
+
"cors",
|
|
89
|
+
"dotenv"
|
|
90
|
+
];
|
|
91
|
+
const devDeps = [
|
|
92
|
+
"typescript",
|
|
93
|
+
"ts-node",
|
|
94
|
+
"nodemon",
|
|
95
|
+
"@types/express",
|
|
96
|
+
"@types/cors",
|
|
97
|
+
"@types/node"
|
|
98
|
+
];
|
|
99
|
+
(0, child_process_1.execSync)(`npm install ${deps.join(" ")}`, { stdio: "inherit" });
|
|
100
|
+
(0, child_process_1.execSync)(`npm install -D ${devDeps.join(" ")}`, { stdio: "inherit" });
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
console.log("⚠️ Skipping dependency installation. You will need to run 'npm install' manually.");
|
|
104
|
+
}
|
|
105
|
+
// 5. Update package.json in the new project to include scripts
|
|
106
|
+
const pkgPath = path_1.default.join(process.cwd(), "package.json");
|
|
107
|
+
const pkg = JSON.parse(fs_1.default.readFileSync(pkgPath, "utf-8"));
|
|
108
|
+
pkg.scripts = {
|
|
109
|
+
"dev": "nodemon --exec ts-node src/server.ts",
|
|
110
|
+
"build": "tsc",
|
|
111
|
+
"start": "node dist/server.js",
|
|
112
|
+
"generate": "prisma generate",
|
|
113
|
+
"studio": "prisma studio"
|
|
114
|
+
};
|
|
115
|
+
fs_1.default.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
116
|
+
console.log(`
|
|
117
|
+
✅ Project "${projectName}" created successfully!
|
|
118
|
+
`);
|
|
119
|
+
}
|
|
120
|
+
main().catch(err => {
|
|
121
|
+
console.error(err);
|
|
122
|
+
process.exit(1);
|
|
123
|
+
});
|
|
124
|
+
//# sourceMappingURL=cli.js.map
|
package/dist/cli.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import "dotenv/config";
|
|
2
|
+
export declare const auth: import("better-auth").Auth<{
|
|
3
|
+
database: (options: import("better-auth").BetterAuthOptions) => import("better-auth").DBAdapter<import("better-auth").BetterAuthOptions>;
|
|
4
|
+
socialProviders: {
|
|
5
|
+
github: {
|
|
6
|
+
clientId: string;
|
|
7
|
+
clientSecret: string;
|
|
8
|
+
};
|
|
9
|
+
};
|
|
10
|
+
trustedOrigins: string[];
|
|
11
|
+
}>;
|
|
12
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":"AAIA,OAAO,eAAe,CAAA;AAItB,eAAO,MAAM,IAAI;;;;sBAMiC,MAAM;0BACE,MAAM;;;;EAM9D,CAAC"}
|
package/dist/lib/auth.js
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.auth = void 0;
|
|
4
|
+
const better_auth_1 = require("better-auth");
|
|
5
|
+
const prisma_1 = require("better-auth/adapters/prisma");
|
|
6
|
+
const client_1 = require("@prisma/client");
|
|
7
|
+
require("dotenv/config");
|
|
8
|
+
const prisma = new client_1.PrismaClient();
|
|
9
|
+
exports.auth = (0, better_auth_1.betterAuth)({
|
|
10
|
+
database: (0, prisma_1.prismaAdapter)(prisma, {
|
|
11
|
+
provider: "postgresql", // or "mysql", "postgresql", ...etc
|
|
12
|
+
}),
|
|
13
|
+
socialProviders: {
|
|
14
|
+
github: {
|
|
15
|
+
clientId: process.env.GITHUB_CLIENT_ID,
|
|
16
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
trustedOrigins: [
|
|
20
|
+
"http://localhost:3000" //change this to your frontend url
|
|
21
|
+
],
|
|
22
|
+
});
|
|
23
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/lib/auth.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AACzC,wDAA4D;AAC5D,2CAA8C;AAE9C,yBAAsB;AACtB,MAAM,MAAM,GAAG,IAAI,qBAAY,EAAE,CAAC;AAGrB,QAAA,IAAI,GAAG,IAAA,wBAAU,EAAC;IAC3B,QAAQ,EAAE,IAAA,sBAAa,EAAC,MAAM,EAAE;QAC5B,QAAQ,EAAE,YAAY,EAAE,mCAAmC;KAC9D,CAAC;IACF,eAAe,EAAE;QACf,MAAM,EAAE;YACN,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,gBAA0B;YAChD,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAA8B;SACzD;KACF;IACD,cAAc,EAAE;QACZ,uBAAuB,CAAC,kCAAkC;KAC3D;CACN,CAAC,CAAC"}
|
package/dist/server.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":""}
|
package/dist/server.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
const express_1 = __importDefault(require("express"));
|
|
7
|
+
const node_1 = require("better-auth/node");
|
|
8
|
+
const cors_1 = __importDefault(require("cors")); // Import the CORS middleware
|
|
9
|
+
const auth_1 = require("./lib/auth");
|
|
10
|
+
const app = (0, express_1.default)();
|
|
11
|
+
const port = process.env.PORT;
|
|
12
|
+
app.use((0, cors_1.default)({
|
|
13
|
+
origin: "http://localhost:3000", // Replace with your frontend's origin
|
|
14
|
+
methods: ["GET", "POST", "PUT", "DELETE"], // Specify allowed HTTP methods
|
|
15
|
+
credentials: true, // Allow credentials (cookies, authorization headers, etc.)
|
|
16
|
+
}));
|
|
17
|
+
// app.all("/api/auth/*", toNodeHandler(auth)); // For ExpressJS v4
|
|
18
|
+
app.all("/api/auth/*splat", (0, node_1.toNodeHandler)(auth_1.auth)); // For ExpressJS v5
|
|
19
|
+
// Mount express json middleware after Better Auth handler
|
|
20
|
+
// or only apply it to routes that don't interact with Better Auth
|
|
21
|
+
app.get("/api/me", async (req, res) => {
|
|
22
|
+
const session = await auth_1.auth.api.getSession({
|
|
23
|
+
headers: (0, node_1.fromNodeHeaders)(req.headers),
|
|
24
|
+
});
|
|
25
|
+
return res.json(session);
|
|
26
|
+
});
|
|
27
|
+
app.use(express_1.default.json());
|
|
28
|
+
app.listen(port, () => {
|
|
29
|
+
console.log(`Example app listening on port ${port}`);
|
|
30
|
+
});
|
|
31
|
+
//# sourceMappingURL=server.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":";;;;;AAAA,sDAA8B;AAC9B,2CAAkE;AAClE,gDAAwB,CAAC,6BAA6B;AACtD,qCAAkC;AAClC,MAAM,GAAG,GAAG,IAAA,iBAAO,GAAE,CAAC;AACtB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAA;AAE7B,GAAG,CAAC,GAAG,CACL,IAAA,cAAI,EAAC;IACH,MAAM,EAAE,uBAAuB,EAAE,sCAAsC;IACvE,OAAO,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,CAAC,EAAE,+BAA+B;IAC1E,WAAW,EAAE,IAAI,EAAE,2DAA2D;CAC/E,CAAC,CACH,CAAC;AAEF,mEAAmE;AACnE,GAAG,CAAC,GAAG,CAAC,kBAAkB,EAAE,IAAA,oBAAa,EAAC,WAAI,CAAC,CAAC,CAAC,CAAC,oBAAoB;AAEtE,0DAA0D;AAC1D,kEAAkE;AAElE,GAAG,CAAC,GAAG,CAAC,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,EAAE,EAAE;IACpC,MAAM,OAAO,GAAG,MAAM,WAAI,CAAC,GAAG,CAAC,UAAU,CAAC;QACtC,OAAO,EAAE,IAAA,sBAAe,EAAC,GAAG,CAAC,OAAO,CAAC;KACtC,CAAC,CAAC;IACN,OAAO,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC1B,CAAC,CAAC,CAAC;AAUH,GAAG,CAAC,GAAG,CAAC,iBAAO,CAAC,IAAI,EAAE,CAAC,CAAC;AACxB,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,EAAE;IACrB,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;AACtD,CAAC,CAAC,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "create-pba",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "",
|
|
5
|
+
"main": "dist/server.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"create-pba": "./dist/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "echo \"Error: no test specified\" && exit 1",
|
|
11
|
+
"dev": "nodemon --exec ts-node src/server.ts",
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"prepublishOnly": "npm run build"
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"src",
|
|
18
|
+
"prisma",
|
|
19
|
+
"tsconfig.json",
|
|
20
|
+
"prisma.config.ts",
|
|
21
|
+
".env.example"
|
|
22
|
+
],
|
|
23
|
+
"keywords": [],
|
|
24
|
+
"author": "",
|
|
25
|
+
"license": "ISC",
|
|
26
|
+
"type": "commonjs",
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@prisma/client": "^6.19.2",
|
|
29
|
+
"better-auth": "^1.5.4",
|
|
30
|
+
"cors": "^2.8.6",
|
|
31
|
+
"dotenv": "^17.3.1",
|
|
32
|
+
"express": "^5.2.1",
|
|
33
|
+
"nodemon": "^3.1.14",
|
|
34
|
+
"prisma": "^6.19.2"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/cors": "^2.8.19",
|
|
38
|
+
"@types/express": "^5.0.6",
|
|
39
|
+
"@types/node": "^25.5.0",
|
|
40
|
+
"ts-node": "^10.9.2",
|
|
41
|
+
"typescript": "^5.9.3"
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Warnings:
|
|
3
|
+
|
|
4
|
+
- You are about to drop the `Account` table. If the table is not empty, all the data it contains will be lost.
|
|
5
|
+
- You are about to drop the `Session` table. If the table is not empty, all the data it contains will be lost.
|
|
6
|
+
- You are about to drop the `User` table. If the table is not empty, all the data it contains will be lost.
|
|
7
|
+
- You are about to drop the `Verification` table. If the table is not empty, all the data it contains will be lost.
|
|
8
|
+
|
|
9
|
+
*/
|
|
10
|
+
-- DropForeignKey
|
|
11
|
+
ALTER TABLE "Account" DROP CONSTRAINT "Account_userId_fkey";
|
|
12
|
+
|
|
13
|
+
-- DropForeignKey
|
|
14
|
+
ALTER TABLE "Session" DROP CONSTRAINT "Session_userId_fkey";
|
|
15
|
+
|
|
16
|
+
-- DropTable
|
|
17
|
+
DROP TABLE "Account";
|
|
18
|
+
|
|
19
|
+
-- DropTable
|
|
20
|
+
DROP TABLE "Session";
|
|
21
|
+
|
|
22
|
+
-- DropTable
|
|
23
|
+
DROP TABLE "User";
|
|
24
|
+
|
|
25
|
+
-- DropTable
|
|
26
|
+
DROP TABLE "Verification";
|
|
27
|
+
|
|
28
|
+
-- CreateTable
|
|
29
|
+
CREATE TABLE "user" (
|
|
30
|
+
"id" TEXT NOT NULL,
|
|
31
|
+
"name" TEXT NOT NULL,
|
|
32
|
+
"email" TEXT NOT NULL,
|
|
33
|
+
"emailVerified" BOOLEAN NOT NULL DEFAULT false,
|
|
34
|
+
"image" TEXT,
|
|
35
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
36
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
37
|
+
|
|
38
|
+
CONSTRAINT "user_pkey" PRIMARY KEY ("id")
|
|
39
|
+
);
|
|
40
|
+
|
|
41
|
+
-- CreateTable
|
|
42
|
+
CREATE TABLE "session" (
|
|
43
|
+
"id" TEXT NOT NULL,
|
|
44
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
45
|
+
"token" TEXT NOT NULL,
|
|
46
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
47
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
48
|
+
"ipAddress" TEXT,
|
|
49
|
+
"userAgent" TEXT,
|
|
50
|
+
"userId" TEXT NOT NULL,
|
|
51
|
+
|
|
52
|
+
CONSTRAINT "session_pkey" PRIMARY KEY ("id")
|
|
53
|
+
);
|
|
54
|
+
|
|
55
|
+
-- CreateTable
|
|
56
|
+
CREATE TABLE "account" (
|
|
57
|
+
"id" TEXT NOT NULL,
|
|
58
|
+
"accountId" TEXT NOT NULL,
|
|
59
|
+
"providerId" TEXT NOT NULL,
|
|
60
|
+
"userId" TEXT NOT NULL,
|
|
61
|
+
"accessToken" TEXT,
|
|
62
|
+
"refreshToken" TEXT,
|
|
63
|
+
"idToken" TEXT,
|
|
64
|
+
"accessTokenExpiresAt" TIMESTAMP(3),
|
|
65
|
+
"refreshTokenExpiresAt" TIMESTAMP(3),
|
|
66
|
+
"scope" TEXT,
|
|
67
|
+
"password" TEXT,
|
|
68
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
69
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
70
|
+
|
|
71
|
+
CONSTRAINT "account_pkey" PRIMARY KEY ("id")
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
-- CreateTable
|
|
75
|
+
CREATE TABLE "verification" (
|
|
76
|
+
"id" TEXT NOT NULL,
|
|
77
|
+
"identifier" TEXT NOT NULL,
|
|
78
|
+
"value" TEXT NOT NULL,
|
|
79
|
+
"expiresAt" TIMESTAMP(3) NOT NULL,
|
|
80
|
+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
|
81
|
+
"updatedAt" TIMESTAMP(3) NOT NULL,
|
|
82
|
+
|
|
83
|
+
CONSTRAINT "verification_pkey" PRIMARY KEY ("id")
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
-- CreateIndex
|
|
87
|
+
CREATE UNIQUE INDEX "user_email_key" ON "user"("email");
|
|
88
|
+
|
|
89
|
+
-- CreateIndex
|
|
90
|
+
CREATE INDEX "session_userId_idx" ON "session"("userId");
|
|
91
|
+
|
|
92
|
+
-- CreateIndex
|
|
93
|
+
CREATE UNIQUE INDEX "session_token_key" ON "session"("token");
|
|
94
|
+
|
|
95
|
+
-- CreateIndex
|
|
96
|
+
CREATE INDEX "account_userId_idx" ON "account"("userId");
|
|
97
|
+
|
|
98
|
+
-- CreateIndex
|
|
99
|
+
CREATE INDEX "verification_identifier_idx" ON "verification"("identifier");
|
|
100
|
+
|
|
101
|
+
-- AddForeignKey
|
|
102
|
+
ALTER TABLE "session" ADD CONSTRAINT "session_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
103
|
+
|
|
104
|
+
-- AddForeignKey
|
|
105
|
+
ALTER TABLE "account" ADD CONSTRAINT "account_userId_fkey" FOREIGN KEY ("userId") REFERENCES "user"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
|
|
2
|
+
generator client {
|
|
3
|
+
provider = "prisma-client-js"
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
datasource db {
|
|
7
|
+
provider = "postgresql"
|
|
8
|
+
url = env("DATABASE_URL")
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
model User {
|
|
13
|
+
id String @id
|
|
14
|
+
name String
|
|
15
|
+
email String
|
|
16
|
+
emailVerified Boolean @default(false)
|
|
17
|
+
image String?
|
|
18
|
+
createdAt DateTime @default(now())
|
|
19
|
+
updatedAt DateTime @updatedAt
|
|
20
|
+
sessions Session[]
|
|
21
|
+
accounts Account[]
|
|
22
|
+
|
|
23
|
+
@@unique([email])
|
|
24
|
+
@@map("user")
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
model Session {
|
|
28
|
+
id String @id
|
|
29
|
+
expiresAt DateTime
|
|
30
|
+
token String
|
|
31
|
+
createdAt DateTime @default(now())
|
|
32
|
+
updatedAt DateTime @updatedAt
|
|
33
|
+
ipAddress String?
|
|
34
|
+
userAgent String?
|
|
35
|
+
userId String
|
|
36
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
37
|
+
|
|
38
|
+
@@unique([token])
|
|
39
|
+
@@index([userId])
|
|
40
|
+
@@map("session")
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
model Account {
|
|
44
|
+
id String @id
|
|
45
|
+
accountId String
|
|
46
|
+
providerId String
|
|
47
|
+
userId String
|
|
48
|
+
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
|
49
|
+
accessToken String?
|
|
50
|
+
refreshToken String?
|
|
51
|
+
idToken String?
|
|
52
|
+
accessTokenExpiresAt DateTime?
|
|
53
|
+
refreshTokenExpiresAt DateTime?
|
|
54
|
+
scope String?
|
|
55
|
+
password String?
|
|
56
|
+
createdAt DateTime @default(now())
|
|
57
|
+
updatedAt DateTime @updatedAt
|
|
58
|
+
|
|
59
|
+
@@index([userId])
|
|
60
|
+
@@map("account")
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
model Verification {
|
|
64
|
+
id String @id
|
|
65
|
+
identifier String
|
|
66
|
+
value String
|
|
67
|
+
expiresAt DateTime
|
|
68
|
+
createdAt DateTime @default(now())
|
|
69
|
+
updatedAt DateTime @updatedAt
|
|
70
|
+
|
|
71
|
+
@@index([identifier])
|
|
72
|
+
@@map("verification")
|
|
73
|
+
}
|
package/prisma.config.ts
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
// This file was generated by Prisma, and assumes you have installed the following:
|
|
2
|
+
// npm install --save-dev prisma dotenv
|
|
3
|
+
import "dotenv/config";
|
|
4
|
+
import { defineConfig } from "prisma/config";
|
|
5
|
+
|
|
6
|
+
export default defineConfig({
|
|
7
|
+
schema: "prisma/schema.prisma",
|
|
8
|
+
migrations: {
|
|
9
|
+
path: "prisma/migrations",
|
|
10
|
+
},
|
|
11
|
+
datasource: {
|
|
12
|
+
url: process.env["DATABASE_URL"],
|
|
13
|
+
},
|
|
14
|
+
});
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from "child_process";
|
|
4
|
+
import fs from "fs";
|
|
5
|
+
import path from "path";
|
|
6
|
+
import readline from "readline";
|
|
7
|
+
|
|
8
|
+
const rl = readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
output: process.stdout
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const ask = (query: string): Promise<string> => new Promise((resolve) => rl.question(query, resolve));
|
|
14
|
+
|
|
15
|
+
async function main() {
|
|
16
|
+
const args = process.argv.slice(2);
|
|
17
|
+
let projectName = "";
|
|
18
|
+
|
|
19
|
+
// Parse arguments
|
|
20
|
+
for (let i = 0; i < args.length; i++) {
|
|
21
|
+
if (args[i] === "--name" || args[i] === "-n") {
|
|
22
|
+
projectName = args[i + 1] || "";
|
|
23
|
+
break;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// If no name found via flag, check positional argument
|
|
28
|
+
if (!projectName && args[0] && !args[0].startsWith("-")) {
|
|
29
|
+
projectName = args[0];
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// If still no name, prompt the user
|
|
33
|
+
if (!projectName) {
|
|
34
|
+
projectName = await ask("📁 Enter project name (default: my-pba-app): ");
|
|
35
|
+
projectName = projectName.trim() || "my-pba-app";
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const templateDir = path.resolve(__dirname, "..");
|
|
39
|
+
|
|
40
|
+
console.log(`🚀 Creating a new Prisma Better Auth project in: ${projectName}`);
|
|
41
|
+
|
|
42
|
+
if (fs.existsSync(projectName)) {
|
|
43
|
+
console.error(`❌ Error: Directory "${projectName}" already exists.`);
|
|
44
|
+
rl.close();
|
|
45
|
+
process.exit(1);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// 1. Create project directory
|
|
49
|
+
fs.mkdirSync(projectName);
|
|
50
|
+
process.chdir(projectName);
|
|
51
|
+
|
|
52
|
+
// 2. Initialize npm
|
|
53
|
+
console.log("📦 Initializing project...");
|
|
54
|
+
execSync("npm init -y", { stdio: "inherit" });
|
|
55
|
+
|
|
56
|
+
// 3. Copy files from template
|
|
57
|
+
console.log("📂 Copying template files...");
|
|
58
|
+
const itemsToCopy = [
|
|
59
|
+
"src",
|
|
60
|
+
"prisma",
|
|
61
|
+
"tsconfig.json",
|
|
62
|
+
"prisma.config.ts",
|
|
63
|
+
".env.example",
|
|
64
|
+
".gitignore"
|
|
65
|
+
];
|
|
66
|
+
|
|
67
|
+
itemsToCopy.forEach((item) => {
|
|
68
|
+
const srcPath = path.join(templateDir, item);
|
|
69
|
+
const destPath = path.join(process.cwd(), item);
|
|
70
|
+
|
|
71
|
+
if (fs.existsSync(srcPath)) {
|
|
72
|
+
if (item === "src") {
|
|
73
|
+
// Copy src while excluding cli.ts
|
|
74
|
+
if (!fs.existsSync(destPath)) fs.mkdirSync(destPath, { recursive: true });
|
|
75
|
+
const files = fs.readdirSync(srcPath);
|
|
76
|
+
files.forEach(file => {
|
|
77
|
+
if (file !== "cli.ts") {
|
|
78
|
+
fs.cpSync(path.join(srcPath, file), path.join(destPath, file), { recursive: true });
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
} else {
|
|
82
|
+
fs.cpSync(srcPath, destPath, { recursive: true });
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 4. Ask to install dependencies
|
|
88
|
+
const installDeps = await ask("📥 Do you want to install dependencies now? (y/n): ");
|
|
89
|
+
rl.close();
|
|
90
|
+
|
|
91
|
+
if (installDeps.toLowerCase() === "y" || installDeps.toLowerCase() === "yes") {
|
|
92
|
+
console.log("📥 Installing dependencies...");
|
|
93
|
+
const deps = [
|
|
94
|
+
"express",
|
|
95
|
+
"prisma",
|
|
96
|
+
"better-auth",
|
|
97
|
+
"@prisma/client",
|
|
98
|
+
"cors",
|
|
99
|
+
"dotenv"
|
|
100
|
+
];
|
|
101
|
+
const devDeps = [
|
|
102
|
+
"typescript",
|
|
103
|
+
"ts-node",
|
|
104
|
+
"nodemon",
|
|
105
|
+
"@types/express",
|
|
106
|
+
"@types/cors",
|
|
107
|
+
"@types/node"
|
|
108
|
+
];
|
|
109
|
+
|
|
110
|
+
execSync(`npm install ${deps.join(" ")}`, { stdio: "inherit" });
|
|
111
|
+
execSync(`npm install -D ${devDeps.join(" ")}`, { stdio: "inherit" });
|
|
112
|
+
} else {
|
|
113
|
+
console.log("⚠️ Skipping dependency installation. You will need to run 'npm install' manually.");
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// 5. Update package.json in the new project to include scripts
|
|
117
|
+
const pkgPath = path.join(process.cwd(), "package.json");
|
|
118
|
+
const pkg = JSON.parse(fs.readFileSync(pkgPath, "utf-8"));
|
|
119
|
+
pkg.scripts = {
|
|
120
|
+
"dev": "nodemon --exec ts-node src/server.ts",
|
|
121
|
+
"build": "tsc",
|
|
122
|
+
"start": "node dist/server.js",
|
|
123
|
+
"generate": "prisma generate",
|
|
124
|
+
"studio": "prisma studio"
|
|
125
|
+
};
|
|
126
|
+
fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2));
|
|
127
|
+
|
|
128
|
+
console.log(`
|
|
129
|
+
✅ Project "${projectName}" created successfully!
|
|
130
|
+
`);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
main().catch(err => {
|
|
134
|
+
console.error(err);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
});
|
package/src/lib/auth.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { betterAuth } from "better-auth";
|
|
2
|
+
import { prismaAdapter } from "better-auth/adapters/prisma";
|
|
3
|
+
import { PrismaClient } from "@prisma/client";
|
|
4
|
+
import dotenv from "dotenv";
|
|
5
|
+
import "dotenv/config"
|
|
6
|
+
const prisma = new PrismaClient();
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
export const auth = betterAuth({
|
|
10
|
+
database: prismaAdapter(prisma, {
|
|
11
|
+
provider: "postgresql", // or "mysql", "postgresql", ...etc
|
|
12
|
+
}),
|
|
13
|
+
socialProviders: {
|
|
14
|
+
github: {
|
|
15
|
+
clientId: process.env.GITHUB_CLIENT_ID as string,
|
|
16
|
+
clientSecret: process.env.GITHUB_CLIENT_SECRET as string,
|
|
17
|
+
},
|
|
18
|
+
},
|
|
19
|
+
trustedOrigins: [
|
|
20
|
+
"http://localhost:3000" //change this to your frontend url
|
|
21
|
+
],
|
|
22
|
+
});
|
package/src/server.ts
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import express from "express";
|
|
2
|
+
import { toNodeHandler, fromNodeHeaders } from "better-auth/node";
|
|
3
|
+
import cors from "cors"; // Import the CORS middleware
|
|
4
|
+
import { auth } from "./lib/auth";
|
|
5
|
+
const app = express();
|
|
6
|
+
const port = process.env.PORT
|
|
7
|
+
|
|
8
|
+
app.use(
|
|
9
|
+
cors({
|
|
10
|
+
origin: "http://localhost:3000", // Replace with your frontend's origin
|
|
11
|
+
methods: ["GET", "POST", "PUT", "DELETE"], // Specify allowed HTTP methods
|
|
12
|
+
credentials: true, // Allow credentials (cookies, authorization headers, etc.)
|
|
13
|
+
})
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
// app.all("/api/auth/*", toNodeHandler(auth)); // For ExpressJS v4
|
|
17
|
+
app.all("/api/auth/*splat", toNodeHandler(auth)); // For ExpressJS v5
|
|
18
|
+
|
|
19
|
+
// Mount express json middleware after Better Auth handler
|
|
20
|
+
// or only apply it to routes that don't interact with Better Auth
|
|
21
|
+
|
|
22
|
+
app.get("/api/me", async (req, res) => {
|
|
23
|
+
const session = await auth.api.getSession({
|
|
24
|
+
headers: fromNodeHeaders(req.headers),
|
|
25
|
+
});
|
|
26
|
+
return res.json(session);
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
app.use(express.json());
|
|
38
|
+
app.listen(port, () => {
|
|
39
|
+
console.log(`Example app listening on port ${port}`);
|
|
40
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
// Visit https://aka.ms/tsconfig to read more about this file
|
|
3
|
+
"compilerOptions": {
|
|
4
|
+
// File Layout
|
|
5
|
+
"rootDir": "./src",
|
|
6
|
+
"outDir": "./dist",
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
// Environment Settings
|
|
11
|
+
// See also https://aka.ms/tsconfig/module
|
|
12
|
+
"module": "CommonJS",
|
|
13
|
+
"target": "ES2020",
|
|
14
|
+
"esModuleInterop": true,
|
|
15
|
+
"types": [],
|
|
16
|
+
// For nodejs:
|
|
17
|
+
// "lib": ["esnext"],
|
|
18
|
+
// "types": ["node"],
|
|
19
|
+
// and npm install -D @types/node
|
|
20
|
+
|
|
21
|
+
// Other Outputs
|
|
22
|
+
"sourceMap": true,
|
|
23
|
+
"declaration": true,
|
|
24
|
+
"declarationMap": true,
|
|
25
|
+
|
|
26
|
+
// Stricter Typechecking Options
|
|
27
|
+
"noUncheckedIndexedAccess": true,
|
|
28
|
+
"exactOptionalPropertyTypes": true,
|
|
29
|
+
|
|
30
|
+
// Style Options
|
|
31
|
+
// "noImplicitReturns": true,
|
|
32
|
+
// "noImplicitOverride": true,
|
|
33
|
+
// "noUnusedLocals": true,
|
|
34
|
+
// "noUnusedParameters": true,
|
|
35
|
+
// "noFallthroughCasesInSwitch": true,
|
|
36
|
+
// "noPropertyAccessFromIndexSignature": true,
|
|
37
|
+
|
|
38
|
+
// Recommended Options
|
|
39
|
+
"strict": true,
|
|
40
|
+
"jsx": "react-jsx",
|
|
41
|
+
"verbatimModuleSyntax": false,
|
|
42
|
+
"isolatedModules": true,
|
|
43
|
+
"noUncheckedSideEffectImports": true,
|
|
44
|
+
"moduleDetection": "force",
|
|
45
|
+
"skipLibCheck": true,
|
|
46
|
+
},
|
|
47
|
+
"include": ["src"],
|
|
48
|
+
"exclude": ["node_modules"],
|
|
49
|
+
}
|