@dbmason/core 0.1.0-alpha.1

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.
Files changed (104) hide show
  1. package/README.md +17 -0
  2. package/dist/DbmasonContext-Baf-v6-B.mjs +31 -0
  3. package/dist/DbmasonContext-Baf-v6-B.mjs.map +1 -0
  4. package/dist/DbmasonContext-Dw0gG7AV.js +2 -0
  5. package/dist/DbmasonContext-Dw0gG7AV.js.map +1 -0
  6. package/dist/ast/nodes.d.ts +192 -0
  7. package/dist/ast/nodes.d.ts.map +1 -0
  8. package/dist/cli/commands/client.d.ts +2 -0
  9. package/dist/cli/commands/client.d.ts.map +1 -0
  10. package/dist/cli/commands/generate.d.ts +2 -0
  11. package/dist/cli/commands/generate.d.ts.map +1 -0
  12. package/dist/cli/commands/init.d.ts +2 -0
  13. package/dist/cli/commands/init.d.ts.map +1 -0
  14. package/dist/cli/commands/migrate.d.ts +2 -0
  15. package/dist/cli/commands/migrate.d.ts.map +1 -0
  16. package/dist/cli/commands/pull.d.ts +2 -0
  17. package/dist/cli/commands/pull.d.ts.map +1 -0
  18. package/dist/cli/index.d.ts +3 -0
  19. package/dist/cli/index.d.ts.map +1 -0
  20. package/dist/cli/index.js +81 -0
  21. package/dist/cli/index.js.map +1 -0
  22. package/dist/cli/index.mjs +929 -0
  23. package/dist/cli/index.mjs.map +1 -0
  24. package/dist/client/generateClientMetadata.d.ts +8 -0
  25. package/dist/client/generateClientMetadata.d.ts.map +1 -0
  26. package/dist/client/standaloneGenerator.d.ts +5 -0
  27. package/dist/client/standaloneGenerator.d.ts.map +1 -0
  28. package/dist/compiler/DbmasonContext.d.ts +74 -0
  29. package/dist/compiler/DbmasonContext.d.ts.map +1 -0
  30. package/dist/compiler/Dialect.d.ts +25 -0
  31. package/dist/compiler/Dialect.d.ts.map +1 -0
  32. package/dist/compiler/Introspector.d.ts +5 -0
  33. package/dist/compiler/Introspector.d.ts.map +1 -0
  34. package/dist/compiler/SnapshotBuilder.d.ts +5 -0
  35. package/dist/compiler/SnapshotBuilder.d.ts.map +1 -0
  36. package/dist/compiler/analyzers/dependency.resolver.d.ts +11 -0
  37. package/dist/compiler/analyzers/dependency.resolver.d.ts.map +1 -0
  38. package/dist/compiler/analyzers/schema.analyzer.d.ts +11 -0
  39. package/dist/compiler/analyzers/schema.analyzer.d.ts.map +1 -0
  40. package/dist/compiler/compile.d.ts +18 -0
  41. package/dist/compiler/compile.d.ts.map +1 -0
  42. package/dist/compiler/diff.d.ts +25 -0
  43. package/dist/compiler/diff.d.ts.map +1 -0
  44. package/dist/definitions/Cron.d.ts +2 -0
  45. package/dist/definitions/Cron.d.ts.map +1 -0
  46. package/dist/definitions/Extension.d.ts +2 -0
  47. package/dist/definitions/Extension.d.ts.map +1 -0
  48. package/dist/definitions/Function.d.ts +2 -0
  49. package/dist/definitions/Function.d.ts.map +1 -0
  50. package/dist/definitions/Grant.d.ts +2 -0
  51. package/dist/definitions/Grant.d.ts.map +1 -0
  52. package/dist/definitions/Module.d.ts +2 -0
  53. package/dist/definitions/Module.d.ts.map +1 -0
  54. package/dist/definitions/Policy.d.ts +2 -0
  55. package/dist/definitions/Policy.d.ts.map +1 -0
  56. package/dist/definitions/Procedure.d.ts +2 -0
  57. package/dist/definitions/Procedure.d.ts.map +1 -0
  58. package/dist/definitions/Role.d.ts +2 -0
  59. package/dist/definitions/Role.d.ts.map +1 -0
  60. package/dist/definitions/Table.d.ts +4 -0
  61. package/dist/definitions/Table.d.ts.map +1 -0
  62. package/dist/definitions/Trigger.d.ts +2 -0
  63. package/dist/definitions/Trigger.d.ts.map +1 -0
  64. package/dist/definitions/Type.d.ts +2 -0
  65. package/dist/definitions/Type.d.ts.map +1 -0
  66. package/dist/definitions/View.d.ts +3 -0
  67. package/dist/definitions/View.d.ts.map +1 -0
  68. package/dist/definitions/collectors/Cron.internal.d.ts +6 -0
  69. package/dist/definitions/collectors/Cron.internal.d.ts.map +1 -0
  70. package/dist/definitions/collectors/Extension.internal.d.ts +9 -0
  71. package/dist/definitions/collectors/Extension.internal.d.ts.map +1 -0
  72. package/dist/definitions/collectors/Function.internal.d.ts +8 -0
  73. package/dist/definitions/collectors/Function.internal.d.ts.map +1 -0
  74. package/dist/definitions/collectors/Grant.internal.d.ts +8 -0
  75. package/dist/definitions/collectors/Grant.internal.d.ts.map +1 -0
  76. package/dist/definitions/collectors/Policy.internal.d.ts +7 -0
  77. package/dist/definitions/collectors/Policy.internal.d.ts.map +1 -0
  78. package/dist/definitions/collectors/Procedure.internal.d.ts +8 -0
  79. package/dist/definitions/collectors/Procedure.internal.d.ts.map +1 -0
  80. package/dist/definitions/collectors/Role.internal.d.ts +8 -0
  81. package/dist/definitions/collectors/Role.internal.d.ts.map +1 -0
  82. package/dist/definitions/collectors/Table.internal.d.ts +23 -0
  83. package/dist/definitions/collectors/Table.internal.d.ts.map +1 -0
  84. package/dist/definitions/collectors/Trigger.internal.d.ts +5 -0
  85. package/dist/definitions/collectors/Trigger.internal.d.ts.map +1 -0
  86. package/dist/definitions/collectors/Type.internal.d.ts +11 -0
  87. package/dist/definitions/collectors/Type.internal.d.ts.map +1 -0
  88. package/dist/definitions/collectors/View.internal.d.ts +10 -0
  89. package/dist/definitions/collectors/View.internal.d.ts.map +1 -0
  90. package/dist/definitions/handles.d.ts +121 -0
  91. package/dist/definitions/handles.d.ts.map +1 -0
  92. package/dist/index.d.ts +21 -0
  93. package/dist/index.d.ts.map +1 -0
  94. package/dist/index.js +2 -0
  95. package/dist/index.js.map +1 -0
  96. package/dist/index.mjs +353 -0
  97. package/dist/index.mjs.map +1 -0
  98. package/dist/templates/cli/auth.cli.template.ts +95 -0
  99. package/dist/templates/cli/minimal.cli.template.ts +5 -0
  100. package/dist/types.d.ts +18 -0
  101. package/dist/types.d.ts.map +1 -0
  102. package/package.json +38 -0
  103. package/templates/cli/auth.cli.template.ts +95 -0
  104. package/templates/cli/minimal.cli.template.ts +5 -0
@@ -0,0 +1,929 @@
1
+ #!/usr/bin/env node
2
+ import { Command as I } from "commander";
3
+ import * as p from "fs";
4
+ import * as d from "path";
5
+ import { execSync as H } from "child_process";
6
+ import { D as P } from "../DbmasonContext-Baf-v6-B.mjs";
7
+ import * as U from "crypto";
8
+ function W(i, e) {
9
+ const o = d.resolve(process.cwd(), i);
10
+ p.existsSync(o) && (console.error(`Directory ${i} already exists.`), process.exit(1)), p.mkdirSync(o);
11
+ const t = d.join(o, "src");
12
+ p.mkdirSync(t), p.mkdirSync(d.join(o, "migrations"));
13
+ const s = d.join(o, "dbmason");
14
+ p.mkdirSync(s);
15
+ const n = d.resolve(__dirname, "../../templates/cli"), r = (e.template || "auth").toLowerCase(), c = r.endsWith(".ts") ? r : `${r}.ts`, a = d.join(n, c);
16
+ p.existsSync(a) || (console.error(`Template '${r}' not found in ${n}`), process.exit(1));
17
+ const l = p.readFileSync(a, "utf8");
18
+ p.writeFileSync(d.join(s, "schema.ts"), l.trim()), p.writeFileSync(d.join(s, "helpers.ts"), `import { DbmasonContext, definePolicy, DbOperation, TableReference } from '@dbmason/postgres';
19
+
20
+ /**
21
+ * RLS Helper: Restricts WHICH ROWS a user can see.
22
+ */
23
+ export function defineRLSPolicy(ctx: DbmasonContext, table: TableReference, name: string) {
24
+ definePolicy(table, name, {
25
+ method: 'rls',
26
+ sql: \\\`(SELECT role FROM users WHERE id = current_setting('app.user_id')::uuid) = 'admin'\\\`
27
+ });
28
+ }
29
+
30
+ /**
31
+ * RBAC Helper: Restricts WHICH ACTIONS (SELECT, INSERT, etc.) a role can perform.
32
+ */
33
+ export function defineRBACPolicy(ctx: DbmasonContext, table: TableReference, role: string, operations: DbOperation[]) {
34
+ definePolicy(table, \\\`\\\${role}_rbac\\\`, {
35
+ method: 'rbac',
36
+ rbac: [{ roles: [role], operations }]
37
+ });
38
+ }
39
+ `.trim()), p.writeFileSync(d.join(s, "index.ts"), `import { DbmasonContext } from '@dbmason/core';
40
+ import { PostgresDialect } from '@dbmason/postgres';
41
+ import { setupSchema } from './schema';
42
+
43
+ const ctx = new DbmasonContext();
44
+
45
+ // Setup Authentication (Tables, Procedures, Crons)
46
+ setupSchema(ctx);
47
+
48
+ export const dialect = new PostgresDialect(ctx);
49
+ export default ctx;
50
+ `.trim()), p.writeFileSync(d.join(o, "docker-compose.yml"), `
51
+ services:
52
+ db:
53
+ image: postgres:latest
54
+ environment:
55
+ POSTGRES_USER: postgres
56
+ POSTGRES_PASSWORD: postgres
57
+ POSTGRES_DB: postgres
58
+ ports:
59
+ - "5432:5432"
60
+ volumes:
61
+ - pgdata:/var/lib/postgresql/data
62
+
63
+ volumes:
64
+ pgdata:
65
+ `.trim()), p.writeFileSync(d.join(o, ".env"), "DATABASE_URL=postgres://postgres:postgres@localhost:5432/postgres".trim());
66
+ const T = {
67
+ compilerOptions: {
68
+ target: "ES2020",
69
+ module: "CommonJS",
70
+ moduleResolution: "node",
71
+ esModuleInterop: !0,
72
+ resolveJsonModule: !0,
73
+ skipLibCheck: !0,
74
+ strict: !0,
75
+ outDir: "./dist",
76
+ rootDir: "./"
77
+ }
78
+ };
79
+ p.writeFileSync(d.join(o, "tsconfig.json"), JSON.stringify(T, null, 2));
80
+ const y = {
81
+ name: i,
82
+ version: "1.0.0",
83
+ scripts: {
84
+ generate: "dbmason generate",
85
+ migrate: "dbmason migrate",
86
+ "db:up": "docker compose up -d",
87
+ "db:down": "docker compose down"
88
+ },
89
+ dependencies: {
90
+ "@dbmason/core": "file:../packages/core",
91
+ "@dbmason/postgres": "file:../packages/postgres",
92
+ pg: "^8.11.0",
93
+ dotenv: "^16.3.1"
94
+ },
95
+ devDependencies: {
96
+ typescript: "^5.0.0",
97
+ "ts-node": "^10.9.1"
98
+ }
99
+ };
100
+ p.writeFileSync(d.join(o, "package.json"), JSON.stringify(y, null, 2)), console.log(`Dbmason project ${i} initialized with default Auth template.`);
101
+ try {
102
+ console.log("Installing dependencies..."), H("npm install", { cwd: o, stdio: "inherit" }), console.log("Dependencies installed successfully.");
103
+ } catch (w) {
104
+ console.error("Failed to install dependencies:", w);
105
+ }
106
+ }
107
+ class B {
108
+ constructor(e) {
109
+ this.ctx = e;
110
+ }
111
+ resolveOrder() {
112
+ const e = [], o = /* @__PURE__ */ new Set(), t = /* @__PURE__ */ new Set();
113
+ for (const r of this.ctx.extensions.keys()) e.push(`extension:${r}`);
114
+ for (const r of this.ctx.roles.keys()) e.push(`role:${r}`);
115
+ const s = Array.from(this.ctx.types.keys());
116
+ for (const r of s)
117
+ this.visit(`type:${r}`, o, t, e);
118
+ const n = Array.from(this.ctx.tables.keys());
119
+ for (const r of n)
120
+ this.visit(`table:${r}`, o, t, e);
121
+ for (const r of this.ctx.views.keys()) e.push(`view:${r}`);
122
+ for (const r of this.ctx.procedures.keys()) e.push(`procedure:${r}`);
123
+ for (const r of this.ctx.functions.keys()) e.push(`function:${r}`);
124
+ for (const r of this.ctx.crons.keys()) e.push(`cron:${r}`);
125
+ for (const r of this.ctx.policies.keys()) e.push(`policy:${r}`);
126
+ for (const r of this.ctx.triggers.keys()) e.push(`trigger:${r}`);
127
+ for (const r of this.ctx.grants.keys()) e.push(`grant:${r}`);
128
+ return e;
129
+ }
130
+ visit(e, o, t, s) {
131
+ if (o.has(e)) return;
132
+ if (t.has(e)) throw new Error(`Circular dependency detected: ${e}`);
133
+ t.add(e);
134
+ const [n, r] = e.split(":");
135
+ if (n === "table") {
136
+ const c = this.ctx.tables.get(r);
137
+ if (c)
138
+ for (const a of Object.values(c.columns))
139
+ a.references && this.visit(`table:${a.references.table}`, o, t, s), this.ctx.types.has(a.type) && this.visit(`type:${a.type}`, o, t, s);
140
+ }
141
+ t.delete(e), o.add(e), s.push(e);
142
+ }
143
+ }
144
+ class C {
145
+ constructor(e, o) {
146
+ this.ctx = e, this.dialect = o, this.dependencyResolver = new B(e);
147
+ }
148
+ analyze() {
149
+ const e = /* @__PURE__ */ new Map();
150
+ for (const [s, n] of this.ctx.tables.entries())
151
+ e.set(s, this.dialect.analyzeTable(n));
152
+ const o = this.dependencyResolver.resolveOrder();
153
+ return {
154
+ tables: e,
155
+ types: new Map(this.ctx.types),
156
+ views: new Map(this.ctx.views),
157
+ materializedViews: new Map(this.ctx.materializedViews),
158
+ procedures: new Map(this.ctx.procedures),
159
+ functions: new Map(this.ctx.functions),
160
+ extensions: new Map(this.ctx.extensions),
161
+ roles: new Map(this.ctx.roles),
162
+ grants: new Map(this.ctx.grants),
163
+ crons: new Map(this.ctx.crons),
164
+ policies: new Map(this.ctx.policies),
165
+ triggers: new Map(this.ctx.triggers),
166
+ order: o
167
+ };
168
+ }
169
+ }
170
+ class V {
171
+ constructor(e, o) {
172
+ this.analyzedSchema = e, this.oldSnapshot = o;
173
+ }
174
+ plan() {
175
+ const e = [];
176
+ for (const o of this.analyzedSchema.order) {
177
+ const [t, s] = o.split(":");
178
+ switch (t) {
179
+ case "extension":
180
+ this.planExtension(s, e);
181
+ break;
182
+ case "type":
183
+ this.planType(s, e);
184
+ break;
185
+ case "table":
186
+ this.planTable(s, e);
187
+ break;
188
+ case "view":
189
+ this.planView(s, e);
190
+ break;
191
+ case "procedure":
192
+ this.planProcedure(s, e);
193
+ break;
194
+ case "function":
195
+ this.planFunction(s, e);
196
+ break;
197
+ case "cron":
198
+ this.planCron(s, e);
199
+ break;
200
+ case "policy":
201
+ this.planPolicy(s, e);
202
+ break;
203
+ case "trigger":
204
+ this.planTrigger(s, e);
205
+ break;
206
+ case "role":
207
+ this.planRole(s, e);
208
+ break;
209
+ case "grant":
210
+ this.planGrant(s, e);
211
+ break;
212
+ }
213
+ }
214
+ return this.oldSnapshot && this.planDeletions(e), e;
215
+ }
216
+ planExtension(e, o) {
217
+ const t = this.analyzedSchema.extensions.get(e), s = this.oldSnapshot?.extensions[e];
218
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
219
+ }
220
+ planType(e, o) {
221
+ const t = this.analyzedSchema.types.get(e), s = this.oldSnapshot?.types[e];
222
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
223
+ }
224
+ planTable(e, o) {
225
+ const t = this.analyzedSchema.tables.get(e);
226
+ if (!t) return;
227
+ const s = this.oldSnapshot?.tables[e];
228
+ s ? JSON.stringify(t) !== JSON.stringify(s) && o.push({ action: "alter", node: t, diff: { old: s } }) : o.push({ action: "create", node: t });
229
+ }
230
+ planView(e, o) {
231
+ const t = this.analyzedSchema.views.get(e);
232
+ if (!t) return;
233
+ const s = this.oldSnapshot?.views[e];
234
+ (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "replace", node: t });
235
+ }
236
+ planProcedure(e, o) {
237
+ const t = this.analyzedSchema.procedures.get(e);
238
+ if (!t) return;
239
+ const s = this.oldSnapshot?.hashes?.[e], n = require("crypto").createHash("md5").update(t.body).digest("hex");
240
+ (!s || s !== n) && o.push({ action: "replace", node: t });
241
+ }
242
+ planFunction(e, o) {
243
+ const t = this.analyzedSchema.functions.get(e);
244
+ if (!t) return;
245
+ const s = this.oldSnapshot?.hashes?.[e], n = require("crypto").createHash("md5").update(t.body).digest("hex");
246
+ (!s || s !== n) && o.push({ action: "replace", node: t });
247
+ }
248
+ planCron(e, o) {
249
+ const t = this.analyzedSchema.crons.get(e), s = this.oldSnapshot?.crons[e];
250
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
251
+ }
252
+ planPolicy(e, o) {
253
+ const t = this.analyzedSchema.policies.get(e), s = this.oldSnapshot?.policies?.[e];
254
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
255
+ }
256
+ planTrigger(e, o) {
257
+ const t = this.analyzedSchema.triggers.get(e), s = this.oldSnapshot?.triggers?.[e];
258
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
259
+ }
260
+ planRole(e, o) {
261
+ const t = this.analyzedSchema.roles.get(e), s = this.oldSnapshot?.roles?.[e];
262
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
263
+ }
264
+ planGrant(e, o) {
265
+ const t = this.analyzedSchema.grants.get(e), s = this.oldSnapshot?.grants?.[e];
266
+ t && (!s || JSON.stringify(t) !== JSON.stringify(s)) && o.push({ action: "create", node: t });
267
+ }
268
+ planDeletions(e) {
269
+ for (const o of Object.keys(this.oldSnapshot.tables))
270
+ this.analyzedSchema.tables.has(o) || e.push({ action: "drop", node: this.oldSnapshot.tables[o] });
271
+ for (const o of Object.keys(this.oldSnapshot.roles || {}))
272
+ this.analyzedSchema.roles.has(o) || e.push({ action: "drop", node: this.oldSnapshot.roles[o] });
273
+ }
274
+ }
275
+ class D {
276
+ constructor(e, o) {
277
+ this.ctx = e, this.dialect = o;
278
+ }
279
+ /**
280
+ * compile
281
+ */
282
+ compile(e) {
283
+ const t = new C(this.ctx, this.dialect).analyze(), n = new V(t, e).plan();
284
+ return this.dialect.emit(n);
285
+ }
286
+ }
287
+ function G(i, e) {
288
+ const o = {
289
+ tables: {},
290
+ procedures: {},
291
+ functions: {},
292
+ views: {},
293
+ types: {},
294
+ modules: {}
295
+ };
296
+ function t(r) {
297
+ if (!r || r === "global") return o;
298
+ const c = r.split(".");
299
+ let a = o;
300
+ for (const l of c)
301
+ a.modules[l] || (a.modules[l] = {
302
+ tables: {},
303
+ procedures: {},
304
+ functions: {},
305
+ views: {},
306
+ types: {},
307
+ modules: {}
308
+ }), a = a.modules[l];
309
+ return a;
310
+ }
311
+ function s(r) {
312
+ if (!r) return "any";
313
+ let c = r.replace(/\\"/g, "").replace(/"/g, "");
314
+ return c.toUpperCase().startsWith("SETOF ") ? `SETOF '${c.substring(6).trim()}'` : c;
315
+ }
316
+ for (const r of i.tables.values()) {
317
+ const c = t(r.module);
318
+ c.tables[r.name] = {
319
+ name: r.name,
320
+ module: r.module,
321
+ columns: Object.fromEntries(
322
+ Object.entries(r.columns).map(([a, l]) => [a, {
323
+ type: s(l.type),
324
+ primaryKey: !!l.primaryKey,
325
+ notNull: !!l.notNull
326
+ }])
327
+ )
328
+ };
329
+ }
330
+ for (const r of i.procedures.values()) {
331
+ const c = t(r.module);
332
+ c.procedures[r.name] = {
333
+ kind: r.kind,
334
+ name: r.name,
335
+ module: r.module,
336
+ args: Object.fromEntries(
337
+ Object.entries(r.args).map(([a, l]) => [a, s(l)])
338
+ ),
339
+ returns: s(r.returns)
340
+ };
341
+ }
342
+ for (const r of i.functions.values()) {
343
+ const c = t(r.module);
344
+ c.functions[r.name] = {
345
+ kind: r.kind,
346
+ name: r.name,
347
+ module: r.module,
348
+ args: Object.fromEntries(
349
+ Object.entries(r.args).map(([a, l]) => [a, s(l)])
350
+ ),
351
+ returns: s(r.returns)
352
+ };
353
+ }
354
+ for (const r of i.views.values()) {
355
+ const c = t(r.module);
356
+ c.views[r.name] = {
357
+ name: r.name,
358
+ module: r.module,
359
+ columns: {}
360
+ // Views might not have analyzed columns yet in all paths
361
+ };
362
+ }
363
+ for (const r of i.types.values()) {
364
+ const c = t(r.module);
365
+ c.types[r.name] = {
366
+ name: r.name,
367
+ kind: r.type,
368
+ module: r.module,
369
+ values: r.values,
370
+ fields: r.fields ? Object.fromEntries(
371
+ Object.entries(r.fields).map(([a, l]) => [a, s(l)])
372
+ ) : void 0
373
+ };
374
+ }
375
+ const n = d.join(e, "dbmason.metadata.json");
376
+ return p.existsSync(e) || p.mkdirSync(e, { recursive: !0 }), p.writeFileSync(n, JSON.stringify(o, null, 2)), { configPath: n };
377
+ }
378
+ class k {
379
+ static build(e) {
380
+ const o = {}, t = new Map([...e.procedures, ...e.functions]);
381
+ for (const [s, n] of t.entries()) {
382
+ const r = n.body || "";
383
+ o[s] = U.createHash("md5").update(r).digest("hex");
384
+ }
385
+ return {
386
+ tables: Object.fromEntries(e.tables),
387
+ procedures: Object.fromEntries(e.procedures),
388
+ functions: Object.fromEntries(e.functions),
389
+ views: Object.fromEntries(e.views),
390
+ materializedViews: Object.fromEntries(e.materializedViews),
391
+ types: Object.fromEntries(e.types),
392
+ crons: Object.fromEntries(e.crons),
393
+ extensions: Object.fromEntries(e.extensions),
394
+ roles: Object.fromEntries(e.roles),
395
+ grants: Object.fromEntries(e.grants),
396
+ policies: Object.fromEntries(e.policies),
397
+ triggers: Object.fromEntries(e.triggers),
398
+ hashes: o
399
+ };
400
+ }
401
+ }
402
+ async function K(i, e = {}) {
403
+ const o = d.resolve(process.cwd(), "dbmason/index.ts");
404
+ p.existsSync(o) || (console.error("dbmason/index.ts not found."), process.exit(1));
405
+ try {
406
+ require("ts-node").register({ transpileOnly: !0 });
407
+ const t = require(o), s = t.default || t.ctx;
408
+ let n = t.dialect;
409
+ if (!(s instanceof P) && s?.constructor?.name !== "DbmasonContext")
410
+ throw new Error("dbmason/index.ts must export a DbmasonContext.");
411
+ if (!n && s.config?.dialect && (n = s.config.dialect), !n)
412
+ throw new Error('dbmason/index.ts must export a "dialect" or pass it to DbmasonContext constructor.');
413
+ const c = new C(s, n).analyze(), a = d.resolve(process.cwd(), "node_modules/@dbmason/core"), l = d.join(a, ".dbmason-snapshot.json");
414
+ let h;
415
+ p.existsSync(l) && (h = JSON.parse(p.readFileSync(l, "utf8")));
416
+ const f = new D(s, n).compile(h), g = f.split(`
417
+ `).filter((y) => !y.trim().startsWith("--")).join(`
418
+ `).trim();
419
+ if (g) {
420
+ if ((g.toLowerCase().includes("drop table") || g.toLowerCase().includes("drop column")) && (e.allowDestructive || (console.error("Destructive changes detected! Use --allow-destructive to confirm."), process.exit(1))), e.dry) {
421
+ console.log("-- Dry Run Output (No files written) --"), console.log(f);
422
+ return;
423
+ }
424
+ const y = d.resolve(process.cwd(), s.config.paths?.migrations || "migrations");
425
+ p.existsSync(y) || p.mkdirSync(y, { recursive: !0 });
426
+ const w = `${Date.now()}_${i || "migration"}.sql`;
427
+ p.writeFileSync(d.join(y, w), f);
428
+ const b = k.build(c);
429
+ p.existsSync(a) || p.mkdirSync(a, { recursive: !0 }), p.writeFileSync(l, JSON.stringify(b, null, 2)), console.log(`Generated migration: ${d.relative(process.cwd(), d.join(y, w))}`);
430
+ } else
431
+ console.log("No changes detected.");
432
+ const T = s.config.paths?.client ? d.resolve(process.cwd(), s.config.paths.client) : process.cwd();
433
+ G(c, T);
434
+ } catch (t) {
435
+ console.error("Generation failed:", t.message), process.exit(1);
436
+ }
437
+ }
438
+ class Q {
439
+ constructor(e, o = "migrations") {
440
+ this.driver = e, this.migrationDir = d.resolve(process.cwd(), o);
441
+ }
442
+ async runMigrations() {
443
+ await this.driver.connect();
444
+ try {
445
+ await this.driver.query(`
446
+ CREATE TABLE IF NOT EXISTS dbmason_migrations (
447
+ id SERIAL PRIMARY KEY,
448
+ name TEXT NOT NULL UNIQUE,
449
+ applied_at TIMESTAMPTZ DEFAULT NOW()
450
+ );
451
+ `);
452
+ const e = await this.driver.query("SELECT name FROM dbmason_migrations"), o = new Set(e.rows.map((s) => s.name));
453
+ if (!p.existsSync(this.migrationDir)) return;
454
+ const t = p.readdirSync(this.migrationDir).sort();
455
+ for (const s of t)
456
+ if (s.endsWith(".sql") && !o.has(s)) {
457
+ const n = p.readFileSync(d.join(this.migrationDir, s), "utf-8");
458
+ console.log(`Running migration: ${s}`), await this.driver.beginTransaction();
459
+ try {
460
+ await this.driver.query(n), await this.driver.query("INSERT INTO dbmason_migrations (name) VALUES ($1)", [s]), await this.driver.commitTransaction();
461
+ } catch (r) {
462
+ throw await this.driver.rollbackTransaction(), console.error(`Error in migration ${s}:`, r), r;
463
+ }
464
+ } else s.endsWith(".sql");
465
+ } finally {
466
+ await this.driver.close();
467
+ }
468
+ }
469
+ }
470
+ async function Y(i = {}) {
471
+ const e = d.resolve(process.cwd(), "dbmason/index.ts"), o = d.resolve(process.cwd(), ".env");
472
+ if (p.existsSync(o)) {
473
+ const t = p.readFileSync(o, "utf8");
474
+ for (const s of t.split(`
475
+ `)) {
476
+ const [n, ...r] = s.split("=");
477
+ n && r.length > 0 && (process.env[n.trim()] = r.join("=").trim().replace(/^['"]|['"]$/g, ""));
478
+ }
479
+ }
480
+ p.existsSync(e) || (console.error("dbmason/index.ts not found."), process.exit(1));
481
+ try {
482
+ require("ts-node").register({ transpileOnly: !0 });
483
+ const t = require(e), s = t.default || t.ctx;
484
+ let n = t.dialect;
485
+ if (!n && s.config?.dialect && (n = s.config.dialect), !n)
486
+ throw new Error('dbmason/index.ts must export a "dialect" or pass it to DbmasonContext constructor.');
487
+ const r = s.config?.connectionString || process.env.DATABASE_URL;
488
+ if (!r)
489
+ throw new Error("Connection string not found. Please configure it in DbmasonContext or set DATABASE_URL.");
490
+ const c = n.getDriver(r);
491
+ console.log("Applying migrations to database...");
492
+ const a = s.config?.paths?.migrations;
493
+ await new Q(c, a).runMigrations(), console.log("Migration completed successfully.");
494
+ } catch (t) {
495
+ console.error("Migration failed:", t.message), process.exit(1);
496
+ }
497
+ }
498
+ function X(i, e) {
499
+ const o = {
500
+ types: /* @__PURE__ */ new Map()
501
+ };
502
+ R(i, o);
503
+ const t = [
504
+ "// Generated by @dbmason/core - DO NOT EDIT DIRECTLY",
505
+ 'import { Pool, PoolConfig, QueryResult, QueryResultRow } from "pg";',
506
+ "",
507
+ `/**
508
+ * Base Client Logic (Bundled)
509
+ */`,
510
+ te.join(`
511
+ `),
512
+ "",
513
+ "/**",
514
+ " * Internal Helper Types",
515
+ " */",
516
+ "export type Trigger = void; // Type alias for procedure returns",
517
+ "",
518
+ "/**",
519
+ " * Database Schema Types & Enums",
520
+ " */"
521
+ ];
522
+ return A(i, t, o), t.push(""), t.push("/**"), t.push(" * Database Table & View Interfaces", " */"), _(i, t, o, ""), t.push(""), t.push("/**"), t.push(" * Typed DbmasonClient", " */"), t.push("export class DbmasonClient extends StandaloneDbmasonClient {"), t.push(" constructor(options?: StandaloneDbmasonClientOptions) {"), t.push(" super(options);"), t.push(" }"), t.push(""), Z(i, t, 1, o), t.push("}"), t.push(""), t.join(`
523
+ `);
524
+ }
525
+ function S(i, e) {
526
+ const o = i.replace(/['"]/g, ""), t = o.split(".");
527
+ if (t.length > 1)
528
+ return O(t.join("_"));
529
+ const s = e.endsWith("_") ? e : e ? e + "_" : "", n = ee(o);
530
+ return s && (n.startsWith(s) || o.startsWith(s)) ? O(o) : O(s + o);
531
+ }
532
+ function R(i, e, o = "") {
533
+ if (i.types)
534
+ for (const [t, s] of Object.entries(i.types)) {
535
+ const n = S(t, o);
536
+ if (e.types.set(t, n), o) {
537
+ const r = o.replace(/_$/, "").replace(/_/g, ".");
538
+ e.types.set(`${r}.${t}`, n);
539
+ }
540
+ }
541
+ if (i.modules)
542
+ for (const [t, s] of Object.entries(i.modules))
543
+ R(s, e, o + t + "_");
544
+ }
545
+ function A(i, e, o, t = "") {
546
+ if (i.types)
547
+ for (const [s, n] of Object.entries(i.types)) {
548
+ const r = o.types.get(s) || S(s, t);
549
+ if (n.kind === "enum" && n.values) {
550
+ const c = n.values.map((a) => `'${a}'`).join(" | ");
551
+ e.push(`export type ${r} = ${c};`);
552
+ } else if (n.kind === "composite" && n.fields) {
553
+ e.push(`export interface ${r} {`);
554
+ for (const [c, a] of Object.entries(n.fields))
555
+ e.push(` ${c}: ${x(a, o, t)};`);
556
+ e.push("}");
557
+ }
558
+ }
559
+ if (i.modules)
560
+ for (const [s, n] of Object.entries(i.modules))
561
+ A(n, e, o, t + s + "_");
562
+ }
563
+ function _(i, e, o, t = "") {
564
+ const s = { ...i.tables || {}, ...i.views || {} };
565
+ for (const [n, r] of Object.entries(s)) {
566
+ const c = r, a = S(n, t);
567
+ if (e.push(`export interface ${a} {`), c.columns && Object.keys(c.columns).length > 0)
568
+ for (const [l, h] of Object.entries(c.columns)) {
569
+ const u = x(h.type, o, t);
570
+ e.push(` ${l}${h.notNull ? "" : "?"}: ${u};`);
571
+ }
572
+ else
573
+ e.push(" [key: string]: any;");
574
+ e.push("}"), e.push("");
575
+ }
576
+ if (i.modules)
577
+ for (const [n, r] of Object.entries(i.modules))
578
+ _(r, e, o, t + n + "_");
579
+ }
580
+ function Z(i, e, o, t, s = "") {
581
+ const n = " ".repeat(o);
582
+ if (i.tables)
583
+ for (const [c] of Object.entries(i.tables)) {
584
+ const a = S(c, s);
585
+ e.push(`${n}get ${c}() {`), e.push(`${n} return this.getTableHandler<${a}>("${s ? s.replace(/_/g, ".") + "." + c : c}");`), e.push(`${n}}`), e.push("");
586
+ }
587
+ if (i.views)
588
+ for (const [c] of Object.entries(i.views)) {
589
+ const a = S(c, s);
590
+ e.push(`${n}get ${c}() {`), e.push(`${n} return this.getTableHandler<${a}>("${s ? s.replace(/_/g, ".") + "." + c : c}");`), e.push(`${n}}`), e.push("");
591
+ }
592
+ const r = { ...i.procedures || {}, ...i.functions || {} };
593
+ for (const [c, a] of Object.entries(r)) {
594
+ const l = L(a, t, s), h = M(a, t, s), u = l === "void" ? "undefined" : "params", f = JSON.stringify(a.args), g = a.kind === "Procedure" && a.returns.toLowerCase() === "void";
595
+ e.push(`${n}async ${c}(params?: ${l}): Promise<${h}> {`), e.push(`${n} return this.rpc("${s ? s.replace(/_/g, ".") + "." + c : c}", ${u}, ${f}, ${g}) as any;`), e.push(`${n}}`), e.push("");
596
+ }
597
+ if (i.modules)
598
+ for (const [c, a] of Object.entries(i.modules))
599
+ e.push(`${n}get ${c}() {`), e.push(`${n} const self = this;`), e.push(`${n} return {`), q(a, e, o + 2, t, s ? `${s}.${c}` : c), e.push(`${n} };`), e.push(`${n}}`), e.push("");
600
+ }
601
+ function q(i, e, o, t, s) {
602
+ const n = " ".repeat(o), r = s.replace(/\./g, "_") + "_";
603
+ if (i.tables)
604
+ for (const [a] of Object.entries(i.tables)) {
605
+ const l = S(a, r);
606
+ e.push(`${n}get ${a}() { return self.getTableHandler<${l}>("${s}.${a}"); },`);
607
+ }
608
+ if (i.views)
609
+ for (const [a] of Object.entries(i.views)) {
610
+ const l = S(a, r);
611
+ e.push(`${n}get ${a}() { return self.getTableHandler<${l}>("${s}.${a}"); },`);
612
+ }
613
+ const c = { ...i.procedures || {}, ...i.functions || {} };
614
+ for (const [a, l] of Object.entries(c)) {
615
+ const h = L(l, t, r), u = M(l, t, r), f = JSON.stringify(l.args), g = l.kind === "Procedure" && l.returns.toLowerCase() === "void";
616
+ e.push(`${n}${a}(params?: ${h}): Promise<${u}> { return self.rpc("${s}.${a}", params, ${f}, ${g}) as any; },`);
617
+ }
618
+ if (i.modules)
619
+ for (const [a, l] of Object.entries(i.modules))
620
+ e.push(`${n}get ${a}() {`), e.push(`${n} return {`), q(l, e, o + 2, t, `${s}.${a}`), e.push(`${n} };`), e.push(`${n}},`);
621
+ }
622
+ function L(i, e, o) {
623
+ if (!i.args || Object.keys(i.args).length === 0) return "void";
624
+ const t = [];
625
+ for (const [s, n] of Object.entries(i.args)) {
626
+ const r = n, c = r.toLowerCase().includes("default"), a = r.split(" ")[0];
627
+ t.push(`${s}${c ? "?" : ""}: ${x(a, e, o)}`);
628
+ }
629
+ return `{ ${t.join(", ")} }`;
630
+ }
631
+ function M(i, e, o) {
632
+ const t = i.returns || "any", s = t.toLowerCase().includes("setof"), n = t.replace(/setof/i, "").replace(/'/g, "").trim(), r = x(n, e, o);
633
+ return r.toLowerCase() === "trigger" ? "Trigger" : s ? `${r}[]` : r;
634
+ }
635
+ function x(i, e, o = "") {
636
+ const t = i.toLowerCase().replace(/['"]/g, "").trim();
637
+ return e.types.has(t) ? e.types.get(t) : t.includes("serial") || t.includes("int") || t.includes("float") || t.includes("double") || t.includes("numeric") || t.includes("decimal") || t.includes("real") || t.includes("money") ? "number" : t.includes("bool") ? "boolean" : t.includes("json") ? "any" : t.includes("date") || t.includes("timestamp") ? "Date | string" : t === "void" ? "void" : ["text", "varchar", "char", "uuid", "bytea", "interval", "xml", "point", "line", "lseg", "box", "path", "polygon", "circle", "cidr", "inet", "macaddr"].some((n) => t.includes(n)) ? "string" : S(t, o);
638
+ }
639
+ function O(i) {
640
+ return i ? i.replace(/['"]/g, "").split(/[\._-]/).filter(Boolean).map((e) => e.charAt(0).toUpperCase() + e.slice(1)).join("") : "Any";
641
+ }
642
+ function ee(i) {
643
+ return i.replace(/[A-Z]/g, (e) => `_${e.toLowerCase()}`).replace(/^_/, "");
644
+ }
645
+ const te = [
646
+ "export interface StandaloneDbmasonClientOptions {",
647
+ " returnCase?: 'camel' | 'pascal' | 'snake';",
648
+ " poolConfig?: PoolConfig;",
649
+ "}",
650
+ "",
651
+ "export type TableMethods<T> = {",
652
+ " create: (data: Partial<T>) => Promise<T[]>;",
653
+ " read: (filter?: Partial<T>) => Promise<T[]>;",
654
+ " update: (data: Partial<T>, filter: Partial<T>) => Promise<T[]>;",
655
+ " delete: (filter: Partial<T>) => Promise<T[]>;",
656
+ " list: (options?: { where?: Partial<T>; limit?: number; orderBy?: string }) => Promise<T[]>;",
657
+ "};",
658
+ "",
659
+ "export class StandaloneDbmasonClient {",
660
+ " private pool: Pool;",
661
+ " private returnCase: 'camel' | 'pascal' | 'snake';",
662
+ "",
663
+ " constructor(options?: StandaloneDbmasonClientOptions) {",
664
+ " this.returnCase = options?.returnCase || 'camel';",
665
+ " this.pool = new Pool(options?.poolConfig || {",
666
+ " connectionString: process.env.DATABASE_URL",
667
+ " });",
668
+ " }",
669
+ "",
670
+ " protected getTableHandler<T>(tableName: string): TableMethods<T> {",
671
+ " return {",
672
+ " create: (data: Partial<T>) => this.create<T>(tableName, data),",
673
+ " read: (filter?: Partial<T>) => this.read<T>(tableName, filter),",
674
+ " update: (data: Partial<T>, filter: Partial<T>) => this.update<T>(tableName, data, filter),",
675
+ " delete: (filter: Partial<T>) => this.delete<T>(tableName, filter),",
676
+ " list: (options?: { where?: Partial<T> }) => this.read<T>(tableName, options?.where),",
677
+ " };",
678
+ " }",
679
+ "",
680
+ " async query<T extends QueryResultRow = any>(sql: string, params?: any[]): Promise<QueryResult<T>> {",
681
+ " return this.pool.query<T>(sql, params);",
682
+ " }",
683
+ "",
684
+ " async sql<T extends QueryResultRow = any>(text: string, params?: any[]): Promise<T[]> {",
685
+ " const result = await this.pool.query<T>(text, params);",
686
+ " return this.formatReturn(result.rows);",
687
+ " }",
688
+ "",
689
+ " async rpc<T = any>(procName: string, params?: Record<string, any>, types?: Record<string, string>, isProcedure?: boolean): Promise<T[]> {",
690
+ " const argNames = Object.keys(params || {});",
691
+ " const argValues = Object.values(params || {});",
692
+ "",
693
+ " if (argNames.length === 0) {",
694
+ " const sql = isProcedure ? `CALL ${procName}()` : `SELECT * FROM ${procName}()`;",
695
+ " const result = await this.pool.query(sql);",
696
+ " return this.formatReturn(result.rows as T[]);",
697
+ " }",
698
+ "",
699
+ " const placeholders = argNames.map((_, i) => {",
700
+ " const cast = types && argNames[i] && types[argNames[i]] ? `::${types[argNames[i]]}` : '';",
701
+ " return `$${i + 1}${cast}`;",
702
+ " }).join(', ');",
703
+ " ",
704
+ " const sql = isProcedure ? `CALL ${procName}(${placeholders})` : `SELECT * FROM ${procName}(${placeholders})`;",
705
+ " const result = await this.pool.query(sql, argValues);",
706
+ " return this.formatReturn(result.rows as T[]);",
707
+ " }",
708
+ "",
709
+ " async create<T = any>(table: string, data: Partial<T>): Promise<T[]> {",
710
+ " return this.rpc<T>(`${table}_create`, { p_input: data });",
711
+ " }",
712
+ "",
713
+ " async read<T = any>(table: string, filter: Partial<T> = {}): Promise<T[]> {",
714
+ " return this.rpc<T>(`${table}_read`, { p_filter: filter });",
715
+ " }",
716
+ "",
717
+ " async update<T = any>(table: string, data: Partial<T>, filter: Partial<T>): Promise<T[]> {",
718
+ " return this.rpc<T>(`${table}_update`, { p_input: data, p_filter: filter });",
719
+ " }",
720
+ "",
721
+ " async delete<T = any>(table: string, filter: Partial<T>): Promise<T[]> {",
722
+ " return this.rpc<T>(`${table}_delete`, { p_filter: filter });",
723
+ " }",
724
+ "",
725
+ " private formatReturn<T>(data: T): T {",
726
+ " if (this.returnCase === 'snake') return data;",
727
+ " return convertKeysDeep(data, this.returnCase) as T;",
728
+ " }",
729
+ "",
730
+ " async connect() { return Promise.resolve(); }",
731
+ " async disconnect() { return this.close(); }",
732
+ "",
733
+ " async close() {",
734
+ " await this.pool.end();",
735
+ " }",
736
+ "}",
737
+ "",
738
+ "function convertKeysDeep(obj: any, targetCase: 'camel' | 'pascal' | 'snake'): any {",
739
+ " if (Array.isArray(obj)) return obj.map(v => convertKeysDeep(v, targetCase));",
740
+ " if (obj !== null && typeof obj === 'object' && !(obj instanceof Date)) {",
741
+ " return Object.fromEntries(",
742
+ " Object.entries(obj).map(([key, value]) => [",
743
+ " convertCase(key, targetCase),",
744
+ " convertKeysDeep(value, targetCase)",
745
+ " ])",
746
+ " );",
747
+ " }",
748
+ " return obj;",
749
+ "}",
750
+ "",
751
+ "function convertCase(str: string, targetCase: 'camel' | 'pascal' | 'snake'): string {",
752
+ " const parts = str.split('_');",
753
+ " if (targetCase === 'snake') return parts.join('_');",
754
+ " if (targetCase === 'camel') return parts[0] + parts.slice(1).map(p => p.charAt(0).toUpperCase() + p.slice(1)).join('');",
755
+ " if (targetCase === 'pascal') return parts.map(p => p.charAt(0).toUpperCase() + p.slice(1)).join('');",
756
+ " return str;",
757
+ "}"
758
+ ];
759
+ async function se(i) {
760
+ const e = d.resolve(process.cwd(), i.config || "src/generated/dbmason.config.json"), o = d.resolve(process.cwd(), i.output || "src/generated-client.ts");
761
+ p.existsSync(e) || (console.error(`Metadata file not found: ${e}`), console.info('Run "dbmason generate" first to produce the metadata file.'), process.exit(1));
762
+ try {
763
+ const t = JSON.parse(p.readFileSync(e, "utf8"));
764
+ console.log(`Generating ${i.lang || "typescript"} client...`);
765
+ const s = X(t, {
766
+ lang: i.lang || "typescript"
767
+ }), n = d.dirname(o);
768
+ p.existsSync(n) || p.mkdirSync(n, { recursive: !0 }), p.writeFileSync(o, s), console.log(`Client generated successfully: ${o}`);
769
+ } catch (t) {
770
+ console.error("Client generation failed:", t.message), process.exit(1);
771
+ }
772
+ }
773
+ async function ne(i = {}) {
774
+ console.log("Starting introspection...");
775
+ const e = d.resolve(process.cwd(), "dbmason/index.ts");
776
+ p.existsSync(e) || (console.error("dbmason/index.ts not found."), process.exit(1));
777
+ const o = d.resolve(process.cwd(), "dbmason/schema.ts");
778
+ p.existsSync(o) || p.writeFileSync(o, `// Initial empty schema
779
+ `);
780
+ try {
781
+ require("ts-node").register({ transpileOnly: !0 });
782
+ const t = require(e), s = t.default || t.ctx;
783
+ let n = t.dialect;
784
+ if (!(s instanceof P) && s?.constructor?.name !== "DbmasonContext")
785
+ throw new Error("dbmason/index.ts must export a DbmasonContext.");
786
+ if (!n && s.config?.dialect && (n = s.config.dialect), !n)
787
+ throw new Error('dbmason/index.ts must export a "dialect" or pass it to DbmasonContext constructor.');
788
+ if (!n.introspector)
789
+ throw new Error(`Dialect ${n.name} does not support introspection.`);
790
+ const r = s.config?.connectionString;
791
+ if (!r)
792
+ throw new Error('DbmasonContext must have a "connectionString" configured for introspection.');
793
+ const c = await n.introspector.introspect(r), a = d.resolve(process.cwd(), "node_modules/@dbmason/core"), l = d.join(a, ".dbmason-snapshot.json");
794
+ p.existsSync(a) || p.mkdirSync(a, { recursive: !0 }), p.writeFileSync(l, JSON.stringify(c, null, 2)), console.log(`Snapshot saved to ${d.relative(process.cwd(), l)}`);
795
+ const h = oe(c), u = d.resolve(process.cwd(), "dbmason/schema.ts");
796
+ p.writeFileSync(u, h), console.log(`Schema written to ${d.relative(process.cwd(), u)}`), delete require.cache[require.resolve(u)], delete require.cache[require.resolve(e)];
797
+ const f = require(e), g = f.default || f.ctx, y = new C(g, n).analyze(), w = k.build(y);
798
+ if (p.writeFileSync(l, JSON.stringify(w, null, 2)), i.init) {
799
+ console.log("Baselining existing schema...");
800
+ const b = d.resolve(process.cwd(), s.config.paths?.migrations || "migrations");
801
+ if (!p.existsSync(b))
802
+ p.mkdirSync(b, { recursive: !0 });
803
+ else {
804
+ const z = p.readdirSync(b);
805
+ for (const E of z)
806
+ E.endsWith(".sql") && p.unlinkSync(d.join(b, E));
807
+ console.log("Cleared existing migrations.");
808
+ }
809
+ delete require.cache[require.resolve(u)], delete require.cache[require.resolve(e)];
810
+ const j = require(e), F = j.default || j.ctx, J = new D(F, n).compile(void 0), N = `${Date.now()}_init.sql`;
811
+ p.writeFileSync(d.join(b, N), J), console.log(`Created baseline migration: ${d.relative(process.cwd(), d.join(b, N))}`);
812
+ const v = n.getDriver(r);
813
+ await v.connect();
814
+ try {
815
+ await v.query(`
816
+ CREATE TABLE IF NOT EXISTS dbmason_migrations (
817
+ id SERIAL PRIMARY KEY,
818
+ name TEXT NOT NULL UNIQUE,
819
+ applied_at TIMESTAMPTZ DEFAULT NOW()
820
+ );
821
+ `), await v.query("INSERT INTO dbmason_migrations (name) VALUES ($1)", [N]), console.log("Marked baseline migration as applied in database.");
822
+ } finally {
823
+ await v.close();
824
+ }
825
+ }
826
+ } catch (t) {
827
+ console.error("Pull failed:", t.message), process.exit(1);
828
+ }
829
+ }
830
+ const m = (i) => " ".repeat(i);
831
+ function oe(i) {
832
+ const e = [], o = /* @__PURE__ */ new Set([
833
+ "defineTable",
834
+ "defineView",
835
+ "defineEnum",
836
+ "defineFunction",
837
+ "defineProcedure",
838
+ "defineTrigger",
839
+ "text",
840
+ "integer",
841
+ "boolean",
842
+ "timestamp",
843
+ "jsonb",
844
+ "uuid",
845
+ "custom"
846
+ ]);
847
+ if (e.push(`import {
848
+ ${m(1)}${Array.from(o).join(`,
849
+ ${m(1)}`)}
850
+ } from '@dbmason/postgres';`), e.push(`import ctx from './index';
851
+ `), i.types)
852
+ for (const [t, s] of Object.entries(i.types)) {
853
+ const n = s;
854
+ n.type === "enum" && e.push(`export const ${t} = defineEnum(ctx, '${t}', [${n.values?.map((r) => `'${r}'`).join(", ")}]);
855
+ `);
856
+ }
857
+ for (const [t, s] of Object.entries(i.tables)) {
858
+ if (t === "dbmason_migrations") continue;
859
+ const n = s;
860
+ e.push(`export const ${t} = defineTable(ctx, '${t}', {`), e.push(`${m(1)}columns: {`);
861
+ for (const [a, l] of Object.entries(n.columns || {})) {
862
+ const h = l;
863
+ let u = `${m(2)}${a}: `;
864
+ const f = h.type.toLowerCase();
865
+ if (f === "text" || f === "varchar" ? u += "text()" : f === "integer" || f === "int4" ? u += "integer()" : f === "boolean" || f === "bool" ? u += "boolean()" : f === "uuid" ? u += "uuid()" : f === "jsonb" ? u += "jsonb()" : f.includes("timestamp") ? u += "timestamp()" : u += `custom('${h.type}')`, h.notNull && (u += ".notNull()"), h.default) {
866
+ const g = h.default.replace(/"/g, '\\"');
867
+ u += `.default("${g}")`;
868
+ }
869
+ h.primaryKey && (u += ".primaryKey()"), e.push(`${u},`);
870
+ }
871
+ e.push(`${m(1)}},`);
872
+ const r = n.constraints || [], c = n.indexes || [];
873
+ if (r.length > 0 || c.length > 0) {
874
+ if (r.length > 0) {
875
+ e.push(`${m(1)}constraints: [`);
876
+ for (const a of r) {
877
+ const l = a;
878
+ e.push(`${m(2)}{ kind: 'Constraint', type: '${l.type}', name: '${l.name}', definition: \`${l.definition}\`, table: '${t}' },`);
879
+ }
880
+ e.push(`${m(1)}],`);
881
+ }
882
+ if (c.length > 0) {
883
+ e.push(`${m(1)}indexes: [`);
884
+ for (const a of c) {
885
+ const l = a;
886
+ e.push(`${m(2)}{ kind: 'Index', name: '${l.name}', table: '${t}', columns: ${JSON.stringify(l.columns)}, unique: ${l.unique} },`);
887
+ }
888
+ e.push(`${m(1)}],`);
889
+ }
890
+ }
891
+ e.push(`});
892
+ `);
893
+ }
894
+ if (i.views)
895
+ for (const [t, s] of Object.entries(i.views)) {
896
+ const n = s;
897
+ e.push(`export const ${t} = defineView(ctx, '${t}', \`${n.query.replace(/`/g, "\\`")}\`);
898
+ `);
899
+ }
900
+ if (i.procedures)
901
+ for (const [t, s] of Object.entries(i.procedures)) {
902
+ const n = s;
903
+ e.push(`export const ${t} = defineProcedure(ctx, '${t}', {`), e.push(`${m(1)}args: ${JSON.stringify(n.args)},`), e.push(`${m(1)}returns: '${n.returns}',`), e.push(`${m(1)}language: '${n.language}',`), e.push(`${m(1)}body: \`${n.body.replace(/`/g, "\\`")}\``), e.push(`});
904
+ `);
905
+ }
906
+ if (i.functions)
907
+ for (const [t, s] of Object.entries(i.functions)) {
908
+ const n = s;
909
+ e.push(`export const ${t} = defineFunction(ctx, '${t}', {`), e.push(`${m(1)}args: ${JSON.stringify(n.args)},`), e.push(`${m(1)}returns: '${n.returns}',`), e.push(`${m(1)}language: '${n.language}',`), e.push(`${m(1)}body: \`${n.body.replace(/`/g, "\\`")}\``), e.push(`});
910
+ `);
911
+ }
912
+ if (i.triggers)
913
+ for (const [t, s] of Object.entries(i.triggers)) {
914
+ const n = s;
915
+ e.push(`export const ${t} = defineTrigger(ctx, '${n.table}', '${t}', {`), e.push(`${m(1)}events: ${JSON.stringify(n.events)},`), e.push(`${m(1)}procedure: '${n.functionName}',`), e.push(`${m(1)}when: '${n.when}',`), e.push(`${m(1)}forEach: '${n.forEach}'`), e.push(`});
916
+ `);
917
+ }
918
+ return e.join(`
919
+ `);
920
+ }
921
+ const $ = new I();
922
+ $.command("pull").description("Introspect database and generate schema").option("--init", "Initialize migration history and create a baseline migration").action((i) => ne(i));
923
+ $.name("dbmason").description("Dbmason Database Management CLI").version("0.2.0");
924
+ $.command("init <projectName>").description("Initialize a new PDK project").option("-t, --template <name>", "Project template to use", "auth.cli.template").action((i, e) => W(i, e));
925
+ $.command("generate [name]").description("Generate migration files").option("--allow-destructive", "Allow generated migrations to include destructive operations").option("-d, --dry", "Dry run (log SQL but do not write files)").action((i, e) => K(i, e));
926
+ $.command("migrate").description("Apply migrations to the database").action((i) => Y(i));
927
+ $.command("client").description("Generate a type-safe database client").option("-c, --config <path>", "Path to dbmason.metadata.json", "dbmason.metadata.json").option("-l, --lang <language>", "Target language (typescript)", "typescript").option("-o, --output <path>", "Output file path", "src/generated-client.ts").action((i) => se(i));
928
+ $.parse(process.argv);
929
+ //# sourceMappingURL=index.mjs.map