@rfjs/pg-toolkit 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -0
- package/dist/admin/index.d.mts +8 -0
- package/dist/admin/index.d.mts.map +1 -0
- package/dist/admin/index.d.ts +8 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +47 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/index.mjs +46 -0
- package/dist/admin/index.mjs.map +1 -0
- package/dist/esm-9QNtbaRS.js +160 -0
- package/dist/esm-9QNtbaRS.js.map +1 -0
- package/dist/esm-v1isYkCK.mjs +151 -0
- package/dist/esm-v1isYkCK.mjs.map +1 -0
- package/dist/index.d.mts +19 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +51 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +50 -0
- package/dist/index.mjs.map +1 -0
- package/dist/package.json +27 -0
- package/package.json +105 -0
package/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
pg-bootstrap
|
|
2
|
+
===
|
|
3
|
+
|
|
4
|
+
This project is a `royfuwei/start-ts-templates#main/templates/lib-tsdown` template for creating a new project using the [start-ts-by](https://www.npmjs.com/package/start-ts-by) CLI.
|
|
5
|
+
|
|
6
|
+
## Getting Started
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
# 1. Install dependencies
|
|
10
|
+
npm install
|
|
11
|
+
## or pnpm
|
|
12
|
+
pnpm install
|
|
13
|
+
# 2. Run the project
|
|
14
|
+
npm run dev
|
|
15
|
+
# 3. Build the project
|
|
16
|
+
npm run build
|
|
17
|
+
# 4. Run tests
|
|
18
|
+
npm run test
|
|
19
|
+
# 5. Run lint
|
|
20
|
+
npm run lint
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Release
|
|
24
|
+
```bash
|
|
25
|
+
# 1. Release the project
|
|
26
|
+
npx standard-version
|
|
27
|
+
## or
|
|
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
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Reference
|
|
37
|
+
- [Original README](./START_BY_README.md)
|
|
38
|
+
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/admin/ensure-db.d.ts
|
|
2
|
+
declare function checkAndCreateDB(connectionString: string): Promise<void>;
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/admin/ensure-schema.d.ts
|
|
5
|
+
declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { checkAndCreateDB, checkAndCreateSchema };
|
|
8
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts"],"sourcesContent":[],"mappings":";iBAGsB,gBAAA,4BAA4C;;;iBCD5C,oBAAA,+CAGnB"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
//#region src/admin/ensure-db.d.ts
|
|
2
|
+
declare function checkAndCreateDB(connectionString: string): Promise<void>;
|
|
3
|
+
//#endregion
|
|
4
|
+
//#region src/admin/ensure-schema.d.ts
|
|
5
|
+
declare function checkAndCreateSchema(connectionString: string, schemas: string[]): Promise<void>;
|
|
6
|
+
//#endregion
|
|
7
|
+
export { checkAndCreateDB, checkAndCreateSchema };
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/admin/ensure-db.ts","../../src/admin/ensure-schema.ts"],"sourcesContent":[],"mappings":";iBAGsB,gBAAA,4BAA4C;;;iBCD5C,oBAAA,+CAGnB"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
const require_esm = require('../esm-9QNtbaRS.js');
|
|
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 } = require_esm.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
|
+
exports.checkAndCreateDB = checkAndCreateDB;
|
|
46
|
+
exports.checkAndCreateSchema = checkAndCreateSchema;
|
|
47
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["parse","Client","Client"],"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,aADrBA,kBAAM,iBAAiB;CAEtC,MAAM,wBAAwB,cAAc,KAAK,GAAG,SAAS,GAAG,KAAK,GAAG,KAAK;CAC7E,MAAM,WAAW,YAAY;CAC7B,MAAM,SAAS,IAAIC,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"}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { t as parse } from "../esm-v1isYkCK.mjs";
|
|
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
|
+
export { checkAndCreateDB, checkAndCreateSchema };
|
|
46
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,160 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOA,SAASA,QAAM,KAAK,UAAU,EAAE,EAAE;AAEhC,MAAI,IAAI,OAAO,EAAE,KAAK,KAAK;GACzB,MAAMC,WAAS,IAAI,MAAM,IAAI;AAC7B,UAAO;IAAE,MAAMA,SAAO;IAAI,UAAUA,SAAO;IAAI;;EAKjD,MAAM,SAAS,EAAE;EACjB,IAAI;EACJ,IAAI,YAAY;AAChB,MAAI,mCAAmC,KAAK,IAAI,CAE9C,OAAM,UAAU,IAAI,CAAC,QAAQ,cAAc,MAAM;AAGnD,MAAI;AACF,OAAI;AACF,aAAS,IAAI,IAAI,KAAK,kBAAkB;YACjC,GAAG;AAEV,aAAS,IAAI,IAAI,IAAI,QAAQ,MAAM,gBAAgB,EAAE,kBAAkB;AACvE,gBAAY;;WAEP,KAAK;AAEZ,OAAI,UAAU,IAAI,QAAQ;;AAI5B,OAAK,MAAM,SAAS,OAAO,aAAa,SAAS,CAC/C,QAAO,MAAM,MAAM,MAAM;AAG3B,SAAO,OAAO,OAAO,QAAQ,mBAAmB,OAAO,SAAS;AAChE,SAAO,WAAW,OAAO,YAAY,mBAAmB,OAAO,SAAS;AAExE,MAAI,OAAO,YAAY,WAAW;AAChC,UAAO,OAAO,UAAU,OAAO,SAAS;AACxC,UAAO,WAAW,OAAO,aAAa,IAAI,KAAK;AAC/C,UAAO,kBAAkB,OAAO,aAAa,IAAI,WAAW;AAC5D,UAAO;;EAET,MAAM,WAAW,YAAY,KAAK,OAAO;AACzC,MAAI,CAAC,OAAO,KAEV,QAAO,OAAO,mBAAmB,SAAS;WACjC,YAAY,QAAQ,KAAK,SAAS,CAE3C,QAAO,WAAW,WAAW,OAAO;AAEtC,MAAI,CAAC,OAAO,KAEV,QAAO,OAAO,OAAO;EAGvB,MAAM,WAAW,OAAO,SAAS,MAAM,EAAE,IAAI;AAC7C,SAAO,WAAW,WAAW,UAAU,SAAS,GAAG;AAEnD,MAAI,OAAO,QAAQ,UAAU,OAAO,QAAQ,IAC1C,QAAO,MAAM;AAGf,MAAI,OAAO,QAAQ,IACjB,QAAO,MAAM;AAGf,MAAI,OAAO,WAAW,OAAO,UAAU,OAAO,eAAe,OAAO,QAClE,QAAO,MAAM,EAAE;EAIjB,MAAM,KAAK,OAAO,WAAW,OAAO,UAAU,OAAO,cAAc,QAAQ,KAAK,GAAG;AAEnF,MAAI,OAAO,QACT,QAAO,IAAI,OAAO,GAAG,aAAa,OAAO,QAAQ,CAAC,UAAU;AAG9D,MAAI,OAAO,OACT,QAAO,IAAI,MAAM,GAAG,aAAa,OAAO,OAAO,CAAC,UAAU;AAG5D,MAAI,OAAO,YACT,QAAO,IAAI,KAAK,GAAG,aAAa,OAAO,YAAY,CAAC,UAAU;AAGhE,MAAI,QAAQ,kBAAkB,OAAO,eACnC,OAAM,IAAI,MAAM,+EAA+E;AAGjG,MAAI,OAAO,mBAAmB,UAAU,QAAQ,eAC9C,SAAQ,OAAO,SAAf;GACE,KAAK;AACH,WAAO,MAAM;AACb;GAEF,KAAK;AACH,WAAO,IAAI,qBAAqB;AAChC;GAEF,KAAK;AACH,QAAI,OAAO,YAET,QAAO,IAAI,sBAAsB,WAAY;QAE7C,QAAO,IAAI,qBAAqB;AAElC;GAEF,KAAK;AACH,QAAI,CAAC,OAAO,IAAI,GACd,OAAM,IAAI,MACR,kXACD;AAEH,WAAO,IAAI,sBAAsB,WAAY;AAC7C;GAEF,KAAK,cACH;;MAIJ,SAAQ,OAAO,SAAf;GACE,KAAK;AACH,WAAO,MAAM;AACb;GAEF,KAAK;GACL,KAAK;GACL,KAAK;GACL,KAAK,cACH;GAEF,KAAK;AACH,WAAO,IAAI,qBAAqB;AAChC;;AAKN,SAAO;;CAIT,SAAS,oBAAoB,WAAW;AAWtC,SAV0B,OAAO,QAAQ,UAAU,CAAC,QAAQ,GAAG,CAAC,KAAK,WAAW;AAG9E,OAAI,UAAU,UAAa,UAAU,KACnC,GAAE,OAAO;AAGX,UAAO;KACN,EAAE,CAAC;;CAMR,SAASC,iBAAe,QAAQ;AAgC9B,SA/BmB,OAAO,QAAQ,OAAO,CAAC,QAAQ,GAAG,CAAC,KAAK,WAAW;AACpE,OAAI,QAAQ,OAAO;IACjB,MAAM,YAAY;AAElB,QAAI,OAAO,cAAc,UACvB,GAAE,OAAO;AAGX,QAAI,OAAO,cAAc,SACvB,GAAE,OAAO,oBAAoB,UAAU;cAEhC,UAAU,UAAa,UAAU,KAC1C,KAAI,QAAQ,QAGV;QAAI,UAAU,IAAI;KAChB,MAAM,IAAI,SAAS,OAAO,GAAG;AAC7B,SAAI,MAAM,EAAE,CACV,OAAM,IAAI,MAAM,WAAW,IAAI,IAAI,QAAQ;AAG7C,OAAE,OAAO;;SAGX,GAAE,OAAO;AAIb,UAAO;KACN,EAAE,CAAC;;CAMR,SAASC,wBAAsB,KAAK;AAClC,SAAOD,iBAAeF,QAAM,IAAI,CAAC;;AAGnC,QAAO,UAAUA;AAEjB,SAAM,QAAQA;AACd,SAAM,iBAAiBE;AACvB,SAAM,wBAAwBC;;;;;;AChN9B,kBAAeC,oCAAiB;AAChC,MAAa,QAAQA,oCAAiB;AACtC,MAAa,iBAAiBA,oCAAiB;AAC/C,MAAa,wBAAwBA,oCAAiB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
const require_esm = require('./esm-9QNtbaRS.js');
|
|
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 = require_esm.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
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["parse"],"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,SAASA,kBAAM,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
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { t as parse } from "./esm-v1isYkCK.mjs";
|
|
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
|
|
@@ -0,0 +1 @@
|
|
|
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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rfjs/pg-toolkit",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "A project created by lib-tsdown",
|
|
5
|
+
"files": [
|
|
6
|
+
"dist",
|
|
7
|
+
"README.md",
|
|
8
|
+
"LICENSE"
|
|
9
|
+
],
|
|
10
|
+
"publishConfig": {
|
|
11
|
+
"access": "public"
|
|
12
|
+
},
|
|
13
|
+
"keywords": [],
|
|
14
|
+
"author": "royfuwei",
|
|
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
|
+
"tslib": "^2.8.1"
|
|
23
|
+
},
|
|
24
|
+
"main": "index.js",
|
|
25
|
+
"module": "index.mjs",
|
|
26
|
+
"types": "index.d.ts"
|
|
27
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rfjs/pg-toolkit",
|
|
3
|
+
"version": "0.0.3",
|
|
4
|
+
"description": "A project created by lib-tsdown",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"README.md",
|
|
11
|
+
"LICENSE"
|
|
12
|
+
],
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"exports": {
|
|
17
|
+
".": {
|
|
18
|
+
"types": "./dist/index.d.ts",
|
|
19
|
+
"import": "./dist/index.mjs",
|
|
20
|
+
"require": "./dist/index.js"
|
|
21
|
+
},
|
|
22
|
+
"./admin": {
|
|
23
|
+
"types": "./dist/admin/index.d.ts",
|
|
24
|
+
"import": "./dist/admin/index.mjs",
|
|
25
|
+
"require": "./dist/admin/index.js"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"lint-staged": {
|
|
29
|
+
"*.ts": [
|
|
30
|
+
"npx vitest related --run",
|
|
31
|
+
"npx prettier --write",
|
|
32
|
+
"npx eslint --fix"
|
|
33
|
+
]
|
|
34
|
+
},
|
|
35
|
+
"config": {
|
|
36
|
+
"commitizen": {
|
|
37
|
+
"path": "cz-conventional-changelog"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"keywords": [],
|
|
41
|
+
"author": "royfuwei",
|
|
42
|
+
"license": "ISC",
|
|
43
|
+
"engines": {
|
|
44
|
+
"node": ">=18",
|
|
45
|
+
"pnpm": ">=10.24.0 <11.0.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@commitlint/cli": "^19.7.1",
|
|
49
|
+
"@commitlint/config-conventional": "^19.7.1",
|
|
50
|
+
"@commitlint/cz-commitlint": "^19.6.1",
|
|
51
|
+
"@eslint/js": "^9.20.0",
|
|
52
|
+
"@types/pg": "^8.16.0",
|
|
53
|
+
"@types/pg-connection-string": "^2.0.0",
|
|
54
|
+
"@types/supertest": "^6.0.2",
|
|
55
|
+
"@vitest/coverage-istanbul": "^3.2.3",
|
|
56
|
+
"@vitest/ui": "^3.2.3",
|
|
57
|
+
"commitizen": "^4.3.1",
|
|
58
|
+
"cz-conventional-changelog": "^3.3.0",
|
|
59
|
+
"eslint": "^9.20.1",
|
|
60
|
+
"eslint-config-prettier": "^10.0.1",
|
|
61
|
+
"husky": "^9.1.7",
|
|
62
|
+
"inquirer": "9",
|
|
63
|
+
"lint-staged": "^15.4.3",
|
|
64
|
+
"pg-connection-string": "^2.9.1",
|
|
65
|
+
"prettier": "^3.5.1",
|
|
66
|
+
"rimraf": "^6.0.1",
|
|
67
|
+
"supertest": "^7.0.0",
|
|
68
|
+
"ts-node": "^10.9.2",
|
|
69
|
+
"tsdown": "0.17.0-beta.6",
|
|
70
|
+
"typescript": "^5.7.3",
|
|
71
|
+
"typescript-eslint": "^8.24.0",
|
|
72
|
+
"vitepress": "^1.6.3",
|
|
73
|
+
"vitest": "^3.2.3"
|
|
74
|
+
},
|
|
75
|
+
"dependencies": {
|
|
76
|
+
"pg": "^8.16.3",
|
|
77
|
+
"tslib": "^2.8.1"
|
|
78
|
+
},
|
|
79
|
+
"scripts": {
|
|
80
|
+
"clean": "npx npm-run-all --parallel clean:dist clean:types",
|
|
81
|
+
"clean:types": "npx rimraf ./types",
|
|
82
|
+
"clean:dist": "npx rimraf ./dist",
|
|
83
|
+
"dev": "npx npm-run-all --parallel dev:tsdown typecheck:watch",
|
|
84
|
+
"dev:tsdown": "npm run clean && tsdown --config-loader unrun --watch",
|
|
85
|
+
"build": "npm run build:tsdown",
|
|
86
|
+
"build:tsdown": "npm run clean && tsdown --config-loader unrun",
|
|
87
|
+
"typecheck": "tsc --noEmit",
|
|
88
|
+
"typecheck:watch": "tsc --noEmit --watch",
|
|
89
|
+
"lint-staged": "npx lint-staged",
|
|
90
|
+
"lint": "eslint \"{src,apps,libs,test}/**/*.ts\"",
|
|
91
|
+
"lint:fix": "eslint \"{src,apps,libs,test}/**/*.ts\" --fix",
|
|
92
|
+
"test": "npm run vitest:run",
|
|
93
|
+
"vitest": "vitest --passWithNoTests",
|
|
94
|
+
"vitest:run": "vitest --passWithNoTests --run",
|
|
95
|
+
"vitest:ui": "vitest --passWithNoTests --ui",
|
|
96
|
+
"vitest:e2e": "vitest --config vitest.config.e2e.mts --passWithNoTests",
|
|
97
|
+
"vitest:e2e:ui": "vitest --config vitest.config.e2e.mts --passWithNoTests --ui",
|
|
98
|
+
"release": "npx standard-version",
|
|
99
|
+
"commit": "npx cz",
|
|
100
|
+
"preinstall": "npx -y only-allow pnpm",
|
|
101
|
+
"docs:dev": "vitepress dev docs",
|
|
102
|
+
"docs:build": "vitepress build docs",
|
|
103
|
+
"docs:preview": "vitepress preview docs"
|
|
104
|
+
}
|
|
105
|
+
}
|