@rfjs/pg-toolkit 0.0.7 → 0.0.8-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rfjs/pg-toolkit",
3
- "version": "0.0.7",
3
+ "version": "0.0.8-alpha.0",
4
4
  "description": "Shared PostgreSQL utilities and management scripts for Drizzle, Prisma, Kysely, and TypeORM",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",
@@ -59,7 +59,6 @@
59
59
  "eslint": "^9.20.1",
60
60
  "eslint-config-prettier": "^10.0.1",
61
61
  "husky": "^9.1.7",
62
- "inquirer": "9",
63
62
  "lint-staged": "^15.4.3",
64
63
  "prettier": "^3.5.1",
65
64
  "rimraf": "^6.0.1",
@@ -77,10 +76,10 @@
77
76
  "tslib": "^2.8.1"
78
77
  },
79
78
  "scripts": {
80
- "clean": "pnpm --parallel clean:dist clean:types",
79
+ "clean": "pnpm --filter . --parallel clean:dist clean:types",
81
80
  "clean:types": "pnpm exec rimraf ./types",
82
81
  "clean:dist": "pnpm exec rimraf ./dist",
83
- "dev": "pnpm --parallel dev:tsdown typecheck:watch",
82
+ "dev": "pnpm --filter . --parallel dev:tsdown typecheck:watch",
84
83
  "dev:tsdown": "npm run clean && tsdown --config-loader unrun --watch",
85
84
  "build": "npm run build:tsdown",
86
85
  "build:tsdown": "npm run clean && tsdown --config-loader unrun",
@@ -1,33 +0,0 @@
1
- import { Client, Pool } from "pg";
2
-
3
- //#region src/admin/ensure-db.d.ts
4
- declare function checkAndCreateDB(connectionString: string): Promise<void>;
5
- //#endregion
6
- //#region src/admin/ensure-schema.d.ts
7
- declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
8
- //#endregion
9
- //#region src/admin/seed-history.d.ts
10
- /**
11
- * 確保種子資料歷史紀錄表存在
12
- * @param client PG Client 或 Pool
13
- * @param tableName 資料表名稱 (預設: __seed_history)
14
- */
15
- declare function ensureSeedHistoryTable(client: Client | Pool, tableName?: string): Promise<void>;
16
- /**
17
- * 檢查種子資料是否已執行過
18
- * @param client PG Client 或 Pool
19
- * @param name 種子資料名稱
20
- * @param tableName 資料表名稱 (預設: __seed_history)
21
- * @returns 是否已執行
22
- */
23
- declare function checkSeedExecuted(client: Client | Pool, name: string, tableName?: string): Promise<boolean>;
24
- /**
25
- * 紀錄種子資料執行紀錄
26
- * @param client PG Client 或 Pool
27
- * @param name 種子資料名稱
28
- * @param tableName 資料表名稱 (預設: __seed_history)
29
- */
30
- declare function recordSeedExecution(client: Client | Pool, name: string, tableName?: string): Promise<void>;
31
- //#endregion
32
- export { checkAndCreateDB, checkAndCreateSchema, checkSeedExecuted, ensureSeedHistoryTable, recordSeedExecution };
33
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts","../../src/admin/seed-history.ts"],"sourcesContent":[],"mappings":";;;iBAGsB,gBAAA,4BAA4C;;;iBCD5C,oBAAA,+CAGnB;;;;;ADFH;;;iBEMsB,sBAAA,SACZ,SAAS,2BAEhB;ADVH;;;;ACOA;;;AAGG,iBAiBmB,iBAAA,CAjBnB,MAAA,EAkBO,MAlBP,GAkBgB,IAlBhB,EAAA,IAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAqBA,OArBA,CAAA,OAAA,CAAA;;AAiBH;;;;;AAiBsB,iBAAA,mBAAA,CAAA,MAAA,EACZ,MADY,GACH,IADG,EAAA,IAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAInB,OAJmB,CAAA,IAAA,CAAA"}
@@ -1,33 +0,0 @@
1
- import { Client, Pool } from "pg";
2
-
3
- //#region src/admin/ensure-db.d.ts
4
- declare function checkAndCreateDB(connectionString: string): Promise<void>;
5
- //#endregion
6
- //#region src/admin/ensure-schema.d.ts
7
- declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
8
- //#endregion
9
- //#region src/admin/seed-history.d.ts
10
- /**
11
- * 確保種子資料歷史紀錄表存在
12
- * @param client PG Client 或 Pool
13
- * @param tableName 資料表名稱 (預設: __seed_history)
14
- */
15
- declare function ensureSeedHistoryTable(client: Client | Pool, tableName?: string): Promise<void>;
16
- /**
17
- * 檢查種子資料是否已執行過
18
- * @param client PG Client 或 Pool
19
- * @param name 種子資料名稱
20
- * @param tableName 資料表名稱 (預設: __seed_history)
21
- * @returns 是否已執行
22
- */
23
- declare function checkSeedExecuted(client: Client | Pool, name: string, tableName?: string): Promise<boolean>;
24
- /**
25
- * 紀錄種子資料執行紀錄
26
- * @param client PG Client 或 Pool
27
- * @param name 種子資料名稱
28
- * @param tableName 資料表名稱 (預設: __seed_history)
29
- */
30
- declare function recordSeedExecution(client: Client | Pool, name: string, tableName?: string): Promise<void>;
31
- //#endregion
32
- export { checkAndCreateDB, checkAndCreateSchema, checkSeedExecuted, ensureSeedHistoryTable, recordSeedExecution };
33
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts","../../src/admin/seed-history.ts"],"sourcesContent":[],"mappings":";;;iBAGsB,gBAAA,4BAA4C;;;iBCD5C,oBAAA,+CAGnB;;;;;ADFH;;;iBEMsB,sBAAA,SACZ,SAAS,2BAEhB;ADVH;;;;ACOA;;;AAGG,iBAiBmB,iBAAA,CAjBnB,MAAA,EAkBO,MAlBP,GAkBgB,IAlBhB,EAAA,IAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAqBA,OArBA,CAAA,OAAA,CAAA;;AAiBH;;;;;AAiBsB,iBAAA,mBAAA,CAAA,MAAA,EACZ,MADY,GACH,IADG,EAAA,IAAA,EAAA,MAAA,EAAA,SAAA,CAAA,EAAA,MAAA,CAAA,EAInB,OAJmB,CAAA,IAAA,CAAA"}
@@ -1,87 +0,0 @@
1
- let pg_connection_string = require("pg-connection-string");
2
- let pg = require("pg");
3
-
4
- //#region src/admin/ensure-db.ts
5
- async function checkAndCreateDB(connectionString) {
6
- const { user, password, host, port, database } = (0, pg_connection_string.parse)(connectionString);
7
- const adminConnectionString = `postgres://${user}:${password}@${host}:${port}/postgres`;
8
- const targetDb = database ?? "orm";
9
- const client = new pg.Client({ connectionString: adminConnectionString });
10
- let isConnected = false;
11
- try {
12
- await client.connect();
13
- isConnected = true;
14
- if ((await client.query(`SELECT 1 FROM pg_database WHERE datname = $1`, [targetDb])).rowCount === 0) {
15
- console.log(`Database "${targetDb}" does not exist. Creating...`);
16
- await client.query(`CREATE DATABASE "${targetDb}"`);
17
- console.log(`Database "${targetDb}" created successfully.`);
18
- }
19
- } catch (error) {
20
- console.error(`Failed to ensure database exists: ${error}`);
21
- throw error;
22
- } finally {
23
- if (isConnected) await client.end();
24
- }
25
- }
26
-
27
- //#endregion
28
- //#region src/admin/ensure-schema.ts
29
- async function checkAndCreateSchema(connectionString, schemas) {
30
- const client = new pg.Client(connectionString);
31
- let isConnected = false;
32
- try {
33
- await client.connect();
34
- isConnected = true;
35
- for (const schema of schemas) await client.query(`CREATE SCHEMA IF NOT EXISTS "${schema}"`);
36
- } catch (error) {
37
- console.error(`Failed to ensure schema exists: ${error}`);
38
- throw error;
39
- } finally {
40
- if (isConnected) await client.end();
41
- }
42
- }
43
-
44
- //#endregion
45
- //#region src/admin/seed-history.ts
46
- const DEFAULT_TABLE_NAME = "__seed_history";
47
- /**
48
- * 確保種子資料歷史紀錄表存在
49
- * @param client PG Client 或 Pool
50
- * @param tableName 資料表名稱 (預設: __seed_history)
51
- */
52
- async function ensureSeedHistoryTable(client, tableName = DEFAULT_TABLE_NAME) {
53
- await client.query(`
54
- CREATE TABLE IF NOT EXISTS "${tableName}" (
55
- "id" SERIAL PRIMARY KEY,
56
- "name" VARCHAR(255) NOT NULL UNIQUE,
57
- "executed_at" TIMESTAMPTZ DEFAULT NOW()
58
- );
59
- `);
60
- }
61
- /**
62
- * 檢查種子資料是否已執行過
63
- * @param client PG Client 或 Pool
64
- * @param name 種子資料名稱
65
- * @param tableName 資料表名稱 (預設: __seed_history)
66
- * @returns 是否已執行
67
- */
68
- async function checkSeedExecuted(client, name, tableName = DEFAULT_TABLE_NAME) {
69
- return ((await client.query(`SELECT 1 FROM "${tableName}" WHERE "name" = $1`, [name])).rowCount ?? 0) > 0;
70
- }
71
- /**
72
- * 紀錄種子資料執行紀錄
73
- * @param client PG Client 或 Pool
74
- * @param name 種子資料名稱
75
- * @param tableName 資料表名稱 (預設: __seed_history)
76
- */
77
- async function recordSeedExecution(client, name, tableName = DEFAULT_TABLE_NAME) {
78
- await client.query(`INSERT INTO "${tableName}" ("name") VALUES ($1)`, [name]);
79
- }
80
-
81
- //#endregion
82
- exports.checkAndCreateDB = checkAndCreateDB;
83
- exports.checkAndCreateSchema = checkAndCreateSchema;
84
- exports.checkSeedExecuted = checkSeedExecuted;
85
- exports.ensureSeedHistoryTable = ensureSeedHistoryTable;
86
- exports.recordSeedExecution = recordSeedExecution;
87
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":["Client","Client"],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts","../../src/admin/seed-history.ts"],"sourcesContent":["import { Client } from 'pg';\nimport { parse } from 'pg-connection-string';\n\nexport async function checkAndCreateDB(connectionString: string): Promise<void> {\n // Use pg-connection-string for more robust parsing and to generate admin connection string\n // Default fallback\n const config = parse(connectionString);\n const { user, password, host, port, database } = config;\n const adminConnectionString = `postgres://${user}:${password}@${host}:${port}/postgres`;\n const targetDb = database ?? 'orm';\n const client = new Client({\n connectionString: adminConnectionString,\n });\n let isConnected = false;\n\n try {\n await client.connect();\n isConnected = true;\n const res = await client.query(`SELECT 1 FROM pg_database WHERE datname = $1`, [\n targetDb,\n ]);\n\n if (res.rowCount === 0) {\n console.log(`Database \"${targetDb}\" does not exist. Creating...`);\n await client.query(`CREATE DATABASE \"${targetDb}\"`);\n console.log(`Database \"${targetDb}\" created successfully.`);\n }\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`Failed to ensure database exists: ${error}`);\n throw error;\n } finally {\n if (isConnected) {\n await client.end();\n }\n }\n}\n","import { Client } from 'pg';\n\nexport async function checkAndCreateSchema(\n connectionString: string,\n schemas: string[],\n): Promise<void> {\n const client = new Client(connectionString);\n let isConnected = false;\n\n try {\n await client.connect();\n isConnected = true;\n for (const schema of schemas) {\n await client.query(`CREATE SCHEMA IF NOT EXISTS \"${schema}\"`);\n }\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`Failed to ensure schema exists: ${error}`);\n throw error;\n } finally {\n if (isConnected) {\n await client.end();\n }\n }\n}\n","import { Client, Pool } from 'pg';\n\nconst DEFAULT_TABLE_NAME = '__seed_history';\n\n/**\n * 確保種子資料歷史紀錄表存在\n * @param client PG Client 或 Pool\n * @param tableName 資料表名稱 (預設: __seed_history)\n */\nexport async function ensureSeedHistoryTable(\n client: Client | Pool,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<void> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS \"${tableName}\" (\n \"id\" SERIAL PRIMARY KEY,\n \"name\" VARCHAR(255) NOT NULL UNIQUE,\n \"executed_at\" TIMESTAMPTZ DEFAULT NOW()\n );\n `);\n}\n\n/**\n * 檢查種子資料是否已執行過\n * @param client PG Client 或 Pool\n * @param name 種子資料名稱\n * @param tableName 資料表名稱 (預設: __seed_history)\n * @returns 是否已執行\n */\nexport async function checkSeedExecuted(\n client: Client | Pool,\n name: string,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<boolean> {\n const res = await client.query(`SELECT 1 FROM \"${tableName}\" WHERE \"name\" = $1`, [\n name,\n ]);\n return (res.rowCount ?? 0) > 0;\n}\n\n/**\n * 紀錄種子資料執行紀錄\n * @param client PG Client 或 Pool\n * @param name 種子資料名稱\n * @param tableName 資料表名稱 (預設: __seed_history)\n */\nexport async function recordSeedExecution(\n client: Client | Pool,\n name: string,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<void> {\n await client.query(`INSERT INTO \"${tableName}\" (\"name\") VALUES ($1)`, [name]);\n}\n"],"mappings":";;;;AAGA,eAAsB,iBAAiB,kBAAyC;CAI9E,MAAM,EAAE,MAAM,UAAU,MAAM,MAAM,6CADf,iBAAiB;CAEtC,MAAM,wBAAwB,cAAc,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK;CAC7E,MAAM,WAAW,YAAY;CAC7B,MAAM,SAAS,IAAIA,UAAO,EACxB,kBAAkB,uBACnB,CAAC;CACF,IAAI,cAAc;AAElB,KAAI;AACF,QAAM,OAAO,SAAS;AACtB,gBAAc;AAKd,OAJY,MAAM,OAAO,MAAM,gDAAgD,CAC7E,SACD,CAAC,EAEM,aAAa,GAAG;AACtB,WAAQ,IAAI,aAAa,SAAS,+BAA+B;AACjE,SAAM,OAAO,MAAM,oBAAoB,SAAS,GAAG;AACnD,WAAQ,IAAI,aAAa,SAAS,yBAAyB;;UAEtD,OAAO;AAEd,UAAQ,MAAM,qCAAqC,QAAQ;AAC3D,QAAM;WACE;AACR,MAAI,YACF,OAAM,OAAO,KAAK;;;;;;AC/BxB,eAAsB,qBACpB,kBACA,SACe;CACf,MAAM,SAAS,IAAIC,UAAO,iBAAiB;CAC3C,IAAI,cAAc;AAElB,KAAI;AACF,QAAM,OAAO,SAAS;AACtB,gBAAc;AACd,OAAK,MAAM,UAAU,QACnB,OAAM,OAAO,MAAM,gCAAgC,OAAO,GAAG;UAExD,OAAO;AAEd,UAAQ,MAAM,mCAAmC,QAAQ;AACzD,QAAM;WACE;AACR,MAAI,YACF,OAAM,OAAO,KAAK;;;;;;ACnBxB,MAAM,qBAAqB;;;;;;AAO3B,eAAsB,uBACpB,QACA,YAAoB,oBACL;AACf,OAAM,OAAO,MAAM;kCACa,UAAU;;;;;IAKxC;;;;;;;;;AAUJ,eAAsB,kBACpB,QACA,MACA,YAAoB,oBACF;AAIlB,UAHY,MAAM,OAAO,MAAM,kBAAkB,UAAU,sBAAsB,CAC/E,KACD,CAAC,EACU,YAAY,KAAK;;;;;;;;AAS/B,eAAsB,oBACpB,QACA,MACA,YAAoB,oBACL;AACf,OAAM,OAAO,MAAM,gBAAgB,UAAU,yBAAyB,CAAC,KAAK,CAAC"}
@@ -1,83 +0,0 @@
1
- import { parse } from "pg-connection-string";
2
- import { Client } from "pg";
3
-
4
- //#region src/admin/ensure-db.ts
5
- async function checkAndCreateDB(connectionString) {
6
- const { user, password, host, port, database } = parse(connectionString);
7
- const adminConnectionString = `postgres://${user}:${password}@${host}:${port}/postgres`;
8
- const targetDb = database ?? "orm";
9
- const client = new Client({ connectionString: adminConnectionString });
10
- let isConnected = false;
11
- try {
12
- await client.connect();
13
- isConnected = true;
14
- if ((await client.query(`SELECT 1 FROM pg_database WHERE datname = $1`, [targetDb])).rowCount === 0) {
15
- console.log(`Database "${targetDb}" does not exist. Creating...`);
16
- await client.query(`CREATE DATABASE "${targetDb}"`);
17
- console.log(`Database "${targetDb}" created successfully.`);
18
- }
19
- } catch (error) {
20
- console.error(`Failed to ensure database exists: ${error}`);
21
- throw error;
22
- } finally {
23
- if (isConnected) await client.end();
24
- }
25
- }
26
-
27
- //#endregion
28
- //#region src/admin/ensure-schema.ts
29
- async function checkAndCreateSchema(connectionString, schemas) {
30
- const client = new Client(connectionString);
31
- let isConnected = false;
32
- try {
33
- await client.connect();
34
- isConnected = true;
35
- for (const schema of schemas) await client.query(`CREATE SCHEMA IF NOT EXISTS "${schema}"`);
36
- } catch (error) {
37
- console.error(`Failed to ensure schema exists: ${error}`);
38
- throw error;
39
- } finally {
40
- if (isConnected) await client.end();
41
- }
42
- }
43
-
44
- //#endregion
45
- //#region src/admin/seed-history.ts
46
- const DEFAULT_TABLE_NAME = "__seed_history";
47
- /**
48
- * 確保種子資料歷史紀錄表存在
49
- * @param client PG Client 或 Pool
50
- * @param tableName 資料表名稱 (預設: __seed_history)
51
- */
52
- async function ensureSeedHistoryTable(client, tableName = DEFAULT_TABLE_NAME) {
53
- await client.query(`
54
- CREATE TABLE IF NOT EXISTS "${tableName}" (
55
- "id" SERIAL PRIMARY KEY,
56
- "name" VARCHAR(255) NOT NULL UNIQUE,
57
- "executed_at" TIMESTAMPTZ DEFAULT NOW()
58
- );
59
- `);
60
- }
61
- /**
62
- * 檢查種子資料是否已執行過
63
- * @param client PG Client 或 Pool
64
- * @param name 種子資料名稱
65
- * @param tableName 資料表名稱 (預設: __seed_history)
66
- * @returns 是否已執行
67
- */
68
- async function checkSeedExecuted(client, name, tableName = DEFAULT_TABLE_NAME) {
69
- return ((await client.query(`SELECT 1 FROM "${tableName}" WHERE "name" = $1`, [name])).rowCount ?? 0) > 0;
70
- }
71
- /**
72
- * 紀錄種子資料執行紀錄
73
- * @param client PG Client 或 Pool
74
- * @param name 種子資料名稱
75
- * @param tableName 資料表名稱 (預設: __seed_history)
76
- */
77
- async function recordSeedExecution(client, name, tableName = DEFAULT_TABLE_NAME) {
78
- await client.query(`INSERT INTO "${tableName}" ("name") VALUES ($1)`, [name]);
79
- }
80
-
81
- //#endregion
82
- export { checkAndCreateDB, checkAndCreateSchema, checkSeedExecuted, ensureSeedHistoryTable, recordSeedExecution };
83
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts","../../src/admin/seed-history.ts"],"sourcesContent":["import { Client } from 'pg';\nimport { parse } from 'pg-connection-string';\n\nexport async function checkAndCreateDB(connectionString: string): Promise<void> {\n // Use pg-connection-string for more robust parsing and to generate admin connection string\n // Default fallback\n const config = parse(connectionString);\n const { user, password, host, port, database } = config;\n const adminConnectionString = `postgres://${user}:${password}@${host}:${port}/postgres`;\n const targetDb = database ?? 'orm';\n const client = new Client({\n connectionString: adminConnectionString,\n });\n let isConnected = false;\n\n try {\n await client.connect();\n isConnected = true;\n const res = await client.query(`SELECT 1 FROM pg_database WHERE datname = $1`, [\n targetDb,\n ]);\n\n if (res.rowCount === 0) {\n console.log(`Database \"${targetDb}\" does not exist. Creating...`);\n await client.query(`CREATE DATABASE \"${targetDb}\"`);\n console.log(`Database \"${targetDb}\" created successfully.`);\n }\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`Failed to ensure database exists: ${error}`);\n throw error;\n } finally {\n if (isConnected) {\n await client.end();\n }\n }\n}\n","import { Client } from 'pg';\n\nexport async function checkAndCreateSchema(\n connectionString: string,\n schemas: string[],\n): Promise<void> {\n const client = new Client(connectionString);\n let isConnected = false;\n\n try {\n await client.connect();\n isConnected = true;\n for (const schema of schemas) {\n await client.query(`CREATE SCHEMA IF NOT EXISTS \"${schema}\"`);\n }\n } catch (error) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n console.error(`Failed to ensure schema exists: ${error}`);\n throw error;\n } finally {\n if (isConnected) {\n await client.end();\n }\n }\n}\n","import { Client, Pool } from 'pg';\n\nconst DEFAULT_TABLE_NAME = '__seed_history';\n\n/**\n * 確保種子資料歷史紀錄表存在\n * @param client PG Client 或 Pool\n * @param tableName 資料表名稱 (預設: __seed_history)\n */\nexport async function ensureSeedHistoryTable(\n client: Client | Pool,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<void> {\n await client.query(`\n CREATE TABLE IF NOT EXISTS \"${tableName}\" (\n \"id\" SERIAL PRIMARY KEY,\n \"name\" VARCHAR(255) NOT NULL UNIQUE,\n \"executed_at\" TIMESTAMPTZ DEFAULT NOW()\n );\n `);\n}\n\n/**\n * 檢查種子資料是否已執行過\n * @param client PG Client 或 Pool\n * @param name 種子資料名稱\n * @param tableName 資料表名稱 (預設: __seed_history)\n * @returns 是否已執行\n */\nexport async function checkSeedExecuted(\n client: Client | Pool,\n name: string,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<boolean> {\n const res = await client.query(`SELECT 1 FROM \"${tableName}\" WHERE \"name\" = $1`, [\n name,\n ]);\n return (res.rowCount ?? 0) > 0;\n}\n\n/**\n * 紀錄種子資料執行紀錄\n * @param client PG Client 或 Pool\n * @param name 種子資料名稱\n * @param tableName 資料表名稱 (預設: __seed_history)\n */\nexport async function recordSeedExecution(\n client: Client | Pool,\n name: string,\n tableName: string = DEFAULT_TABLE_NAME,\n): Promise<void> {\n await client.query(`INSERT INTO \"${tableName}\" (\"name\") VALUES ($1)`, [name]);\n}\n"],"mappings":";;;;AAGA,eAAsB,iBAAiB,kBAAyC;CAI9E,MAAM,EAAE,MAAM,UAAU,MAAM,MAAM,aADrB,MAAM,iBAAiB;CAEtC,MAAM,wBAAwB,cAAc,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK;CAC7E,MAAM,WAAW,YAAY;CAC7B,MAAM,SAAS,IAAI,OAAO,EACxB,kBAAkB,uBACnB,CAAC;CACF,IAAI,cAAc;AAElB,KAAI;AACF,QAAM,OAAO,SAAS;AACtB,gBAAc;AAKd,OAJY,MAAM,OAAO,MAAM,gDAAgD,CAC7E,SACD,CAAC,EAEM,aAAa,GAAG;AACtB,WAAQ,IAAI,aAAa,SAAS,+BAA+B;AACjE,SAAM,OAAO,MAAM,oBAAoB,SAAS,GAAG;AACnD,WAAQ,IAAI,aAAa,SAAS,yBAAyB;;UAEtD,OAAO;AAEd,UAAQ,MAAM,qCAAqC,QAAQ;AAC3D,QAAM;WACE;AACR,MAAI,YACF,OAAM,OAAO,KAAK;;;;;;AC/BxB,eAAsB,qBACpB,kBACA,SACe;CACf,MAAM,SAAS,IAAI,OAAO,iBAAiB;CAC3C,IAAI,cAAc;AAElB,KAAI;AACF,QAAM,OAAO,SAAS;AACtB,gBAAc;AACd,OAAK,MAAM,UAAU,QACnB,OAAM,OAAO,MAAM,gCAAgC,OAAO,GAAG;UAExD,OAAO;AAEd,UAAQ,MAAM,mCAAmC,QAAQ;AACzD,QAAM;WACE;AACR,MAAI,YACF,OAAM,OAAO,KAAK;;;;;;ACnBxB,MAAM,qBAAqB;;;;;;AAO3B,eAAsB,uBACpB,QACA,YAAoB,oBACL;AACf,OAAM,OAAO,MAAM;kCACa,UAAU;;;;;IAKxC;;;;;;;;;AAUJ,eAAsB,kBACpB,QACA,MACA,YAAoB,oBACF;AAIlB,UAHY,MAAM,OAAO,MAAM,kBAAkB,UAAU,sBAAsB,CAC/E,KACD,CAAC,EACU,YAAY,KAAK;;;;;;;;AAS/B,eAAsB,oBACpB,QACA,MACA,YAAoB,oBACL;AACf,OAAM,OAAO,MAAM,gBAAgB,UAAU,yBAAyB,CAAC,KAAK,CAAC"}
package/dist/index.d.mts DELETED
@@ -1,19 +0,0 @@
1
- //#region src/pure/options.d.ts
2
- /**
3
- * 從 options 解析 search_path
4
- * 支援:
5
- * -c search_path=a,b
6
- * -csearch_path=a,b (防呆,但會 normalize)
7
- */
8
- declare function getOptionsSchemas(options?: string): string[];
9
- //#endregion
10
- //#region src/pure/connection-string.d.ts
11
- declare function getConnectionStringInfo(connectionString: string, targetSchema?: string): {
12
- finalConnectionString: string;
13
- finalSchema: string;
14
- optionsSchemas: string[];
15
- hasSearchPath: boolean;
16
- };
17
- //#endregion
18
- export { getConnectionStringInfo, getOptionsSchemas };
19
- //# sourceMappingURL=index.d.mts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/pure/options.ts","../src/pure/connection-string.ts"],"sourcesContent":[],"mappings":";;AAMA;;;;ACQA;iBDRgB,iBAAA;;;iBCQA,uBAAA;EDRhB,qBAAgB,EAAA,MAAA;;;;ACQhB,CAAA"}
package/dist/index.d.ts DELETED
@@ -1,19 +0,0 @@
1
- //#region src/pure/options.d.ts
2
- /**
3
- * 從 options 解析 search_path
4
- * 支援:
5
- * -c search_path=a,b
6
- * -csearch_path=a,b (防呆,但會 normalize)
7
- */
8
- declare function getOptionsSchemas(options?: string): string[];
9
- //#endregion
10
- //#region src/pure/connection-string.d.ts
11
- declare function getConnectionStringInfo(connectionString: string, targetSchema?: string): {
12
- finalConnectionString: string;
13
- finalSchema: string;
14
- optionsSchemas: string[];
15
- hasSearchPath: boolean;
16
- };
17
- //#endregion
18
- export { getConnectionStringInfo, getOptionsSchemas };
19
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/pure/options.ts","../src/pure/connection-string.ts"],"sourcesContent":[],"mappings":";;AAMA;;;;ACQA;iBDRgB,iBAAA;;;iBCQA,uBAAA;EDRhB,qBAAgB,EAAA,MAAA;;;;ACQhB,CAAA"}
package/dist/index.js DELETED
@@ -1,51 +0,0 @@
1
- let pg_connection_string = require("pg-connection-string");
2
-
3
- //#region src/pure/options.ts
4
- /**
5
- * 從 options 解析 search_path
6
- * 支援:
7
- * -c search_path=a,b
8
- * -csearch_path=a,b (防呆,但會 normalize)
9
- */
10
- function getOptionsSchemas(options) {
11
- if (!options) return [];
12
- const m = options.replace(/-csearch_path=/g, "-c search_path=").match(/(?:^|\s)search_path=([^\s]+)/);
13
- if (!m) return [];
14
- return m[1].split(",").map((s) => s.trim()).filter(Boolean);
15
- }
16
-
17
- //#endregion
18
- //#region src/pure/connection-string.ts
19
- function buildSearchPathOption(schema) {
20
- return `-c search_path=${schema}`;
21
- }
22
- function mergeOptions(existing, schema) {
23
- if (getOptionsSchemas(existing).length > 0) return existing ?? "";
24
- const add = buildSearchPathOption(schema);
25
- return existing && existing.trim() ? `${existing.trim()} ${add}` : add;
26
- }
27
- function getConnectionStringInfo(connectionString, targetSchema) {
28
- const config = (0, pg_connection_string.parse)(connectionString);
29
- const url = new URL(connectionString);
30
- const options = url.searchParams.get("options") ?? config.options ?? void 0;
31
- const optionsSchemas = getOptionsSchemas(options);
32
- const hasSearchPath = optionsSchemas.length > 0;
33
- const schemaParam = url.searchParams.get("schema") ?? void 0;
34
- const finalSchema = optionsSchemas[0] ?? schemaParam ?? targetSchema ?? "public";
35
- if (!hasSearchPath && finalSchema !== "public") {
36
- const merged = mergeOptions(options, finalSchema);
37
- url.searchParams.set("options", merged);
38
- }
39
- if (!schemaParam && optionsSchemas.length > 0) url.searchParams.set("schema", optionsSchemas[0]);
40
- return {
41
- optionsSchemas,
42
- finalSchema,
43
- finalConnectionString: url.toString(),
44
- hasSearchPath
45
- };
46
- }
47
-
48
- //#endregion
49
- exports.getConnectionStringInfo = getConnectionStringInfo;
50
- exports.getOptionsSchemas = getOptionsSchemas;
51
- //# sourceMappingURL=index.js.map
package/dist/index.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/pure/options.ts","../src/pure/connection-string.ts"],"sourcesContent":["/**\n * 從 options 解析 search_path\n * 支援:\n * -c search_path=a,b\n * -csearch_path=a,b (防呆,但會 normalize)\n */\nexport function getOptionsSchemas(options?: string): string[] {\n if (!options) return [];\n\n // normalize: -csearch_path -> -c search_path\n const normalized = options.replace(/-csearch_path=/g, '-c search_path=');\n\n // match: search_path=a,b (到空白結束)\n const m = normalized.match(/(?:^|\\s)search_path=([^\\s]+)/);\n if (!m) return [];\n\n return m[1]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n","import { parse } from 'pg-connection-string';\nimport { getOptionsSchemas } from './options';\n\nfunction buildSearchPathOption(schema: string): string {\n return `-c search_path=${schema}`;\n}\n\nfunction mergeOptions(existing: string | undefined, schema: string): string {\n const schemas = getOptionsSchemas(existing);\n if (schemas.length > 0) return existing ?? '';\n const add = buildSearchPathOption(schema);\n return existing && existing.trim() ? `${existing.trim()} ${add}` : add;\n}\n\nexport function getConnectionStringInfo(\n connectionString: string,\n targetSchema?: string,\n): {\n finalConnectionString: string;\n finalSchema: string;\n optionsSchemas: string[];\n hasSearchPath: boolean;\n} {\n const config = parse(connectionString);\n const url = new URL(connectionString);\n\n // 這裡拿到的 options **是 decode 後的字串**(例如 \"-c search_path=prisma_test\")\n const options = url.searchParams.get('options') ?? config.options ?? undefined;\n\n const optionsSchemas = getOptionsSchemas(options);\n const hasSearchPath = optionsSchemas.length > 0;\n\n const schemaParam = url.searchParams.get('schema') ?? undefined;\n\n // options search_path > schema param > targetSchema > public\n const finalSchema = optionsSchemas[0] ?? schemaParam ?? targetSchema ?? 'public';\n\n // (1) 有 schema,沒 search_path → 補 options\n if (!hasSearchPath && finalSchema !== 'public') {\n const merged = mergeOptions(options, finalSchema);\n // ✅ 不要 encodeURIComponent,URLSearchParams 會自動處理\n url.searchParams.set('options', merged);\n }\n\n // (2) 有 search_path,沒 schema → 補 schema\n if (!schemaParam && optionsSchemas.length > 0) {\n url.searchParams.set('schema', optionsSchemas[0]);\n }\n\n const finalConnectionString = url.toString();\n\n return {\n optionsSchemas,\n finalSchema,\n finalConnectionString,\n hasSearchPath,\n };\n}\n"],"mappings":";;;;;;;;;AAMA,SAAgB,kBAAkB,SAA4B;AAC5D,KAAI,CAAC,QAAS,QAAO,EAAE;CAMvB,MAAM,IAHa,QAAQ,QAAQ,mBAAmB,kBAAkB,CAGnD,MAAM,+BAA+B;AAC1D,KAAI,CAAC,EAAG,QAAO,EAAE;AAEjB,QAAO,EAAE,GACN,MAAM,IAAI,CACV,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ;;;;;AChBpB,SAAS,sBAAsB,QAAwB;AACrD,QAAO,kBAAkB;;AAG3B,SAAS,aAAa,UAA8B,QAAwB;AAE1E,KADgB,kBAAkB,SAAS,CAC/B,SAAS,EAAG,QAAO,YAAY;CAC3C,MAAM,MAAM,sBAAsB,OAAO;AACzC,QAAO,YAAY,SAAS,MAAM,GAAG,GAAG,SAAS,MAAM,CAAC,GAAG,QAAQ;;AAGrE,SAAgB,wBACd,kBACA,cAMA;CACA,MAAM,yCAAe,iBAAiB;CACtC,MAAM,MAAM,IAAI,IAAI,iBAAiB;CAGrC,MAAM,UAAU,IAAI,aAAa,IAAI,UAAU,IAAI,OAAO,WAAW;CAErE,MAAM,iBAAiB,kBAAkB,QAAQ;CACjD,MAAM,gBAAgB,eAAe,SAAS;CAE9C,MAAM,cAAc,IAAI,aAAa,IAAI,SAAS,IAAI;CAGtD,MAAM,cAAc,eAAe,MAAM,eAAe,gBAAgB;AAGxE,KAAI,CAAC,iBAAiB,gBAAgB,UAAU;EAC9C,MAAM,SAAS,aAAa,SAAS,YAAY;AAEjD,MAAI,aAAa,IAAI,WAAW,OAAO;;AAIzC,KAAI,CAAC,eAAe,eAAe,SAAS,EAC1C,KAAI,aAAa,IAAI,UAAU,eAAe,GAAG;AAKnD,QAAO;EACL;EACA;EACA,uBAL4B,IAAI,UAAU;EAM1C;EACD"}
package/dist/index.mjs DELETED
@@ -1,50 +0,0 @@
1
- import { parse } from "pg-connection-string";
2
-
3
- //#region src/pure/options.ts
4
- /**
5
- * 從 options 解析 search_path
6
- * 支援:
7
- * -c search_path=a,b
8
- * -csearch_path=a,b (防呆,但會 normalize)
9
- */
10
- function getOptionsSchemas(options) {
11
- if (!options) return [];
12
- const m = options.replace(/-csearch_path=/g, "-c search_path=").match(/(?:^|\s)search_path=([^\s]+)/);
13
- if (!m) return [];
14
- return m[1].split(",").map((s) => s.trim()).filter(Boolean);
15
- }
16
-
17
- //#endregion
18
- //#region src/pure/connection-string.ts
19
- function buildSearchPathOption(schema) {
20
- return `-c search_path=${schema}`;
21
- }
22
- function mergeOptions(existing, schema) {
23
- if (getOptionsSchemas(existing).length > 0) return existing ?? "";
24
- const add = buildSearchPathOption(schema);
25
- return existing && existing.trim() ? `${existing.trim()} ${add}` : add;
26
- }
27
- function getConnectionStringInfo(connectionString, targetSchema) {
28
- const config = parse(connectionString);
29
- const url = new URL(connectionString);
30
- const options = url.searchParams.get("options") ?? config.options ?? void 0;
31
- const optionsSchemas = getOptionsSchemas(options);
32
- const hasSearchPath = optionsSchemas.length > 0;
33
- const schemaParam = url.searchParams.get("schema") ?? void 0;
34
- const finalSchema = optionsSchemas[0] ?? schemaParam ?? targetSchema ?? "public";
35
- if (!hasSearchPath && finalSchema !== "public") {
36
- const merged = mergeOptions(options, finalSchema);
37
- url.searchParams.set("options", merged);
38
- }
39
- if (!schemaParam && optionsSchemas.length > 0) url.searchParams.set("schema", optionsSchemas[0]);
40
- return {
41
- optionsSchemas,
42
- finalSchema,
43
- finalConnectionString: url.toString(),
44
- hasSearchPath
45
- };
46
- }
47
-
48
- //#endregion
49
- export { getConnectionStringInfo, getOptionsSchemas };
50
- //# sourceMappingURL=index.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/pure/options.ts","../src/pure/connection-string.ts"],"sourcesContent":["/**\n * 從 options 解析 search_path\n * 支援:\n * -c search_path=a,b\n * -csearch_path=a,b (防呆,但會 normalize)\n */\nexport function getOptionsSchemas(options?: string): string[] {\n if (!options) return [];\n\n // normalize: -csearch_path -> -c search_path\n const normalized = options.replace(/-csearch_path=/g, '-c search_path=');\n\n // match: search_path=a,b (到空白結束)\n const m = normalized.match(/(?:^|\\s)search_path=([^\\s]+)/);\n if (!m) return [];\n\n return m[1]\n .split(',')\n .map((s) => s.trim())\n .filter(Boolean);\n}\n","import { parse } from 'pg-connection-string';\nimport { getOptionsSchemas } from './options';\n\nfunction buildSearchPathOption(schema: string): string {\n return `-c search_path=${schema}`;\n}\n\nfunction mergeOptions(existing: string | undefined, schema: string): string {\n const schemas = getOptionsSchemas(existing);\n if (schemas.length > 0) return existing ?? '';\n const add = buildSearchPathOption(schema);\n return existing && existing.trim() ? `${existing.trim()} ${add}` : add;\n}\n\nexport function getConnectionStringInfo(\n connectionString: string,\n targetSchema?: string,\n): {\n finalConnectionString: string;\n finalSchema: string;\n optionsSchemas: string[];\n hasSearchPath: boolean;\n} {\n const config = parse(connectionString);\n const url = new URL(connectionString);\n\n // 這裡拿到的 options **是 decode 後的字串**(例如 \"-c search_path=prisma_test\")\n const options = url.searchParams.get('options') ?? config.options ?? undefined;\n\n const optionsSchemas = getOptionsSchemas(options);\n const hasSearchPath = optionsSchemas.length > 0;\n\n const schemaParam = url.searchParams.get('schema') ?? undefined;\n\n // options search_path > schema param > targetSchema > public\n const finalSchema = optionsSchemas[0] ?? schemaParam ?? targetSchema ?? 'public';\n\n // (1) 有 schema,沒 search_path → 補 options\n if (!hasSearchPath && finalSchema !== 'public') {\n const merged = mergeOptions(options, finalSchema);\n // ✅ 不要 encodeURIComponent,URLSearchParams 會自動處理\n url.searchParams.set('options', merged);\n }\n\n // (2) 有 search_path,沒 schema → 補 schema\n if (!schemaParam && optionsSchemas.length > 0) {\n url.searchParams.set('schema', optionsSchemas[0]);\n }\n\n const finalConnectionString = url.toString();\n\n return {\n optionsSchemas,\n finalSchema,\n finalConnectionString,\n hasSearchPath,\n };\n}\n"],"mappings":";;;;;;;;;AAMA,SAAgB,kBAAkB,SAA4B;AAC5D,KAAI,CAAC,QAAS,QAAO,EAAE;CAMvB,MAAM,IAHa,QAAQ,QAAQ,mBAAmB,kBAAkB,CAGnD,MAAM,+BAA+B;AAC1D,KAAI,CAAC,EAAG,QAAO,EAAE;AAEjB,QAAO,EAAE,GACN,MAAM,IAAI,CACV,KAAK,MAAM,EAAE,MAAM,CAAC,CACpB,OAAO,QAAQ;;;;;AChBpB,SAAS,sBAAsB,QAAwB;AACrD,QAAO,kBAAkB;;AAG3B,SAAS,aAAa,UAA8B,QAAwB;AAE1E,KADgB,kBAAkB,SAAS,CAC/B,SAAS,EAAG,QAAO,YAAY;CAC3C,MAAM,MAAM,sBAAsB,OAAO;AACzC,QAAO,YAAY,SAAS,MAAM,GAAG,GAAG,SAAS,MAAM,CAAC,GAAG,QAAQ;;AAGrE,SAAgB,wBACd,kBACA,cAMA;CACA,MAAM,SAAS,MAAM,iBAAiB;CACtC,MAAM,MAAM,IAAI,IAAI,iBAAiB;CAGrC,MAAM,UAAU,IAAI,aAAa,IAAI,UAAU,IAAI,OAAO,WAAW;CAErE,MAAM,iBAAiB,kBAAkB,QAAQ;CACjD,MAAM,gBAAgB,eAAe,SAAS;CAE9C,MAAM,cAAc,IAAI,aAAa,IAAI,SAAS,IAAI;CAGtD,MAAM,cAAc,eAAe,MAAM,eAAe,gBAAgB;AAGxE,KAAI,CAAC,iBAAiB,gBAAgB,UAAU;EAC9C,MAAM,SAAS,aAAa,SAAS,YAAY;AAEjD,MAAI,aAAa,IAAI,WAAW,OAAO;;AAIzC,KAAI,CAAC,eAAe,eAAe,SAAS,EAC1C,KAAI,aAAa,IAAI,UAAU,eAAe,GAAG;AAKnD,QAAO;EACL;EACA;EACA,uBAL4B,IAAI,UAAU;EAM1C;EACD"}
package/dist/package.json DELETED
@@ -1,28 +0,0 @@
1
- {
2
- "name": "@rfjs/pg-toolkit",
3
- "version": "0.0.7",
4
- "description": "Shared PostgreSQL utilities and management scripts for Drizzle, Prisma, Kysely, and TypeORM",
5
- "files": [
6
- "dist",
7
- "README.md",
8
- "LICENSE"
9
- ],
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "keywords": [],
14
- "author": "Roy Chuang",
15
- "license": "ISC",
16
- "engines": {
17
- "node": ">=18",
18
- "pnpm": ">=10.24.0 <11.0.0"
19
- },
20
- "dependencies": {
21
- "pg": "^8.16.3",
22
- "pg-connection-string": "^2.9.1",
23
- "tslib": "^2.8.1"
24
- },
25
- "main": "index.js",
26
- "module": "index.mjs",
27
- "types": "index.d.ts"
28
- }