pulsewatch-server 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.
Files changed (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +437 -0
  3. package/dist/database/index.d.ts +17 -0
  4. package/dist/database/index.d.ts.map +1 -0
  5. package/dist/database/index.js +18 -0
  6. package/dist/database/index.js.map +1 -0
  7. package/dist/database/schema.d.ts +1053 -0
  8. package/dist/database/schema.d.ts.map +1 -0
  9. package/dist/database/schema.js +101 -0
  10. package/dist/database/schema.js.map +1 -0
  11. package/dist/index.d.ts +7 -0
  12. package/dist/index.d.ts.map +1 -0
  13. package/dist/index.js +11 -0
  14. package/dist/index.js.map +1 -0
  15. package/dist/monitors/checks.d.ts +67 -0
  16. package/dist/monitors/checks.d.ts.map +1 -0
  17. package/dist/monitors/checks.js +300 -0
  18. package/dist/monitors/checks.js.map +1 -0
  19. package/dist/monitors/index.d.ts +3 -0
  20. package/dist/monitors/index.d.ts.map +1 -0
  21. package/dist/monitors/index.js +3 -0
  22. package/dist/monitors/index.js.map +1 -0
  23. package/dist/monitors/runner.d.ts +86 -0
  24. package/dist/monitors/runner.d.ts.map +1 -0
  25. package/dist/monitors/runner.js +272 -0
  26. package/dist/monitors/runner.js.map +1 -0
  27. package/dist/routes/index.d.ts +3 -0
  28. package/dist/routes/index.d.ts.map +1 -0
  29. package/dist/routes/index.js +3 -0
  30. package/dist/routes/index.js.map +1 -0
  31. package/dist/routes/monitors.d.ts +16 -0
  32. package/dist/routes/monitors.d.ts.map +1 -0
  33. package/dist/routes/monitors.js +196 -0
  34. package/dist/routes/monitors.js.map +1 -0
  35. package/dist/routes/push.d.ts +11 -0
  36. package/dist/routes/push.d.ts.map +1 -0
  37. package/dist/routes/push.js +33 -0
  38. package/dist/routes/push.js.map +1 -0
  39. package/dist/server.d.ts +37 -0
  40. package/dist/server.d.ts.map +1 -0
  41. package/dist/server.js +53 -0
  42. package/dist/server.js.map +1 -0
  43. package/package.json +88 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 PulseWatch
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 ADDED
@@ -0,0 +1,437 @@
1
+ # @pulsewatch/server
2
+
3
+ **Complete uptime monitoring server** - Drop-in Express backend with monitoring engine, database, REST API, and real-time updates. **No authentication required** - integrate your own!
4
+
5
+ ## 🎯 One Complete Package
6
+
7
+ This package combines everything you need for uptime monitoring:
8
+
9
+ - ✅ **Monitoring Engine** - 8 monitor types (HTTP, TCP, DNS, Ping, WebSocket, Keyword, JSON Query, Push)
10
+ - ✅ **Express Backend** - Complete REST API
11
+ - ✅ **Database Schema** - Drizzle ORM ready
12
+ - ✅ **Real-time Updates** - Socket.IO integration
13
+ - ✅ **No Authentication** - Use your own auth system
14
+
15
+ ## 📦 Installation
16
+
17
+ ```bash
18
+ npm install @pulsewatch/server
19
+ ```
20
+
21
+ ### Peer Dependencies
22
+
23
+ ```bash
24
+ npm install express socket.io drizzle-orm pg
25
+ ```
26
+
27
+ ## 🚀 Quick Start
28
+
29
+ ```typescript
30
+ import express from "express";
31
+ import { createPulseWatch, createDatabase } from "@pulsewatch/server";
32
+ import * as schema from "@pulsewatch/server/database";
33
+
34
+ const app = express();
35
+
36
+ // Create database connection
37
+ const { db } = createDatabase({
38
+ connectionString: process.env.DATABASE_URL,
39
+ });
40
+
41
+ // Create PulseWatch server
42
+ const pulsewatch = createPulseWatch({ app, db, schema });
43
+
44
+ // Start monitoring
45
+ await pulsewatch.start();
46
+
47
+ // Start HTTP server
48
+ pulsewatch.httpServer.listen(3000, () => {
49
+ console.log("Server running on port 3000");
50
+ });
51
+ ```
52
+
53
+ That's it! You now have a complete monitoring system with:
54
+
55
+ - REST API at `/api/monitors`
56
+ - Push endpoints at `/api/push/:token`
57
+ - Real-time updates via WebSocket at `/ws`
58
+
59
+ ## 📊 Monitor Types
60
+
61
+ ### 1. HTTP/HTTPS
62
+
63
+ ```typescript
64
+ {
65
+ name: "My API",
66
+ type: "http",
67
+ url: "https://api.example.com",
68
+ method: "GET",
69
+ intervalSeconds: 60
70
+ }
71
+ ```
72
+
73
+ ### 2. TCP Port
74
+
75
+ ```typescript
76
+ {
77
+ name: "Database",
78
+ type: "tcp",
79
+ host: "db.example.com",
80
+ port: 5432
81
+ }
82
+ ```
83
+
84
+ ### 3. DNS
85
+
86
+ ```typescript
87
+ {
88
+ name: "DNS Check",
89
+ type: "dns",
90
+ host: "example.com",
91
+ dnsRecordType: "A"
92
+ }
93
+ ```
94
+
95
+ ### 4. Ping
96
+
97
+ ```typescript
98
+ {
99
+ name: "Server Ping",
100
+ type: "ping",
101
+ host: "example.com"
102
+ }
103
+ ```
104
+
105
+ ### 5. WebSocket
106
+
107
+ ```typescript
108
+ {
109
+ name: "WebSocket",
110
+ type: "websocket",
111
+ url: "wss://example.com/socket"
112
+ }
113
+ ```
114
+
115
+ ### 6. Keyword Search
116
+
117
+ ```typescript
118
+ {
119
+ name: "Homepage Check",
120
+ type: "keyword",
121
+ url: "https://example.com",
122
+ keyword: "Welcome"
123
+ }
124
+ ```
125
+
126
+ ### 7. JSON Query
127
+
128
+ ```typescript
129
+ {
130
+ name: "API Health",
131
+ type: "json_query",
132
+ url: "https://api.example.com/health",
133
+ jsonQuery: "$.status",
134
+ expectedValue: "healthy"
135
+ }
136
+ ```
137
+
138
+ ### 8. Push (Heartbeat)
139
+
140
+ ```typescript
141
+ {
142
+ name: "Cron Job",
143
+ type: "push",
144
+ intervalSeconds: 300
145
+ }
146
+ ```
147
+
148
+ Then send heartbeats:
149
+
150
+ ```bash
151
+ curl https://your-server.com/api/push/YOUR_TOKEN
152
+ ```
153
+
154
+ ## 🔌 API Endpoints
155
+
156
+ Once integrated, these endpoints are available:
157
+
158
+ ```
159
+ GET /api/monitors - List all monitors
160
+ GET /api/monitors/summary - Get monitors with uptime stats
161
+ POST /api/monitors - Create monitor
162
+ PUT /api/monitors/:id - Update monitor
163
+ DELETE /api/monitors/:id - Delete monitor
164
+ POST /api/monitors/:id/pause - Pause/unpause monitor
165
+ POST /api/monitors/:id/clone - Clone monitor
166
+ GET /api/monitors/:id/results - Get check results
167
+ POST /api/push/:token - Receive heartbeat
168
+ GET /api/push/:token - Receive heartbeat (GET)
169
+ GET /api/health - Health check
170
+ ```
171
+
172
+ ## 🔄 Real-time Updates
173
+
174
+ Listen for monitor updates via Socket.IO:
175
+
176
+ ```typescript
177
+ import { io } from "socket.io-client";
178
+
179
+ const socket = io("http://localhost:3000", {
180
+ path: "/ws",
181
+ });
182
+
183
+ socket.on("monitor:update", (data) => {
184
+ console.log("Monitor update:", data);
185
+ // {
186
+ // monitorId: '123',
187
+ // status: 'up',
188
+ // message: 'OK',
189
+ // pingMs: 145,
190
+ // httpStatus: 200,
191
+ // checkedAt: '2026-01-30T12:00:00.000Z'
192
+ // }
193
+ });
194
+ ```
195
+
196
+ ## 💾 Database
197
+
198
+ The package includes a complete Drizzle ORM schema:
199
+
200
+ ```typescript
201
+ import * as schema from "@pulsewatch/server/database";
202
+
203
+ // Tables included:
204
+ // - monitors
205
+ // - monitorResults
206
+ // - proxies
207
+ // - notifications
208
+ // - monitorNotifications
209
+ // - statusPages
210
+ // - statusPageMonitors
211
+ ```
212
+
213
+ ### Run Migrations
214
+
215
+ ```bash
216
+ # Install drizzle-kit
217
+ npm install -D drizzle-kit
218
+
219
+ # Generate migrations
220
+ npx drizzle-kit generate
221
+
222
+ # Push to database
223
+ npx drizzle-kit push
224
+ ```
225
+
226
+ ## 🔐 Adding Authentication
227
+
228
+ The package doesn't include authentication - add your own:
229
+
230
+ ```typescript
231
+ import express from "express";
232
+ import { createPulseWatch } from "@pulsewatch/server";
233
+
234
+ const app = express();
235
+
236
+ // Your auth middleware
237
+ function authMiddleware(req, res, next) {
238
+ // Check JWT, session, API key, etc.
239
+ if (!req.headers.authorization) {
240
+ return res.status(401).json({ error: "Unauthorized" });
241
+ }
242
+ next();
243
+ }
244
+
245
+ // Protect all API routes
246
+ app.use("/api", authMiddleware);
247
+
248
+ // Add PulseWatch (now protected by your auth)
249
+ const pulsewatch = createPulseWatch({ app, db, schema });
250
+ ```
251
+
252
+ ## ⚙️ Configuration
253
+
254
+ ### Full Configuration
255
+
256
+ ```typescript
257
+ const pulsewatch = createPulseWatch({
258
+ app, // Express app
259
+ db, // Drizzle database instance
260
+ schema: {
261
+ // Database schema
262
+ monitors,
263
+ monitorResults,
264
+ proxies,
265
+ notifications,
266
+ monitorNotifications,
267
+ },
268
+ socketIO: {
269
+ // Optional Socket.IO config
270
+ cors: { origin: "*" },
271
+ path: "/ws",
272
+ },
273
+ logger: {
274
+ // Optional logger
275
+ error: (err, msg) => console.error(msg, err),
276
+ warn: (msg) => console.warn(msg),
277
+ info: (msg) => console.log(msg),
278
+ },
279
+ });
280
+ ```
281
+
282
+ ## 🎯 Advanced Usage
283
+
284
+ ### Use Check Functions Directly
285
+
286
+ ```typescript
287
+ import { checkHttp, checkTcp } from "@pulsewatch/server";
288
+
289
+ // Run checks manually
290
+ const result = await checkHttp({
291
+ type: "http",
292
+ url: "https://example.com",
293
+ timeoutMs: 5000,
294
+ });
295
+
296
+ console.log(result);
297
+ // { status: 'up', message: 'OK', pingMs: 123, httpStatus: 200 }
298
+ ```
299
+
300
+ ### Custom Routes
301
+
302
+ ```typescript
303
+ import {
304
+ createMonitorsRouter,
305
+ createPushRouter,
306
+ } from "@pulsewatch/server/routes";
307
+
308
+ // Create routes separately
309
+ const monitorsRouter = createMonitorsRouter({ db, schema, runner });
310
+ const pushRouter = createPushRouter({ runner });
311
+
312
+ // Mount with custom paths
313
+ app.use("/monitoring/monitors", monitorsRouter);
314
+ app.use("/monitoring/push", pushRouter);
315
+ ```
316
+
317
+ ### Use MonitorRunner Directly
318
+
319
+ ```typescript
320
+ import { MonitorRunner } from "@pulsewatch/server";
321
+ import { eq, desc, inArray } from "drizzle-orm";
322
+
323
+ const runner = new MonitorRunner({
324
+ io,
325
+ db,
326
+ schema,
327
+ orm: { eq, desc, inArray },
328
+ logger: console,
329
+ });
330
+
331
+ await runner.start();
332
+ ```
333
+
334
+ ## 📝 Complete Example
335
+
336
+ ```typescript
337
+ import express from "express";
338
+ import { createPulseWatch, createDatabase } from "@pulsewatch/server";
339
+ import * as schema from "@pulsewatch/server/database";
340
+
341
+ const app = express();
342
+
343
+ // Create database
344
+ const { db, pool } = createDatabase({
345
+ connectionString: process.env.DATABASE_URL,
346
+ max: 20,
347
+ });
348
+
349
+ // Create PulseWatch
350
+ const pulsewatch = createPulseWatch({
351
+ app,
352
+ db,
353
+ schema,
354
+ socketIO: {
355
+ cors: { origin: process.env.FRONTEND_URL },
356
+ path: "/ws",
357
+ },
358
+ logger: console,
359
+ });
360
+
361
+ // Start monitoring
362
+ await pulsewatch.start();
363
+
364
+ // Start server
365
+ const PORT = process.env.PORT || 3000;
366
+ pulsewatch.httpServer.listen(PORT, () => {
367
+ console.log(`PulseWatch running on port ${PORT}`);
368
+ });
369
+
370
+ // Graceful shutdown
371
+ process.on("SIGTERM", () => {
372
+ pulsewatch.stop();
373
+ pool.end();
374
+ process.exit(0);
375
+ });
376
+ ```
377
+
378
+ ## 🌟 Features
379
+
380
+ - ✅ **8 Monitor Types** - HTTP, TCP, DNS, Ping, WebSocket, Keyword, JSON Query, Push
381
+ - ✅ **Real-time Updates** - Socket.IO for live monitoring
382
+ - ✅ **Database Included** - Complete Drizzle ORM schema
383
+ - ✅ **REST API** - Full CRUD for monitors
384
+ - ✅ **No Auth Required** - Integrate your own authentication
385
+ - ✅ **TypeScript** - Full type definitions
386
+ - ✅ **Lightweight** - Minimal dependencies
387
+ - ✅ **Flexible** - Use as-is or customize
388
+
389
+ ## 📦 Exports
390
+
391
+ ```typescript
392
+ // Main server
393
+ export { createPulseWatch, type PulseWatchConfig, type PulseWatchServer };
394
+
395
+ // Database
396
+ export { createDatabase, type DatabaseConfig };
397
+ export * from "./database/schema";
398
+
399
+ // Routes
400
+ export { createMonitorsRouter, createPushRouter };
401
+
402
+ // Monitor checks
403
+ export {
404
+ checkHttp,
405
+ checkTcp,
406
+ checkDns,
407
+ checkPing,
408
+ checkWebsocket,
409
+ checkKeyword,
410
+ checkJsonQuery,
411
+ };
412
+
413
+ // MonitorRunner
414
+ export { MonitorRunner, type MonitorRunnerConfig };
415
+
416
+ // Types
417
+ export type { Monitor, Proxy, CheckResult, MonitorType, MonitorStatus };
418
+ ```
419
+
420
+ ## 🔧 Environment Variables
421
+
422
+ ```env
423
+ DATABASE_URL=postgresql://user:password@localhost:5432/pulsewatch
424
+ PORT=3000
425
+ ```
426
+
427
+ ## 📄 License
428
+
429
+ MIT
430
+
431
+ ## 🤝 Support
432
+
433
+ For issues and questions, visit [GitHub Issues](https://github.com/yourusername/pulsewatch/issues).
434
+
435
+ ---
436
+
437
+ **Made with ❤️ by Abishek**
@@ -0,0 +1,17 @@
1
+ import pg from "pg";
2
+ import * as schema from "./schema.js";
3
+ export interface DatabaseConfig {
4
+ connectionString: string;
5
+ max?: number;
6
+ }
7
+ /**
8
+ * Create a database connection pool
9
+ */
10
+ export declare function createDatabase(config: DatabaseConfig): {
11
+ db: import("drizzle-orm/node-postgres").NodePgDatabase<typeof schema> & {
12
+ $client: pg.Pool;
13
+ };
14
+ pool: pg.Pool;
15
+ };
16
+ export * from "./schema.js";
17
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAItC,MAAM,WAAW,cAAc;IAC7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,cAAc;;;;;EASpD;AAGD,cAAc,aAAa,CAAC"}
@@ -0,0 +1,18 @@
1
+ import { drizzle } from "drizzle-orm/node-postgres";
2
+ import pg from "pg";
3
+ import * as schema from "./schema.js";
4
+ const { Pool } = pg;
5
+ /**
6
+ * Create a database connection pool
7
+ */
8
+ export function createDatabase(config) {
9
+ const pool = new Pool({
10
+ connectionString: config.connectionString,
11
+ max: config.max ?? 20,
12
+ });
13
+ const db = drizzle(pool, { schema });
14
+ return { db, pool };
15
+ }
16
+ // Export schema
17
+ export * from "./schema.js";
18
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/database/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,2BAA2B,CAAC;AACpD,OAAO,EAAE,MAAM,IAAI,CAAC;AACpB,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AAEtC,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AAOpB;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,MAAsB;IACnD,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC;QACpB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,GAAG,EAAE,MAAM,CAAC,GAAG,IAAI,EAAE;KACtB,CAAC,CAAC;IAEH,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;IAErC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC;AAED,gBAAgB;AAChB,cAAc,aAAa,CAAC"}