hooklistener 0.3.10
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 +43 -0
- package/bin/hooklistener.js +30 -0
- package/package.json +24 -0
- package/scripts/install.js +123 -0
package/README.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# hooklistener
|
|
2
|
+
|
|
3
|
+
A fast, terminal-based CLI for browsing webhooks, forwarding events, and exposing local servers using [Hooklistener](https://hooklistener.com).
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g hooklistener
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
# Authenticate
|
|
15
|
+
hooklistener login
|
|
16
|
+
|
|
17
|
+
# List orgs and select a default org for API-backed commands
|
|
18
|
+
hooklistener org list
|
|
19
|
+
hooklistener org use <organization-id>
|
|
20
|
+
|
|
21
|
+
# Forward webhooks to localhost
|
|
22
|
+
hooklistener listen my-endpoint
|
|
23
|
+
|
|
24
|
+
# Manage endpoints and requests
|
|
25
|
+
hooklistener endpoint list
|
|
26
|
+
hooklistener endpoint requests <endpoint-id>
|
|
27
|
+
hooklistener endpoint forward-request <endpoint-id> <request-id> http://localhost:3000/webhook
|
|
28
|
+
|
|
29
|
+
# Expose local server with a public URL
|
|
30
|
+
hooklistener tunnel --port 3000
|
|
31
|
+
|
|
32
|
+
# Use JSON output for scripts
|
|
33
|
+
hooklistener --json endpoint list
|
|
34
|
+
|
|
35
|
+
# Generate shell completions
|
|
36
|
+
hooklistener completions bash
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
For full documentation, visit the [GitHub repository](https://github.com/hooklistener/hooklistener-cli).
|
|
40
|
+
|
|
41
|
+
## License
|
|
42
|
+
|
|
43
|
+
MIT
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const { execFileSync } = require("child_process");
|
|
6
|
+
const path = require("path");
|
|
7
|
+
const fs = require("fs");
|
|
8
|
+
|
|
9
|
+
const BIN_NAME = process.platform === "win32" ? "hooklistener.exe" : "hooklistener";
|
|
10
|
+
const BIN_PATH = path.join(__dirname, "..", "native", BIN_NAME);
|
|
11
|
+
|
|
12
|
+
if (!fs.existsSync(BIN_PATH)) {
|
|
13
|
+
console.error(
|
|
14
|
+
`hooklistener binary not found at ${BIN_PATH}\n\n` +
|
|
15
|
+
`This usually means the postinstall script failed to download the binary.\n` +
|
|
16
|
+
`Try reinstalling:\n\n` +
|
|
17
|
+
` npm install -g hooklistener\n\n` +
|
|
18
|
+
`Or set HOOKLISTENER_BINARY_PATH to a pre-downloaded binary and reinstall.`
|
|
19
|
+
);
|
|
20
|
+
process.exit(1);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
execFileSync(BIN_PATH, process.argv.slice(2), { stdio: "inherit" });
|
|
25
|
+
} catch (err) {
|
|
26
|
+
if (err.status !== null) {
|
|
27
|
+
process.exit(err.status);
|
|
28
|
+
}
|
|
29
|
+
throw err;
|
|
30
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "hooklistener",
|
|
3
|
+
"version": "0.3.10",
|
|
4
|
+
"description": "A fast, terminal-based CLI for browsing webhooks, forwarding events, and exposing local servers",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "https://github.com/hooklistener/hooklistener-cli.git"
|
|
9
|
+
},
|
|
10
|
+
"homepage": "https://hooklistener.com",
|
|
11
|
+
"bin": {
|
|
12
|
+
"hooklistener": "bin/hooklistener.js"
|
|
13
|
+
},
|
|
14
|
+
"scripts": {
|
|
15
|
+
"postinstall": "node scripts/install.js"
|
|
16
|
+
},
|
|
17
|
+
"files": [
|
|
18
|
+
"bin/hooklistener.js",
|
|
19
|
+
"scripts/install.js"
|
|
20
|
+
],
|
|
21
|
+
"engines": {
|
|
22
|
+
"node": ">=16"
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
"use strict";
|
|
4
|
+
|
|
5
|
+
const https = require("https");
|
|
6
|
+
const fs = require("fs");
|
|
7
|
+
const path = require("path");
|
|
8
|
+
const { execSync } = require("child_process");
|
|
9
|
+
const os = require("os");
|
|
10
|
+
|
|
11
|
+
const REPO = "hooklistener/hooklistener-cli";
|
|
12
|
+
|
|
13
|
+
const PLATFORM_MAP = {
|
|
14
|
+
"linux-x64": { target: "x86_64-unknown-linux-gnu", archive: "tar.gz" },
|
|
15
|
+
"darwin-x64": { target: "x86_64-apple-darwin", archive: "tar.gz" },
|
|
16
|
+
"darwin-arm64": { target: "aarch64-apple-darwin", archive: "tar.gz" },
|
|
17
|
+
"win32-x64": { target: "x86_64-pc-windows-msvc", archive: "zip" },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const BIN_NAME = process.platform === "win32" ? "hooklistener.exe" : "hooklistener";
|
|
21
|
+
const BIN_DIR = path.join(__dirname, "..", "native");
|
|
22
|
+
const BIN_PATH = path.join(BIN_DIR, BIN_NAME);
|
|
23
|
+
|
|
24
|
+
function getPackageVersion() {
|
|
25
|
+
const pkgPath = path.join(__dirname, "..", "package.json");
|
|
26
|
+
return JSON.parse(fs.readFileSync(pkgPath, "utf8")).version;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function download(url) {
|
|
30
|
+
return new Promise((resolve, reject) => {
|
|
31
|
+
https
|
|
32
|
+
.get(url, { headers: { "User-Agent": "hooklistener-npm" } }, (res) => {
|
|
33
|
+
if (res.statusCode >= 300 && res.statusCode < 400 && res.headers.location) {
|
|
34
|
+
return download(res.headers.location).then(resolve, reject);
|
|
35
|
+
}
|
|
36
|
+
if (res.statusCode !== 200) {
|
|
37
|
+
return reject(new Error(`HTTP ${res.statusCode} for ${url}`));
|
|
38
|
+
}
|
|
39
|
+
const chunks = [];
|
|
40
|
+
res.on("data", (chunk) => chunks.push(chunk));
|
|
41
|
+
res.on("end", () => resolve(Buffer.concat(chunks)));
|
|
42
|
+
res.on("error", reject);
|
|
43
|
+
})
|
|
44
|
+
.on("error", reject);
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
function extractArchive(buffer, archiveType, destDir) {
|
|
49
|
+
const tmpFile = path.join(os.tmpdir(), `hooklistener-${Date.now()}.${archiveType}`);
|
|
50
|
+
fs.writeFileSync(tmpFile, buffer);
|
|
51
|
+
try {
|
|
52
|
+
fs.mkdirSync(destDir, { recursive: true });
|
|
53
|
+
if (archiveType === "zip") {
|
|
54
|
+
if (process.platform === "win32") {
|
|
55
|
+
execSync(
|
|
56
|
+
`powershell -Command "Expand-Archive -Path '${tmpFile}' -DestinationPath '${destDir}' -Force"`,
|
|
57
|
+
{ stdio: "pipe" }
|
|
58
|
+
);
|
|
59
|
+
} else {
|
|
60
|
+
execSync(`unzip -o "${tmpFile}" -d "${destDir}"`, { stdio: "pipe" });
|
|
61
|
+
}
|
|
62
|
+
} else {
|
|
63
|
+
execSync(`tar -xzf "${tmpFile}" -C "${destDir}"`, { stdio: "pipe" });
|
|
64
|
+
}
|
|
65
|
+
} finally {
|
|
66
|
+
fs.unlinkSync(tmpFile);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function markExecutable(filePath) {
|
|
71
|
+
if (process.platform !== "win32") {
|
|
72
|
+
fs.chmodSync(filePath, 0o755);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
async function main() {
|
|
77
|
+
const envBinary = process.env.HOOKLISTENER_BINARY_PATH;
|
|
78
|
+
if (envBinary) {
|
|
79
|
+
console.log(`Using binary from HOOKLISTENER_BINARY_PATH: ${envBinary}`);
|
|
80
|
+
fs.mkdirSync(BIN_DIR, { recursive: true });
|
|
81
|
+
fs.copyFileSync(envBinary, BIN_PATH);
|
|
82
|
+
markExecutable(BIN_PATH);
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const platformKey = `${process.platform}-${process.arch}`;
|
|
87
|
+
const platform = PLATFORM_MAP[platformKey];
|
|
88
|
+
|
|
89
|
+
if (!platform) {
|
|
90
|
+
console.error(
|
|
91
|
+
`Unsupported platform: ${platformKey}\n` +
|
|
92
|
+
`hooklistener currently supports: ${Object.keys(PLATFORM_MAP).join(", ")}`
|
|
93
|
+
);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const version = getPackageVersion();
|
|
98
|
+
const archiveName = `hooklistener-${platform.target}.${platform.archive}`;
|
|
99
|
+
const url = `https://github.com/${REPO}/releases/download/v${version}/${archiveName}`;
|
|
100
|
+
|
|
101
|
+
console.log(`Downloading hooklistener v${version} for ${platformKey}...`);
|
|
102
|
+
|
|
103
|
+
try {
|
|
104
|
+
const buffer = await download(url);
|
|
105
|
+
extractArchive(buffer, platform.archive, BIN_DIR);
|
|
106
|
+
|
|
107
|
+
if (!fs.existsSync(BIN_PATH)) {
|
|
108
|
+
console.error(`Binary not found at expected path: ${BIN_PATH}`);
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
markExecutable(BIN_PATH);
|
|
113
|
+
console.log(`hooklistener v${version} installed successfully.`);
|
|
114
|
+
} catch (err) {
|
|
115
|
+
console.error(`Failed to download hooklistener v${version}: ${err.message}`);
|
|
116
|
+
console.error(
|
|
117
|
+
`\nYou can manually install the binary and set HOOKLISTENER_BINARY_PATH to its location.`
|
|
118
|
+
);
|
|
119
|
+
process.exit(1);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
main();
|