oopsx 1.3.0 → 1.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/bin/merr.js +22 -2
- package/package.json +1 -1
- package/src/instant.js +48 -0
package/README.md
CHANGED
|
@@ -12,6 +12,14 @@ Restart your terminal. Every failed command now plays a sound.
|
|
|
12
12
|
|
|
13
13
|
## Custom sound
|
|
14
14
|
|
|
15
|
+
Pick any sound from [myinstants.com](https://www.myinstants.com) and set it as your error sound:
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
oopsx instant https://www.myinstants.com/en/instant/bruh-sound-effect-26614/
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
Or use a local file:
|
|
22
|
+
|
|
15
23
|
```bash
|
|
16
24
|
oopsx --sound ~/bruh.mp3 --set-default echo hi
|
|
17
25
|
```
|
package/bin/merr.js
CHANGED
|
@@ -52,7 +52,10 @@ program
|
|
|
52
52
|
console.log(`
|
|
53
53
|
__oopsx_precmd() {
|
|
54
54
|
local exit_code=$?
|
|
55
|
-
[[ $exit_code -ne 0 ]]
|
|
55
|
+
if [[ $exit_code -ne 0 ]]; then
|
|
56
|
+
oopsx play &>/dev/null &
|
|
57
|
+
disown 2>/dev/null
|
|
58
|
+
fi
|
|
56
59
|
return $exit_code
|
|
57
60
|
}
|
|
58
61
|
precmd_functions+=(__oopsx_precmd)
|
|
@@ -61,7 +64,10 @@ precmd_functions+=(__oopsx_precmd)
|
|
|
61
64
|
console.log(`
|
|
62
65
|
__oopsx_prompt_command() {
|
|
63
66
|
local exit_code=$?
|
|
64
|
-
[[ $exit_code -ne 0 ]]
|
|
67
|
+
if [[ $exit_code -ne 0 ]]; then
|
|
68
|
+
oopsx play &>/dev/null &
|
|
69
|
+
disown 2>/dev/null
|
|
70
|
+
fi
|
|
65
71
|
return $exit_code
|
|
66
72
|
}
|
|
67
73
|
PROMPT_COMMAND="__oopsx_prompt_command;\${PROMPT_COMMAND}"
|
|
@@ -123,6 +129,20 @@ program
|
|
|
123
129
|
console.log("Restart your terminal or run: source " + rc.file);
|
|
124
130
|
});
|
|
125
131
|
|
|
132
|
+
// --- `oopsx instant <url>` — download a sound from myinstants.com ---
|
|
133
|
+
program
|
|
134
|
+
.command("instant <url>")
|
|
135
|
+
.description("Download a sound from myinstants.com and set as default")
|
|
136
|
+
.action(async (url) => {
|
|
137
|
+
try {
|
|
138
|
+
const { fetchInstantSound } = await import("../src/instant.js");
|
|
139
|
+
await fetchInstantSound(url);
|
|
140
|
+
} catch (err) {
|
|
141
|
+
console.error(`Error: ${err.message}`);
|
|
142
|
+
process.exit(1);
|
|
143
|
+
}
|
|
144
|
+
});
|
|
145
|
+
|
|
126
146
|
// --- `oopsx play` — just play the sound (used by shell hook) ---
|
|
127
147
|
program
|
|
128
148
|
.command("play")
|
package/package.json
CHANGED
package/src/instant.js
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { join } from "node:path";
|
|
2
|
+
import { existsSync, createWriteStream, copyFileSync } from "node:fs";
|
|
3
|
+
import { pipeline } from "node:stream/promises";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import { SOUNDS_DIR, DEFAULT_SOUND_PATH, ensureDirs } from "./config.js";
|
|
6
|
+
|
|
7
|
+
const MP3_REGEX = /https?:\/\/www\.myinstants\.com\/media\/sounds\/[^\s"']+\.mp3/;
|
|
8
|
+
const TITLE_REGEX = /<title>([^<]+)<\/title>/i;
|
|
9
|
+
|
|
10
|
+
const fetchInstantSound = async (pageUrl) => {
|
|
11
|
+
if (!pageUrl.includes("myinstants.com")) {
|
|
12
|
+
throw new Error("URL must be from myinstants.com");
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
console.log("Fetching page...");
|
|
16
|
+
const res = await fetch(pageUrl, {
|
|
17
|
+
headers: { "User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)" },
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
if (!res.ok) throw new Error(`Failed to fetch page: ${res.status}`);
|
|
21
|
+
|
|
22
|
+
const html = await res.text();
|
|
23
|
+
|
|
24
|
+
const mp3Match = html.match(MP3_REGEX);
|
|
25
|
+
if (!mp3Match) throw new Error("Could not find MP3 link on this page");
|
|
26
|
+
const mp3Url = mp3Match[0];
|
|
27
|
+
|
|
28
|
+
const titleMatch = html.match(TITLE_REGEX);
|
|
29
|
+
const title = titleMatch
|
|
30
|
+
? titleMatch[1].replace(/\s*[-–|].*$/, "").trim()
|
|
31
|
+
: "Unknown sound";
|
|
32
|
+
|
|
33
|
+
ensureDirs();
|
|
34
|
+
const hash = createHash("sha1").update(mp3Url).digest("hex");
|
|
35
|
+
const cached = join(SOUNDS_DIR, `${hash}.mp3`);
|
|
36
|
+
|
|
37
|
+
if (!existsSync(cached)) {
|
|
38
|
+
console.log(`Downloading "${title}"...`);
|
|
39
|
+
const mp3Res = await fetch(mp3Url);
|
|
40
|
+
if (!mp3Res.ok) throw new Error(`Failed to download MP3: ${mp3Res.status}`);
|
|
41
|
+
await pipeline(mp3Res.body, createWriteStream(cached));
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
copyFileSync(cached, DEFAULT_SOUND_PATH);
|
|
45
|
+
console.log(`✓ "${title}" set as default error sound`);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
export { fetchInstantSound };
|