@jakaman/nestjs-pris-lite 1.0.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/bin/cli.js +161 -0
- package/package.json +11 -0
package/bin/cli.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { execSync } from 'child_process';
|
|
3
|
+
import fs from 'fs';
|
|
4
|
+
import path from 'path';
|
|
5
|
+
import * as readline from 'readline/promises';
|
|
6
|
+
import { setTimeout } from 'node:timers/promises';
|
|
7
|
+
|
|
8
|
+
const rl = readline.createInterface({
|
|
9
|
+
input: process.stdin,
|
|
10
|
+
output: process.stdout
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
async function run() {
|
|
14
|
+
console.log("This script will set up Prisma with SQLite in your NestJS project.\nProceed? (y/n)");
|
|
15
|
+
const proceed = await rl.question("> ");
|
|
16
|
+
|
|
17
|
+
if (proceed.toLowerCase() !== 'y') {
|
|
18
|
+
console.log("ā Setup cancelled by user.");
|
|
19
|
+
rl.close();
|
|
20
|
+
process.exit(0);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
console.log("\nš Starting...");
|
|
24
|
+
await setTimeout(1000);
|
|
25
|
+
|
|
26
|
+
if (!fs.existsSync('nest-cli.json')) {
|
|
27
|
+
console.error("\nā Error: Please run this in your NestJS project root.");
|
|
28
|
+
rl.close();
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
console.log("\nš Checking for NestJS project...");
|
|
33
|
+
await setTimeout(1000);
|
|
34
|
+
console.log("ā
NestJS project detected!");
|
|
35
|
+
|
|
36
|
+
const userInput = await rl.question('Enter preferred name of SQLite db (e.g., dev): ');
|
|
37
|
+
const dbName = userInput.trim() || 'dev';
|
|
38
|
+
const dbFileName = `${dbName}.db`;
|
|
39
|
+
rl.close();
|
|
40
|
+
|
|
41
|
+
try {
|
|
42
|
+
console.log("\nš¦ 1. Installing Prisma...");
|
|
43
|
+
execSync('npm install -D prisma', { stdio: 'inherit' });
|
|
44
|
+
|
|
45
|
+
// npx prisma init handles existing files gracefully, but we'll wrap it just in case
|
|
46
|
+
try {
|
|
47
|
+
execSync('npx --yes prisma init --datasource-provider sqlite', { stdio: 'inherit' });
|
|
48
|
+
} catch (e) {
|
|
49
|
+
console.log("ā¹ļø Prisma already initialized, skipping init...");
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log(`\nš 4. Configuring .env with ${dbFileName}...`);
|
|
53
|
+
const envPath = path.join(process.cwd(), '.env');
|
|
54
|
+
const dbUrlLine = `DATABASE_URL="file:./${dbFileName}"`;
|
|
55
|
+
|
|
56
|
+
if (fs.existsSync(envPath)) {
|
|
57
|
+
let env = fs.readFileSync(envPath, 'utf8');
|
|
58
|
+
// Check if DATABASE_URL already exists to replace it, otherwise append
|
|
59
|
+
if (env.includes('DATABASE_URL=')) {
|
|
60
|
+
env = env.replace(/DATABASE_URL=.*/g, dbUrlLine);
|
|
61
|
+
} else {
|
|
62
|
+
env += `\n${dbUrlLine}`;
|
|
63
|
+
}
|
|
64
|
+
fs.writeFileSync(envPath, env);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
const schemaPath = path.join(process.cwd(), 'prisma', 'schema.prisma');
|
|
68
|
+
const schemaContent = `generator client {
|
|
69
|
+
provider = "prisma-client"
|
|
70
|
+
output = "../generated/prisma"
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
datasource db {
|
|
74
|
+
provider = "sqlite"
|
|
75
|
+
}
|
|
76
|
+
`;
|
|
77
|
+
fs.writeFileSync(schemaPath, schemaContent);
|
|
78
|
+
|
|
79
|
+
console.log("\nš 5. Installing Better-SQLite3 Adapter...");
|
|
80
|
+
execSync('npm install @prisma/client @prisma/adapter-better-sqlite3 better-sqlite3', { stdio: 'inherit' });
|
|
81
|
+
execSync('npm install -D @types/better-sqlite3', { stdio: 'inherit' });
|
|
82
|
+
|
|
83
|
+
console.log("\nšļø Generating NestJS files...");
|
|
84
|
+
|
|
85
|
+
// --- SAFE GENERATION LOGIC ---
|
|
86
|
+
try {
|
|
87
|
+
execSync('nest g module prisma', { stdio: 'ignore' }); // ignore errors if folder exists
|
|
88
|
+
} catch (e) {
|
|
89
|
+
console.log("ā¹ļø Prisma module folder exists, proceeding to override content...");
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
execSync('nest g service prisma --no-spec', { stdio: 'ignore' });
|
|
94
|
+
} catch (e) {
|
|
95
|
+
console.log("ā¹ļø Prisma service file exists, proceeding to override content...");
|
|
96
|
+
}
|
|
97
|
+
// -----------------------------
|
|
98
|
+
|
|
99
|
+
const prismaDirPath = path.join(process.cwd(), 'src', 'prisma');
|
|
100
|
+
|
|
101
|
+
// Overwrite Module Content
|
|
102
|
+
fs.writeFileSync(path.join(prismaDirPath, 'prisma.module.ts'),
|
|
103
|
+
`import { Global, Module } from '@nestjs/common';
|
|
104
|
+
import { PrismaService } from './prisma.service';
|
|
105
|
+
|
|
106
|
+
@Global()
|
|
107
|
+
@Module({
|
|
108
|
+
providers: [PrismaService],
|
|
109
|
+
exports: [PrismaService],
|
|
110
|
+
})
|
|
111
|
+
export class PrismaModule {}
|
|
112
|
+
`);
|
|
113
|
+
|
|
114
|
+
// Overwrite Service Content (Fixed with proper imports and methods)
|
|
115
|
+
fs.writeFileSync(path.join(prismaDirPath, 'prisma.service.ts'),
|
|
116
|
+
`import { Injectable } from '@nestjs/common';
|
|
117
|
+
import { PrismaClient } from 'generated/prisma/client';
|
|
118
|
+
import { PrismaBetterSqlite3 } from '@prisma/adapter-better-sqlite3';
|
|
119
|
+
|
|
120
|
+
@Injectable()
|
|
121
|
+
export class PrismaService extends PrismaClient {
|
|
122
|
+
constructor() {
|
|
123
|
+
|
|
124
|
+
const adapter = new PrismaBetterSqlite3({ url: "file:./${dbFileName}?_journal_mode=WAL&_foreign_keys=on" });
|
|
125
|
+
super({ adapter });
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
`);
|
|
131
|
+
|
|
132
|
+
console.log("\nšļø Finalizing Prisma Client...");
|
|
133
|
+
await setTimeout(2000);
|
|
134
|
+
|
|
135
|
+
// --- TERMINAL-BASED DB OPTIMIZATION ---
|
|
136
|
+
try {
|
|
137
|
+
console.log(`\nš ļø 6. Optimizing database (${dbFileName})...`);
|
|
138
|
+
|
|
139
|
+
// Path to the db file relative to project root
|
|
140
|
+
const dbPath = `./prisma/${dbFileName}`;
|
|
141
|
+
|
|
142
|
+
// One-liner: Requires better-sqlite3, opens db, sets WAL, then closes.
|
|
143
|
+
const optimizeCmd = `node -e "const db = require('better-sqlite3')('${dbPath}'); db.pragma('journal_mode = WAL'); db.pragma('foreign_keys = ON'); db.close();"`;
|
|
144
|
+
|
|
145
|
+
execSync(optimizeCmd, { stdio: 'ignore' });
|
|
146
|
+
|
|
147
|
+
console.log("ā
Database file pre-optimized via terminal.");
|
|
148
|
+
} catch (e) {
|
|
149
|
+
console.log("ā¹ļø Optimization skipped (will initialize on app start).");
|
|
150
|
+
}
|
|
151
|
+
// --------------------------------------
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
console.log(`\nā
Success! Database ${dbFileName} is ready and WAL mode is active.`);
|
|
155
|
+
|
|
156
|
+
} catch (e) {
|
|
157
|
+
console.error("\nā Setup failed:", e.message);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
run();
|