@kookyharsh/daas 0.0.0-stage → 1.0.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 +251 -2
- package/app.js +56 -0
- package/index.js +13 -0
- package/package.json +21 -4
- package/reasons.json +53 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 kooky.harsh
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,252 @@
|
|
|
1
|
-
#
|
|
1
|
+
☠️ # Death-as-a-Service (DaaS)
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
> A darkly humorous API that returns random, ridiculous death scenarios. Because everyone's gotta go sometime.
|
|
4
|
+
|
|
5
|
+
Inspired by [no-as-a-service](https://github.com/hotheadhacker/no-as-a-service), this tiny API delivers comedic ways to meet your maker—perfect for games, apps, chatbots, or just a morbid chuckle.
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 📦 Use as an npm package
|
|
10
|
+
|
|
11
|
+
Install it in an existing Express application:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install daas express
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
Mount the exported Express app (it does not start a server when imported):
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const express = require('express');
|
|
21
|
+
const deathApi = require('daas');
|
|
22
|
+
|
|
23
|
+
const app = express();
|
|
24
|
+
app.use('/api', deathApi());
|
|
25
|
+
app.listen(3000);
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
The routes are then available at `/api/death`, `/api/deaths`, and `/api/health`.
|
|
29
|
+
You can also customize the rate limit with `deathApi({ rateLimitMax: 60 })`.
|
|
30
|
+
|
|
31
|
+
## 🚀 API Usage
|
|
32
|
+
|
|
33
|
+
**Base URL**
|
|
34
|
+
```
|
|
35
|
+
https://death-as-a-service.onrender.com/
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Method:** `GET`
|
|
39
|
+
**Rate Limit:** `120 requests per minute per IP`
|
|
40
|
+
|
|
41
|
+
### Endpoints
|
|
42
|
+
|
|
43
|
+
#### 1. `/death` — Get a random reason
|
|
44
|
+
```bash
|
|
45
|
+
curl https://death-as-a-service.onrender.com/death
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
**Response:**
|
|
49
|
+
```json
|
|
50
|
+
{
|
|
51
|
+
"reason": "Defeated in a staring contest with a pigeon"
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
#### 2. `/deaths` — Alias for `/death`
|
|
56
|
+
```bash
|
|
57
|
+
curl https://death-as-a-service.onrender.com/deaths
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
Same response shape as `/death`.
|
|
61
|
+
|
|
62
|
+
#### 3. `/health` — Health check
|
|
63
|
+
```bash
|
|
64
|
+
curl https://death-as-a-service.onrender.com/health
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Response:**
|
|
68
|
+
```json
|
|
69
|
+
{
|
|
70
|
+
"status": "alive"
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
---
|
|
75
|
+
|
|
76
|
+
## 🛠️ Self-Hosting
|
|
77
|
+
|
|
78
|
+
### 1. Clone & Setup
|
|
79
|
+
```bash
|
|
80
|
+
git clone https://github.com/kookyharsh/death-as-a-service.git
|
|
81
|
+
cd death-as-a-service
|
|
82
|
+
npm install
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### 2. Start the server
|
|
86
|
+
```bash
|
|
87
|
+
npm start
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
The API will be live at:
|
|
91
|
+
```
|
|
92
|
+
http://localhost:3000/death
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 3. Custom port
|
|
96
|
+
```bash
|
|
97
|
+
PORT=5000 npm start
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
102
|
+
## 📁 Project Structure
|
|
103
|
+
|
|
104
|
+
```
|
|
105
|
+
death-as-a-service/
|
|
106
|
+
├── index.js # Express API server
|
|
107
|
+
├── reasons.json # Random reason strings
|
|
108
|
+
├── package.json # Dependencies
|
|
109
|
+
├── Dockerfile # Docker configuration (optional)
|
|
110
|
+
└── README.md # This file
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
---
|
|
114
|
+
|
|
115
|
+
## 🐳 Docker Support (Optional)
|
|
116
|
+
|
|
117
|
+
### Build the image
|
|
118
|
+
```bash
|
|
119
|
+
docker build -t daas .
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Run the container
|
|
123
|
+
```bash
|
|
124
|
+
docker run -p 3000:3000 daas
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
---
|
|
128
|
+
|
|
129
|
+
## 📋 Example Usage
|
|
130
|
+
|
|
131
|
+
### JavaScript/Node.js
|
|
132
|
+
```javascript
|
|
133
|
+
async function getDeath() {
|
|
134
|
+
const response = await fetch('http://localhost:3000/death');
|
|
135
|
+
const data = await response.json();
|
|
136
|
+
console.log(data.reason);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
getDeath();
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Python
|
|
143
|
+
```python
|
|
144
|
+
import requests
|
|
145
|
+
|
|
146
|
+
response = requests.get('http://localhost:3000/death')
|
|
147
|
+
print(response.json()['reason'])
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
### cURL
|
|
151
|
+
```bash
|
|
152
|
+
curl http://localhost:3000/death | jq
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
### Shell Script
|
|
156
|
+
```bash
|
|
157
|
+
#!/bin/bash
|
|
158
|
+
curl -s http://localhost:3000/death | jq -r '.reason'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
---
|
|
162
|
+
|
|
163
|
+
## 🎮 Use Cases
|
|
164
|
+
|
|
165
|
+
- **Games** — Random death messages for game overs
|
|
166
|
+
- **Chatbots** — Morbid humor in AI responses
|
|
167
|
+
- **Terminals** — Easter eggs in CLI tools
|
|
168
|
+
- **Web Apps** — Dark comedy generators
|
|
169
|
+
- **Discord Bots** — `/death` command for servers
|
|
170
|
+
- **Slack Integrations** — Morbid slack status updates
|
|
171
|
+
- **Just for fun** — Because why not?
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 📊 Sample Responses
|
|
176
|
+
|
|
177
|
+
Here's what you might get:
|
|
178
|
+
|
|
179
|
+
- "Choked on a single grain of rice"
|
|
180
|
+
- "Lost a fight to a rubber duck"
|
|
181
|
+
- "Died of boredom waiting for Windows updates"
|
|
182
|
+
- "Sneezed so hard they achieved orbit"
|
|
183
|
+
- "Got tangled in their own phone charger cable"
|
|
184
|
+
- "Typed 'sudo' before a question they shouldn't have asked"
|
|
185
|
+
- "Became a living meme and the internet killed it"
|
|
186
|
+
- "Stepped on a LEGO and never recovered"
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 🤔 Adding More Deaths
|
|
191
|
+
|
|
192
|
+
Want to add more reasons? Add a string to `reasons.json`:
|
|
193
|
+
|
|
194
|
+
```json
|
|
195
|
+
[
|
|
196
|
+
"Your new reason here",
|
|
197
|
+
"Another ridiculous way to go"
|
|
198
|
+
]
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Then restart the server.
|
|
202
|
+
|
|
203
|
+
---
|
|
204
|
+
|
|
205
|
+
## 🔧 Configuration
|
|
206
|
+
|
|
207
|
+
### Environment Variables
|
|
208
|
+
```bash
|
|
209
|
+
PORT=3000 # Server port (default: 3000)
|
|
210
|
+
NODE_ENV=production # Environment (optional)
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
### Rate Limiting
|
|
214
|
+
Edit `index.js` to adjust rate limits:
|
|
215
|
+
```javascript
|
|
216
|
+
const limiter = rateLimit({
|
|
217
|
+
windowMs: 1 * 60 * 1000, // 1 minute window
|
|
218
|
+
max: 120, // 120 requests per window
|
|
219
|
+
});
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
---
|
|
223
|
+
|
|
224
|
+
## 📜 License
|
|
225
|
+
|
|
226
|
+
MIT — Do whatever you want, just don't blame me if you die laughing.
|
|
227
|
+
|
|
228
|
+
---
|
|
229
|
+
|
|
230
|
+
## 👤 Credits
|
|
231
|
+
|
|
232
|
+
Created in the spirit of [no-as-a-service](https://github.com/hotheadhacker/no-as-a-service) by hotheadhacker.
|
|
233
|
+
|
|
234
|
+
Darkly humorous content & API design by [You].
|
|
235
|
+
|
|
236
|
+
---
|
|
237
|
+
|
|
238
|
+
## 🚨 Disclaimer
|
|
239
|
+
|
|
240
|
+
This is purely for entertainment. Any resemblance to actual deaths is purely coincidental (and darkly comedic). Please don't actually die. We need the active users.
|
|
241
|
+
|
|
242
|
+
---
|
|
243
|
+
|
|
244
|
+
## 🎭 Testimonials
|
|
245
|
+
|
|
246
|
+
> "This API is killer." — Your Therapist (probably)
|
|
247
|
+
|
|
248
|
+
> "Death never looked so funny." — The Grim Reaper (allegedly)
|
|
249
|
+
|
|
250
|
+
---
|
|
251
|
+
|
|
252
|
+
**Remember:** Life is short, make it funny. 💀
|
package/app.js
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const express = require('express');
|
|
2
|
+
const rateLimit = require('express-rate-limit');
|
|
3
|
+
const reasons = require('./reasons.json');
|
|
4
|
+
|
|
5
|
+
function createApp(options = {}) {
|
|
6
|
+
const app = express();
|
|
7
|
+
const limiter = rateLimit({
|
|
8
|
+
windowMs: options.rateLimitWindowMs || 60 * 1000,
|
|
9
|
+
max: options.rateLimitMax || 120,
|
|
10
|
+
message: 'Too many requests from this IP, please try again later.'
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
app.use(limiter);
|
|
14
|
+
app.use((req, res, next) => {
|
|
15
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
16
|
+
res.header('Access-Control-Allow-Methods', 'GET');
|
|
17
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type');
|
|
18
|
+
next();
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
app.get('/health', (req, res) => res.json({ status: 'alive' }));
|
|
22
|
+
const randomReason = (req, res) => {
|
|
23
|
+
const randomIndex = Math.floor(Math.random() * reasons.length);
|
|
24
|
+
|
|
25
|
+
res.json({ reason: reasons[randomIndex] });
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Optionally, prepend a custom phrase to the death message.
|
|
29
|
+
*
|
|
30
|
+
* Example:
|
|
31
|
+
* res.json({ reason: `Died because they ${reasons[randomIndex]}` });
|
|
32
|
+
*
|
|
33
|
+
* Note: Make sure each entry in the reasons array is grammatically
|
|
34
|
+
* compatible with the prefix.
|
|
35
|
+
*/
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
app.get(['/death', '/deaths'], randomReason);
|
|
39
|
+
|
|
40
|
+
app.use((req, res) => {
|
|
41
|
+
res.status(404).json({
|
|
42
|
+
error: 'Endpoint not found. Available endpoints: /death, /deaths, /health'
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
app.use((err, req, res, next) => {
|
|
47
|
+
console.error(err.stack);
|
|
48
|
+
res.status(500).json({ error: 'Internal server error', message: err.message });
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
return app;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
module.exports = createApp;
|
|
55
|
+
module.exports.createApp = createApp;
|
|
56
|
+
module.exports.reasons = reasons;
|
package/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const createApp = require('./app');
|
|
2
|
+
|
|
3
|
+
const port = Number(process.env.PORT) || 3000;
|
|
4
|
+
const app = createApp();
|
|
5
|
+
|
|
6
|
+
if (require.main === module) {
|
|
7
|
+
app.listen(port, '0.0.0.0', () => {
|
|
8
|
+
console.log(`Death-as-a-Service running on port ${port}`);
|
|
9
|
+
console.log(`Try: http://localhost:${port}/death`);
|
|
10
|
+
});
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = app;
|
package/package.json
CHANGED
|
@@ -1,6 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kookyharsh/daas",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
6
|
-
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "A darkly humorous API that returns random reasons for death . Because everyone's gotta go sometime.",
|
|
5
|
+
"main": "app.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"start": "node index.js",
|
|
8
|
+
"dev": "node index.js",
|
|
9
|
+
"test": "node --check app.js && node --check index.js",
|
|
10
|
+
"prepublishOnly": "npm test"
|
|
11
|
+
},
|
|
12
|
+
"author": "kookyharsh",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"keywords": ["express", "api", "random", "humor", "death"],
|
|
15
|
+
"files": ["app.js", "index.js", "reasons.json", "README.md", "LICENSE"],
|
|
16
|
+
"engines": { "node": ">=18" },
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"express-rate-limit": "^7.0.0"
|
|
19
|
+
},
|
|
20
|
+
"peerDependencies": {
|
|
21
|
+
"express": ">=4.18.0"
|
|
22
|
+
}
|
|
23
|
+
}
|
package/reasons.json
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
[
|
|
2
|
+
"Defeated in a staring contest with a pigeon",
|
|
3
|
+
"Choked on a single grain of rice",
|
|
4
|
+
"Tripped over a very small pebble",
|
|
5
|
+
"Lost a fight to a rubber duck",
|
|
6
|
+
"Died doing what they loved: nothing",
|
|
7
|
+
"Turned into a pillar of salt after looking back one too many times",
|
|
8
|
+
"Sneezed so hard they achieved orbit",
|
|
9
|
+
"Suffocated under an avalanche of their own bad decisions",
|
|
10
|
+
"Stepped on a LEGO and never recovered",
|
|
11
|
+
"Laughed so hard they forgot how to breathe",
|
|
12
|
+
"Tried to pet a tiger. Did not work out.",
|
|
13
|
+
"Got distracted and walked off a cliff while texting",
|
|
14
|
+
"Ate spoiled gas station sushi",
|
|
15
|
+
"Challenged someone to a competitive napping session and lost",
|
|
16
|
+
"Typed 'rm -rf /' into their real computer instead of a virtual one",
|
|
17
|
+
"Slipped on a banana peel... off a roof",
|
|
18
|
+
"Died of boredom waiting for Windows updates",
|
|
19
|
+
"Finally organized their sock drawer and had a heart attack from the excitement",
|
|
20
|
+
"Got tangled in their own phone charger cable",
|
|
21
|
+
"Tried to teach their cat calculus",
|
|
22
|
+
"Ascended to a higher plane of existence after drinking expired coffee",
|
|
23
|
+
"Fell down the stairs carrying laundry. The laundry survived.",
|
|
24
|
+
"Got caught in a temporal paradox while time-traveling for lunch",
|
|
25
|
+
"Challenged AI to a chess match, lost existentially",
|
|
26
|
+
"Suffocated under a mountain of unread emails",
|
|
27
|
+
"Took 'dying of laughter' too literally",
|
|
28
|
+
"Lost at rock-paper-scissors against themselves",
|
|
29
|
+
"Forgot to pay their oxygen bill",
|
|
30
|
+
"Achieved true enlightenment and simply stopped existing",
|
|
31
|
+
"Confused a cactus for a pet, found out the hard way",
|
|
32
|
+
"Tried to catch the road runner, became a splat",
|
|
33
|
+
"Typed 'sudo' before a question they shouldn't have asked",
|
|
34
|
+
"Starved while deciding what to eat",
|
|
35
|
+
"Bit into a sandwich and discovered it was made of paper",
|
|
36
|
+
"Willed themselves into the digital realm via sheer willpower",
|
|
37
|
+
"Got stuck in an infinite loop of apologies",
|
|
38
|
+
"Sneezed, hiccupped, and yawned simultaneously",
|
|
39
|
+
"Attempted to debug their own existence",
|
|
40
|
+
"Failed the Turing test (they were the AI)",
|
|
41
|
+
"Became too meta about death and ceased to exist",
|
|
42
|
+
"Lost the game (you lose too)",
|
|
43
|
+
"Tried to unplug and plug back in again, permanently",
|
|
44
|
+
"Believed in their own memes too hard",
|
|
45
|
+
"Got cancelled so hard they disappeared from existence",
|
|
46
|
+
"Died from cringe at their own joke",
|
|
47
|
+
"Entered the fifth dimension and couldn't find the exit",
|
|
48
|
+
"Became a living meme and the internet killed it",
|
|
49
|
+
"Sacrificed themselves for the perfect screenshot",
|
|
50
|
+
"Glitched out of reality",
|
|
51
|
+
"Died updating their status about dying",
|
|
52
|
+
"Final answer to life, universe, and everything: wrong"
|
|
53
|
+
]
|