@deessejs/collections 0.4.1 → 0.4.3
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.js +132 -152
- package/dist/cli.js.map +1 -1
- package/dist/index.js +120 -93
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +120 -100
- package/dist/index.mjs.map +1 -1
- package/dist/next/index.js +2 -15
- package/dist/next/index.js.map +1 -1
- package/dist/next/index.mjs +2 -15
- package/dist/next/index.mjs.map +1 -1
- package/package.json +3 -3
package/dist/cli.js
CHANGED
|
@@ -37,182 +37,162 @@ __export(cli_exports, {
|
|
|
37
37
|
validatePath: () => validatePath
|
|
38
38
|
});
|
|
39
39
|
module.exports = __toCommonJS(cli_exports);
|
|
40
|
-
var
|
|
40
|
+
var import_process2 = __toESM(require("process"));
|
|
41
41
|
|
|
42
42
|
// src/migrations.ts
|
|
43
|
-
var
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
id: (0, import_pg_core.serial)("id").primaryKey()
|
|
51
|
-
};
|
|
52
|
-
for (const [fieldName, fieldDef] of Object.entries(collection.fields)) {
|
|
53
|
-
if (fieldName === "id") continue;
|
|
54
|
-
const fieldType = fieldDef.fieldType;
|
|
55
|
-
const fieldTypeName = fieldType.name || fieldType.type || "text";
|
|
56
|
-
switch (fieldTypeName) {
|
|
57
|
-
case "text":
|
|
58
|
-
columns[fieldName] = (0, import_pg_core.text)(fieldName);
|
|
59
|
-
break;
|
|
60
|
-
case "varchar":
|
|
61
|
-
columns[fieldName] = (0, import_pg_core.varchar)(fieldName, { length: 255 });
|
|
62
|
-
break;
|
|
63
|
-
case "number":
|
|
64
|
-
case "integer":
|
|
65
|
-
columns[fieldName] = (0, import_pg_core.integer)(fieldName);
|
|
66
|
-
break;
|
|
67
|
-
case "boolean":
|
|
68
|
-
columns[fieldName] = (0, import_pg_core.boolean)(fieldName);
|
|
69
|
-
break;
|
|
70
|
-
case "timestamp":
|
|
71
|
-
columns[fieldName] = (0, import_pg_core.timestamp)(fieldName);
|
|
72
|
-
break;
|
|
73
|
-
case "uuid":
|
|
74
|
-
columns[fieldName] = (0, import_pg_core.uuid)(fieldName);
|
|
75
|
-
break;
|
|
76
|
-
default:
|
|
77
|
-
columns[fieldName] = (0, import_pg_core.text)(fieldName);
|
|
43
|
+
var import_child_process = require("child_process");
|
|
44
|
+
var import_path = require("path");
|
|
45
|
+
var import_process = __toESM(require("process"));
|
|
46
|
+
function runCommand(command, args, options = {}) {
|
|
47
|
+
return new Promise((resolve2, reject) => {
|
|
48
|
+
if (options.verbose) {
|
|
49
|
+
console.log(`[collections] Running: ${command} ${args.join(" ")}`);
|
|
78
50
|
}
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
51
|
+
const child = (0, import_child_process.spawn)(command, args, {
|
|
52
|
+
stdio: options.verbose ? "inherit" : "pipe",
|
|
53
|
+
shell: true,
|
|
54
|
+
cwd: import_process.default.cwd()
|
|
55
|
+
});
|
|
56
|
+
let output = "";
|
|
57
|
+
if (!options.verbose) {
|
|
58
|
+
child.stdout?.on("data", (data) => {
|
|
59
|
+
output += data.toString();
|
|
60
|
+
});
|
|
61
|
+
child.stderr?.on("data", (data) => {
|
|
62
|
+
output += data.toString();
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
child.on("close", (code) => {
|
|
66
|
+
if (code === 0) {
|
|
67
|
+
resolve2(code ?? 0);
|
|
68
|
+
} else {
|
|
69
|
+
reject(new Error(`Command failed with code ${code}: ${output}`));
|
|
70
|
+
}
|
|
71
|
+
});
|
|
72
|
+
child.on("error", (error) => {
|
|
73
|
+
reject(error);
|
|
74
|
+
});
|
|
75
|
+
});
|
|
94
76
|
}
|
|
95
|
-
|
|
96
|
-
const
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
77
|
+
function buildDrizzleConfig(options) {
|
|
78
|
+
const config = {
|
|
79
|
+
dialect: "postgresql",
|
|
80
|
+
schema: options.schemaPath,
|
|
81
|
+
out: options.out,
|
|
82
|
+
dbCredentials: {
|
|
83
|
+
url: options.dbUrl
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
return JSON.stringify(config, null, 2);
|
|
87
|
+
}
|
|
88
|
+
var push = async (adapter, _collections, options = {}) => {
|
|
89
|
+
const {
|
|
90
|
+
verbose = false,
|
|
91
|
+
dryRun = false,
|
|
92
|
+
out = "./drizzle"
|
|
93
|
+
} = options;
|
|
94
|
+
const configContent = buildDrizzleConfig({
|
|
95
|
+
out,
|
|
96
|
+
schemaPath: "./collections/config.ts",
|
|
97
|
+
dbUrl: adapter.config.url
|
|
98
|
+
});
|
|
99
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
100
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
101
|
+
try {
|
|
102
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
103
|
+
const args = ["drizzle-kit", "push"];
|
|
104
|
+
if (dryRun) {
|
|
105
|
+
args.push("--dry-run");
|
|
110
106
|
}
|
|
111
|
-
console.log("[collections] Statements to execute:", result.statementsToExecute.length);
|
|
112
|
-
}
|
|
113
|
-
if (dryRun) {
|
|
114
|
-
console.log("[collections] Dry run - not applying changes");
|
|
115
107
|
if (verbose) {
|
|
116
|
-
|
|
117
|
-
|
|
108
|
+
args.push("--verbose");
|
|
109
|
+
}
|
|
110
|
+
await runCommand("npx", args, { verbose });
|
|
111
|
+
if (verbose) {
|
|
112
|
+
console.log("[collections] Schema pushed successfully");
|
|
113
|
+
}
|
|
114
|
+
} finally {
|
|
115
|
+
try {
|
|
116
|
+
unlinkSync(drizzleConfigPath);
|
|
117
|
+
} catch {
|
|
118
118
|
}
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
await result.apply();
|
|
122
|
-
if (verbose) {
|
|
123
|
-
console.log("[collections] Schema pushed successfully");
|
|
124
119
|
}
|
|
125
120
|
};
|
|
126
|
-
var generate = async (
|
|
127
|
-
const {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
}
|
|
138
|
-
const migrationSQL = [
|
|
139
|
-
"-- Generated migration",
|
|
140
|
-
`-- Snapshot: ${currentSnapshot.id}`,
|
|
141
|
-
"",
|
|
142
|
-
"-- Tables will be created based on current collections schema",
|
|
143
|
-
...currentSnapshot.tables?.map((table) => `-- Table: ${table}`) ?? []
|
|
144
|
-
];
|
|
145
|
-
const { writeFileSync, mkdirSync } = await import("fs");
|
|
121
|
+
var generate = async (adapter, _collections, options = {}) => {
|
|
122
|
+
const {
|
|
123
|
+
verbose = false,
|
|
124
|
+
out = "./drizzle"
|
|
125
|
+
} = options;
|
|
126
|
+
const configContent = buildDrizzleConfig({
|
|
127
|
+
out,
|
|
128
|
+
schemaPath: "./collections/config.ts",
|
|
129
|
+
dbUrl: adapter.config.url
|
|
130
|
+
});
|
|
131
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
132
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
146
133
|
try {
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
134
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
135
|
+
const args = ["drizzle-kit", "generate"];
|
|
136
|
+
if (verbose) {
|
|
137
|
+
args.push("--verbose");
|
|
138
|
+
}
|
|
139
|
+
await runCommand("npx", args, { verbose });
|
|
140
|
+
if (verbose) {
|
|
141
|
+
console.log("[collections] Migrations generated successfully");
|
|
142
|
+
}
|
|
143
|
+
} finally {
|
|
144
|
+
try {
|
|
145
|
+
unlinkSync(drizzleConfigPath);
|
|
146
|
+
} catch {
|
|
147
|
+
}
|
|
155
148
|
}
|
|
156
149
|
};
|
|
157
150
|
var migrate = async (adapter, options = {}) => {
|
|
158
|
-
const {
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
151
|
+
const {
|
|
152
|
+
verbose = false,
|
|
153
|
+
out = "./drizzle"
|
|
154
|
+
} = options;
|
|
155
|
+
const configContent = buildDrizzleConfig({
|
|
156
|
+
out,
|
|
157
|
+
schemaPath: "./collections/config.ts",
|
|
158
|
+
dbUrl: adapter.config.url
|
|
159
|
+
});
|
|
160
|
+
const drizzleConfigPath = (0, import_path.resolve)(import_process.default.cwd(), "./drizzle.config.json");
|
|
161
|
+
const { writeFileSync, unlinkSync } = await import("fs");
|
|
165
162
|
try {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
}
|
|
171
|
-
return;
|
|
172
|
-
}
|
|
173
|
-
for (const file of files) {
|
|
174
|
-
if (verbose) {
|
|
175
|
-
console.log("[collections] Applying migration:", file);
|
|
176
|
-
}
|
|
177
|
-
const sql = readFileSync(`${migrationsPath}/${file}`, "utf-8");
|
|
178
|
-
await pool.query(sql);
|
|
163
|
+
writeFileSync(drizzleConfigPath, configContent);
|
|
164
|
+
const args = ["drizzle-kit", "migrate"];
|
|
165
|
+
if (verbose) {
|
|
166
|
+
args.push("--verbose");
|
|
179
167
|
}
|
|
168
|
+
await runCommand("npx", args, { verbose });
|
|
180
169
|
if (verbose) {
|
|
181
170
|
console.log("[collections] Migrations applied successfully");
|
|
182
171
|
}
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
|
|
172
|
+
} finally {
|
|
173
|
+
try {
|
|
174
|
+
unlinkSync(drizzleConfigPath);
|
|
175
|
+
} catch {
|
|
186
176
|
}
|
|
187
177
|
}
|
|
188
178
|
};
|
|
189
179
|
|
|
190
180
|
// src/adapter.ts
|
|
191
181
|
var pgAdapter = (config) => {
|
|
192
|
-
let pool = null;
|
|
193
182
|
return {
|
|
194
183
|
type: "postgres",
|
|
195
184
|
config: {
|
|
196
185
|
url: config.url,
|
|
197
186
|
migrationsPath: config.migrationsPath ?? "./migrations"
|
|
198
|
-
},
|
|
199
|
-
getPool: async () => {
|
|
200
|
-
if (!pool) {
|
|
201
|
-
const { Pool } = await import("pg");
|
|
202
|
-
pool = new Pool({
|
|
203
|
-
connectionString: config.url
|
|
204
|
-
});
|
|
205
|
-
}
|
|
206
|
-
return pool;
|
|
207
187
|
}
|
|
208
188
|
};
|
|
209
189
|
};
|
|
210
190
|
|
|
211
191
|
// src/cli.ts
|
|
212
|
-
|
|
213
|
-
dotenv.config();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
192
|
+
try {
|
|
193
|
+
require("dotenv").config();
|
|
194
|
+
} catch {
|
|
195
|
+
}
|
|
216
196
|
function printUsage() {
|
|
217
197
|
console.log(`
|
|
218
198
|
@deessejs/collections CLI
|
|
@@ -240,11 +220,11 @@ Examples:
|
|
|
240
220
|
function validatePath(path, name) {
|
|
241
221
|
if (path.includes("..")) {
|
|
242
222
|
console.error(`Error: ${name} path cannot contain ".." (path traversal not allowed)`);
|
|
243
|
-
|
|
223
|
+
import_process2.default.exit(1);
|
|
244
224
|
}
|
|
245
225
|
}
|
|
246
226
|
function parseArgs() {
|
|
247
|
-
const args =
|
|
227
|
+
const args = import_process2.default.argv.slice(2);
|
|
248
228
|
const options = {
|
|
249
229
|
verbose: false,
|
|
250
230
|
dryRun: false,
|
|
@@ -269,13 +249,13 @@ function parseArgs() {
|
|
|
269
249
|
if (!outValue || outValue.startsWith("-")) {
|
|
270
250
|
console.error("Error: --out requires a value");
|
|
271
251
|
printUsage();
|
|
272
|
-
|
|
252
|
+
import_process2.default.exit(1);
|
|
273
253
|
}
|
|
274
254
|
validatePath(outValue, "--out");
|
|
275
255
|
options.out = outValue;
|
|
276
256
|
} else if (arg === "--help" || arg === "-h") {
|
|
277
257
|
printUsage();
|
|
278
|
-
|
|
258
|
+
import_process2.default.exit(0);
|
|
279
259
|
}
|
|
280
260
|
}
|
|
281
261
|
return { command, options };
|
|
@@ -285,7 +265,7 @@ async function main() {
|
|
|
285
265
|
if (!command) {
|
|
286
266
|
console.error("Error: No command specified");
|
|
287
267
|
printUsage();
|
|
288
|
-
|
|
268
|
+
import_process2.default.exit(1);
|
|
289
269
|
}
|
|
290
270
|
if (options.verbose) {
|
|
291
271
|
console.log("[collections] Command:", command);
|
|
@@ -295,11 +275,11 @@ async function main() {
|
|
|
295
275
|
console.warn("Warning: --dry-run is only applicable to db:push command, ignoring");
|
|
296
276
|
options.dryRun = false;
|
|
297
277
|
}
|
|
298
|
-
const dbUrl =
|
|
278
|
+
const dbUrl = import_process2.default.env.DATABASE_URL;
|
|
299
279
|
if (!dbUrl) {
|
|
300
280
|
console.error("Error: DATABASE_URL environment variable is required");
|
|
301
281
|
console.error('Set it with: export DATABASE_URL="postgres://user:pass@localhost:5432/db"');
|
|
302
|
-
|
|
282
|
+
import_process2.default.exit(1);
|
|
303
283
|
}
|
|
304
284
|
const adapter = pgAdapter({ url: dbUrl });
|
|
305
285
|
try {
|
|
@@ -328,14 +308,14 @@ async function main() {
|
|
|
328
308
|
default:
|
|
329
309
|
console.error(`Error: Unknown command "${command}"`);
|
|
330
310
|
printUsage();
|
|
331
|
-
|
|
311
|
+
import_process2.default.exit(1);
|
|
332
312
|
}
|
|
333
313
|
} catch (error) {
|
|
334
314
|
console.error("Error:", error instanceof Error ? error.message : error);
|
|
335
|
-
|
|
315
|
+
import_process2.default.exit(1);
|
|
336
316
|
}
|
|
337
317
|
}
|
|
338
|
-
if (
|
|
318
|
+
if (import_process2.default.argv[1]?.includes("cli")) {
|
|
339
319
|
main();
|
|
340
320
|
}
|
|
341
321
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts","../src/migrations.ts","../src/schema.ts","../src/adapter.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point for @deessejs/collections\r\n *\r\n * Provides commands for database migrations and schema management\r\n */\r\n\r\nimport process from 'process'\r\n\r\n// Load dotenv to read .env file\r\nimport('dotenv').then((dotenv) => {\r\n dotenv.config()\r\n}).catch(() => {\r\n // dotenv not installed, ignore\r\n})\r\n\r\nimport { push, generate, migrate, type MigrationOptions } from './migrations'\r\nimport { pgAdapter } from './adapter'\r\n\r\n/**\r\n * Print usage information\r\n */\r\nfunction printUsage(): void {\r\n console.log(`\r\n@deessejs/collections CLI\r\n\r\nUsage: collections <command> [options]\r\n\r\nCommands:\r\n db:push Push schema to database (development mode)\r\n db:generate Generate migration files\r\n db:migrate Apply pending migrations\r\n\r\nGlobal Options:\r\n --out <path> Output directory for migrations (default: ./drizzle)\r\n --verbose Enable verbose output\r\n --dry-run Dry run mode (only for db:push)\r\n\r\nExamples:\r\n collections db:push\r\n collections db:push --verbose\r\n collections db:generate\r\n collections db:migrate --verbose\r\n collections db:push --dry-run\r\n`)\r\n}\r\n\r\n/**\r\n * Validate path to prevent path traversal attacks\r\n */\r\nfunction validatePath(path: string, name: string): void {\r\n if (path.includes('..')) {\r\n console.error(`Error: ${name} path cannot contain \"..\" (path traversal not allowed)`)\r\n process.exit(1)\r\n }\r\n}\r\n\r\n/**\r\n * Parse command line arguments\r\n */\r\nfunction parseArgs(): {\r\n command: string | null\r\n options: MigrationOptions\r\n} {\r\n const args = process.argv.slice(2)\r\n const options: MigrationOptions = {\r\n verbose: false,\r\n dryRun: false,\r\n out: './drizzle'\r\n }\r\n\r\n let command: string | null = null\r\n let dryRunWarningShown = false\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i]\r\n\r\n if (arg === 'db:push' || arg === 'db:generate' || arg === 'db:migrate') {\r\n command = arg\r\n } else if (arg === '--verbose' || arg === '-v') {\r\n options.verbose = true\r\n } else if (arg === '--dry-run') {\r\n options.dryRun = true\r\n // Warn if --dry-run is used with non-push command\r\n if (command && command !== 'db:push' && !dryRunWarningShown) {\r\n console.warn('Warning: --dry-run is only applicable to db:push command')\r\n dryRunWarningShown = true\r\n }\r\n } else if (arg === '--out' || arg === '-o') {\r\n const outValue = args[++i]\r\n if (!outValue || outValue.startsWith('-')) {\r\n console.error('Error: --out requires a value')\r\n printUsage()\r\n process.exit(1)\r\n }\r\n validatePath(outValue, '--out')\r\n options.out = outValue\r\n } else if (arg === '--help' || arg === '-h') {\r\n printUsage()\r\n process.exit(0)\r\n }\r\n }\r\n\r\n return { command, options }\r\n}\r\n\r\n/**\r\n * Main CLI function\r\n */\r\nasync function main(): Promise<void> {\r\n const { command, options } = parseArgs()\r\n\r\n if (!command) {\r\n console.error('Error: No command specified')\r\n printUsage()\r\n process.exit(1)\r\n }\r\n\r\n if (options.verbose) {\r\n console.log('[collections] Command:', command)\r\n console.log('[collections] Options:', options)\r\n }\r\n\r\n // Validate --dry-run is only used with db:push\r\n if (options.dryRun && command !== 'db:push') {\r\n console.warn('Warning: --dry-run is only applicable to db:push command, ignoring')\r\n options.dryRun = false\r\n }\r\n\r\n // Get database URL from environment or prompt\r\n const dbUrl = process.env.DATABASE_URL\r\n if (!dbUrl) {\r\n console.error('Error: DATABASE_URL environment variable is required')\r\n console.error('Set it with: export DATABASE_URL=\"postgres://user:pass@localhost:5432/db\"')\r\n process.exit(1)\r\n }\r\n\r\n const adapter = pgAdapter({ url: dbUrl })\r\n\r\n try {\r\n switch (command) {\r\n case 'db:push':\r\n if (options.verbose) {\r\n console.log('[collections] Pushing schema to database...')\r\n }\r\n await push(adapter, [], options)\r\n console.log('Schema pushed successfully')\r\n break\r\n\r\n case 'db:generate':\r\n if (options.verbose) {\r\n console.log('[collections] Generating migrations...')\r\n }\r\n await generate(adapter, [], options)\r\n console.log('Migrations generated successfully')\r\n break\r\n\r\n case 'db:migrate':\r\n if (options.verbose) {\r\n console.log('[collections] Applying migrations...')\r\n }\r\n await migrate(adapter, options)\r\n console.log('Migrations applied successfully')\r\n break\r\n\r\n default:\r\n console.error(`Error: Unknown command \"${command}\"`)\r\n printUsage()\r\n process.exit(1)\r\n }\r\n } catch (error) {\r\n console.error('Error:', error instanceof Error ? error.message : error)\r\n process.exit(1)\r\n }\r\n}\r\n\r\n// Export for testing\r\nexport { main, parseArgs, printUsage, validatePath }\r\n\r\n// Run if executed directly (not when imported for tests)\r\nif (process.argv[1]?.includes('cli')) {\r\n main()\r\n}\r\n","import { drizzle } from 'drizzle-orm/node-postgres'\r\n\r\nimport type { PgAdapter } from './adapter'\r\nimport type { Collection } from './collection'\r\nimport { buildSchema } from './schema'\r\n\r\n/**\r\n * Get drizzle-kit API lazily to avoid import errors during module load\r\n */\r\nasync function getDrizzleKitApi() {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n const api = require('drizzle-kit/api')\r\n return api\r\n}\r\n\r\n/**\r\n * Migration options\r\n */\r\nexport type MigrationOptions = {\r\n /** Output directory for generated files */\r\n out?: string\r\n /** Enable verbose output */\r\n verbose?: boolean\r\n /** Dry run mode - don't apply changes */\r\n dryRun?: boolean\r\n}\r\n\r\n/**\r\n * Push schema to database (development mode)\r\n *\r\n * Uses drizzle-kit programmatic API to push schema changes to the database\r\n *\r\n * @example\r\n * import { push } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await push(adapter, collections)\r\n */\r\nexport const push = async (\r\n adapter: PgAdapter,\r\n collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false, dryRun = false } = options\r\n\r\n // Build schema from collections\r\n const schema = buildSchema(collections)\r\n\r\n // Get pool and create drizzle instance\r\n const pool = await adapter.getPool()\r\n const db = drizzle(pool, { schema })\r\n\r\n // Use drizzle-kit API\r\n const { pushSchema } = await getDrizzleKitApi()\r\n\r\n if (verbose) {\r\n console.log('[collections] Building schema from collections...')\r\n console.log('[collections] Tables:', Object.keys(schema).join(', '))\r\n }\r\n\r\n // Use pushSchema directly\r\n const result = await pushSchema(schema as Record<string, unknown>, db)\r\n\r\n if (verbose) {\r\n if (result.warnings.length > 0) {\r\n console.log('[collections] Warnings:')\r\n result.warnings.forEach((w: string) => console.log(' -', w))\r\n }\r\n console.log('[collections] Statements to execute:', result.statementsToExecute.length)\r\n }\r\n\r\n if (dryRun) {\r\n console.log('[collections] Dry run - not applying changes')\r\n if (verbose) {\r\n console.log('[collections] SQL statements:')\r\n result.statementsToExecute.forEach((stmt: string) => console.log(' ', stmt))\r\n }\r\n return\r\n }\r\n\r\n // Apply changes\r\n await result.apply()\r\n\r\n if (verbose) {\r\n console.log('[collections] Schema pushed successfully')\r\n }\r\n}\r\n\r\n/**\r\n * Generate migration files\r\n *\r\n * Uses drizzle-kit programmatic API to generate migration SQL files\r\n *\r\n * @example\r\n * import { generate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await generate(adapter, collections, { out: './migrations' })\r\n */\r\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\r\nexport const generate = async (\r\n _adapter: PgAdapter,\r\n collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false, out = './drizzle' } = options\r\n\r\n // Build schema from collections\r\n const schema = buildSchema(collections)\r\n\r\n // Use drizzle-kit API\r\n const { generateDrizzleJson } = await getDrizzleKitApi()\r\n\r\n if (verbose) {\r\n console.log('[collections] Building schema from collections...')\r\n console.log('[collections] Tables:', Object.keys(schema).join(', '))\r\n }\r\n\r\n // Generate current schema snapshot\r\n const currentSnapshot = generateDrizzleJson(schema as Record<string, unknown>)\r\n\r\n // For now, we'll create a basic migration\r\n // In a full implementation, we'd need to:\r\n // 1. Read existing migrations from the database\r\n // 2. Get the previous snapshot\r\n // 3. Generate migration between prev and current\r\n\r\n if (verbose) {\r\n console.log('[collections] Current snapshot ID:', currentSnapshot.id)\r\n }\r\n\r\n // For simplicity, we'll just output the current schema as a migration\r\n // This is a simplified version - full implementation would track migrations\r\n const migrationSQL = [\r\n '-- Generated migration',\r\n `-- Snapshot: ${currentSnapshot.id}`,\r\n '',\r\n '-- Tables will be created based on current collections schema',\r\n ...currentSnapshot.tables?.map((table: string) => `-- Table: ${table}`) ?? []\r\n ]\r\n\r\n // Write to file\r\n const { writeFileSync, mkdirSync } = await import('fs')\r\n try {\r\n mkdirSync(out, { recursive: true })\r\n } catch {\r\n // Directory might already exist\r\n }\r\n\r\n const timestamp = new Date().toISOString().replace(/[:.]/g, '-')\r\n const filename = `${out}/migration-${timestamp}.sql`\r\n\r\n writeFileSync(filename, migrationSQL.join('\\n'))\r\n\r\n if (verbose) {\r\n console.log('[collections] Migration written to:', filename)\r\n }\r\n}\r\n\r\n/**\r\n * Apply migrations\r\n *\r\n * Uses drizzle-kit programmatic API to apply pending migrations\r\n *\r\n * @example\r\n * import { migrate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await migrate(adapter)\r\n */\r\nexport const migrate = async (\r\n adapter: PgAdapter,\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const { verbose = false } = options\r\n\r\n // Get pool\r\n const pool = await adapter.getPool()\r\n\r\n if (verbose) {\r\n console.log('[collections] Applying migrations...')\r\n }\r\n\r\n // For migrations, we use the same approach as push\r\n // The migrations table tracks which migrations have been applied\r\n // This is a simplified version\r\n\r\n // Get all migration files\r\n const { readdirSync, readFileSync } = await import('fs')\r\n const migrationsPath = adapter.config.migrationsPath ?? './migrations'\r\n\r\n try {\r\n const files = readdirSync(migrationsPath)\r\n .filter(f => f.endsWith('.sql'))\r\n .sort()\r\n\r\n if (files.length === 0) {\r\n if (verbose) {\r\n console.log('[collections] No migration files found')\r\n }\r\n return\r\n }\r\n\r\n // Execute each migration\r\n for (const file of files) {\r\n if (verbose) {\r\n console.log('[collections] Applying migration:', file)\r\n }\r\n\r\n const sql = readFileSync(`${migrationsPath}/${file}`, 'utf-8')\r\n await pool.query(sql)\r\n }\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations applied successfully')\r\n }\r\n } catch (error) {\r\n if (verbose) {\r\n console.log('[collections] No migrations directory or error:', error)\r\n }\r\n // If no migrations directory, just return\r\n }\r\n}\r\n","import { pgTable, serial, text, timestamp, uuid, varchar, boolean, integer } from 'drizzle-orm/pg-core'\r\n\r\nimport type { Collection } from './collection'\r\n\r\n/**\r\n * Build Drizzle table from collection definition\r\n */\r\nexport const buildTable = (collection: Collection) => {\r\n // Build columns object\r\n const columns: Record<string, unknown> = {\r\n // Add default id column\r\n id: serial('id').primaryKey()\r\n }\r\n\r\n // Build columns from fields\r\n for (const [fieldName, fieldDef] of Object.entries(collection.fields)) {\r\n // Skip the id field if explicitly defined in fields\r\n if (fieldName === 'id') continue\r\n\r\n const fieldType = fieldDef.fieldType as { name?: string; type?: string }\r\n const fieldTypeName = fieldType.name || fieldType.type || 'text'\r\n\r\n switch (fieldTypeName) {\r\n case 'text':\r\n columns[fieldName] = text(fieldName)\r\n break\r\n case 'varchar':\r\n columns[fieldName] = varchar(fieldName, { length: 255 })\r\n break\r\n case 'number':\r\n case 'integer':\r\n columns[fieldName] = integer(fieldName)\r\n break\r\n case 'boolean':\r\n columns[fieldName] = boolean(fieldName)\r\n break\r\n case 'timestamp':\r\n columns[fieldName] = timestamp(fieldName)\r\n break\r\n case 'uuid':\r\n columns[fieldName] = uuid(fieldName)\r\n break\r\n default:\r\n columns[fieldName] = text(fieldName)\r\n }\r\n }\r\n\r\n return pgTable(collection.slug, columns as Record<string, ReturnType<typeof text>>)\r\n}\r\n\r\n/**\r\n * Build all tables from collections\r\n */\r\nexport const buildSchema = (collections: Collection[]) => {\r\n const tables: Record<string, ReturnType<typeof pgTable>> = {}\r\n\r\n for (const coll of collections) {\r\n tables[coll.slug] = buildTable(coll)\r\n }\r\n\r\n return tables\r\n}\r\n","/**\r\n * PostgreSQL adapter configuration\r\n */\r\nexport type PgAdapterConfig = {\r\n url: string\r\n migrationsPath?: string\r\n}\r\n\r\n/**\r\n * PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n *\r\n * // Get pool for drizzle\r\n * const pool = adapter.getPool()\r\n */\r\nexport interface PgAdapter {\r\n type: 'postgres'\r\n config: PgAdapterConfig\r\n /** Get the underlying connection pool */\r\n getPool: () => Promise<import('pg').Pool>\r\n}\r\n\r\n/**\r\n * Database adapter type\r\n */\r\nexport type DatabaseAdapter = PgAdapter\r\n\r\n/**\r\n * Creates a PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n *\r\n * // Get pool for drizzle\r\n * const pool = await adapter.getPool()\r\n */\r\nexport const pgAdapter = (config: PgAdapterConfig): PgAdapter => {\r\n let pool: import('pg').Pool | null = null\r\n\r\n return {\r\n type: 'postgres',\r\n config: {\r\n url: config.url,\r\n migrationsPath: config.migrationsPath ?? './migrations'\r\n },\r\n getPool: async () => {\r\n if (!pool) {\r\n const { Pool } = await import('pg')\r\n pool = new Pool({\r\n connectionString: config.url\r\n })\r\n }\r\n return pool\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["timestamp","process","process"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli.ts","../src/migrations.ts","../src/adapter.ts"],"sourcesContent":["#!/usr/bin/env node\r\n\r\n/**\r\n * CLI entry point for @deessejs/collections\r\n *\r\n * Provides commands for database migrations and schema management\r\n */\r\n\r\nimport process from 'process'\r\n\r\n// Load dotenv to read .env file (synchronous)\r\ntry {\r\n // eslint-disable-next-line @typescript-eslint/no-var-requires\r\n require('dotenv').config()\r\n} catch {\r\n // dotenv not installed, ignore\r\n}\r\n\r\nimport { push, generate, migrate, type MigrationOptions } from './migrations'\r\nimport { pgAdapter } from './adapter'\r\n\r\n/**\r\n * Print usage information\r\n */\r\nfunction printUsage(): void {\r\n console.log(`\r\n@deessejs/collections CLI\r\n\r\nUsage: collections <command> [options]\r\n\r\nCommands:\r\n db:push Push schema to database (development mode)\r\n db:generate Generate migration files\r\n db:migrate Apply pending migrations\r\n\r\nGlobal Options:\r\n --out <path> Output directory for migrations (default: ./drizzle)\r\n --verbose Enable verbose output\r\n --dry-run Dry run mode (only for db:push)\r\n\r\nExamples:\r\n collections db:push\r\n collections db:push --verbose\r\n collections db:generate\r\n collections db:migrate --verbose\r\n collections db:push --dry-run\r\n`)\r\n}\r\n\r\n/**\r\n * Validate path to prevent path traversal attacks\r\n */\r\nfunction validatePath(path: string, name: string): void {\r\n if (path.includes('..')) {\r\n console.error(`Error: ${name} path cannot contain \"..\" (path traversal not allowed)`)\r\n process.exit(1)\r\n }\r\n}\r\n\r\n/**\r\n * Parse command line arguments\r\n */\r\nfunction parseArgs(): {\r\n command: string | null\r\n options: MigrationOptions\r\n} {\r\n const args = process.argv.slice(2)\r\n const options: MigrationOptions = {\r\n verbose: false,\r\n dryRun: false,\r\n out: './drizzle'\r\n }\r\n\r\n let command: string | null = null\r\n let dryRunWarningShown = false\r\n\r\n for (let i = 0; i < args.length; i++) {\r\n const arg = args[i]\r\n\r\n if (arg === 'db:push' || arg === 'db:generate' || arg === 'db:migrate') {\r\n command = arg\r\n } else if (arg === '--verbose' || arg === '-v') {\r\n options.verbose = true\r\n } else if (arg === '--dry-run') {\r\n options.dryRun = true\r\n // Warn if --dry-run is used with non-push command\r\n if (command && command !== 'db:push' && !dryRunWarningShown) {\r\n console.warn('Warning: --dry-run is only applicable to db:push command')\r\n dryRunWarningShown = true\r\n }\r\n } else if (arg === '--out' || arg === '-o') {\r\n const outValue = args[++i]\r\n if (!outValue || outValue.startsWith('-')) {\r\n console.error('Error: --out requires a value')\r\n printUsage()\r\n process.exit(1)\r\n }\r\n validatePath(outValue, '--out')\r\n options.out = outValue\r\n } else if (arg === '--help' || arg === '-h') {\r\n printUsage()\r\n process.exit(0)\r\n }\r\n }\r\n\r\n return { command, options }\r\n}\r\n\r\n/**\r\n * Main CLI function\r\n */\r\nasync function main(): Promise<void> {\r\n const { command, options } = parseArgs()\r\n\r\n if (!command) {\r\n console.error('Error: No command specified')\r\n printUsage()\r\n process.exit(1)\r\n }\r\n\r\n if (options.verbose) {\r\n console.log('[collections] Command:', command)\r\n console.log('[collections] Options:', options)\r\n }\r\n\r\n // Validate --dry-run is only used with db:push\r\n if (options.dryRun && command !== 'db:push') {\r\n console.warn('Warning: --dry-run is only applicable to db:push command, ignoring')\r\n options.dryRun = false\r\n }\r\n\r\n // Get database URL from environment or prompt\r\n const dbUrl = process.env.DATABASE_URL\r\n if (!dbUrl) {\r\n console.error('Error: DATABASE_URL environment variable is required')\r\n console.error('Set it with: export DATABASE_URL=\"postgres://user:pass@localhost:5432/db\"')\r\n process.exit(1)\r\n }\r\n\r\n const adapter = pgAdapter({ url: dbUrl })\r\n\r\n try {\r\n switch (command) {\r\n case 'db:push':\r\n if (options.verbose) {\r\n console.log('[collections] Pushing schema to database...')\r\n }\r\n await push(adapter, [], options)\r\n console.log('Schema pushed successfully')\r\n break\r\n\r\n case 'db:generate':\r\n if (options.verbose) {\r\n console.log('[collections] Generating migrations...')\r\n }\r\n await generate(adapter, [], options)\r\n console.log('Migrations generated successfully')\r\n break\r\n\r\n case 'db:migrate':\r\n if (options.verbose) {\r\n console.log('[collections] Applying migrations...')\r\n }\r\n await migrate(adapter, options)\r\n console.log('Migrations applied successfully')\r\n break\r\n\r\n default:\r\n console.error(`Error: Unknown command \"${command}\"`)\r\n printUsage()\r\n process.exit(1)\r\n }\r\n } catch (error) {\r\n console.error('Error:', error instanceof Error ? error.message : error)\r\n process.exit(1)\r\n }\r\n}\r\n\r\n// Export for testing\r\nexport { main, parseArgs, printUsage, validatePath }\r\n\r\n// Run if executed directly (not when imported for tests)\r\nif (process.argv[1]?.includes('cli')) {\r\n main()\r\n}\r\n","import { spawn } from 'child_process'\r\nimport { resolve } from 'path'\r\nimport process from 'process'\r\n\r\nimport type { PgAdapter } from './adapter'\r\nimport type { Collection } from './collection'\r\n\r\n/**\r\n * Migration options\r\n */\r\nexport type MigrationOptions = {\r\n /** Output directory for generated files */\r\n out?: string\r\n /** Enable verbose output */\r\n verbose?: boolean\r\n /** Dry run mode - don't apply changes */\r\n dryRun?: boolean\r\n}\r\n\r\n/**\r\n * Run a command and return a promise\r\n */\r\nfunction runCommand(command: string, args: string[], options: { verbose?: boolean } = {}): Promise<number> {\r\n return new Promise((resolve, reject) => {\r\n if (options.verbose) {\r\n console.log(`[collections] Running: ${command} ${args.join(' ')}`)\r\n }\r\n\r\n const child = spawn(command, args, {\r\n stdio: options.verbose ? 'inherit' : 'pipe',\r\n shell: true,\r\n cwd: process.cwd()\r\n })\r\n\r\n let output = ''\r\n if (!options.verbose) {\r\n child.stdout?.on('data', (data) => {\r\n output += data.toString()\r\n })\r\n child.stderr?.on('data', (data) => {\r\n output += data.toString()\r\n })\r\n }\r\n\r\n child.on('close', (code) => {\r\n if (code === 0) {\r\n resolve(code ?? 0)\r\n } else {\r\n reject(new Error(`Command failed with code ${code}: ${output}`))\r\n }\r\n })\r\n\r\n child.on('error', (error) => {\r\n reject(error)\r\n })\r\n })\r\n}\r\n\r\n/**\r\n * Build drizzle-kit config file content\r\n */\r\nfunction buildDrizzleConfig(options: {\r\n out: string\r\n schemaPath: string\r\n dbUrl: string\r\n}): string {\r\n const config: Record<string, unknown> = {\r\n dialect: 'postgresql',\r\n schema: options.schemaPath,\r\n out: options.out,\r\n dbCredentials: {\r\n url: options.dbUrl\r\n }\r\n }\r\n\r\n return JSON.stringify(config, null, 2)\r\n}\r\n\r\n/**\r\n * Push schema to database (development mode)\r\n *\r\n * Uses drizzle-kit CLI to push schema changes to the database\r\n *\r\n * @example\r\n * import { push } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await push(adapter, collections)\r\n */\r\nexport const push = async (\r\n adapter: PgAdapter,\r\n _collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n dryRun = false,\r\n out = './drizzle'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'push']\r\n\r\n if (dryRun) {\r\n args.push('--dry-run')\r\n }\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Schema pushed successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Generate migration files\r\n *\r\n * Uses drizzle-kit CLI to create migration files\r\n *\r\n * @example\r\n * import { generate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await generate(adapter, collections, { out: './migrations' })\r\n */\r\nexport const generate = async (\r\n adapter: PgAdapter,\r\n _collections: Collection[],\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n out = './drizzle'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'generate']\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations generated successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n\r\n/**\r\n * Apply migrations\r\n *\r\n * Uses drizzle-kit CLI to apply pending migrations\r\n *\r\n * @example\r\n * import { migrate } from '@deessejs/collections'\r\n * import { pgAdapter } from '@deessejs/collections'\r\n *\r\n * const adapter = pgAdapter({ url: process.env.DATABASE_URL })\r\n * await migrate(adapter)\r\n */\r\nexport const migrate = async (\r\n adapter: PgAdapter,\r\n options: MigrationOptions = {}\r\n): Promise<void> => {\r\n const {\r\n verbose = false,\r\n out = './drizzle'\r\n } = options\r\n\r\n // Build temporary drizzle config\r\n const configContent = buildDrizzleConfig({\r\n out,\r\n schemaPath: './collections/config.ts',\r\n dbUrl: adapter.config.url\r\n })\r\n\r\n const drizzleConfigPath = resolve(process.cwd(), './drizzle.config.json')\r\n const { writeFileSync, unlinkSync } = await import('fs')\r\n\r\n try {\r\n // Write config file\r\n writeFileSync(drizzleConfigPath, configContent)\r\n\r\n const args = ['drizzle-kit', 'migrate']\r\n\r\n if (verbose) {\r\n args.push('--verbose')\r\n }\r\n\r\n await runCommand('npx', args, { verbose })\r\n\r\n if (verbose) {\r\n console.log('[collections] Migrations applied successfully')\r\n }\r\n } finally {\r\n // Cleanup config file\r\n try {\r\n unlinkSync(drizzleConfigPath)\r\n } catch {\r\n // Ignore cleanup errors\r\n }\r\n }\r\n}\r\n","/**\r\n * PostgreSQL adapter configuration\r\n */\r\nexport type PgAdapterConfig = {\r\n url: string\r\n migrationsPath?: string\r\n}\r\n\r\n/**\r\n * PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n */\r\nexport interface PgAdapter {\r\n type: 'postgres'\r\n config: PgAdapterConfig\r\n}\r\n\r\n/**\r\n * Database adapter type\r\n */\r\nexport type DatabaseAdapter = PgAdapter\r\n\r\n/**\r\n * Creates a PostgreSQL adapter\r\n *\r\n * @example\r\n * const adapter = pgAdapter({\r\n * url: 'postgres://user:pass@localhost:5432/db'\r\n * })\r\n */\r\nexport const pgAdapter = (config: PgAdapterConfig): PgAdapter => {\r\n return {\r\n type: 'postgres',\r\n config: {\r\n url: config.url,\r\n migrationsPath: config.migrationsPath ?? './migrations'\r\n }\r\n }\r\n}\r\n"],"mappings":"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","names":["import_process","resolve","process","process","process"]}
|