-
Notifications
You must be signed in to change notification settings - Fork 47
Expand file tree
/
Copy pathgenerate.ts
More file actions
122 lines (111 loc) · 3.11 KB
/
Copy pathgenerate.ts
File metadata and controls
122 lines (111 loc) · 3.11 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as zg from "zapatos/generate"
import {
getConnectionStringFromEnv,
getPgConnectionFromEnv,
} from "pg-connection-from-env"
import { Context } from "./get-project-context"
import { dumpTree } from "pg-schema-dump"
import path from "path"
import { migrate } from "./migrate"
export const generate = async ({
schemas,
defaultDatabase,
dbDir,
pglite = true,
migrationsDir,
}: Pick<Context, "schemas" | "defaultDatabase" | "dbDir"> & {
pglite?: boolean
migrationsDir?: string
}) => {
dbDir = dbDir ?? "./src/db"
migrationsDir = migrationsDir ?? path.join(dbDir, "migrations")
if (pglite) {
const { PGlite } = await import("@electric-sql/pglite")
const { fromNodeSocket } = await import("pg-gateway/node")
const net = await import("node:net")
const db = new PGlite()
await migrate({
client: db as any,
migrationsDir,
defaultDatabase,
cwd: process.cwd(),
schemas,
})
const server = net.createServer(async (socket) => {
const connection = await fromNodeSocket(socket, {
serverVersion: "16.3 (PGlite)",
auth: {
method: "password",
validateCredentials: ({ username, password }: any) =>
username === "postgres" && password === "postgres",
getClearTextPassword: () => "postgres",
},
async onStartup() {
await (db as any).waitReady
},
async onMessage(data: Uint8Array, { isAuthenticated }: any) {
if (!isAuthenticated) return
try {
const { data: responseData } = await (db as any).execProtocol(data)
return responseData
} catch {
return undefined
}
},
})
})
await new Promise<void>((resolve) => server.listen(0, resolve))
const port = (server.address() as any).port
const connectionString = `postgres://postgres:postgres@127.0.0.1:${port}/postgres`
const prevDbUrl = process.env.DATABASE_URL
process.env.DATABASE_URL = connectionString
try {
await zg.generate({
db: {
connectionString,
},
schemas: Object.fromEntries(
schemas.map((s) => [s, { include: "*", exclude: [] }]),
),
outDir: dbDir,
})
await dumpTree({
targetDir: path.join(dbDir, "structure"),
defaultDatabase: "postgres",
schemas,
})
} finally {
await new Promise<void>((resolve, reject) => {
server.close((err) => (err ? reject(err) : resolve()))
})
await db.close()
if (prevDbUrl === undefined) delete process.env.DATABASE_URL
else process.env.DATABASE_URL = prevDbUrl
}
return
}
await zg.generate({
db: {
connectionString: getConnectionStringFromEnv({
fallbackDefaults: {
database: defaultDatabase,
},
}),
},
schemas: Object.fromEntries(
schemas.map((s) => [
s,
{
include: "*",
exclude: [],
},
]),
),
outDir: dbDir,
})
await dumpTree({
targetDir: path.join(dbDir, "structure"),
defaultDatabase,
schemas,
})
}