outlet-orm 6.0.0 → 7.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.
@@ -0,0 +1,522 @@
1
+ # Outlet ORM - API Reference
2
+
3
+ [← Back to Index](SKILL.md) | [Previous: Advanced](ADVANCED.md)
4
+
5
+ > 📘 **TypeScript** : Full type definitions available. Import types from`outlet-orm`. See [TYPESCRIPT.md](TYPESCRIPT.md)
6
+
7
+ ---
8
+
9
+ ## DatabaseConnection
10
+
11
+ ### Constructor
12
+
13
+ ```javascript
14
+ const { DatabaseConnection } = require('outlet-orm');
15
+
16
+ // From .env (automatic)
17
+ const db = new DatabaseConnection();
18
+
19
+ // Manual configuration
20
+ const db = new DatabaseConnection({
21
+ driver: 'mysql', // mysql | postgres | sqlite
22
+ host: 'localhost',
23
+ port: 3306,
24
+ database: 'myapp',
25
+ user: 'root',
26
+ password: 'secret'
27
+ });
28
+ ```
29
+
30
+ ### Methods
31
+
32
+ | Method | Description |
33
+ |--------|-------------|
34
+ |`connect()`| Establish connection (called automatically) |
35
+ |`close()`| Close connection |
36
+ |`disconnect()`| Alias for close() |
37
+
38
+ ### Transaction Methods
39
+
40
+ | Method | Description |
41
+ |--------|-------------|
42
+ |`beginTransaction()`| Start transaction |
43
+ |`commit()`| Commit transaction |
44
+ |`rollback()`| Rollback transaction |
45
+ |`transaction(callback)`| Execute in transaction (auto commit/rollback) |
46
+
47
+ ### Query Methods
48
+
49
+ | Method | Description |
50
+ |--------|-------------|
51
+ |`select(table, query)`| Execute SELECT |
52
+ |`insert(table, data)`| Insert record |
53
+ |`insertMany(table, data[])`| Insert multiple records |
54
+ |`update(table, data, query)`| Update records |
55
+ |`delete(table, query)`| Delete records |
56
+ |`count(table, query)`| Count records |
57
+ |`executeRawQuery(sql, params?)`| Raw query (normalised results) |
58
+ |`execute(sql, params?)`| Raw query (native driver results) |
59
+ |`increment(table, column, query, amount?)`| Atomic increment |
60
+ |`decrement(table, column, query, amount?)`| Atomic decrement |
61
+
62
+ ### Query Logging
63
+
64
+ | Method | Description |
65
+ |--------|-------------|
66
+ |`enableQueryLog()`| Enable query logging |
67
+ |`disableQueryLog()`| Disable query logging |
68
+ |`getQueryLog()`| Get array of logged queries |
69
+ |`flushQueryLog()`| Clear query log |
70
+ |`isLogging()`| Check if logging is enabled |
71
+
72
+ ---
73
+
74
+ ## Model (Static Methods)
75
+
76
+ ### Connection
77
+
78
+ | Method | Description |
79
+ |--------|-------------|
80
+ |`setConnection(db)`| Set default connection |
81
+ |`getConnection()`| Get current connection |
82
+ |`setMorphMap(map)`| Set polymorphic mapping |
83
+
84
+ ### Query
85
+
86
+ | Method | Description |
87
+ |--------|-------------|
88
+ |`query()`| Get QueryBuilder instance |
89
+ |`all()`| Get all records |
90
+ |`find(id)`| Find by ID |
91
+ |`findOrFail(id)`| Find or throw error |
92
+ |`first()`| Get first record |
93
+ |`where(col, op?, val)`| WHERE clause |
94
+ |`whereIn(col, vals)`| WHERE IN |
95
+ |`whereNotIn(col, vals)`| WHERE NOT IN |
96
+ |`whereNull(col)`| WHERE IS NULL |
97
+ |`whereNotNull(col)`| WHERE IS NOT NULL |
98
+ |`whereBetween(col, [min, max])`| WHERE BETWEEN |
99
+ |`whereLike(col, pattern)`| WHERE LIKE |
100
+ |`orWhere(col, op?, val)`| OR WHERE |
101
+
102
+ ### CRUD
103
+
104
+ | Method | Description |
105
+ |--------|-------------|
106
+ |`create(attrs)`| Create and save |
107
+ |`insert(data)`| Raw insert |
108
+ |`update(attrs)`| Bulk update |
109
+ |`updateById(id, attrs)`| Update by ID |
110
+ |`updateAndFetchById(id, attrs, rels?)`| Update + fetch with relationships |
111
+ |`delete()`| Bulk delete |
112
+
113
+ ### Relationships
114
+
115
+ | Method | Description |
116
+ |--------|-------------|
117
+ |`with(...relationships)`| Eager load relationships |
118
+ |`withCount(relation)`| Add relation count |
119
+ |`whereHas(rel, callback?)`| Filter by relation existence |
120
+ |`has(rel, op?, count)`| Filter by relation count |
121
+ |`whereDoesntHave(rel, callback?)`| Filter by relation absence |
122
+
123
+ ### Query Modifiers
124
+
125
+ | Method | Description |
126
+ |--------|-------------|
127
+ |`select(...cols)`| Select columns |
128
+ |`columns([...])`| Select columns (alias) |
129
+ |`distinct()`| SELECT DISTINCT |
130
+ |`orderBy(col, dir?)`| ORDER BY |
131
+ |`ordrer(col, dir?)`| ORDER BY (typo alias) |
132
+ |`limit(n)`| LIMIT |
133
+ |`take(n)`| LIMIT (alias) |
134
+ |`offset(n)`| OFFSET |
135
+ |`skip(n)`| OFFSET (alias) |
136
+ |`groupBy(...cols)`| GROUP BY |
137
+ |`having(col, op, val)`| HAVING |
138
+ |`join(table, col1, op?, col2)`| INNER JOIN |
139
+ |`leftJoin(table, col1, op?, col2)`| LEFT JOIN |
140
+ |`paginate(page, perPage)`| Pagination |
141
+ |`count()`| Count records |
142
+ |`exists()`| Check existence |
143
+
144
+ ### Hidden Attributes
145
+
146
+ | Method | Description |
147
+ |--------|-------------|
148
+ |`withHidden()`| Include hidden attributes |
149
+ |`withoutHidden(show?)`| Control hidden visibility |
150
+
151
+ ### Soft Deletes
152
+
153
+ | Method | Description |
154
+ |--------|-------------|
155
+ |`withTrashed()`| Include soft deleted |
156
+ |`onlyTrashed()`| Only soft deleted |
157
+
158
+ ### Scopes
159
+
160
+ | Method | Description |
161
+ |--------|-------------|
162
+ |`addGlobalScope(name, callback)`| Add global scope |
163
+ |`removeGlobalScope(name)`| Remove global scope |
164
+ |`withoutGlobalScope(name)`| Query without specific scope |
165
+ |`withoutGlobalScopes()`| Query without all scopes |
166
+
167
+ ### Events
168
+
169
+ | Method | Description |
170
+ |--------|-------------|
171
+ |`on(event, callback)`| Register event listener |
172
+ |`creating(callback)`| Before create |
173
+ |`created(callback)`| After create |
174
+ |`updating(callback)`| Before update |
175
+ |`updated(callback)`| After update |
176
+ |`saving(callback)`| Before create/update |
177
+ |`saved(callback)`| After create/update |
178
+ |`deleting(callback)`| Before delete |
179
+ |`deleted(callback)`| After delete |
180
+ |`restoring(callback)`| Before restore |
181
+ |`restored(callback)`| After restore |
182
+
183
+ ---
184
+
185
+ ## Model (Instance Methods)
186
+
187
+ ### Attributes
188
+
189
+ | Method | Description |
190
+ |--------|-------------|
191
+ |`fill(attrs)`| Fill attributes |
192
+ |`setAttribute(key, val)`| Set single attribute |
193
+ |`getAttribute(key)`| Get single attribute |
194
+ |`getDirty()`| Get modified attributes |
195
+ |`isDirty()`| Check if modified |
196
+ |`toJSON()`| Convert to plain object |
197
+
198
+ ### Persistence
199
+
200
+ | Method | Description |
201
+ |--------|-------------|
202
+ |`save()`| Save (insert or update) |
203
+ |`destroy()`| Delete (soft if enabled) |
204
+
205
+ ### Relationships
206
+
207
+ | Method | Description |
208
+ |--------|-------------|
209
+ |`load(...relationships)`| Load relationships on instance |
210
+ |`hasOne(Model, fk, lk)`| Define has-one relation |
211
+ |`hasMany(Model, fk, lk)`| Define has-many relation |
212
+ |`belongsTo(Model, fk, ok)`| Define belongs-to relation |
213
+ |`belongsToMany(Model, pivot, fk, rk)`| Define many-to-many |
214
+ |`hasManyThrough(Model, Through, fk1, fk2)`| Has-many via intermediate |
215
+ |`hasOneThrough(Model, Through, fk1, fk2)`| Has-one via intermediate |
216
+ |`morphOne(Model, name)`| Polymorphic has-one |
217
+ |`morphMany(Model, name)`| Polymorphic has-many |
218
+ |`morphTo(name)`| Polymorphic belongs-to |
219
+
220
+ ### Soft Deletes
221
+
222
+ | Method | Description |
223
+ |--------|-------------|
224
+ |`trashed()`| Check if soft deleted |
225
+ |`restore()`| Restore soft deleted |
226
+ |`forceDelete()`| Permanent delete |
227
+
228
+ ### Validation
229
+
230
+ | Method | Description |
231
+ |--------|-------------|
232
+ |`validate()`| Validate against rules |
233
+ |`validateOrFail()`| Validate or throw error |
234
+
235
+ ---
236
+
237
+ ## QueryBuilder
238
+
239
+ ### Selection
240
+
241
+ | Method | Description |
242
+ |--------|-------------|
243
+ |`select(...cols)`| Select columns |
244
+ |`columns([...])`| Select columns (alias) |
245
+ |`distinct()`| SELECT DISTINCT |
246
+
247
+ ### Conditions
248
+
249
+ | Method | Description |
250
+ |--------|-------------|
251
+ |`where(col, op?, val)`| WHERE clause |
252
+ |`orWhere(col, op?, val)`| OR WHERE |
253
+ |`whereIn(col, vals)`| WHERE IN |
254
+ |`whereNotIn(col, vals)`| WHERE NOT IN |
255
+ |`whereNull(col)`| WHERE IS NULL |
256
+ |`whereNotNull(col)`| WHERE IS NOT NULL |
257
+ |`whereBetween(col, [min, max])`| WHERE BETWEEN |
258
+ |`whereLike(col, pattern)`| WHERE LIKE |
259
+
260
+ ### Relational Filters
261
+
262
+ | Method | Description |
263
+ |--------|-------------|
264
+ |`whereHas(rel, callback?)`| Filter by relation |
265
+ |`has(rel, op?, count)`| Relation count filter |
266
+ |`whereDoesntHave(rel, callback?)`| No relation filter |
267
+ |`withCount(rel)`| Add {rel}_count column |
268
+
269
+ ### Ordering & Limiting
270
+
271
+ | Method | Description |
272
+ |--------|-------------|
273
+ |`orderBy(col, dir?)`| ORDER BY |
274
+ |`ordrer(col, dir?)`| ORDER BY (typo alias) |
275
+ |`limit(n)`/`take(n)`| LIMIT |
276
+ |`offset(n)`/`skip(n)`| OFFSET |
277
+
278
+ ### Grouping
279
+
280
+ | Method | Description |
281
+ |--------|-------------|
282
+ |`groupBy(...cols)`| GROUP BY |
283
+ |`having(col, op, val)`| HAVING |
284
+
285
+ ### Joins
286
+
287
+ | Method | Description |
288
+ |--------|-------------|
289
+ |`join(table, col1, op?, col2)`| INNER JOIN |
290
+ |`leftJoin(table, col1, op?, col2)`| LEFT JOIN |
291
+
292
+ ### Eager Loading
293
+
294
+ | Method | Description |
295
+ |--------|-------------|
296
+ |`with(...relationships)`| Eager load relationships |
297
+ |`with({ rel: callback })`| Eager load with constraints |
298
+
299
+ ### Soft Deletes
300
+
301
+ | Method | Description |
302
+ |--------|-------------|
303
+ |`withTrashed()`| Include soft deleted |
304
+ |`onlyTrashed()`| Only soft deleted |
305
+
306
+ ### Scopes
307
+
308
+ | Method | Description |
309
+ |--------|-------------|
310
+ |`withoutGlobalScope(name)`| Without specific scope |
311
+ |`withoutGlobalScopes()`| Without all scopes |
312
+
313
+ ### Execution
314
+
315
+ | Method | Description |
316
+ |--------|-------------|
317
+ |`get()`| Execute and get all results |
318
+ |`first()`| Get first result |
319
+ |`firstOrFail()`| First or throw error |
320
+ |`find(id)`| Find by ID |
321
+ |`findOrFail(id)`| Find or throw error |
322
+ |`paginate(page, perPage)`| Paginated results |
323
+ |`count()`| Count results |
324
+ |`exists()`| Check existence |
325
+
326
+ ### Mutations
327
+
328
+ | Method | Description |
329
+ |--------|-------------|
330
+ |`insert(data)`| Insert record(s) |
331
+ |`update(attrs)`| Update records |
332
+ |`updateAndFetch(attrs, rels?)`| Update + fetch |
333
+ |`delete()`| Delete records |
334
+ |`increment(col, amount?)`| Atomic increment |
335
+ |`decrement(col, amount?)`| Atomic decrement |
336
+
337
+ ### Utility
338
+
339
+ | Method | Description |
340
+ |--------|-------------|
341
+ |`clone()`| Clone QueryBuilder |
342
+
343
+ ---
344
+
345
+ ## Schema Builder
346
+
347
+ ### Table Operations
348
+
349
+ | Method | Description |
350
+ |--------|-------------|
351
+ |`create(table, callback)`| Create table |
352
+ |`table(table, callback)`| Alter table |
353
+ |`drop(table)`| Drop table |
354
+ |`dropIfExists(table)`| Drop if exists |
355
+ |`rename(from, to)`| Rename table |
356
+ |`hasTable(table)`| Check table exists |
357
+ |`hasColumn(table, column)`| Check column exists |
358
+
359
+ ### Column Types
360
+
361
+ | Method | SQL Type |
362
+ |--------|----------|
363
+ |`id()`| BIGINT UNSIGNED AUTO_INCREMENT PK |
364
+ |`string(col, length?)`| VARCHAR |
365
+ |`text(col)`| TEXT |
366
+ |`integer(col)`| INT |
367
+ |`bigInteger(col)`| BIGINT |
368
+ |`boolean(col)`| TINYINT(1) |
369
+ |`date(col)`| DATE |
370
+ |`datetime(col)`| DATETIME |
371
+ |`timestamp(col)`| TIMESTAMP |
372
+ |`decimal(col, precision, scale)`| DECIMAL |
373
+ |`float(col, precision, scale)`| FLOAT |
374
+ |`json(col)`| JSON |
375
+ |`enum(col, values)`| ENUM |
376
+ |`uuid(col)`| CHAR(36) |
377
+ |`foreignId(col)`| BIGINT UNSIGNED |
378
+ |`timestamps()`| created_at, updated_at |
379
+ |`softDeletes()`| deleted_at |
380
+
381
+ ### Column Modifiers
382
+
383
+ | Method | Description |
384
+ |--------|-------------|
385
+ |`nullable()`| Allow NULL |
386
+ |`default(value)`| Default value |
387
+ |`unique()`| UNIQUE constraint |
388
+ |`unsigned()`| UNSIGNED |
389
+ |`comment(text)`| Column comment |
390
+ |`after(column)`| Position after |
391
+ |`first()`| Position first |
392
+ |`useCurrent()`| DEFAULT CURRENT_TIMESTAMP |
393
+ |`useCurrentOnUpdate()`| ON UPDATE CURRENT_TIMESTAMP |
394
+
395
+ ### Foreign Keys
396
+
397
+ | Method | Description |
398
+ |--------|-------------|
399
+ |`foreign(col)`| Start FK definition |
400
+ |`references(col)`| Reference column |
401
+ |`on(table)`| Reference table |
402
+ |`onDelete(action)`| ON DELETE action |
403
+ |`onUpdate(action)`| ON UPDATE action |
404
+ |`cascadeOnDelete()`| ON DELETE CASCADE |
405
+ |`cascadeOnUpdate()`| ON UPDATE CASCADE |
406
+ |`constrained(table?)`| Simplified FK |
407
+ |`dropForeign([cols])`| Drop FK |
408
+
409
+ ### Indexes
410
+
411
+ | Method | Description |
412
+ |--------|-------------|
413
+ |`index(col)`| Add index |
414
+ |`index([cols])`| Composite index |
415
+ |`unique(col)`| Unique index |
416
+ |`fullText(col)`| Full text index |
417
+ |`dropIndex([cols])`| Drop index |
418
+
419
+ ### Column Manipulation
420
+
421
+ | Method | Description |
422
+ |--------|-------------|
423
+ |`renameColumn(from, to)`| Rename column |
424
+ |`dropColumn(col)`| Drop column |
425
+ |`dropColumn([cols])`| Drop multiple columns |
426
+ |`dropTimestamps()`| Drop created_at, updated_at |
427
+
428
+ ---
429
+
430
+ ## Migration Class
431
+
432
+ ### Properties
433
+
434
+ | Property | Description |
435
+ |----------|-------------|
436
+ |`connection`| Database connection |
437
+
438
+ ### Methods
439
+
440
+ | Method | Description |
441
+ |--------|-------------|
442
+ |`getSchema()`| Get Schema Builder |
443
+ |`execute(sql)`| Execute raw SQL |
444
+
445
+ ### Lifecycle Methods
446
+
447
+ | Method | Description |
448
+ |--------|-------------|
449
+ |`up()`| Run migration |
450
+ |`down()`| Rollback migration |
451
+
452
+ ---
453
+
454
+ ## Model Static Properties
455
+
456
+ | Property | Type | Default | Description |
457
+ |----------|------|---------|-------------|
458
+ |`table`| string | required | Table name |
459
+ |`primaryKey`| string |`'id'`| Primary key column |
460
+ |`timestamps`| boolean |`true`| Auto timestamps |
461
+ |`softDeletes`| boolean |`false`| Enable soft delete |
462
+ |`DELETED_AT`| string |`'deleted_at'`| Soft delete column |
463
+ |`fillable`| array |`[]`| Mass assignable fields |
464
+ |`hidden`| array |`[]`| Hidden from JSON |
465
+ |`casts`| object |`{}`| Type casting |
466
+ |`rules`| object |`{}`| Validation rules |
467
+ |`connection`| object |`null`| Custom connection |
468
+
469
+ ---
470
+
471
+ ## Validation Rules
472
+
473
+ | Rule | Description |
474
+ |------|-------------|
475
+ |`required`| Field required |
476
+ |`string`| Must be string |
477
+ |`number`/`numeric`| Must be number |
478
+ |`email`| Valid email |
479
+ |`boolean`| Must be boolean |
480
+ |`date`| Valid date |
481
+ |`min:N`| Min length/value |
482
+ |`max:N`| Max length/value |
483
+ |`in:a,b,c`| Value in list |
484
+ |`regex:pattern`| Match regex |
485
+
486
+ ---
487
+
488
+ ## Cast Types
489
+
490
+ | Type | Description |
491
+ |------|-------------|
492
+ |`int`/`integer`| Integer |
493
+ |`float`/`double`| Float |
494
+ |`boolean`/`bool`| Boolean |
495
+ |`json`| JSON object |
496
+ |`array`| JSON array |
497
+ |`date`| Date object |
498
+
499
+ ---
500
+
501
+ ## Event Names
502
+
503
+ | Event | Description |
504
+ |-------|-------------|
505
+ |`creating`| Before insert |
506
+ |`created`| After insert |
507
+ |`updating`| Before update |
508
+ |`updated`| After update |
509
+ |`saving`| Before insert/update |
510
+ |`saved`| After insert/update |
511
+ |`deleting`| Before delete |
512
+ |`deleted`| After delete |
513
+ |`restoring`| Before restore |
514
+ |`restored`| After restore |
515
+
516
+ ---
517
+
518
+ ## References
519
+
520
+ - <https://github.com/omgbwa-yasse/outlet-orm>
521
+ - <https://www.npmjs.com/package/outlet-orm>
522
+ - <https://github.com/omgbwa-yasse/outlet-orm/blob/main/docs/INDEX.md>
@@ -0,0 +1,150 @@
1
+ # Outlet ORM – Backup Module
2
+
3
+ [← Back to Index](SKILL.md) | [See also: Advanced](ADVANCED.md)
4
+
5
+ ## When to use
6
+
7
+ Use the Backup module when you need to:
8
+
9
+ - take periodic **full / partial / journal** snapshots of the database;
10
+ - **schedule** recurring backups without cron or external dependencies;
11
+ - **encrypt** backup files at rest (AES-256-GCM, built-in Node.js `crypto`);
12
+ - **restore** data from any backup (auto-detects encrypted `.enc` files);
13
+ - manage backup jobs remotely via a **TCP socket daemon**.
14
+
15
+ ---
16
+
17
+ ## Quick imports
18
+
19
+ ```javascript
20
+ const {
21
+ BackupManager,
22
+ BackupScheduler,
23
+ BackupEncryption,
24
+ BackupSocketServer,
25
+ BackupSocketClient,
26
+ } = require('outlet-orm');
27
+ ```
28
+
29
+ ---
30
+
31
+ ## BackupManager – core API
32
+
33
+ ```javascript
34
+ const manager = new BackupManager(connection, {
35
+ backupPath: './database/backups',
36
+ encrypt: true, // AES-256-GCM
37
+ encryptionPassword: 'pwd', // required when encrypt: true
38
+ saltLength: 6, // grain de sable: 4 | 5 | 6
39
+ });
40
+
41
+ // Full dump (schema + data)
42
+ const file = await manager.full();
43
+ const file = await manager.full({ format: 'json' });
44
+
45
+ // Selected tables only
46
+ const file = await manager.partial(['users', 'orders']);
47
+
48
+ // Transaction log (requires DatabaseConnection.enableQueryLog() first)
49
+ const file = await manager.journal({ flush: true });
50
+
51
+ // Restore – decrypts .enc files automatically
52
+ const { statements } = await manager.restore(filePath);
53
+ const { statements } = await manager.restore(filePath, { encryptionPassword: 'pwd' });
54
+ ```
55
+
56
+ ---
57
+
58
+ ## BackupScheduler – recurring jobs
59
+
60
+ ```javascript
61
+ const scheduler = new BackupScheduler(connection, { backupPath: './database/backups' });
62
+
63
+ scheduler.schedule('full', {
64
+ intervalMs: 86_400_000, // every 24 h
65
+ name: 'daily_full',
66
+ runNow: true, // fire immediately on registration
67
+ onSuccess: (path) => console.log('done:', path),
68
+ onError: (err) => console.error(err.message),
69
+ });
70
+
71
+ scheduler.schedule('partial', {
72
+ intervalMs: 900_000,
73
+ tables: ['orders'],
74
+ name: 'orders_15m',
75
+ });
76
+
77
+ scheduler.activeJobs(); // ['daily_full', 'orders_15m']
78
+ scheduler.stop('orders_15m');
79
+ scheduler.stopAll();
80
+ ```
81
+
82
+ ---
83
+
84
+ ## BackupEncryption – low-level helpers
85
+
86
+ ```javascript
87
+ const { encryptedContent, salt } = BackupEncryption.encrypt(sql, 'password', 6);
88
+ const plain = BackupEncryption.decrypt(encryptedContent, 'password');
89
+ BackupEncryption.isEncrypted(content); // boolean
90
+ BackupEncryption.generateSalt(5); // random 5-char alphanumeric
91
+ ```
92
+
93
+ File format: `OUTLET_ENC_V1 / <salt(4-6)> / <iv_hex> / <authTag_hex> / <ciphertext_base64>`
94
+
95
+ Key derivation: `scryptSync(password, salt, 32, { N: 16384, r: 8, p: 1 })`
96
+
97
+ ---
98
+
99
+ ## BackupSocketServer – TCP daemon
100
+
101
+ ```javascript
102
+ const server = new BackupSocketServer(connection, {
103
+ port: 9119,
104
+ backupPath: './database/backups',
105
+ encrypt: true,
106
+ encryptionPassword: process.env.BACKUP_PASSWORD,
107
+ });
108
+ await server.listen();
109
+ await server.close(); // graceful shutdown + stopAll()
110
+ ```
111
+
112
+ Push events broadcast to all clients: `jobStart`, `jobDone`, `jobError`.
113
+
114
+ ---
115
+
116
+ ## BackupSocketClient – remote control
117
+
118
+ ```javascript
119
+ const client = new BackupSocketClient({ port: 9119 });
120
+ await client.connect();
121
+
122
+ await client.ping(); // 'pong'
123
+ await client.status(); // { uptime, jobs, clients }
124
+ await client.jobs(); // string[]
125
+
126
+ await client.schedule('full', { intervalMs: 3_600_000, name: 'hourly', runNow: true });
127
+ await client.run('full'); // → absolute file path
128
+ await client.run('partial', ['users']);
129
+ await client.restore('/path/to/backup.sql');
130
+ await client.restore('/path/to/backup.sql.enc', { encryptionPassword: 'pwd' });
131
+
132
+ await client.stop('hourly');
133
+ await client.stopAll();
134
+ await client.disconnect();
135
+
136
+ // Push events
137
+ client.on('jobDone', ({ name, filePath }) => console.log(filePath));
138
+ client.on('jobError', ({ name, error }) => console.error(error));
139
+ ```
140
+
141
+ ---
142
+
143
+ ## Rules & best practices
144
+
145
+ - Always call `scheduler.stopAll()` (or `server.close()`) before process exit to avoid timer leaks.
146
+ - Enable `DatabaseConnection.enableQueryLog()` **before** operations you want captured in a `journal` backup.
147
+ - For `journal` backups, pass `flush: true` to avoid replaying old entries on the next run.
148
+ - Do not store `encryptionPassword` in source code — use environment variables or a secrets manager.
149
+ - PostgreSQL: schema DDL (`CREATE TABLE`) is **not** included in the dump; only INSERT rows are written.
150
+ - `saltLength` of 6 (default) provides ~56 billion possible salt values — use it unless you have a specific reason to choose 4 or 5.