@rfjs/pg-toolkit 0.0.3 → 0.0.5-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/README.md +39 -31
- package/README.zh-TW.md +46 -0
- package/dist/admin/index.d.mts +26 -1
- package/dist/admin/index.d.mts.map +1 -1
- package/dist/admin/index.d.ts +26 -1
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +42 -2
- package/dist/admin/index.js.map +1 -1
- package/dist/admin/index.mjs +39 -2
- package/dist/admin/index.mjs.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/package.json +3 -2
- package/package.json +13 -14
- package/dist/esm-9QNtbaRS.js +0 -160
- package/dist/esm-9QNtbaRS.js.map +0 -1
- package/dist/esm-v1isYkCK.mjs +0 -151
- package/dist/esm-v1isYkCK.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -1,38 +1,46 @@
|
|
|
1
|
-
pg-
|
|
2
|
-
===
|
|
1
|
+
# @packages/pg-toolkit
|
|
3
2
|
|
|
4
|
-
|
|
3
|
+
A utility toolkit for PostgreSQL, designed to share common functionality and management scripts across different ORMs (Drizzle, Prisma, Kysely, TypeORM).
|
|
5
4
|
|
|
6
|
-
##
|
|
5
|
+
## Features
|
|
7
6
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
```
|
|
7
|
+
### Admin
|
|
8
|
+
Provides database-level management functions, useful for CI/CD or environment initialization.
|
|
9
|
+
- `ensureSeedHistoryTable`: Creates and manages a seed execution history table (`__seed_history`).
|
|
10
|
+
- `checkSeedExecuted`: Checks if a specific seed has already been executed.
|
|
11
|
+
- `recordSeedExecution`: Records the execution status of a seed.
|
|
12
|
+
- `checkAndCreateDB`: Checks and automatically creates the database.
|
|
13
|
+
- `checkAndCreateSchema`: Checks and automatically creates Schemas.
|
|
14
|
+
|
|
15
|
+
### Pure
|
|
16
|
+
Utility functions that do not depend on database connections.
|
|
17
|
+
- `getConnectionStringInfo`: Parses Connection Strings, handling logic for `schema` parameters and merging `search_path` options.
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
22
20
|
|
|
23
|
-
## Release
|
|
24
21
|
```bash
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
npm run release
|
|
29
|
-
# dry run
|
|
30
|
-
npm run release -- --dry-run
|
|
31
|
-
|
|
32
|
-
# 2. Release the project with version
|
|
33
|
-
npm run release -- --version 1.0.0
|
|
22
|
+
npm install @rfjs/pg-toolkit
|
|
23
|
+
# or
|
|
24
|
+
pnpm add @rfjs/pg-toolkit
|
|
34
25
|
```
|
|
35
26
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
|
|
27
|
+
## Usage Example
|
|
28
|
+
|
|
29
|
+
### Managing Seed History
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { ensureSeedHistoryTable, checkSeedExecuted, recordSeedExecution } from '@rfjs/pg-toolkit/admin';
|
|
33
|
+
import { Client } from 'pg';
|
|
34
|
+
|
|
35
|
+
const client = new Client(process.env.DATABASE_URL);
|
|
36
|
+
await client.connect();
|
|
37
|
+
|
|
38
|
+
// Ensure history table exists
|
|
39
|
+
await ensureSeedHistoryTable(client);
|
|
40
|
+
|
|
41
|
+
// Check and execute
|
|
42
|
+
if (!await checkSeedExecuted(client, 'init_data')) {
|
|
43
|
+
// await runMySeed();
|
|
44
|
+
await recordSeedExecution(client, 'init_data');
|
|
45
|
+
}
|
|
46
|
+
```
|
package/README.zh-TW.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @packages/pg-toolkit
|
|
2
|
+
|
|
3
|
+
PostgreSQL 工具庫,提供跨 ORM (Drizzle, Prisma, Kysely, TypeORM) 共用的基礎功能與管理腳本。
|
|
4
|
+
|
|
5
|
+
## 功能特色
|
|
6
|
+
|
|
7
|
+
### Admin (管理工具)
|
|
8
|
+
提供資料庫層級的管理功能,通常用於 CI/CD 或開發環境初始化。
|
|
9
|
+
- `ensureSeedHistoryTable`: 建立並管理種子資料執行紀錄表 (`__seed_history`)。
|
|
10
|
+
- `checkSeedExecuted`: 檢查特定種子資料是否已執行。
|
|
11
|
+
- `recordSeedExecution`: 紀錄種子資料執行狀態。
|
|
12
|
+
- `checkAndCreateDB`: 檢查並自動建立資料庫。
|
|
13
|
+
- `checkAndCreateSchema`: 檢查並自動建立 Schema。
|
|
14
|
+
|
|
15
|
+
### Pure (純函數)
|
|
16
|
+
不依賴資料庫連線的工具函數。
|
|
17
|
+
- `getConnectionStringInfo`: 解析 Connection String,處理 `schema` 參數與 `search_path` options 的合併邏輯。
|
|
18
|
+
|
|
19
|
+
## 安裝
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install @rfjs/pg-toolkit
|
|
23
|
+
# 或
|
|
24
|
+
pnpm add @rfjs/pg-toolkit
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 使用範例
|
|
28
|
+
|
|
29
|
+
### 管理種子紀錄
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
import { ensureSeedHistoryTable, checkSeedExecuted, recordSeedExecution } from '@rfjs/pg-toolkit/admin';
|
|
33
|
+
import { Client } from 'pg';
|
|
34
|
+
|
|
35
|
+
const client = new Client(process.env.DATABASE_URL);
|
|
36
|
+
await client.connect();
|
|
37
|
+
|
|
38
|
+
// 確保紀錄表存在
|
|
39
|
+
await ensureSeedHistoryTable(client);
|
|
40
|
+
|
|
41
|
+
// 檢查並執行
|
|
42
|
+
if (!await checkSeedExecuted(client, 'init_data')) {
|
|
43
|
+
// await runMySeed();
|
|
44
|
+
await recordSeedExecution(client, 'init_data');
|
|
45
|
+
}
|
|
46
|
+
```
|
package/dist/admin/index.d.mts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
+
import { Client, Pool } from "pg";
|
|
2
|
+
|
|
1
3
|
//#region src/admin/ensure-db.d.ts
|
|
2
4
|
declare function checkAndCreateDB(connectionString: string): Promise<void>;
|
|
3
5
|
//#endregion
|
|
4
6
|
//#region src/admin/ensure-schema.d.ts
|
|
5
7
|
declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
|
|
6
8
|
//#endregion
|
|
7
|
-
|
|
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 };
|
|
8
33
|
//# sourceMappingURL=index.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts"],"sourcesContent":[],"mappings":"
|
|
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"}
|
package/dist/admin/index.d.ts
CHANGED
|
@@ -1,8 +1,33 @@
|
|
|
1
|
+
import { Client, Pool } from "pg";
|
|
2
|
+
|
|
1
3
|
//#region src/admin/ensure-db.d.ts
|
|
2
4
|
declare function checkAndCreateDB(connectionString: string): Promise<void>;
|
|
3
5
|
//#endregion
|
|
4
6
|
//#region src/admin/ensure-schema.d.ts
|
|
5
7
|
declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
|
|
6
8
|
//#endregion
|
|
7
|
-
|
|
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 };
|
|
8
33
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts"],"sourcesContent":[],"mappings":"
|
|
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"}
|
package/dist/admin/index.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
|
|
1
|
+
let pg_connection_string = require("pg-connection-string");
|
|
2
2
|
let pg = require("pg");
|
|
3
3
|
|
|
4
4
|
//#region src/admin/ensure-db.ts
|
|
5
5
|
async function checkAndCreateDB(connectionString) {
|
|
6
|
-
const { user, password, host, port, database } =
|
|
6
|
+
const { user, password, host, port, database } = (0, pg_connection_string.parse)(connectionString);
|
|
7
7
|
const adminConnectionString = `postgres://${user}:${password}@${host}:${port}/postgres`;
|
|
8
8
|
const targetDb = database ?? "orm";
|
|
9
9
|
const client = new pg.Client({ connectionString: adminConnectionString });
|
|
@@ -41,7 +41,47 @@ async function checkAndCreateSchema(connectionString, schemas) {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
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
|
+
|
|
44
81
|
//#endregion
|
|
45
82
|
exports.checkAndCreateDB = checkAndCreateDB;
|
|
46
83
|
exports.checkAndCreateSchema = checkAndCreateSchema;
|
|
84
|
+
exports.checkSeedExecuted = checkSeedExecuted;
|
|
85
|
+
exports.ensureSeedHistoryTable = ensureSeedHistoryTable;
|
|
86
|
+
exports.recordSeedExecution = recordSeedExecution;
|
|
47
87
|
//# sourceMappingURL=index.js.map
|
package/dist/admin/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["
|
|
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"}
|
package/dist/admin/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parse } from "pg-connection-string";
|
|
2
2
|
import { Client } from "pg";
|
|
3
3
|
|
|
4
4
|
//#region src/admin/ensure-db.ts
|
|
@@ -42,5 +42,42 @@ async function checkAndCreateSchema(connectionString, schemas) {
|
|
|
42
42
|
}
|
|
43
43
|
|
|
44
44
|
//#endregion
|
|
45
|
-
|
|
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 };
|
|
46
83
|
//# sourceMappingURL=index.mjs.map
|
package/dist/admin/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.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"],"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"}
|
|
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.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
let pg_connection_string = require("pg-connection-string");
|
|
2
2
|
|
|
3
3
|
//#region src/pure/options.ts
|
|
4
4
|
/**
|
|
@@ -25,7 +25,7 @@ function mergeOptions(existing, schema) {
|
|
|
25
25
|
return existing && existing.trim() ? `${existing.trim()} ${add}` : add;
|
|
26
26
|
}
|
|
27
27
|
function getConnectionStringInfo(connectionString, targetSchema) {
|
|
28
|
-
const config =
|
|
28
|
+
const config = (0, pg_connection_string.parse)(connectionString);
|
|
29
29
|
const url = new URL(connectionString);
|
|
30
30
|
const options = url.searchParams.get("options") ?? config.options ?? void 0;
|
|
31
31
|
const optionsSchemas = getOptionsSchemas(options);
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[
|
|
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
CHANGED
package/dist/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rfjs/pg-toolkit",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.5-alpha.0",
|
|
4
|
+
"description": "Shared PostgreSQL utilities and management scripts for Drizzle, Prisma, Kysely, and TypeORM",
|
|
5
5
|
"files": [
|
|
6
6
|
"dist",
|
|
7
7
|
"README.md",
|
|
@@ -19,6 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
21
|
"pg": "^8.16.3",
|
|
22
|
+
"pg-connection-string": "^2.9.1",
|
|
22
23
|
"tslib": "^2.8.1"
|
|
23
24
|
},
|
|
24
25
|
"main": "index.js",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rfjs/pg-toolkit",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.0.5-alpha.0",
|
|
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",
|
|
7
7
|
"types": "dist/index.d.ts",
|
|
@@ -27,9 +27,9 @@
|
|
|
27
27
|
},
|
|
28
28
|
"lint-staged": {
|
|
29
29
|
"*.ts": [
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
30
|
+
"pnpm exec vitest related --run",
|
|
31
|
+
"pnpm exec prettier --write",
|
|
32
|
+
"pnpm exec eslint --fix"
|
|
33
33
|
]
|
|
34
34
|
},
|
|
35
35
|
"config": {
|
|
@@ -61,7 +61,6 @@
|
|
|
61
61
|
"husky": "^9.1.7",
|
|
62
62
|
"inquirer": "9",
|
|
63
63
|
"lint-staged": "^15.4.3",
|
|
64
|
-
"pg-connection-string": "^2.9.1",
|
|
65
64
|
"prettier": "^3.5.1",
|
|
66
65
|
"rimraf": "^6.0.1",
|
|
67
66
|
"supertest": "^7.0.0",
|
|
@@ -74,19 +73,20 @@
|
|
|
74
73
|
},
|
|
75
74
|
"dependencies": {
|
|
76
75
|
"pg": "^8.16.3",
|
|
76
|
+
"pg-connection-string": "^2.9.1",
|
|
77
77
|
"tslib": "^2.8.1"
|
|
78
78
|
},
|
|
79
79
|
"scripts": {
|
|
80
|
-
"clean": "
|
|
81
|
-
"clean:types": "
|
|
82
|
-
"clean:dist": "
|
|
83
|
-
"dev": "
|
|
80
|
+
"clean": "pnpm -r --parallel clean:dist clean:types",
|
|
81
|
+
"clean:types": "pnpm exec rimraf ./types",
|
|
82
|
+
"clean:dist": "pnpm exec rimraf ./dist",
|
|
83
|
+
"dev": "pnpm -r --parallel dev:tsdown typecheck:watch",
|
|
84
84
|
"dev:tsdown": "npm run clean && tsdown --config-loader unrun --watch",
|
|
85
85
|
"build": "npm run build:tsdown",
|
|
86
86
|
"build:tsdown": "npm run clean && tsdown --config-loader unrun",
|
|
87
87
|
"typecheck": "tsc --noEmit",
|
|
88
88
|
"typecheck:watch": "tsc --noEmit --watch",
|
|
89
|
-
"lint-staged": "
|
|
89
|
+
"lint-staged": "pnpm exec lint-staged",
|
|
90
90
|
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
|
|
91
91
|
"lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
|
92
92
|
"test": "npm run vitest:run",
|
|
@@ -95,9 +95,8 @@
|
|
|
95
95
|
"vitest:ui": "vitest --passWithNoTests --ui",
|
|
96
96
|
"vitest:e2e": "vitest --config vitest.config.e2e.mts --passWithNoTests",
|
|
97
97
|
"vitest:e2e:ui": "vitest --config vitest.config.e2e.mts --passWithNoTests --ui",
|
|
98
|
-
"release": "
|
|
99
|
-
"commit": "
|
|
100
|
-
"preinstall": "npx -y only-allow pnpm",
|
|
98
|
+
"release": "pnpm exec standard-version",
|
|
99
|
+
"commit": "pnpm exec cz",
|
|
101
100
|
"docs:dev": "vitepress dev docs",
|
|
102
101
|
"docs:build": "vitepress build docs",
|
|
103
102
|
"docs:preview": "vitepress preview docs"
|
package/dist/esm-9QNtbaRS.js
DELETED
|
@@ -1,160 +0,0 @@
|
|
|
1
|
-
//#region rolldown:runtime
|
|
2
|
-
var __create = Object.create;
|
|
3
|
-
var __defProp = Object.defineProperty;
|
|
4
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
9
|
-
var __copyProps = (to, from, except, desc) => {
|
|
10
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
12
|
-
key = keys[i];
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
14
|
-
__defProp(to, key, {
|
|
15
|
-
get: ((k) => from[k]).bind(null, key),
|
|
16
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
17
|
-
});
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
return to;
|
|
22
|
-
};
|
|
23
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
24
|
-
value: mod,
|
|
25
|
-
enumerable: true
|
|
26
|
-
}) : target, mod));
|
|
27
|
-
|
|
28
|
-
//#endregion
|
|
29
|
-
|
|
30
|
-
//#region ../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/index.js
|
|
31
|
-
var require_pg_connection_string = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
32
|
-
function parse$1(str, options = {}) {
|
|
33
|
-
if (str.charAt(0) === "/") {
|
|
34
|
-
const config$1 = str.split(" ");
|
|
35
|
-
return {
|
|
36
|
-
host: config$1[0],
|
|
37
|
-
database: config$1[1]
|
|
38
|
-
};
|
|
39
|
-
}
|
|
40
|
-
const config = {};
|
|
41
|
-
let result;
|
|
42
|
-
let dummyHost = false;
|
|
43
|
-
if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) str = encodeURI(str).replace(/%25(\d\d)/g, "%$1");
|
|
44
|
-
try {
|
|
45
|
-
try {
|
|
46
|
-
result = new URL(str, "postgres://base");
|
|
47
|
-
} catch (e) {
|
|
48
|
-
result = new URL(str.replace("@/", "@___DUMMY___/"), "postgres://base");
|
|
49
|
-
dummyHost = true;
|
|
50
|
-
}
|
|
51
|
-
} catch (err) {
|
|
52
|
-
err.input && (err.input = "*****REDACTED*****");
|
|
53
|
-
}
|
|
54
|
-
for (const entry of result.searchParams.entries()) config[entry[0]] = entry[1];
|
|
55
|
-
config.user = config.user || decodeURIComponent(result.username);
|
|
56
|
-
config.password = config.password || decodeURIComponent(result.password);
|
|
57
|
-
if (result.protocol == "socket:") {
|
|
58
|
-
config.host = decodeURI(result.pathname);
|
|
59
|
-
config.database = result.searchParams.get("db");
|
|
60
|
-
config.client_encoding = result.searchParams.get("encoding");
|
|
61
|
-
return config;
|
|
62
|
-
}
|
|
63
|
-
const hostname = dummyHost ? "" : result.hostname;
|
|
64
|
-
if (!config.host) config.host = decodeURIComponent(hostname);
|
|
65
|
-
else if (hostname && /^%2f/i.test(hostname)) result.pathname = hostname + result.pathname;
|
|
66
|
-
if (!config.port) config.port = result.port;
|
|
67
|
-
const pathname = result.pathname.slice(1) || null;
|
|
68
|
-
config.database = pathname ? decodeURI(pathname) : null;
|
|
69
|
-
if (config.ssl === "true" || config.ssl === "1") config.ssl = true;
|
|
70
|
-
if (config.ssl === "0") config.ssl = false;
|
|
71
|
-
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) config.ssl = {};
|
|
72
|
-
const fs = config.sslcert || config.sslkey || config.sslrootcert ? require("fs") : null;
|
|
73
|
-
if (config.sslcert) config.ssl.cert = fs.readFileSync(config.sslcert).toString();
|
|
74
|
-
if (config.sslkey) config.ssl.key = fs.readFileSync(config.sslkey).toString();
|
|
75
|
-
if (config.sslrootcert) config.ssl.ca = fs.readFileSync(config.sslrootcert).toString();
|
|
76
|
-
if (options.useLibpqCompat && config.uselibpqcompat) throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
|
|
77
|
-
if (config.uselibpqcompat === "true" || options.useLibpqCompat) switch (config.sslmode) {
|
|
78
|
-
case "disable":
|
|
79
|
-
config.ssl = false;
|
|
80
|
-
break;
|
|
81
|
-
case "prefer":
|
|
82
|
-
config.ssl.rejectUnauthorized = false;
|
|
83
|
-
break;
|
|
84
|
-
case "require":
|
|
85
|
-
if (config.sslrootcert) config.ssl.checkServerIdentity = function() {};
|
|
86
|
-
else config.ssl.rejectUnauthorized = false;
|
|
87
|
-
break;
|
|
88
|
-
case "verify-ca":
|
|
89
|
-
if (!config.ssl.ca) throw new Error("SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.");
|
|
90
|
-
config.ssl.checkServerIdentity = function() {};
|
|
91
|
-
break;
|
|
92
|
-
case "verify-full": break;
|
|
93
|
-
}
|
|
94
|
-
else switch (config.sslmode) {
|
|
95
|
-
case "disable":
|
|
96
|
-
config.ssl = false;
|
|
97
|
-
break;
|
|
98
|
-
case "prefer":
|
|
99
|
-
case "require":
|
|
100
|
-
case "verify-ca":
|
|
101
|
-
case "verify-full": break;
|
|
102
|
-
case "no-verify":
|
|
103
|
-
config.ssl.rejectUnauthorized = false;
|
|
104
|
-
break;
|
|
105
|
-
}
|
|
106
|
-
return config;
|
|
107
|
-
}
|
|
108
|
-
function toConnectionOptions(sslConfig) {
|
|
109
|
-
return Object.entries(sslConfig).reduce((c, [key, value]) => {
|
|
110
|
-
if (value !== void 0 && value !== null) c[key] = value;
|
|
111
|
-
return c;
|
|
112
|
-
}, {});
|
|
113
|
-
}
|
|
114
|
-
function toClientConfig$1(config) {
|
|
115
|
-
return Object.entries(config).reduce((c, [key, value]) => {
|
|
116
|
-
if (key === "ssl") {
|
|
117
|
-
const sslConfig = value;
|
|
118
|
-
if (typeof sslConfig === "boolean") c[key] = sslConfig;
|
|
119
|
-
if (typeof sslConfig === "object") c[key] = toConnectionOptions(sslConfig);
|
|
120
|
-
} else if (value !== void 0 && value !== null) if (key === "port") {
|
|
121
|
-
if (value !== "") {
|
|
122
|
-
const v = parseInt(value, 10);
|
|
123
|
-
if (isNaN(v)) throw new Error(`Invalid ${key}: ${value}`);
|
|
124
|
-
c[key] = v;
|
|
125
|
-
}
|
|
126
|
-
} else c[key] = value;
|
|
127
|
-
return c;
|
|
128
|
-
}, {});
|
|
129
|
-
}
|
|
130
|
-
function parseIntoClientConfig$1(str) {
|
|
131
|
-
return toClientConfig$1(parse$1(str));
|
|
132
|
-
}
|
|
133
|
-
module.exports = parse$1;
|
|
134
|
-
parse$1.parse = parse$1;
|
|
135
|
-
parse$1.toClientConfig = toClientConfig$1;
|
|
136
|
-
parse$1.parseIntoClientConfig = parseIntoClientConfig$1;
|
|
137
|
-
}));
|
|
138
|
-
|
|
139
|
-
//#endregion
|
|
140
|
-
//#region ../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/esm/index.mjs
|
|
141
|
-
var import_pg_connection_string = /* @__PURE__ */ __toESM(require_pg_connection_string(), 1);
|
|
142
|
-
var esm_default = import_pg_connection_string.default.parse;
|
|
143
|
-
const parse = import_pg_connection_string.default.parse;
|
|
144
|
-
const toClientConfig = import_pg_connection_string.default.toClientConfig;
|
|
145
|
-
const parseIntoClientConfig = import_pg_connection_string.default.parseIntoClientConfig;
|
|
146
|
-
|
|
147
|
-
//#endregion
|
|
148
|
-
Object.defineProperty(exports, '__toESM', {
|
|
149
|
-
enumerable: true,
|
|
150
|
-
get: function () {
|
|
151
|
-
return __toESM;
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
Object.defineProperty(exports, 'parse', {
|
|
155
|
-
enumerable: true,
|
|
156
|
-
get: function () {
|
|
157
|
-
return parse;
|
|
158
|
-
}
|
|
159
|
-
});
|
|
160
|
-
//# sourceMappingURL=esm-9QNtbaRS.js.map
|
package/dist/esm-9QNtbaRS.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"esm-9QNtbaRS.js","names":["parse","config","toClientConfig","parseIntoClientConfig","connectionString"],"sources":["../../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/index.js","../../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/esm/index.mjs"],"sourcesContent":["'use strict'\n\n//Parse method copied from https://github.com/brianc/node-postgres\n//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)\n//MIT License\n\n//parses a connection string\nfunction parse(str, options = {}) {\n //unix socket\n if (str.charAt(0) === '/') {\n const config = str.split(' ')\n return { host: config[0], database: config[1] }\n }\n\n // Check for empty host in URL\n\n const config = {}\n let result\n let dummyHost = false\n if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) {\n // Ensure spaces are encoded as %20\n str = encodeURI(str).replace(/%25(\\d\\d)/g, '%$1')\n }\n\n try {\n try {\n result = new URL(str, 'postgres://base')\n } catch (e) {\n // The URL is invalid so try again with a dummy host\n result = new URL(str.replace('@/', '@___DUMMY___/'), 'postgres://base')\n dummyHost = true\n }\n } catch (err) {\n // Remove the input from the error message to avoid leaking sensitive information\n err.input && (err.input = '*****REDACTED*****')\n }\n\n // We'd like to use Object.fromEntries() here but Node.js 10 does not support it\n for (const entry of result.searchParams.entries()) {\n config[entry[0]] = entry[1]\n }\n\n config.user = config.user || decodeURIComponent(result.username)\n config.password = config.password || decodeURIComponent(result.password)\n\n if (result.protocol == 'socket:') {\n config.host = decodeURI(result.pathname)\n config.database = result.searchParams.get('db')\n config.client_encoding = result.searchParams.get('encoding')\n return config\n }\n const hostname = dummyHost ? '' : result.hostname\n if (!config.host) {\n // Only set the host if there is no equivalent query param.\n config.host = decodeURIComponent(hostname)\n } else if (hostname && /^%2f/i.test(hostname)) {\n // Only prepend the hostname to the pathname if it is not a URL encoded Unix socket host.\n result.pathname = hostname + result.pathname\n }\n if (!config.port) {\n // Only set the port if there is no equivalent query param.\n config.port = result.port\n }\n\n const pathname = result.pathname.slice(1) || null\n config.database = pathname ? decodeURI(pathname) : null\n\n if (config.ssl === 'true' || config.ssl === '1') {\n config.ssl = true\n }\n\n if (config.ssl === '0') {\n config.ssl = false\n }\n\n if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {\n config.ssl = {}\n }\n\n // Only try to load fs if we expect to read from the disk\n const fs = config.sslcert || config.sslkey || config.sslrootcert ? require('fs') : null\n\n if (config.sslcert) {\n config.ssl.cert = fs.readFileSync(config.sslcert).toString()\n }\n\n if (config.sslkey) {\n config.ssl.key = fs.readFileSync(config.sslkey).toString()\n }\n\n if (config.sslrootcert) {\n config.ssl.ca = fs.readFileSync(config.sslrootcert).toString()\n }\n\n if (options.useLibpqCompat && config.uselibpqcompat) {\n throw new Error('Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.')\n }\n\n if (config.uselibpqcompat === 'true' || options.useLibpqCompat) {\n switch (config.sslmode) {\n case 'disable': {\n config.ssl = false\n break\n }\n case 'prefer': {\n config.ssl.rejectUnauthorized = false\n break\n }\n case 'require': {\n if (config.sslrootcert) {\n // If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca`\n config.ssl.checkServerIdentity = function () {}\n } else {\n config.ssl.rejectUnauthorized = false\n }\n break\n }\n case 'verify-ca': {\n if (!config.ssl.ca) {\n throw new Error(\n 'SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.'\n )\n }\n config.ssl.checkServerIdentity = function () {}\n break\n }\n case 'verify-full': {\n break\n }\n }\n } else {\n switch (config.sslmode) {\n case 'disable': {\n config.ssl = false\n break\n }\n case 'prefer':\n case 'require':\n case 'verify-ca':\n case 'verify-full': {\n break\n }\n case 'no-verify': {\n config.ssl.rejectUnauthorized = false\n break\n }\n }\n }\n\n return config\n}\n\n// convert pg-connection-string ssl config to a ClientConfig.ConnectionOptions\nfunction toConnectionOptions(sslConfig) {\n const connectionOptions = Object.entries(sslConfig).reduce((c, [key, value]) => {\n // we explicitly check for undefined and null instead of `if (value)` because some\n // options accept falsy values. Example: `ssl.rejectUnauthorized = false`\n if (value !== undefined && value !== null) {\n c[key] = value\n }\n\n return c\n }, {})\n\n return connectionOptions\n}\n\n// convert pg-connection-string config to a ClientConfig\nfunction toClientConfig(config) {\n const poolConfig = Object.entries(config).reduce((c, [key, value]) => {\n if (key === 'ssl') {\n const sslConfig = value\n\n if (typeof sslConfig === 'boolean') {\n c[key] = sslConfig\n }\n\n if (typeof sslConfig === 'object') {\n c[key] = toConnectionOptions(sslConfig)\n }\n } else if (value !== undefined && value !== null) {\n if (key === 'port') {\n // when port is not specified, it is converted into an empty string\n // we want to avoid NaN or empty string as a values in ClientConfig\n if (value !== '') {\n const v = parseInt(value, 10)\n if (isNaN(v)) {\n throw new Error(`Invalid ${key}: ${value}`)\n }\n\n c[key] = v\n }\n } else {\n c[key] = value\n }\n }\n\n return c\n }, {})\n\n return poolConfig\n}\n\n// parses a connection string into ClientConfig\nfunction parseIntoClientConfig(str) {\n return toClientConfig(parse(str))\n}\n\nmodule.exports = parse\n\nparse.parse = parse\nparse.toClientConfig = toClientConfig\nparse.parseIntoClientConfig = parseIntoClientConfig\n","// ESM wrapper for pg-connection-string\nimport connectionString from '../index.js'\n\n// Re-export the parse function\nexport default connectionString.parse\nexport const parse = connectionString.parse\nexport const toClientConfig = connectionString.toClientConfig\nexport const parseIntoClientConfig = connectionString.parseIntoClientConfig\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|
package/dist/esm-v1isYkCK.mjs
DELETED
|
@@ -1,151 +0,0 @@
|
|
|
1
|
-
import { createRequire } from "node:module";
|
|
2
|
-
|
|
3
|
-
//#region rolldown:runtime
|
|
4
|
-
var __create = Object.create;
|
|
5
|
-
var __defProp = Object.defineProperty;
|
|
6
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
8
|
-
var __getProtoOf = Object.getPrototypeOf;
|
|
9
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
10
|
-
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
11
|
-
var __copyProps = (to, from, except, desc) => {
|
|
12
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
-
for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
|
|
14
|
-
key = keys[i];
|
|
15
|
-
if (!__hasOwnProp.call(to, key) && key !== except) {
|
|
16
|
-
__defProp(to, key, {
|
|
17
|
-
get: ((k) => from[k]).bind(null, key),
|
|
18
|
-
enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
return to;
|
|
24
|
-
};
|
|
25
|
-
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
|
|
26
|
-
value: mod,
|
|
27
|
-
enumerable: true
|
|
28
|
-
}) : target, mod));
|
|
29
|
-
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
30
|
-
|
|
31
|
-
//#endregion
|
|
32
|
-
//#region ../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/index.js
|
|
33
|
-
var require_pg_connection_string = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
34
|
-
function parse$1(str, options = {}) {
|
|
35
|
-
if (str.charAt(0) === "/") {
|
|
36
|
-
const config$1 = str.split(" ");
|
|
37
|
-
return {
|
|
38
|
-
host: config$1[0],
|
|
39
|
-
database: config$1[1]
|
|
40
|
-
};
|
|
41
|
-
}
|
|
42
|
-
const config = {};
|
|
43
|
-
let result;
|
|
44
|
-
let dummyHost = false;
|
|
45
|
-
if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) str = encodeURI(str).replace(/%25(\d\d)/g, "%$1");
|
|
46
|
-
try {
|
|
47
|
-
try {
|
|
48
|
-
result = new URL(str, "postgres://base");
|
|
49
|
-
} catch (e) {
|
|
50
|
-
result = new URL(str.replace("@/", "@___DUMMY___/"), "postgres://base");
|
|
51
|
-
dummyHost = true;
|
|
52
|
-
}
|
|
53
|
-
} catch (err) {
|
|
54
|
-
err.input && (err.input = "*****REDACTED*****");
|
|
55
|
-
}
|
|
56
|
-
for (const entry of result.searchParams.entries()) config[entry[0]] = entry[1];
|
|
57
|
-
config.user = config.user || decodeURIComponent(result.username);
|
|
58
|
-
config.password = config.password || decodeURIComponent(result.password);
|
|
59
|
-
if (result.protocol == "socket:") {
|
|
60
|
-
config.host = decodeURI(result.pathname);
|
|
61
|
-
config.database = result.searchParams.get("db");
|
|
62
|
-
config.client_encoding = result.searchParams.get("encoding");
|
|
63
|
-
return config;
|
|
64
|
-
}
|
|
65
|
-
const hostname = dummyHost ? "" : result.hostname;
|
|
66
|
-
if (!config.host) config.host = decodeURIComponent(hostname);
|
|
67
|
-
else if (hostname && /^%2f/i.test(hostname)) result.pathname = hostname + result.pathname;
|
|
68
|
-
if (!config.port) config.port = result.port;
|
|
69
|
-
const pathname = result.pathname.slice(1) || null;
|
|
70
|
-
config.database = pathname ? decodeURI(pathname) : null;
|
|
71
|
-
if (config.ssl === "true" || config.ssl === "1") config.ssl = true;
|
|
72
|
-
if (config.ssl === "0") config.ssl = false;
|
|
73
|
-
if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) config.ssl = {};
|
|
74
|
-
const fs = config.sslcert || config.sslkey || config.sslrootcert ? __require("fs") : null;
|
|
75
|
-
if (config.sslcert) config.ssl.cert = fs.readFileSync(config.sslcert).toString();
|
|
76
|
-
if (config.sslkey) config.ssl.key = fs.readFileSync(config.sslkey).toString();
|
|
77
|
-
if (config.sslrootcert) config.ssl.ca = fs.readFileSync(config.sslrootcert).toString();
|
|
78
|
-
if (options.useLibpqCompat && config.uselibpqcompat) throw new Error("Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.");
|
|
79
|
-
if (config.uselibpqcompat === "true" || options.useLibpqCompat) switch (config.sslmode) {
|
|
80
|
-
case "disable":
|
|
81
|
-
config.ssl = false;
|
|
82
|
-
break;
|
|
83
|
-
case "prefer":
|
|
84
|
-
config.ssl.rejectUnauthorized = false;
|
|
85
|
-
break;
|
|
86
|
-
case "require":
|
|
87
|
-
if (config.sslrootcert) config.ssl.checkServerIdentity = function() {};
|
|
88
|
-
else config.ssl.rejectUnauthorized = false;
|
|
89
|
-
break;
|
|
90
|
-
case "verify-ca":
|
|
91
|
-
if (!config.ssl.ca) throw new Error("SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.");
|
|
92
|
-
config.ssl.checkServerIdentity = function() {};
|
|
93
|
-
break;
|
|
94
|
-
case "verify-full": break;
|
|
95
|
-
}
|
|
96
|
-
else switch (config.sslmode) {
|
|
97
|
-
case "disable":
|
|
98
|
-
config.ssl = false;
|
|
99
|
-
break;
|
|
100
|
-
case "prefer":
|
|
101
|
-
case "require":
|
|
102
|
-
case "verify-ca":
|
|
103
|
-
case "verify-full": break;
|
|
104
|
-
case "no-verify":
|
|
105
|
-
config.ssl.rejectUnauthorized = false;
|
|
106
|
-
break;
|
|
107
|
-
}
|
|
108
|
-
return config;
|
|
109
|
-
}
|
|
110
|
-
function toConnectionOptions(sslConfig) {
|
|
111
|
-
return Object.entries(sslConfig).reduce((c, [key, value]) => {
|
|
112
|
-
if (value !== void 0 && value !== null) c[key] = value;
|
|
113
|
-
return c;
|
|
114
|
-
}, {});
|
|
115
|
-
}
|
|
116
|
-
function toClientConfig$1(config) {
|
|
117
|
-
return Object.entries(config).reduce((c, [key, value]) => {
|
|
118
|
-
if (key === "ssl") {
|
|
119
|
-
const sslConfig = value;
|
|
120
|
-
if (typeof sslConfig === "boolean") c[key] = sslConfig;
|
|
121
|
-
if (typeof sslConfig === "object") c[key] = toConnectionOptions(sslConfig);
|
|
122
|
-
} else if (value !== void 0 && value !== null) if (key === "port") {
|
|
123
|
-
if (value !== "") {
|
|
124
|
-
const v = parseInt(value, 10);
|
|
125
|
-
if (isNaN(v)) throw new Error(`Invalid ${key}: ${value}`);
|
|
126
|
-
c[key] = v;
|
|
127
|
-
}
|
|
128
|
-
} else c[key] = value;
|
|
129
|
-
return c;
|
|
130
|
-
}, {});
|
|
131
|
-
}
|
|
132
|
-
function parseIntoClientConfig$1(str) {
|
|
133
|
-
return toClientConfig$1(parse$1(str));
|
|
134
|
-
}
|
|
135
|
-
module.exports = parse$1;
|
|
136
|
-
parse$1.parse = parse$1;
|
|
137
|
-
parse$1.toClientConfig = toClientConfig$1;
|
|
138
|
-
parse$1.parseIntoClientConfig = parseIntoClientConfig$1;
|
|
139
|
-
}));
|
|
140
|
-
|
|
141
|
-
//#endregion
|
|
142
|
-
//#region ../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/esm/index.mjs
|
|
143
|
-
var import_pg_connection_string = /* @__PURE__ */ __toESM(require_pg_connection_string(), 1);
|
|
144
|
-
var esm_default = import_pg_connection_string.default.parse;
|
|
145
|
-
const parse = import_pg_connection_string.default.parse;
|
|
146
|
-
const toClientConfig = import_pg_connection_string.default.toClientConfig;
|
|
147
|
-
const parseIntoClientConfig = import_pg_connection_string.default.parseIntoClientConfig;
|
|
148
|
-
|
|
149
|
-
//#endregion
|
|
150
|
-
export { parse as t };
|
|
151
|
-
//# sourceMappingURL=esm-v1isYkCK.mjs.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"esm-v1isYkCK.mjs","names":["parse","config","toClientConfig","parseIntoClientConfig","connectionString"],"sources":["../../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/index.js","../../../node_modules/.pnpm/pg-connection-string@2.9.1/node_modules/pg-connection-string/esm/index.mjs"],"sourcesContent":["'use strict'\n\n//Parse method copied from https://github.com/brianc/node-postgres\n//Copyright (c) 2010-2014 Brian Carlson (brian.m.carlson@gmail.com)\n//MIT License\n\n//parses a connection string\nfunction parse(str, options = {}) {\n //unix socket\n if (str.charAt(0) === '/') {\n const config = str.split(' ')\n return { host: config[0], database: config[1] }\n }\n\n // Check for empty host in URL\n\n const config = {}\n let result\n let dummyHost = false\n if (/ |%[^a-f0-9]|%[a-f0-9][^a-f0-9]/i.test(str)) {\n // Ensure spaces are encoded as %20\n str = encodeURI(str).replace(/%25(\\d\\d)/g, '%$1')\n }\n\n try {\n try {\n result = new URL(str, 'postgres://base')\n } catch (e) {\n // The URL is invalid so try again with a dummy host\n result = new URL(str.replace('@/', '@___DUMMY___/'), 'postgres://base')\n dummyHost = true\n }\n } catch (err) {\n // Remove the input from the error message to avoid leaking sensitive information\n err.input && (err.input = '*****REDACTED*****')\n }\n\n // We'd like to use Object.fromEntries() here but Node.js 10 does not support it\n for (const entry of result.searchParams.entries()) {\n config[entry[0]] = entry[1]\n }\n\n config.user = config.user || decodeURIComponent(result.username)\n config.password = config.password || decodeURIComponent(result.password)\n\n if (result.protocol == 'socket:') {\n config.host = decodeURI(result.pathname)\n config.database = result.searchParams.get('db')\n config.client_encoding = result.searchParams.get('encoding')\n return config\n }\n const hostname = dummyHost ? '' : result.hostname\n if (!config.host) {\n // Only set the host if there is no equivalent query param.\n config.host = decodeURIComponent(hostname)\n } else if (hostname && /^%2f/i.test(hostname)) {\n // Only prepend the hostname to the pathname if it is not a URL encoded Unix socket host.\n result.pathname = hostname + result.pathname\n }\n if (!config.port) {\n // Only set the port if there is no equivalent query param.\n config.port = result.port\n }\n\n const pathname = result.pathname.slice(1) || null\n config.database = pathname ? decodeURI(pathname) : null\n\n if (config.ssl === 'true' || config.ssl === '1') {\n config.ssl = true\n }\n\n if (config.ssl === '0') {\n config.ssl = false\n }\n\n if (config.sslcert || config.sslkey || config.sslrootcert || config.sslmode) {\n config.ssl = {}\n }\n\n // Only try to load fs if we expect to read from the disk\n const fs = config.sslcert || config.sslkey || config.sslrootcert ? require('fs') : null\n\n if (config.sslcert) {\n config.ssl.cert = fs.readFileSync(config.sslcert).toString()\n }\n\n if (config.sslkey) {\n config.ssl.key = fs.readFileSync(config.sslkey).toString()\n }\n\n if (config.sslrootcert) {\n config.ssl.ca = fs.readFileSync(config.sslrootcert).toString()\n }\n\n if (options.useLibpqCompat && config.uselibpqcompat) {\n throw new Error('Both useLibpqCompat and uselibpqcompat are set. Please use only one of them.')\n }\n\n if (config.uselibpqcompat === 'true' || options.useLibpqCompat) {\n switch (config.sslmode) {\n case 'disable': {\n config.ssl = false\n break\n }\n case 'prefer': {\n config.ssl.rejectUnauthorized = false\n break\n }\n case 'require': {\n if (config.sslrootcert) {\n // If a root CA is specified, behavior of `sslmode=require` will be the same as that of `verify-ca`\n config.ssl.checkServerIdentity = function () {}\n } else {\n config.ssl.rejectUnauthorized = false\n }\n break\n }\n case 'verify-ca': {\n if (!config.ssl.ca) {\n throw new Error(\n 'SECURITY WARNING: Using sslmode=verify-ca requires specifying a CA with sslrootcert. If a public CA is used, verify-ca allows connections to a server that somebody else may have registered with the CA, making you vulnerable to Man-in-the-Middle attacks. Either specify a custom CA certificate with sslrootcert parameter or use sslmode=verify-full for proper security.'\n )\n }\n config.ssl.checkServerIdentity = function () {}\n break\n }\n case 'verify-full': {\n break\n }\n }\n } else {\n switch (config.sslmode) {\n case 'disable': {\n config.ssl = false\n break\n }\n case 'prefer':\n case 'require':\n case 'verify-ca':\n case 'verify-full': {\n break\n }\n case 'no-verify': {\n config.ssl.rejectUnauthorized = false\n break\n }\n }\n }\n\n return config\n}\n\n// convert pg-connection-string ssl config to a ClientConfig.ConnectionOptions\nfunction toConnectionOptions(sslConfig) {\n const connectionOptions = Object.entries(sslConfig).reduce((c, [key, value]) => {\n // we explicitly check for undefined and null instead of `if (value)` because some\n // options accept falsy values. Example: `ssl.rejectUnauthorized = false`\n if (value !== undefined && value !== null) {\n c[key] = value\n }\n\n return c\n }, {})\n\n return connectionOptions\n}\n\n// convert pg-connection-string config to a ClientConfig\nfunction toClientConfig(config) {\n const poolConfig = Object.entries(config).reduce((c, [key, value]) => {\n if (key === 'ssl') {\n const sslConfig = value\n\n if (typeof sslConfig === 'boolean') {\n c[key] = sslConfig\n }\n\n if (typeof sslConfig === 'object') {\n c[key] = toConnectionOptions(sslConfig)\n }\n } else if (value !== undefined && value !== null) {\n if (key === 'port') {\n // when port is not specified, it is converted into an empty string\n // we want to avoid NaN or empty string as a values in ClientConfig\n if (value !== '') {\n const v = parseInt(value, 10)\n if (isNaN(v)) {\n throw new Error(`Invalid ${key}: ${value}`)\n }\n\n c[key] = v\n }\n } else {\n c[key] = value\n }\n }\n\n return c\n }, {})\n\n return poolConfig\n}\n\n// parses a connection string into ClientConfig\nfunction parseIntoClientConfig(str) {\n return toClientConfig(parse(str))\n}\n\nmodule.exports = parse\n\nparse.parse = parse\nparse.toClientConfig = toClientConfig\nparse.parseIntoClientConfig = parseIntoClientConfig\n","// ESM wrapper for pg-connection-string\nimport connectionString from '../index.js'\n\n// Re-export the parse function\nexport default connectionString.parse\nexport const parse = connectionString.parse\nexport const toClientConfig = connectionString.toClientConfig\nexport const parseIntoClientConfig = connectionString.parseIntoClientConfig\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
|