worker-que 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 (48) hide show
  1. package/DASHBOARD-QUICKSTART.md +278 -0
  2. package/DASHBOARD.md +556 -0
  3. package/LICENSE +21 -0
  4. package/README.md +414 -0
  5. package/SSL-QUICK-REFERENCE.md +225 -0
  6. package/SSL.md +516 -0
  7. package/dist/client.d.ts +11 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +64 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/dashboard/index.d.ts +34 -0
  12. package/dist/dashboard/index.d.ts.map +1 -0
  13. package/dist/dashboard/index.js +164 -0
  14. package/dist/dashboard/index.js.map +1 -0
  15. package/dist/dashboard/service.d.ts +66 -0
  16. package/dist/dashboard/service.d.ts.map +1 -0
  17. package/dist/dashboard/service.js +201 -0
  18. package/dist/dashboard/service.js.map +1 -0
  19. package/dist/dashboard/views.d.ts +3 -0
  20. package/dist/dashboard/views.d.ts.map +1 -0
  21. package/dist/dashboard/views.js +786 -0
  22. package/dist/dashboard/views.js.map +1 -0
  23. package/dist/index.d.ts +6 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +29 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/job.d.ts +19 -0
  28. package/dist/job.d.ts.map +1 -0
  29. package/dist/job.js +36 -0
  30. package/dist/job.js.map +1 -0
  31. package/dist/sql.d.ts +8 -0
  32. package/dist/sql.d.ts.map +1 -0
  33. package/dist/sql.js +57 -0
  34. package/dist/sql.js.map +1 -0
  35. package/dist/types.d.ts +90 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +3 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/utils.d.ts +6 -0
  40. package/dist/utils.d.ts.map +1 -0
  41. package/dist/utils.js +31 -0
  42. package/dist/utils.js.map +1 -0
  43. package/dist/worker.d.ts +19 -0
  44. package/dist/worker.d.ts.map +1 -0
  45. package/dist/worker.js +99 -0
  46. package/dist/worker.js.map +1 -0
  47. package/migrations/schema.sql +26 -0
  48. package/package.json +105 -0
package/SSL.md ADDED
@@ -0,0 +1,516 @@
1
+ # SSL/TLS Configuration Guide
2
+
3
+ This guide explains how to configure SSL/TLS connections to PostgreSQL with client certificates.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Basic SSL Connection](#basic-ssl-connection)
8
+ - [SSL with Client Certificates](#ssl-with-client-certificates)
9
+ - [Certificate File Formats](#certificate-file-formats)
10
+ - [Environment Variables](#environment-variables)
11
+ - [Common SSL Modes](#common-ssl-modes)
12
+ - [Troubleshooting](#troubleshooting)
13
+
14
+ ## Basic SSL Connection
15
+
16
+ ### Simple SSL (sslmode=require)
17
+
18
+ ```typescript
19
+ import { Client } from 'que-ts';
20
+
21
+ const client = new Client({
22
+ host: 'your-database-host.com',
23
+ port: 5432,
24
+ database: 'your_database',
25
+ user: 'your_user',
26
+ password: 'your_password',
27
+ ssl: {
28
+ rejectUnauthorized: true, // Verify server certificate
29
+ }
30
+ });
31
+ ```
32
+
33
+ ### SSL without Certificate Verification (Development Only)
34
+
35
+ ⚠️ **WARNING:** Only use this in development environments!
36
+
37
+ ```typescript
38
+ const client = new Client({
39
+ host: 'localhost',
40
+ port: 5432,
41
+ database: 'test_db',
42
+ user: 'test_user',
43
+ password: 'test_password',
44
+ ssl: {
45
+ rejectUnauthorized: false, // Skip certificate verification
46
+ }
47
+ });
48
+ ```
49
+
50
+ ## SSL with Client Certificates
51
+
52
+ ### Using Certificate Files
53
+
54
+ ```typescript
55
+ import { Client } from 'que-ts';
56
+ import * as fs from 'fs';
57
+ import * as path from 'path';
58
+
59
+ const client = new Client({
60
+ host: 'your-database-host.com',
61
+ port: 5432,
62
+ database: 'your_database',
63
+ user: 'your_user',
64
+ password: 'your_password',
65
+ ssl: {
66
+ // Verify the server's certificate
67
+ rejectUnauthorized: true,
68
+
69
+ // Client certificate (.crt or .pem)
70
+ cert: fs.readFileSync(path.join(__dirname, 'certs/client-cert.pem')),
71
+
72
+ // Client private key (.key)
73
+ key: fs.readFileSync(path.join(__dirname, 'certs/client-key.pem')),
74
+
75
+ // CA certificate to verify server
76
+ ca: fs.readFileSync(path.join(__dirname, 'certs/ca-cert.pem')),
77
+ }
78
+ });
79
+ ```
80
+
81
+ ### Using Certificate Paths (Alternative)
82
+
83
+ You can also pass file paths directly if using string buffers:
84
+
85
+ ```typescript
86
+ import * as fs from 'fs';
87
+
88
+ const client = new Client({
89
+ host: 'your-database-host.com',
90
+ port: 5432,
91
+ database: 'your_database',
92
+ user: 'your_user',
93
+ password: 'your_password',
94
+ ssl: {
95
+ rejectUnauthorized: true,
96
+ cert: fs.readFileSync('/path/to/client-cert.pem'),
97
+ key: fs.readFileSync('/path/to/client-key.pem'),
98
+ ca: fs.readFileSync('/path/to/ca-cert.pem'),
99
+ }
100
+ });
101
+ ```
102
+
103
+ ### Encrypted Private Key
104
+
105
+ If your private key is password-protected:
106
+
107
+ ```typescript
108
+ const client = new Client({
109
+ host: 'your-database-host.com',
110
+ port: 5432,
111
+ database: 'your_database',
112
+ user: 'your_user',
113
+ password: 'your_password',
114
+ ssl: {
115
+ rejectUnauthorized: true,
116
+ cert: fs.readFileSync('./certs/client-cert.pem'),
117
+ key: fs.readFileSync('./certs/client-key-encrypted.pem'),
118
+ ca: fs.readFileSync('./certs/ca-cert.pem'),
119
+ passphrase: 'your-private-key-passphrase', // Passphrase for the key
120
+ }
121
+ });
122
+ ```
123
+
124
+ ### Multiple CA Certificates
125
+
126
+ If you need to trust multiple certificate authorities:
127
+
128
+ ```typescript
129
+ const client = new Client({
130
+ host: 'your-database-host.com',
131
+ port: 5432,
132
+ database: 'your_database',
133
+ user: 'your_user',
134
+ password: 'your_password',
135
+ ssl: {
136
+ rejectUnauthorized: true,
137
+ cert: fs.readFileSync('./certs/client-cert.pem'),
138
+ key: fs.readFileSync('./certs/client-key.pem'),
139
+ ca: [
140
+ fs.readFileSync('./certs/ca-cert-1.pem'),
141
+ fs.readFileSync('./certs/ca-cert-2.pem'),
142
+ ],
143
+ }
144
+ });
145
+ ```
146
+
147
+ ## Certificate File Formats
148
+
149
+ ### Supported Formats
150
+
151
+ - **PEM** (`.pem`, `.crt`, `.cer`, `.key`) - Most common, text-based format
152
+ - **DER** (`.der`) - Binary format (less common)
153
+
154
+ ### PEM File Structure
155
+
156
+ A PEM file looks like this:
157
+
158
+ ```
159
+ -----BEGIN CERTIFICATE-----
160
+ MIIDXTCCAkWgAwIBAgIJAKZ...
161
+ ...
162
+ -----END CERTIFICATE-----
163
+ ```
164
+
165
+ ### Typical Certificate Files
166
+
167
+ | File | Description | Example Name |
168
+ |------|-------------|--------------|
169
+ | CA Certificate | Certificate Authority (verifies server) | `ca-cert.pem`, `root.crt` |
170
+ | Client Certificate | Your client certificate | `client-cert.pem`, `postgresql.crt` |
171
+ | Client Key | Your private key | `client-key.pem`, `postgresql.key` |
172
+
173
+ ### Obtaining Certificates
174
+
175
+ **From PostgreSQL Server:**
176
+ ```bash
177
+ # Server certificates are usually in:
178
+ /var/lib/postgresql/data/
179
+ # Or
180
+ /etc/postgresql/<version>/main/
181
+ ```
182
+
183
+ **Generate Self-Signed Certificates (Development):**
184
+ ```bash
185
+ # Generate CA key and certificate
186
+ openssl req -new -x509 -days 365 -nodes -text \
187
+ -out ca-cert.pem -keyout ca-key.pem
188
+
189
+ # Generate server key and certificate request
190
+ openssl req -new -nodes -text -out server.csr -keyout server-key.pem
191
+
192
+ # Sign server certificate with CA
193
+ openssl x509 -req -in server.csr -text -days 365 \
194
+ -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \
195
+ -out server-cert.pem
196
+
197
+ # Generate client key and certificate request
198
+ openssl req -new -nodes -text -out client.csr -keyout client-key.pem
199
+
200
+ # Sign client certificate with CA
201
+ openssl x509 -req -in client.csr -text -days 365 \
202
+ -CA ca-cert.pem -CAkey ca-key.pem -CAcreateserial \
203
+ -out client-cert.pem
204
+ ```
205
+
206
+ ## Environment Variables
207
+
208
+ ### Recommended Production Setup
209
+
210
+ Create a `.env` file:
211
+
212
+ ```bash
213
+ # Database connection
214
+ DB_HOST=your-database-host.com
215
+ DB_PORT=5432
216
+ DB_NAME=your_database
217
+ DB_USER=your_user
218
+ DB_PASSWORD=your_password
219
+
220
+ # SSL Configuration
221
+ DB_SSL_ENABLED=true
222
+ DB_SSL_REJECT_UNAUTHORIZED=true
223
+ DB_SSL_CERT=/path/to/certs/client-cert.pem
224
+ DB_SSL_KEY=/path/to/certs/client-key.pem
225
+ DB_SSL_CA=/path/to/certs/ca-cert.pem
226
+ DB_SSL_PASSPHRASE=your-key-passphrase # Optional
227
+ ```
228
+
229
+ ### Using Environment Variables in Code
230
+
231
+ ```typescript
232
+ import { Client } from 'que-ts';
233
+ import * as fs from 'fs';
234
+ import * as dotenv from 'dotenv';
235
+
236
+ dotenv.config();
237
+
238
+ function createClient() {
239
+ const sslConfig = process.env.DB_SSL_ENABLED === 'true' ? {
240
+ rejectUnauthorized: process.env.DB_SSL_REJECT_UNAUTHORIZED !== 'false',
241
+ cert: process.env.DB_SSL_CERT ? fs.readFileSync(process.env.DB_SSL_CERT) : undefined,
242
+ key: process.env.DB_SSL_KEY ? fs.readFileSync(process.env.DB_SSL_KEY) : undefined,
243
+ ca: process.env.DB_SSL_CA ? fs.readFileSync(process.env.DB_SSL_CA) : undefined,
244
+ passphrase: process.env.DB_SSL_PASSPHRASE,
245
+ } : false;
246
+
247
+ return new Client({
248
+ host: process.env.DB_HOST,
249
+ port: parseInt(process.env.DB_PORT || '5432'),
250
+ database: process.env.DB_NAME,
251
+ user: process.env.DB_USER,
252
+ password: process.env.DB_PASSWORD,
253
+ ssl: sslConfig,
254
+ });
255
+ }
256
+
257
+ const client = createClient();
258
+ ```
259
+
260
+ ## Common SSL Modes
261
+
262
+ PostgreSQL supports different SSL modes. Here's how to configure them:
263
+
264
+ | SSL Mode | Description | Configuration |
265
+ |----------|-------------|---------------|
266
+ | `disable` | No SSL | `ssl: false` |
267
+ | `prefer` | Try SSL, fallback to non-SSL | Not directly supported (use `require`) |
268
+ | `require` | SSL required, no cert verification | `ssl: { rejectUnauthorized: false }` |
269
+ | `verify-ca` | SSL with CA verification | `ssl: { rejectUnauthorized: true, ca: ... }` |
270
+ | `verify-full` | SSL with full verification | `ssl: { rejectUnauthorized: true, ca: ..., checkServerIdentity: ... }` |
271
+
272
+ ### Example: verify-ca Mode
273
+
274
+ ```typescript
275
+ const client = new Client({
276
+ host: 'your-database-host.com',
277
+ port: 5432,
278
+ database: 'your_database',
279
+ user: 'your_user',
280
+ password: 'your_password',
281
+ ssl: {
282
+ rejectUnauthorized: true,
283
+ ca: fs.readFileSync('./certs/ca-cert.pem'),
284
+ }
285
+ });
286
+ ```
287
+
288
+ ### Example: verify-full Mode
289
+
290
+ ```typescript
291
+ const client = new Client({
292
+ host: 'your-database-host.com',
293
+ port: 5432,
294
+ database: 'your_database',
295
+ user: 'your_user',
296
+ password: 'your_password',
297
+ ssl: {
298
+ rejectUnauthorized: true,
299
+ ca: fs.readFileSync('./certs/ca-cert.pem'),
300
+ // Optional: custom server identity check
301
+ checkServerIdentity: (hostname, cert) => {
302
+ // Custom validation logic
303
+ if (hostname !== 'expected-hostname.com') {
304
+ throw new Error('Hostname mismatch');
305
+ }
306
+ },
307
+ }
308
+ });
309
+ ```
310
+
311
+ ## Cloud Provider Examples
312
+
313
+ ### AWS RDS
314
+
315
+ ```typescript
316
+ import { Client } from 'que-ts';
317
+ import * as https from 'https';
318
+
319
+ // Download RDS CA bundle from:
320
+ // https://truststore.pki.rds.amazonaws.com/global/global-bundle.pem
321
+
322
+ const client = new Client({
323
+ host: 'your-instance.region.rds.amazonaws.com',
324
+ port: 5432,
325
+ database: 'your_database',
326
+ user: 'your_user',
327
+ password: 'your_password',
328
+ ssl: {
329
+ rejectUnauthorized: true,
330
+ ca: fs.readFileSync('./rds-ca-bundle.pem'),
331
+ }
332
+ });
333
+ ```
334
+
335
+ ### Google Cloud SQL
336
+
337
+ ```typescript
338
+ const client = new Client({
339
+ host: '/cloudsql/project:region:instance', // Unix socket
340
+ // Or use IP with SSL:
341
+ // host: 'your-instance-ip',
342
+ port: 5432,
343
+ database: 'your_database',
344
+ user: 'your_user',
345
+ password: 'your_password',
346
+ ssl: {
347
+ rejectUnauthorized: true,
348
+ ca: fs.readFileSync('./server-ca.pem'),
349
+ cert: fs.readFileSync('./client-cert.pem'),
350
+ key: fs.readFileSync('./client-key.pem'),
351
+ }
352
+ });
353
+ ```
354
+
355
+ ### Azure Database for PostgreSQL
356
+
357
+ ```typescript
358
+ const client = new Client({
359
+ host: 'your-server.postgres.database.azure.com',
360
+ port: 5432,
361
+ database: 'your_database',
362
+ user: 'your_user@your-server',
363
+ password: 'your_password',
364
+ ssl: {
365
+ rejectUnauthorized: true,
366
+ // Azure root certificate
367
+ ca: fs.readFileSync('./BaltimoreCyberTrustRoot.crt.pem'),
368
+ }
369
+ });
370
+ ```
371
+
372
+ ### Heroku Postgres
373
+
374
+ ```typescript
375
+ const client = new Client({
376
+ connectionString: process.env.DATABASE_URL,
377
+ ssl: {
378
+ rejectUnauthorized: false, // Heroku uses self-signed certificates
379
+ }
380
+ });
381
+ ```
382
+
383
+ ## Troubleshooting
384
+
385
+ ### Error: "self signed certificate"
386
+
387
+ ```
388
+ Error: self signed certificate
389
+ ```
390
+
391
+ **Solution:** Set `rejectUnauthorized: false` (development only) or add the CA certificate:
392
+
393
+ ```typescript
394
+ ssl: {
395
+ rejectUnauthorized: true,
396
+ ca: fs.readFileSync('./ca-cert.pem'),
397
+ }
398
+ ```
399
+
400
+ ### Error: "unable to verify the first certificate"
401
+
402
+ ```
403
+ Error: unable to verify the first certificate
404
+ ```
405
+
406
+ **Solution:** Add the complete certificate chain:
407
+
408
+ ```typescript
409
+ ssl: {
410
+ rejectUnauthorized: true,
411
+ ca: [
412
+ fs.readFileSync('./root-ca.pem'),
413
+ fs.readFileSync('./intermediate-ca.pem'),
414
+ ],
415
+ }
416
+ ```
417
+
418
+ ### Error: "certificate has expired"
419
+
420
+ ```
421
+ Error: certificate has expired
422
+ ```
423
+
424
+ **Solution:** Renew your certificates. For development, generate new self-signed certificates.
425
+
426
+ ### Error: "ENOENT: no such file or directory"
427
+
428
+ ```
429
+ Error: ENOENT: no such file or directory, open './certs/client-cert.pem'
430
+ ```
431
+
432
+ **Solution:** Check that certificate file paths are correct:
433
+
434
+ ```typescript
435
+ import * as path from 'path';
436
+
437
+ // Use absolute path
438
+ const certPath = path.join(__dirname, 'certs', 'client-cert.pem');
439
+ console.log('Certificate path:', certPath);
440
+ const cert = fs.readFileSync(certPath);
441
+ ```
442
+
443
+ ### Error: "sslmode value 'require' invalid"
444
+
445
+ If using a connection string, SSL configuration must be in the config object:
446
+
447
+ ```typescript
448
+ // ✗ Wrong - sslmode in connection string doesn't configure node-postgres properly
449
+ const client = new Client({
450
+ connectionString: 'postgresql://user:pass@host/db?sslmode=require'
451
+ });
452
+
453
+ // ✓ Correct - use ssl config object
454
+ const client = new Client({
455
+ connectionString: 'postgresql://user:pass@host/db',
456
+ ssl: {
457
+ rejectUnauthorized: true,
458
+ }
459
+ });
460
+ ```
461
+
462
+ ### Testing SSL Connection
463
+
464
+ ```typescript
465
+ import { Client } from 'que-ts';
466
+
467
+ async function testSSLConnection() {
468
+ const client = new Client({
469
+ host: 'your-host.com',
470
+ port: 5432,
471
+ database: 'your_database',
472
+ user: 'your_user',
473
+ password: 'your_password',
474
+ ssl: {
475
+ rejectUnauthorized: true,
476
+ cert: fs.readFileSync('./client-cert.pem'),
477
+ key: fs.readFileSync('./client-key.pem'),
478
+ ca: fs.readFileSync('./ca-cert.pem'),
479
+ }
480
+ });
481
+
482
+ try {
483
+ const job = await client.enqueue('TestJob', []);
484
+ console.log('✓ SSL connection successful! Job ID:', job.id);
485
+ await client.close();
486
+ } catch (error) {
487
+ console.error('✗ SSL connection failed:', error.message);
488
+ if (error.code) {
489
+ console.error('Error code:', error.code);
490
+ }
491
+ }
492
+ }
493
+
494
+ testSSLConnection();
495
+ ```
496
+
497
+ ## Security Best Practices
498
+
499
+ 1. **Always use `rejectUnauthorized: true` in production**
500
+ 2. **Never commit certificates or private keys to version control**
501
+ 3. **Use environment variables for sensitive data**
502
+ 4. **Rotate certificates regularly**
503
+ 5. **Use strong passphrases for encrypted keys**
504
+ 6. **Restrict file permissions on certificate files:**
505
+ ```bash
506
+ chmod 600 client-key.pem
507
+ chmod 644 client-cert.pem
508
+ chmod 644 ca-cert.pem
509
+ ```
510
+ 7. **Store certificates securely** (e.g., AWS Secrets Manager, HashiCorp Vault)
511
+
512
+ ## Additional Resources
513
+
514
+ - [PostgreSQL SSL Documentation](https://www.postgresql.org/docs/current/ssl-tcp.html)
515
+ - [Node.js TLS Documentation](https://nodejs.org/api/tls.html)
516
+ - [node-postgres SSL Guide](https://node-postgres.com/features/ssl)
@@ -0,0 +1,11 @@
1
+ import { PoolClient } from "pg";
2
+ import { Job, EnqueueOptions, ClientConfig, JSONArray } from "./types";
3
+ export declare class Client {
4
+ private pool;
5
+ constructor(config?: ClientConfig);
6
+ enqueue(jobClass: string, args?: JSONArray, options?: EnqueueOptions): Promise<Job>;
7
+ enqueueInTx(client: PoolClient, jobClass: string, args?: JSONArray, options?: EnqueueOptions): Promise<Job>;
8
+ lockJob(queue?: string): Promise<Job | null>;
9
+ close(): Promise<void>;
10
+ }
11
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,UAAU,EAAE,MAAM,IAAI,CAAC;AACtC,OAAO,EAAE,GAAG,EAAE,cAAc,EAAE,YAAY,EAAU,SAAS,EAAE,MAAM,SAAS,CAAC;AAK/E,qBAAa,MAAM;IACjB,OAAO,CAAC,IAAI,CAAO;gBAEP,MAAM,GAAE,YAAiB;IAe/B,OAAO,CACX,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,SAAc,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,GAAG,CAAC;IAiBT,WAAW,CACf,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM,EAChB,IAAI,GAAE,SAAc,EACpB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,GAAG,CAAC;IAiBT,OAAO,CAAC,KAAK,GAAE,MAAW,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI,CAAC;IAWhD,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAK7B"}
package/dist/client.js ADDED
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Client = void 0;
4
+ const pg_1 = require("pg");
5
+ const job_1 = require("./job");
6
+ const sql_1 = require("./sql");
7
+ const utils_1 = require("./utils");
8
+ class Client {
9
+ constructor(config = {}) {
10
+ this.pool = new pg_1.Pool({
11
+ connectionString: config.connectionString,
12
+ host: config.host,
13
+ port: config.port,
14
+ database: config.database,
15
+ user: config.user,
16
+ password: config.password,
17
+ ssl: config.ssl,
18
+ max: config.maxConnections || 10,
19
+ idleTimeoutMillis: 5000, // Close idle connections after 5 seconds
20
+ connectionTimeoutMillis: 5000, // Timeout connection attempts after 5 seconds
21
+ });
22
+ }
23
+ async enqueue(jobClass, args = [], options = {}) {
24
+ const { priority = 100, runAt = new Date(), queue = "" } = options;
25
+ const argsJson = (0, utils_1.formatJobArgs)(args);
26
+ const result = await this.pool.query(sql_1.SQL_QUERIES.ENQUEUE_JOB, [
27
+ jobClass,
28
+ argsJson,
29
+ priority,
30
+ runAt,
31
+ queue,
32
+ ]);
33
+ const row = result.rows[0];
34
+ return new job_1.JobInstance(row, this.pool);
35
+ }
36
+ async enqueueInTx(client, jobClass, args = [], options = {}) {
37
+ const { priority = 100, runAt = new Date(), queue = "" } = options;
38
+ const argsJson = (0, utils_1.formatJobArgs)(args);
39
+ const result = await client.query(sql_1.SQL_QUERIES.ENQUEUE_JOB, [
40
+ jobClass,
41
+ argsJson,
42
+ priority,
43
+ runAt,
44
+ queue,
45
+ ]);
46
+ const row = result.rows[0];
47
+ return new job_1.JobInstance(row, this.pool);
48
+ }
49
+ async lockJob(queue = "") {
50
+ const result = await this.pool.query(sql_1.SQL_QUERIES.LOCK_JOB, [queue]);
51
+ if (result.rows.length === 0) {
52
+ return null;
53
+ }
54
+ const row = result.rows[0];
55
+ return new job_1.JobInstance(row, this.pool);
56
+ }
57
+ async close() {
58
+ await this.pool.end();
59
+ // Small delay to ensure all connections are fully closed
60
+ await new Promise((resolve) => setTimeout(resolve, 50));
61
+ }
62
+ }
63
+ exports.Client = Client;
64
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,34 @@
1
+ import { Router, Request, Response, NextFunction } from 'express';
2
+ import { Pool } from 'pg';
3
+ import { DashboardService, DashboardOptions } from './service';
4
+ export interface DashboardMiddlewareOptions extends DashboardOptions {
5
+ /**
6
+ * Optional authentication middleware
7
+ * Return true to allow access, false to deny
8
+ */
9
+ auth?: (req: Request, res: Response, next: NextFunction) => boolean | Promise<boolean>;
10
+ }
11
+ /**
12
+ * Creates an Express router with the Que dashboard
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * import express from 'express';
17
+ * import { Pool } from 'pg';
18
+ * import { createDashboard } from 'que-ts/dashboard';
19
+ *
20
+ * const app = express();
21
+ * const pool = new Pool({ ... });
22
+ *
23
+ * app.use('/admin/queue', createDashboard(pool, {
24
+ * title: 'My App Queue',
25
+ * auth: (req, res, next) => {
26
+ * // Add your authentication logic
27
+ * return req.isAuthenticated();
28
+ * }
29
+ * }));
30
+ * ```
31
+ */
32
+ export declare function createDashboard(pool: Pool, options?: DashboardMiddlewareOptions): Router;
33
+ export { DashboardService, DashboardOptions };
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/dashboard/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAClE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC1B,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAG/D,MAAM,WAAW,0BAA2B,SAAQ,gBAAgB;IAClE;;;OAGG;IACH,IAAI,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CACxF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,IAAI,EACV,OAAO,GAAE,0BAA+B,GACvC,MAAM,CAqJR;AAED,OAAO,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,CAAC"}