pg-here 0.1.3 → 0.1.5
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 +42 -1
- package/bin/pg-here.mjs +53 -0
- package/package.json +4 -2
- package/scripts/cli-error-help.mjs +57 -0
- package/scripts/pg-dev.mjs +17 -8
package/README.md
CHANGED
|
@@ -31,7 +31,27 @@ If you have Bun installed, you can run the published package directly:
|
|
|
31
31
|
bunx pg-here
|
|
32
32
|
```
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
This is the single command you want from any directory.
|
|
35
|
+
|
|
36
|
+
If it still resolves an older release, the package `latest` dist-tag is behind:
|
|
37
|
+
|
|
38
|
+
To force that version and bypass a stale cache:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
bunx pg-here@0.1.5
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
If maintainers want plain `bunx pg-here` to work for everyone, run once:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm dist-tag add pg-here@0.1.5 latest
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
After that, this should work anywhere:
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
bunx pg-here
|
|
54
|
+
```
|
|
35
55
|
|
|
36
56
|
This starts a local PostgreSQL instance in your current project directory and prints the connection string, then keeps the process alive until you stop it.
|
|
37
57
|
|
|
@@ -49,6 +69,27 @@ Pass CLI flags just like the local script when you want to override defaults:
|
|
|
49
69
|
bunx pg-here --username postgres --password postgres --database my_app --port 55432
|
|
50
70
|
```
|
|
51
71
|
|
|
72
|
+
#### Linux note
|
|
73
|
+
|
|
74
|
+
If `bunx pg-here` fails with `error while loading shared libraries`:
|
|
75
|
+
- install missing system packages on the host (not in npm), then retry
|
|
76
|
+
- restart the command
|
|
77
|
+
|
|
78
|
+
Most commonly:
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
# Ubuntu/Debian
|
|
82
|
+
sudo apt-get update && sudo apt-get install -y libxml2
|
|
83
|
+
|
|
84
|
+
# Fedora/RHEL
|
|
85
|
+
sudo dnf install -y libxml2
|
|
86
|
+
|
|
87
|
+
# Alpine
|
|
88
|
+
sudo apk add libxml2
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
If that machine is intentionally minimal (or containerized), use an image with PostgreSQL runtime dependencies.
|
|
92
|
+
|
|
52
93
|
### Programmatic usage
|
|
53
94
|
|
|
54
95
|
Use `pg-here` directly from your server startup code and auto-create the app database if missing.
|
package/bin/pg-here.mjs
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import yargs from "yargs";
|
|
4
|
+
import { hideBin } from "yargs/helpers";
|
|
5
|
+
import { startPgHere } from "../dist/index.js";
|
|
6
|
+
import { maybePrintLinuxRuntimeHelp } from "../scripts/cli-error-help.mjs";
|
|
7
|
+
|
|
8
|
+
const argv = await yargs(hideBin(process.argv))
|
|
9
|
+
.version(false)
|
|
10
|
+
.option("username", {
|
|
11
|
+
alias: "u",
|
|
12
|
+
default: "postgres",
|
|
13
|
+
describe: "PostgreSQL username",
|
|
14
|
+
})
|
|
15
|
+
.option("password", {
|
|
16
|
+
alias: "p",
|
|
17
|
+
default: "postgres",
|
|
18
|
+
describe: "PostgreSQL password",
|
|
19
|
+
})
|
|
20
|
+
.option("port", {
|
|
21
|
+
default: 55432,
|
|
22
|
+
describe: "PostgreSQL port",
|
|
23
|
+
})
|
|
24
|
+
.option("database", {
|
|
25
|
+
alias: "d",
|
|
26
|
+
default: "postgres",
|
|
27
|
+
describe: "Database to use (created automatically if missing)",
|
|
28
|
+
})
|
|
29
|
+
.option("pg-version", {
|
|
30
|
+
default: process.env.PG_VERSION,
|
|
31
|
+
describe: "PostgreSQL version (e.g. 18.0.0 or >=17.0)",
|
|
32
|
+
})
|
|
33
|
+
.parse();
|
|
34
|
+
|
|
35
|
+
let pg;
|
|
36
|
+
try {
|
|
37
|
+
pg = await startPgHere({
|
|
38
|
+
projectDir: process.cwd(),
|
|
39
|
+
port: argv.port,
|
|
40
|
+
username: argv.username,
|
|
41
|
+
password: argv.password,
|
|
42
|
+
database: argv.database,
|
|
43
|
+
postgresVersion: argv["pg-version"],
|
|
44
|
+
});
|
|
45
|
+
} catch (error) {
|
|
46
|
+
if (process.platform === "linux") {
|
|
47
|
+
maybePrintLinuxRuntimeHelp(error);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
console.log(pg.databaseConnectionString);
|
|
53
|
+
setInterval(() => {}, 1 << 30);
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pg-here",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.5",
|
|
4
4
|
"description": "Per-project embedded PostgreSQL with programmatic startup and auto DB creation.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
8
8
|
"bin": {
|
|
9
|
-
"pg-here": "
|
|
9
|
+
"pg-here": "bin/pg-here.mjs"
|
|
10
10
|
},
|
|
11
11
|
"exports": {
|
|
12
12
|
".": {
|
|
@@ -17,7 +17,9 @@
|
|
|
17
17
|
"files": [
|
|
18
18
|
"dist",
|
|
19
19
|
"index.ts",
|
|
20
|
+
"bin/pg-here.mjs",
|
|
20
21
|
"scripts/pg-dev.mjs",
|
|
22
|
+
"scripts/cli-error-help.mjs",
|
|
21
23
|
"README.md"
|
|
22
24
|
],
|
|
23
25
|
"private": false,
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
|
|
3
|
+
const LIBXML_LIBRARY = /libxml2\.so\.2/;
|
|
4
|
+
|
|
5
|
+
export function maybePrintLinuxRuntimeHelp(error) {
|
|
6
|
+
const message = String(error?.message ?? error);
|
|
7
|
+
const missingLibsFromError = extractMissingLibrariesFromMessage(message);
|
|
8
|
+
const missingLibsFromBinary = extractMissingLibrariesFromBinaryPath(message);
|
|
9
|
+
|
|
10
|
+
const missingLibs = [...new Set([...missingLibsFromError, ...missingLibsFromBinary])];
|
|
11
|
+
|
|
12
|
+
if (missingLibs.length === 0) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
console.error();
|
|
17
|
+
console.error("PostgreSQL startup failed due to missing Linux runtime dependencies.");
|
|
18
|
+
console.error(`Missing libraries: ${missingLibs.join(", ")}`);
|
|
19
|
+
console.error();
|
|
20
|
+
console.error("Install system packages for your distro and retry:");
|
|
21
|
+
console.error(" Ubuntu/Debian: sudo apt-get update && sudo apt-get install -y libxml2");
|
|
22
|
+
console.error(" Fedora/RHEL: sudo dnf install -y libxml2");
|
|
23
|
+
console.error(" Alpine: sudo apk add libxml2");
|
|
24
|
+
console.error(
|
|
25
|
+
`If your distro requires different package names, install packages that provide: ${missingLibs.join(
|
|
26
|
+
", "
|
|
27
|
+
)}`
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
if (LIBXML_LIBRARY.test(message)) {
|
|
31
|
+
console.error("Hint: this project does not ship all optional shared objects in every Linux image.");
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function extractMissingLibrariesFromMessage(message) {
|
|
36
|
+
const regex = /([A-Za-z0-9._-]+\.so(?:\.\d+)*)\b/g;
|
|
37
|
+
const matches = [...message.matchAll(regex)].map((match) => match[1]);
|
|
38
|
+
return matches.filter((value) => value.toLowerCase().includes("so"));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function extractMissingLibrariesFromBinaryPath(message) {
|
|
42
|
+
const pathMatch = message.match(/(\/[^\s"]*\/bin\/postgres)/);
|
|
43
|
+
if (!pathMatch) {
|
|
44
|
+
return [];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const binaryPath = pathMatch[1];
|
|
48
|
+
const result = spawnSync("ldd", [binaryPath], { encoding: "utf8" });
|
|
49
|
+
const output = `${result.stdout ?? ""} ${result.stderr ?? ""}`;
|
|
50
|
+
if (!output) {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return [...output.matchAll(/([^\s]+)\s+=>\s+not found/g)].map(
|
|
55
|
+
(match) => match[1]
|
|
56
|
+
);
|
|
57
|
+
}
|
package/scripts/pg-dev.mjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import yargs from "yargs";
|
|
2
2
|
import { hideBin } from "yargs/helpers";
|
|
3
3
|
import { startPgHere } from "../index.ts";
|
|
4
|
+
import { maybePrintLinuxRuntimeHelp } from "./cli-error-help.mjs";
|
|
4
5
|
|
|
5
6
|
const argv = await yargs(hideBin(process.argv))
|
|
6
7
|
.version(false)
|
|
@@ -29,14 +30,22 @@ const argv = await yargs(hideBin(process.argv))
|
|
|
29
30
|
})
|
|
30
31
|
.parse();
|
|
31
32
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
33
|
+
let pg;
|
|
34
|
+
try {
|
|
35
|
+
pg = await startPgHere({
|
|
36
|
+
projectDir: process.cwd(),
|
|
37
|
+
port: argv.port,
|
|
38
|
+
username: argv.username,
|
|
39
|
+
password: argv.password,
|
|
40
|
+
database: argv.database,
|
|
41
|
+
postgresVersion: argv["pg-version"],
|
|
42
|
+
});
|
|
43
|
+
} catch (error) {
|
|
44
|
+
if (process.platform === "linux") {
|
|
45
|
+
maybePrintLinuxRuntimeHelp(error);
|
|
46
|
+
}
|
|
47
|
+
throw error;
|
|
48
|
+
}
|
|
40
49
|
|
|
41
50
|
// print connection string for tooling
|
|
42
51
|
console.log(pg.databaseConnectionString);
|