lambda-pool 0.1.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/LICENSE +21 -0
- package/README.md +291 -0
- package/dist/adapters/health.d.ts +30 -0
- package/dist/adapters/health.d.ts.map +1 -0
- package/dist/adapters/health.js +36 -0
- package/dist/adapters/health.js.map +1 -0
- package/dist/adapters/mysql.d.ts +40 -0
- package/dist/adapters/mysql.d.ts.map +1 -0
- package/dist/adapters/mysql.js +34 -0
- package/dist/adapters/mysql.js.map +1 -0
- package/dist/adapters/pg.d.ts +46 -0
- package/dist/adapters/pg.d.ts.map +1 -0
- package/dist/adapters/pg.js +34 -0
- package/dist/adapters/pg.js.map +1 -0
- package/dist/application/diagnostics.d.ts +33 -0
- package/dist/application/diagnostics.d.ts.map +1 -0
- package/dist/application/diagnostics.js +94 -0
- package/dist/application/diagnostics.js.map +1 -0
- package/dist/application/inspect.d.ts +20 -0
- package/dist/application/inspect.d.ts.map +1 -0
- package/dist/application/inspect.js +31 -0
- package/dist/application/inspect.js.map +1 -0
- package/dist/application/preflight.d.ts +28 -0
- package/dist/application/preflight.d.ts.map +1 -0
- package/dist/application/preflight.js +49 -0
- package/dist/application/preflight.js.map +1 -0
- package/dist/application/recommend.d.ts +22 -0
- package/dist/application/recommend.d.ts.map +1 -0
- package/dist/application/recommend.js +30 -0
- package/dist/application/recommend.js.map +1 -0
- package/dist/core/budget.d.ts +35 -0
- package/dist/core/budget.d.ts.map +1 -0
- package/dist/core/budget.js +48 -0
- package/dist/core/budget.js.map +1 -0
- package/dist/core/config.d.ts +24 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +32 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/dsn.d.ts +20 -0
- package/dist/core/dsn.d.ts.map +1 -0
- package/dist/core/dsn.js +38 -0
- package/dist/core/dsn.js.map +1 -0
- package/dist/core/env.d.ts +27 -0
- package/dist/core/env.d.ts.map +1 -0
- package/dist/core/env.js +52 -0
- package/dist/core/env.js.map +1 -0
- package/dist/core/providers.d.ts +29 -0
- package/dist/core/providers.d.ts.map +1 -0
- package/dist/core/providers.js +121 -0
- package/dist/core/providers.js.map +1 -0
- package/dist/core/redact.d.ts +20 -0
- package/dist/core/redact.d.ts.map +1 -0
- package/dist/core/redact.js +63 -0
- package/dist/core/redact.js.map +1 -0
- package/dist/core/result.d.ts +16 -0
- package/dist/core/result.d.ts.map +1 -0
- package/dist/core/result.js +32 -0
- package/dist/core/result.js.map +1 -0
- package/dist/core/retry.d.ts +31 -0
- package/dist/core/retry.d.ts.map +1 -0
- package/dist/core/retry.js +67 -0
- package/dist/core/retry.js.map +1 -0
- package/dist/core/url.d.ts +38 -0
- package/dist/core/url.d.ts.map +1 -0
- package/dist/core/url.js +88 -0
- package/dist/core/url.js.map +1 -0
- package/dist/index.d.ts +17 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +35 -0
- package/dist/index.js.map +1 -0
- package/dist/presentation/bin.d.ts +3 -0
- package/dist/presentation/bin.d.ts.map +1 -0
- package/dist/presentation/bin.js +11 -0
- package/dist/presentation/bin.js.map +1 -0
- package/dist/presentation/cli.d.ts +10 -0
- package/dist/presentation/cli.d.ts.map +1 -0
- package/dist/presentation/cli.js +124 -0
- package/dist/presentation/cli.js.map +1 -0
- package/package.json +133 -0
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { Engine } from "./url.ts";
|
|
2
|
+
export type ProviderId = "aiven" | "neon" | "supabase" | "planetscale" | "rds" | "railway" | "render" | "vercel-postgres" | "unknown";
|
|
3
|
+
export interface ProviderPreset {
|
|
4
|
+
id: ProviderId;
|
|
5
|
+
label: string;
|
|
6
|
+
/** Engines this preset is relevant to (informational). */
|
|
7
|
+
engines: Engine[];
|
|
8
|
+
/** Typical `max_connections` on entry/free plans (for the budget calc). */
|
|
9
|
+
typicalMaxConnections: number;
|
|
10
|
+
/** Safe per-instance pool size for a *direct* (un-pooled) connection. */
|
|
11
|
+
safeDirectPoolLimit: number;
|
|
12
|
+
/** Does the provider offer a transaction pooler (PgBouncer-style)? */
|
|
13
|
+
hasPooledEndpoint: boolean;
|
|
14
|
+
/** Whether the host string indicates the *pooled* endpoint specifically. */
|
|
15
|
+
isPooledHost?: (host: string) => boolean;
|
|
16
|
+
/** Short, actionable note shown in diagnostics. */
|
|
17
|
+
note: string;
|
|
18
|
+
/** Hostname matcher. */
|
|
19
|
+
matches: (host: string) => boolean;
|
|
20
|
+
}
|
|
21
|
+
/** All known presets (excluding the catch-all unknown). */
|
|
22
|
+
export declare function listProviders(): ReadonlyArray<ProviderPreset>;
|
|
23
|
+
/** Identify the provider from a hostname. Always returns a preset. */
|
|
24
|
+
export declare function detectProvider(host: string): ProviderPreset;
|
|
25
|
+
/** Look up a preset by id (returns the unknown preset if not found). */
|
|
26
|
+
export declare function getProvider(id: ProviderId): ProviderPreset;
|
|
27
|
+
/** Is this host the provider's pooled endpoint, when one exists? */
|
|
28
|
+
export declare function isPooledEndpoint(host: string): boolean;
|
|
29
|
+
//# sourceMappingURL=providers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.d.ts","sourceRoot":"","sources":["../../src/core/providers.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAEvC,MAAM,MAAM,UAAU,GAClB,OAAO,GACP,MAAM,GACN,UAAU,GACV,aAAa,GACb,KAAK,GACL,SAAS,GACT,QAAQ,GACR,iBAAiB,GACjB,SAAS,CAAC;AAEd,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,UAAU,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,0DAA0D;IAC1D,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,2EAA2E;IAC3E,qBAAqB,EAAE,MAAM,CAAC;IAC9B,yEAAyE;IACzE,mBAAmB,EAAE,MAAM,CAAC;IAC5B,sEAAsE;IACtE,iBAAiB,EAAE,OAAO,CAAC;IAC3B,4EAA4E;IAC5E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;IACzC,mDAAmD;IACnD,IAAI,EAAE,MAAM,CAAC;IACb,wBAAwB;IACxB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC;CACpC;AAmGD,2DAA2D;AAC3D,wBAAgB,aAAa,IAAI,aAAa,CAAC,cAAc,CAAC,CAE7D;AAED,sEAAsE;AACtE,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,cAAc,CAG3D;AAED,wEAAwE;AACxE,wBAAgB,WAAW,CAAC,EAAE,EAAE,UAAU,GAAG,cAAc,CAE1D;AAED,oEAAoE;AACpE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAGtD"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
// Provider presets and host-based auto-detection.
|
|
2
|
+
//
|
|
3
|
+
// Different managed providers have different connection realities. This module
|
|
4
|
+
// is a pure, dependency-free registry: given a host, identify the provider and
|
|
5
|
+
// surface its guidance (typical max_connections, whether a pooled endpoint
|
|
6
|
+
// exists, the safe default pool size). No network calls — detection is purely
|
|
7
|
+
// structural on the hostname.
|
|
8
|
+
const PRESETS = [
|
|
9
|
+
{
|
|
10
|
+
id: "neon",
|
|
11
|
+
label: "Neon",
|
|
12
|
+
engines: ["postgres"],
|
|
13
|
+
typicalMaxConnections: 100,
|
|
14
|
+
safeDirectPoolLimit: 1,
|
|
15
|
+
hasPooledEndpoint: true,
|
|
16
|
+
isPooledHost: (h) => h.includes("-pooler."),
|
|
17
|
+
note: "Use the pooled endpoint (host contains '-pooler') for serverless; it multiplexes connections so a small pool is fine.",
|
|
18
|
+
matches: (h) => h.endsWith(".neon.tech"),
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
id: "supabase",
|
|
22
|
+
label: "Supabase",
|
|
23
|
+
engines: ["postgres"],
|
|
24
|
+
typicalMaxConnections: 60,
|
|
25
|
+
safeDirectPoolLimit: 1,
|
|
26
|
+
hasPooledEndpoint: true,
|
|
27
|
+
isPooledHost: (h) => h.includes("pooler.supabase"),
|
|
28
|
+
note: "Use the Supavisor pooler host (port 6543, 'pooler.supabase.com') in serverless rather than the direct 5432 host.",
|
|
29
|
+
matches: (h) => h.includes("supabase."),
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: "aiven",
|
|
33
|
+
label: "Aiven",
|
|
34
|
+
engines: ["mysql", "postgres"],
|
|
35
|
+
typicalMaxConnections: 20,
|
|
36
|
+
safeDirectPoolLimit: 1,
|
|
37
|
+
hasPooledEndpoint: false,
|
|
38
|
+
note: "Free/Hobbyist plans have a very small max_connections; keep the pool at 1 per warm instance and pass the CA via DATABASE_SSL_CA_BASE64.",
|
|
39
|
+
matches: (h) => h.endsWith(".aivencloud.com"),
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
id: "planetscale",
|
|
43
|
+
label: "PlanetScale",
|
|
44
|
+
engines: ["mysql"],
|
|
45
|
+
typicalMaxConnections: 1000,
|
|
46
|
+
safeDirectPoolLimit: 1,
|
|
47
|
+
hasPooledEndpoint: true,
|
|
48
|
+
note: "PlanetScale proxies connections already; a tiny pool per instance is correct and TLS is required.",
|
|
49
|
+
matches: (h) => h.includes("psdb.cloud") || h.endsWith(".planetscale.com"),
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
id: "vercel-postgres",
|
|
53
|
+
label: "Vercel Postgres",
|
|
54
|
+
engines: ["postgres"],
|
|
55
|
+
typicalMaxConnections: 100,
|
|
56
|
+
safeDirectPoolLimit: 1,
|
|
57
|
+
hasPooledEndpoint: true,
|
|
58
|
+
isPooledHost: (h) => h.includes("-pooler."),
|
|
59
|
+
note: "Backed by Neon; prefer the pooled host in serverless functions.",
|
|
60
|
+
matches: (h) => h.includes(".vercel-storage.com"),
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
id: "railway",
|
|
64
|
+
label: "Railway",
|
|
65
|
+
engines: ["mysql", "postgres"],
|
|
66
|
+
typicalMaxConnections: 100,
|
|
67
|
+
safeDirectPoolLimit: 2,
|
|
68
|
+
hasPooledEndpoint: false,
|
|
69
|
+
note: "No managed pooler; keep the per-instance pool small.",
|
|
70
|
+
matches: (h) => h.includes("railway.app") || h.includes("rlwy.net"),
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: "render",
|
|
74
|
+
label: "Render",
|
|
75
|
+
engines: ["postgres"],
|
|
76
|
+
typicalMaxConnections: 97,
|
|
77
|
+
safeDirectPoolLimit: 2,
|
|
78
|
+
hasPooledEndpoint: false,
|
|
79
|
+
note: "Free/starter Postgres has a modest cap; keep the per-instance pool small.",
|
|
80
|
+
matches: (h) => h.endsWith(".render.com"),
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
id: "rds",
|
|
84
|
+
label: "Amazon RDS / Aurora",
|
|
85
|
+
engines: ["mysql", "postgres"],
|
|
86
|
+
typicalMaxConnections: 30,
|
|
87
|
+
safeDirectPoolLimit: 1,
|
|
88
|
+
hasPooledEndpoint: true,
|
|
89
|
+
note: "max_connections scales with instance size; micro/small classes are tiny. Consider RDS Proxy for serverless fan-out.",
|
|
90
|
+
matches: (h) => h.includes(".rds.amazonaws.com"),
|
|
91
|
+
},
|
|
92
|
+
];
|
|
93
|
+
const UNKNOWN = {
|
|
94
|
+
id: "unknown",
|
|
95
|
+
label: "Unknown provider",
|
|
96
|
+
engines: ["mysql", "postgres"],
|
|
97
|
+
typicalMaxConnections: 100,
|
|
98
|
+
safeDirectPoolLimit: 1,
|
|
99
|
+
hasPooledEndpoint: false,
|
|
100
|
+
note: "Provider not recognized; defaulting to a conservative pool of 1 per instance.",
|
|
101
|
+
matches: () => true,
|
|
102
|
+
};
|
|
103
|
+
/** All known presets (excluding the catch-all unknown). */
|
|
104
|
+
export function listProviders() {
|
|
105
|
+
return PRESETS;
|
|
106
|
+
}
|
|
107
|
+
/** Identify the provider from a hostname. Always returns a preset. */
|
|
108
|
+
export function detectProvider(host) {
|
|
109
|
+
const h = host.toLowerCase();
|
|
110
|
+
return PRESETS.find((p) => p.matches(h)) ?? UNKNOWN;
|
|
111
|
+
}
|
|
112
|
+
/** Look up a preset by id (returns the unknown preset if not found). */
|
|
113
|
+
export function getProvider(id) {
|
|
114
|
+
return PRESETS.find((p) => p.id === id) ?? UNKNOWN;
|
|
115
|
+
}
|
|
116
|
+
/** Is this host the provider's pooled endpoint, when one exists? */
|
|
117
|
+
export function isPooledEndpoint(host) {
|
|
118
|
+
const preset = detectProvider(host);
|
|
119
|
+
return preset.hasPooledEndpoint && (preset.isPooledHost?.(host.toLowerCase()) ?? false);
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=providers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"providers.js","sourceRoot":"","sources":["../../src/core/providers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/** Default key substrings (case-insensitive) whose values get masked. */
|
|
2
|
+
export declare const DEFAULT_SECRET_KEYS: readonly ["password", "passwd", "secret", "token", "apikey", "api_key", "authorization", "auth", "credential", "connectionstring", "connection_string", "dsn", "ssl_ca", "ca"];
|
|
3
|
+
export interface RedactOptions {
|
|
4
|
+
/** Extra key substrings to treat as secret (merged with the defaults). */
|
|
5
|
+
keys?: string[];
|
|
6
|
+
/** Replacement string. Default "***". */
|
|
7
|
+
mask?: string;
|
|
8
|
+
/** Max recursion depth (guards against cycles/huge graphs). Default 8. */
|
|
9
|
+
maxDepth?: number;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Return a deep copy of `value` with secret-looking keys masked.
|
|
13
|
+
*
|
|
14
|
+
* - Object keys are matched case-insensitively against the secret-key list.
|
|
15
|
+
* - Arrays are walked element-wise.
|
|
16
|
+
* - Cycles and over-deep graphs are cut off at `maxDepth` (replaced with the
|
|
17
|
+
* string "[Depth limit]") so this is always safe to call on arbitrary input.
|
|
18
|
+
*/
|
|
19
|
+
export declare function redact<T>(value: T, options?: RedactOptions): T;
|
|
20
|
+
//# sourceMappingURL=redact.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.d.ts","sourceRoot":"","sources":["../../src/core/redact.ts"],"names":[],"mappings":"AAMA,yEAAyE;AACzE,eAAO,MAAM,mBAAmB,gLAetB,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,0EAA0E;IAC1E,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,yCAAyC;IACzC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,0EAA0E;IAC1E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAOD;;;;;;;GAOG;AACH,wBAAgB,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,GAAE,aAAkB,GAAG,CAAC,CA2BlE"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Structural redaction for logs and crash reports.
|
|
2
|
+
//
|
|
3
|
+
// `redactUrl` (core/url) masks a connection string; this masks *objects* —
|
|
4
|
+
// config dumps, error `extra` bags, request context — by key name. Pure and
|
|
5
|
+
// dependency-free. The default key set targets the usual credential leaks.
|
|
6
|
+
/** Default key substrings (case-insensitive) whose values get masked. */
|
|
7
|
+
export const DEFAULT_SECRET_KEYS = [
|
|
8
|
+
"password",
|
|
9
|
+
"passwd",
|
|
10
|
+
"secret",
|
|
11
|
+
"token",
|
|
12
|
+
"apikey",
|
|
13
|
+
"api_key",
|
|
14
|
+
"authorization",
|
|
15
|
+
"auth",
|
|
16
|
+
"credential",
|
|
17
|
+
"connectionstring",
|
|
18
|
+
"connection_string",
|
|
19
|
+
"dsn",
|
|
20
|
+
"ssl_ca",
|
|
21
|
+
"ca",
|
|
22
|
+
];
|
|
23
|
+
function isSecretKey(key, needles) {
|
|
24
|
+
const k = key.toLowerCase();
|
|
25
|
+
return needles.some((n) => k.includes(n));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Return a deep copy of `value` with secret-looking keys masked.
|
|
29
|
+
*
|
|
30
|
+
* - Object keys are matched case-insensitively against the secret-key list.
|
|
31
|
+
* - Arrays are walked element-wise.
|
|
32
|
+
* - Cycles and over-deep graphs are cut off at `maxDepth` (replaced with the
|
|
33
|
+
* string "[Depth limit]") so this is always safe to call on arbitrary input.
|
|
34
|
+
*/
|
|
35
|
+
export function redact(value, options = {}) {
|
|
36
|
+
const needles = [
|
|
37
|
+
...DEFAULT_SECRET_KEYS,
|
|
38
|
+
...(options.keys ?? []).map((k) => k.toLowerCase()),
|
|
39
|
+
];
|
|
40
|
+
const mask = options.mask ?? "***";
|
|
41
|
+
const maxDepth = options.maxDepth ?? 8;
|
|
42
|
+
const seen = new WeakSet();
|
|
43
|
+
function walk(v, depth) {
|
|
44
|
+
if (depth > maxDepth)
|
|
45
|
+
return "[Depth limit]";
|
|
46
|
+
if (v === null || typeof v !== "object")
|
|
47
|
+
return v;
|
|
48
|
+
if (seen.has(v))
|
|
49
|
+
return "[Circular]";
|
|
50
|
+
seen.add(v);
|
|
51
|
+
if (Array.isArray(v))
|
|
52
|
+
return v.map((item) => walk(item, depth + 1));
|
|
53
|
+
const out = {};
|
|
54
|
+
for (const [key, val] of Object.entries(v)) {
|
|
55
|
+
out[key] = isSecretKey(key, needles)
|
|
56
|
+
? mask
|
|
57
|
+
: walk(val, depth + 1);
|
|
58
|
+
}
|
|
59
|
+
return out;
|
|
60
|
+
}
|
|
61
|
+
return walk(value, 0);
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=redact.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redact.js","sourceRoot":"","sources":["../../src/core/redact.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,2EAA2E;AAC3E,4EAA4E;AAC5E,2EAA2E;AAE3E,yEAAyE;AACzE,MAAM,CAAC,MAAM,mBAAmB,GAAG;IACjC,UAAU;IACV,QAAQ;IACR,QAAQ;IACR,OAAO;IACP,QAAQ;IACR,SAAS;IACT,eAAe;IACf,MAAM;IACN,YAAY;IACZ,kBAAkB;IAClB,mBAAmB;IACnB,KAAK;IACL,QAAQ;IACR,IAAI;CACI,CAAC;AAWX,SAAS,WAAW,CAAC,GAAW,EAAE,OAAiB;IACjD,MAAM,CAAC,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC;IAC5B,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;AAC5C,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,MAAM,CAAI,KAAQ,EAAE,UAAyB,EAAE;IAC7D,MAAM,OAAO,GAAG;QACd,GAAG,mBAAmB;QACtB,GAAG,CAAC,OAAO,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC;KACpD,CAAC;IACF,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,IAAI,KAAK,CAAC;IACnC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,OAAO,EAAU,CAAC;IAEnC,SAAS,IAAI,CAAC,CAAU,EAAE,KAAa;QACrC,IAAI,KAAK,GAAG,QAAQ;YAAE,OAAO,eAAe,CAAC;QAC7C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ;YAAE,OAAO,CAAC,CAAC;QAClD,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;YAAE,OAAO,YAAY,CAAC;QACrC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAEZ,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC;QAEpE,MAAM,GAAG,GAA4B,EAAE,CAAC;QACxC,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;YAC3C,GAAG,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC;gBAClC,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,GAAG,CAAC,CAAC,CAAC;QAC3B,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAED,OAAO,IAAI,CAAC,KAAK,EAAE,CAAC,CAAM,CAAC;AAC7B,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type Result<T, E = Error> = {
|
|
2
|
+
ok: true;
|
|
3
|
+
value: T;
|
|
4
|
+
} | {
|
|
5
|
+
ok: false;
|
|
6
|
+
error: E;
|
|
7
|
+
};
|
|
8
|
+
export declare function ok<T>(value: T): Result<T, never>;
|
|
9
|
+
export declare function err<E>(error: E): Result<never, E>;
|
|
10
|
+
/** Run a throwing function and capture the outcome as a Result. */
|
|
11
|
+
export declare function attempt<T>(fn: () => T): Result<T, Error>;
|
|
12
|
+
/** Unwrap a Result, throwing the error if it failed. */
|
|
13
|
+
export declare function unwrap<T, E>(r: Result<T, E>): T;
|
|
14
|
+
/** Unwrap a Result or return a fallback value. */
|
|
15
|
+
export declare function unwrapOr<T, E>(r: Result<T, E>, fallback: T): T;
|
|
16
|
+
//# sourceMappingURL=result.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.d.ts","sourceRoot":"","sources":["../../src/core/result.ts"],"names":[],"mappings":"AAOA,MAAM,MAAM,MAAM,CAAC,CAAC,EAAE,CAAC,GAAG,KAAK,IAC3B;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,GACtB;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,CAAC,CAAA;CAAE,CAAC;AAE5B,wBAAgB,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAEhD;AAED,wBAAgB,GAAG,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAEjD;AAED,mEAAmE;AACnE,wBAAgB,OAAO,CAAC,CAAC,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,MAAM,CAAC,CAAC,EAAE,KAAK,CAAC,CAMxD;AAED,wDAAwD;AACxD,wBAAgB,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,CAG/C;AAED,kDAAkD;AAClD,wBAAgB,QAAQ,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,GAAG,CAAC,CAE9D"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
// A tiny Result/Either type for non-throwing APIs.
|
|
2
|
+
//
|
|
3
|
+
// Some callers (CLIs, request handlers, validators) prefer to branch on a value
|
|
4
|
+
// rather than wrap everything in try/catch. This is the dependency-free
|
|
5
|
+
// primitive the `safe*` helpers return. Single responsibility: model success or
|
|
6
|
+
// failure, nothing else.
|
|
7
|
+
export function ok(value) {
|
|
8
|
+
return { ok: true, value };
|
|
9
|
+
}
|
|
10
|
+
export function err(error) {
|
|
11
|
+
return { ok: false, error };
|
|
12
|
+
}
|
|
13
|
+
/** Run a throwing function and capture the outcome as a Result. */
|
|
14
|
+
export function attempt(fn) {
|
|
15
|
+
try {
|
|
16
|
+
return ok(fn());
|
|
17
|
+
}
|
|
18
|
+
catch (e) {
|
|
19
|
+
return err(e instanceof Error ? e : new Error(String(e)));
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Unwrap a Result, throwing the error if it failed. */
|
|
23
|
+
export function unwrap(r) {
|
|
24
|
+
if (r.ok)
|
|
25
|
+
return r.value;
|
|
26
|
+
throw r.error instanceof Error ? r.error : new Error(String(r.error));
|
|
27
|
+
}
|
|
28
|
+
/** Unwrap a Result or return a fallback value. */
|
|
29
|
+
export function unwrapOr(r, fallback) {
|
|
30
|
+
return r.ok ? r.value : fallback;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"result.js","sourceRoot":"","sources":["../../src/core/result.ts"],"names":[],"mappings":"AAAA,mDAAmD;AACnD,EAAE;AACF,gFAAgF;AAChF,wEAAwE;AACxE,gFAAgF;AAChF,yBAAyB;AAMzB,MAAM,UAAU,EAAE,CAAI,KAAQ;IAC5B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC;AAC7B,CAAC;AAED,MAAM,UAAU,GAAG,CAAI,KAAQ;IAC7B,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC;AAC9B,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,OAAO,CAAI,EAAW;IACpC,IAAI,CAAC;QACH,OAAO,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC;IAClB,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,GAAG,CAAC,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,wDAAwD;AACxD,MAAM,UAAU,MAAM,CAAO,CAAe;IAC1C,IAAI,CAAC,CAAC,EAAE;QAAE,OAAO,CAAC,CAAC,KAAK,CAAC;IACzB,MAAM,CAAC,CAAC,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;AACxE,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,QAAQ,CAAO,CAAe,EAAE,QAAW;IACzD,OAAO,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC;AACnC,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export interface RetryOptions {
|
|
2
|
+
/** Total attempts including the first. Default 3. */
|
|
3
|
+
attempts?: number;
|
|
4
|
+
/** Base delay in ms for the first backoff. Default 100. */
|
|
5
|
+
baseDelayMs?: number;
|
|
6
|
+
/** Upper bound on any single delay. Default 2000. */
|
|
7
|
+
maxDelayMs?: number;
|
|
8
|
+
/** Decide whether an error is worth retrying. Default: always. */
|
|
9
|
+
retryable?: (error: Error) => boolean;
|
|
10
|
+
/** Injectable sleep (tests pass a no-op); defaults to setTimeout. */
|
|
11
|
+
sleep?: (ms: number) => Promise<void>;
|
|
12
|
+
/** Injectable RNG in [0,1); defaults to Math.random. */
|
|
13
|
+
random?: () => number;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Compute the delay before attempt `n` (1-based: the delay *after* attempt n
|
|
17
|
+
* fails). Exponential growth `base * 2^(n-1)`, capped, then full jitter applied.
|
|
18
|
+
*/
|
|
19
|
+
export declare function backoffDelay(attempt: number, baseDelayMs: number, maxDelayMs: number, random?: () => number): number;
|
|
20
|
+
/**
|
|
21
|
+
* Run `fn`, retrying transient failures with jittered exponential backoff.
|
|
22
|
+
* Re-throws the last error once attempts are exhausted or an error is deemed
|
|
23
|
+
* non-retryable.
|
|
24
|
+
*/
|
|
25
|
+
export declare function withRetry<T>(fn: () => Promise<T>, options?: RetryOptions): Promise<T>;
|
|
26
|
+
/**
|
|
27
|
+
* A reasonable default `retryable` predicate for DB connect errors: transient
|
|
28
|
+
* network / availability conditions, not auth or "database does not exist".
|
|
29
|
+
*/
|
|
30
|
+
export declare function isTransientDbError(error: Error): boolean;
|
|
31
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../src/core/retry.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,YAAY;IAC3B,qDAAqD;IACrD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,2DAA2D;IAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,kEAAkE;IAClE,SAAS,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC;IACtC,qEAAqE;IACrE,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;CACvB;AAKD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,EAClB,MAAM,GAAE,MAAM,MAAoB,GACjC,MAAM,CAIR;AAED;;;;GAIG;AACH,wBAAsB,SAAS,CAAC,CAAC,EAC/B,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,CAAC,CAAC,CAsBZ;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO,CAoBxD"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
// Exponential backoff with full jitter.
|
|
2
|
+
//
|
|
3
|
+
// Cold serverless starts and brief DB failovers cause transient connect errors.
|
|
4
|
+
// A short, jittered retry turns most of those into a non-event. Pure scheduling
|
|
5
|
+
// logic with an injectable sleep so it is fully unit-testable (no real waiting).
|
|
6
|
+
const defaultSleep = (ms) => new Promise((r) => setTimeout(r, ms));
|
|
7
|
+
/**
|
|
8
|
+
* Compute the delay before attempt `n` (1-based: the delay *after* attempt n
|
|
9
|
+
* fails). Exponential growth `base * 2^(n-1)`, capped, then full jitter applied.
|
|
10
|
+
*/
|
|
11
|
+
export function backoffDelay(attempt, baseDelayMs, maxDelayMs, random = Math.random) {
|
|
12
|
+
const exp = baseDelayMs * 2 ** (attempt - 1);
|
|
13
|
+
const capped = Math.min(exp, maxDelayMs);
|
|
14
|
+
return Math.floor(random() * capped); // full jitter: [0, capped)
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Run `fn`, retrying transient failures with jittered exponential backoff.
|
|
18
|
+
* Re-throws the last error once attempts are exhausted or an error is deemed
|
|
19
|
+
* non-retryable.
|
|
20
|
+
*/
|
|
21
|
+
export async function withRetry(fn, options = {}) {
|
|
22
|
+
const attempts = Math.max(1, Math.floor(options.attempts ?? 3));
|
|
23
|
+
const baseDelayMs = options.baseDelayMs ?? 100;
|
|
24
|
+
const maxDelayMs = options.maxDelayMs ?? 2000;
|
|
25
|
+
const retryable = options.retryable ?? (() => true);
|
|
26
|
+
const sleep = options.sleep ?? defaultSleep;
|
|
27
|
+
const random = options.random ?? Math.random;
|
|
28
|
+
let lastError = new Error("lambda-pool: withRetry ran zero attempts");
|
|
29
|
+
for (let attempt = 1; attempt <= attempts; attempt++) {
|
|
30
|
+
try {
|
|
31
|
+
return await fn();
|
|
32
|
+
}
|
|
33
|
+
catch (e) {
|
|
34
|
+
lastError = e instanceof Error ? e : new Error(String(e));
|
|
35
|
+
const isLast = attempt === attempts;
|
|
36
|
+
if (isLast || !retryable(lastError))
|
|
37
|
+
throw lastError;
|
|
38
|
+
await sleep(backoffDelay(attempt, baseDelayMs, maxDelayMs, random));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
throw lastError;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* A reasonable default `retryable` predicate for DB connect errors: transient
|
|
45
|
+
* network / availability conditions, not auth or "database does not exist".
|
|
46
|
+
*/
|
|
47
|
+
export function isTransientDbError(error) {
|
|
48
|
+
const msg = error.message.toLowerCase();
|
|
49
|
+
const code = error.code?.toUpperCase() ?? "";
|
|
50
|
+
const transientCodes = new Set([
|
|
51
|
+
"ECONNREFUSED",
|
|
52
|
+
"ECONNRESET",
|
|
53
|
+
"ETIMEDOUT",
|
|
54
|
+
"EPIPE",
|
|
55
|
+
"EAI_AGAIN",
|
|
56
|
+
"PROTOCOL_CONNECTION_LOST",
|
|
57
|
+
"ER_CON_COUNT_ERROR", // too many connections — may clear on retry
|
|
58
|
+
"57P03", // postgres: cannot_connect_now (starting up)
|
|
59
|
+
]);
|
|
60
|
+
if (transientCodes.has(code))
|
|
61
|
+
return true;
|
|
62
|
+
return (msg.includes("timeout") ||
|
|
63
|
+
msg.includes("too many clients") ||
|
|
64
|
+
msg.includes("connection terminated") ||
|
|
65
|
+
msg.includes("server is starting up"));
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../src/core/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { type Result } from "./result.ts";
|
|
2
|
+
export type Engine = "mysql" | "postgres";
|
|
3
|
+
export interface ParsedConnection {
|
|
4
|
+
engine: Engine;
|
|
5
|
+
protocol: string;
|
|
6
|
+
host: string;
|
|
7
|
+
port: number;
|
|
8
|
+
user: string;
|
|
9
|
+
/** Present only when the URI carried a password. */
|
|
10
|
+
password?: string;
|
|
11
|
+
database: string;
|
|
12
|
+
/** Query params (e.g. `sslmode`, `ssl-mode`, `connection_limit`). */
|
|
13
|
+
params: Record<string, string>;
|
|
14
|
+
}
|
|
15
|
+
/** Default port for an engine, used when the URI omits one. */
|
|
16
|
+
export declare function defaultPort(engine: Engine): number;
|
|
17
|
+
/**
|
|
18
|
+
* Parse a database connection URI into typed components.
|
|
19
|
+
*
|
|
20
|
+
* Throws a clear error for a malformed or unsupported URI rather than letting a
|
|
21
|
+
* cryptic driver error surface later at connect time.
|
|
22
|
+
*/
|
|
23
|
+
export declare function parseConnectionString(uri: string): ParsedConnection;
|
|
24
|
+
/**
|
|
25
|
+
* Non-throwing variant of {@link parseConnectionString}. Returns a Result so
|
|
26
|
+
* callers can branch instead of using try/catch.
|
|
27
|
+
*/
|
|
28
|
+
export declare function safeParseConnectionString(uri: string): Result<ParsedConnection, Error>;
|
|
29
|
+
/**
|
|
30
|
+
* Return the URI with the password replaced by `***`, safe for logs.
|
|
31
|
+
*
|
|
32
|
+
* Preserves everything else (host, port, db, params) so the redacted string is
|
|
33
|
+
* still useful for debugging "which database am I pointed at?".
|
|
34
|
+
*/
|
|
35
|
+
export declare function redactUrl(uri: string): string;
|
|
36
|
+
/** True when the URI's query params request SSL/TLS in any common spelling. */
|
|
37
|
+
export declare function urlRequestsSsl(uri: string): boolean;
|
|
38
|
+
//# sourceMappingURL=url.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.d.ts","sourceRoot":"","sources":["../../src/core/url.ts"],"names":[],"mappings":"AAOA,OAAO,EAAW,KAAK,MAAM,EAAE,MAAM,aAAa,CAAC;AAEnD,MAAM,MAAM,MAAM,GAAG,OAAO,GAAG,UAAU,CAAC;AAE1C,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAChC;AAKD,+DAA+D;AAC/D,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAElD;AAUD;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,gBAAgB,CA0BnE;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,GACV,MAAM,CAAC,gBAAgB,EAAE,KAAK,CAAC,CAEjC;AAED;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAS7C;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAQnD"}
|
package/dist/core/url.js
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
// Connection-string parsing and redaction.
|
|
2
|
+
//
|
|
3
|
+
// Useful on its own: parse a `mysql://` / `postgres://` URI into typed parts,
|
|
4
|
+
// and — importantly — produce a redacted form safe to put in logs, error
|
|
5
|
+
// messages, and crash reports. Leaking a DB password into a log aggregator is a
|
|
6
|
+
// classic incident; `redactUrl` makes "log the connection target" safe.
|
|
7
|
+
import { attempt } from "./result.js";
|
|
8
|
+
const POSTGRES_PROTOCOLS = new Set(["postgres:", "postgresql:"]);
|
|
9
|
+
const MYSQL_PROTOCOLS = new Set(["mysql:", "mariadb:"]);
|
|
10
|
+
/** Default port for an engine, used when the URI omits one. */
|
|
11
|
+
export function defaultPort(engine) {
|
|
12
|
+
return engine === "postgres" ? 5432 : 3306;
|
|
13
|
+
}
|
|
14
|
+
function engineFromProtocol(protocol) {
|
|
15
|
+
if (POSTGRES_PROTOCOLS.has(protocol))
|
|
16
|
+
return "postgres";
|
|
17
|
+
if (MYSQL_PROTOCOLS.has(protocol))
|
|
18
|
+
return "mysql";
|
|
19
|
+
throw new Error(`lambda-pool: unsupported connection protocol "${protocol}" — expected mysql:// or postgres://`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Parse a database connection URI into typed components.
|
|
23
|
+
*
|
|
24
|
+
* Throws a clear error for a malformed or unsupported URI rather than letting a
|
|
25
|
+
* cryptic driver error surface later at connect time.
|
|
26
|
+
*/
|
|
27
|
+
export function parseConnectionString(uri) {
|
|
28
|
+
let url;
|
|
29
|
+
try {
|
|
30
|
+
url = new URL(uri);
|
|
31
|
+
}
|
|
32
|
+
catch {
|
|
33
|
+
throw new Error("lambda-pool: connection string is not a valid URI.");
|
|
34
|
+
}
|
|
35
|
+
const engine = engineFromProtocol(url.protocol);
|
|
36
|
+
const params = {};
|
|
37
|
+
for (const [k, v] of url.searchParams)
|
|
38
|
+
params[k] = v;
|
|
39
|
+
const database = decodeURIComponent(url.pathname.replace(/^\//, ""));
|
|
40
|
+
return {
|
|
41
|
+
engine,
|
|
42
|
+
protocol: url.protocol,
|
|
43
|
+
host: url.hostname,
|
|
44
|
+
port: url.port ? Number(url.port) : defaultPort(engine),
|
|
45
|
+
user: decodeURIComponent(url.username),
|
|
46
|
+
...(url.password
|
|
47
|
+
? { password: decodeURIComponent(url.password) }
|
|
48
|
+
: {}),
|
|
49
|
+
database,
|
|
50
|
+
params,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Non-throwing variant of {@link parseConnectionString}. Returns a Result so
|
|
55
|
+
* callers can branch instead of using try/catch.
|
|
56
|
+
*/
|
|
57
|
+
export function safeParseConnectionString(uri) {
|
|
58
|
+
return attempt(() => parseConnectionString(uri));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Return the URI with the password replaced by `***`, safe for logs.
|
|
62
|
+
*
|
|
63
|
+
* Preserves everything else (host, port, db, params) so the redacted string is
|
|
64
|
+
* still useful for debugging "which database am I pointed at?".
|
|
65
|
+
*/
|
|
66
|
+
export function redactUrl(uri) {
|
|
67
|
+
let url;
|
|
68
|
+
try {
|
|
69
|
+
url = new URL(uri);
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
return "<invalid-connection-string>";
|
|
73
|
+
}
|
|
74
|
+
if (url.password)
|
|
75
|
+
url.password = "***";
|
|
76
|
+
return url.toString();
|
|
77
|
+
}
|
|
78
|
+
/** True when the URI's query params request SSL/TLS in any common spelling. */
|
|
79
|
+
export function urlRequestsSsl(uri) {
|
|
80
|
+
const { params } = parseConnectionString(uri);
|
|
81
|
+
const sslmode = (params["sslmode"] ?? params["ssl-mode"] ?? "").toLowerCase();
|
|
82
|
+
if (["require", "required", "verify-ca", "verify-full"].includes(sslmode)) {
|
|
83
|
+
return true;
|
|
84
|
+
}
|
|
85
|
+
const ssl = (params["ssl"] ?? "").toLowerCase();
|
|
86
|
+
return ssl === "true" || ssl === "1";
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=url.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"url.js","sourceRoot":"","sources":["../../src/core/url.ts"],"names":[],"mappings":"AAAA,2CAA2C;AAC3C,EAAE;AACF,8EAA8E;AAC9E,yEAAyE;AACzE,gFAAgF;AAChF,wEAAwE;AAExE,OAAO,EAAE,OAAO,EAAe,MAAM,aAAa,CAAC;AAiBnD,MAAM,kBAAkB,GAAG,IAAI,GAAG,CAAC,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;AACjE,MAAM,eAAe,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;AAExD,+DAA+D;AAC/D,MAAM,UAAU,WAAW,CAAC,MAAc;IACxC,OAAO,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED,SAAS,kBAAkB,CAAC,QAAgB;IAC1C,IAAI,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,UAAU,CAAC;IACxD,IAAI,eAAe,CAAC,GAAG,CAAC,QAAQ,CAAC;QAAE,OAAO,OAAO,CAAC;IAClD,MAAM,IAAI,KAAK,CACb,iDAAiD,QAAQ,sCAAsC,CAChG,CAAC;AACJ,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,qBAAqB,CAAC,GAAW;IAC/C,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;IACxE,CAAC;IAED,MAAM,MAAM,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;IAChD,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,CAAC,YAAY;QAAE,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IAErD,MAAM,QAAQ,GAAG,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC;IAErE,OAAO;QACL,MAAM;QACN,QAAQ,EAAE,GAAG,CAAC,QAAQ;QACtB,IAAI,EAAE,GAAG,CAAC,QAAQ;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC;QACvD,IAAI,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC;QACtC,GAAG,CAAC,GAAG,CAAC,QAAQ;YACd,CAAC,CAAC,EAAE,QAAQ,EAAE,kBAAkB,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE;YAChD,CAAC,CAAC,EAAE,CAAC;QACP,QAAQ;QACR,MAAM;KACP,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,yBAAyB,CACvC,GAAW;IAEX,OAAO,OAAO,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAC,CAAC;AACnD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,GAAW;IACnC,IAAI,GAAQ,CAAC;IACb,IAAI,CAAC;QACH,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC;IACrB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,6BAA6B,CAAC;IACvC,CAAC;IACD,IAAI,GAAG,CAAC,QAAQ;QAAE,GAAG,CAAC,QAAQ,GAAG,KAAK,CAAC;IACvC,OAAO,GAAG,CAAC,QAAQ,EAAE,CAAC;AACxB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAAC,GAAG,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,CAAC,MAAM,CAAC,SAAS,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAC9E,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IACD,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;IAChD,OAAO,GAAG,KAAK,MAAM,IAAI,GAAG,KAAK,GAAG,CAAC;AACvC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
export { type Result, ok, err, attempt, unwrap, unwrapOr, } from "./core/result.ts";
|
|
2
|
+
export { type Env, type DecodedTls, resolvePoolLimit, decodeCaBase64, firstEnv, } from "./core/env.ts";
|
|
3
|
+
export { type Engine, type ParsedConnection, parseConnectionString, safeParseConnectionString, redactUrl, urlRequestsSsl, defaultPort, } from "./core/url.ts";
|
|
4
|
+
export { type ProviderId, type ProviderPreset, detectProvider, getProvider, listProviders, isPooledEndpoint, } from "./core/providers.ts";
|
|
5
|
+
export { type BudgetInput, type BudgetResult, recommendPoolLimit, } from "./core/budget.ts";
|
|
6
|
+
export { type RetryOptions, backoffDelay, withRetry, isTransientDbError, } from "./core/retry.ts";
|
|
7
|
+
export { type PoolConfig, loadPoolConfig } from "./core/config.ts";
|
|
8
|
+
export { type RedactOptions, DEFAULT_SECRET_KEYS, redact, } from "./core/redact.ts";
|
|
9
|
+
export { type DsnParts, buildDsn } from "./core/dsn.ts";
|
|
10
|
+
export { type Severity, type Diagnostic, type DiagnoseInput, type DiagnoseReport, diagnose, formatReport, } from "./application/diagnostics.ts";
|
|
11
|
+
export { type InspectEnv, inspectEnv } from "./application/inspect.ts";
|
|
12
|
+
export { type RecommendInput, type Recommendation, recommendForUrl, } from "./application/recommend.ts";
|
|
13
|
+
export { type PreflightOptions, type PreflightResult, preflight, } from "./application/preflight.ts";
|
|
14
|
+
export { buildMysqlPoolOptions, type MysqlPoolEnv, type MysqlPoolOptions, type BuildMysqlOptions, } from "./adapters/mysql.ts";
|
|
15
|
+
export { buildPgPoolOptions, type PgPoolEnv, type PgPoolOptions, type BuildPgOptions, } from "./adapters/pg.ts";
|
|
16
|
+
export { type Queryable, type HealthResult, type HealthOptions, checkHealth, isReachable, } from "./adapters/health.ts";
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAiBA,OAAO,EACL,KAAK,MAAM,EACX,EAAE,EACF,GAAG,EACH,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,GAAG,EACR,KAAK,UAAU,EACf,gBAAgB,EAChB,cAAc,EACd,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,MAAM,EACX,KAAK,gBAAgB,EACrB,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,EACT,cAAc,EACd,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,cAAc,EACnB,cAAc,EACd,WAAW,EACX,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,YAAY,EACjB,YAAY,EACZ,SAAS,EACT,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,KAAK,UAAU,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EACL,KAAK,aAAa,EAClB,mBAAmB,EACnB,MAAM,GACP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAE,KAAK,QAAQ,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGxD,OAAO,EACL,KAAK,QAAQ,EACb,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,cAAc,EACnB,QAAQ,EACR,YAAY,GACb,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAE,KAAK,UAAU,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,eAAe,GAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EACL,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,SAAS,GACV,MAAM,4BAA4B,CAAC;AAGpC,OAAO,EACL,qBAAqB,EACrB,KAAK,YAAY,EACjB,KAAK,gBAAgB,EACrB,KAAK,iBAAiB,GACvB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,EAClB,KAAK,SAAS,EACd,KAAK,aAAa,EAClB,KAAK,cAAc,GACpB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EACL,KAAK,SAAS,EACd,KAAK,YAAY,EACjB,KAAK,aAAa,EAClB,WAAW,EACX,WAAW,GACZ,MAAM,sBAAsB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
// lambda-pool — serverless-safe connection-pool options for MySQL and Postgres.
|
|
2
|
+
//
|
|
3
|
+
// Clean-architecture layering (dependencies point inward only):
|
|
4
|
+
//
|
|
5
|
+
// presentation/ cli, bin (process I/O)
|
|
6
|
+
// │ depends on
|
|
7
|
+
// adapters/ mysql, pg, health (driver-facing option objects + ports)
|
|
8
|
+
// │ depends on
|
|
9
|
+
// application/ diagnostics, inspect (use-cases composing the core)
|
|
10
|
+
// │ depends on
|
|
11
|
+
// core/ result, env, url, (pure, zero-dep, no I/O)
|
|
12
|
+
// providers, budget, retry
|
|
13
|
+
//
|
|
14
|
+
// Nothing in core imports outward; adapters/presentation never leak into core.
|
|
15
|
+
// Subpaths are published per module so consumers can import the narrowest slice.
|
|
16
|
+
// ---- core ----
|
|
17
|
+
export { ok, err, attempt, unwrap, unwrapOr, } from "./core/result.js";
|
|
18
|
+
export { resolvePoolLimit, decodeCaBase64, firstEnv, } from "./core/env.js";
|
|
19
|
+
export { parseConnectionString, safeParseConnectionString, redactUrl, urlRequestsSsl, defaultPort, } from "./core/url.js";
|
|
20
|
+
export { detectProvider, getProvider, listProviders, isPooledEndpoint, } from "./core/providers.js";
|
|
21
|
+
export { recommendPoolLimit, } from "./core/budget.js";
|
|
22
|
+
export { backoffDelay, withRetry, isTransientDbError, } from "./core/retry.js";
|
|
23
|
+
export { loadPoolConfig } from "./core/config.js";
|
|
24
|
+
export { DEFAULT_SECRET_KEYS, redact, } from "./core/redact.js";
|
|
25
|
+
export { buildDsn } from "./core/dsn.js";
|
|
26
|
+
// ---- application ----
|
|
27
|
+
export { diagnose, formatReport, } from "./application/diagnostics.js";
|
|
28
|
+
export { inspectEnv } from "./application/inspect.js";
|
|
29
|
+
export { recommendForUrl, } from "./application/recommend.js";
|
|
30
|
+
export { preflight, } from "./application/preflight.js";
|
|
31
|
+
// ---- adapters ----
|
|
32
|
+
export { buildMysqlPoolOptions, } from "./adapters/mysql.js";
|
|
33
|
+
export { buildPgPoolOptions, } from "./adapters/pg.js";
|
|
34
|
+
export { checkHealth, isReachable, } from "./adapters/health.js";
|
|
35
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,EAAE;AACF,gEAAgE;AAChE,EAAE;AACF,0DAA0D;AAC1D,uBAAuB;AACvB,mFAAmF;AACnF,uBAAuB;AACvB,2EAA2E;AAC3E,uBAAuB;AACvB,qEAAqE;AACrE,4CAA4C;AAC5C,EAAE;AACF,+EAA+E;AAC/E,iFAAiF;AAEjF,iBAAiB;AACjB,OAAO,EAEL,EAAE,EACF,GAAG,EACH,OAAO,EACP,MAAM,EACN,QAAQ,GACT,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAGL,gBAAgB,EAChB,cAAc,EACd,QAAQ,GACT,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,qBAAqB,EACrB,yBAAyB,EACzB,SAAS,EACT,cAAc,EACd,WAAW,GACZ,MAAM,eAAe,CAAC;AAEvB,OAAO,EAGL,cAAc,EACd,WAAW,EACX,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAGL,kBAAkB,GACnB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAEL,YAAY,EACZ,SAAS,EACT,kBAAkB,GACnB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAmB,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAEnE,OAAO,EAEL,mBAAmB,EACnB,MAAM,GACP,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAAiB,QAAQ,EAAE,MAAM,eAAe,CAAC;AAExD,wBAAwB;AACxB,OAAO,EAKL,QAAQ,EACR,YAAY,GACb,MAAM,8BAA8B,CAAC;AAEtC,OAAO,EAAmB,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEvE,OAAO,EAGL,eAAe,GAChB,MAAM,4BAA4B,CAAC;AAEpC,OAAO,EAGL,SAAS,GACV,MAAM,4BAA4B,CAAC;AAEpC,qBAAqB;AACrB,OAAO,EACL,qBAAqB,GAItB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EACL,kBAAkB,GAInB,MAAM,kBAAkB,CAAC;AAE1B,OAAO,EAIL,WAAW,EACX,WAAW,GACZ,MAAM,sBAAsB,CAAC"}
|