@pipeline-builder/pipeline-data 0.0.1

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/LICENSE +202 -0
  2. package/README.md +61 -0
  3. package/drizzle.config.ts +17 -0
  4. package/lib/api/access-control-builder.d.ts +148 -0
  5. package/lib/api/access-control-builder.js +199 -0
  6. package/lib/api/crud-service.d.ts +343 -0
  7. package/lib/api/crud-service.js +849 -0
  8. package/lib/api/query-builders.d.ts +82 -0
  9. package/lib/api/query-builders.js +460 -0
  10. package/lib/api/reporting-service.d.ts +685 -0
  11. package/lib/api/reporting-service.js +1564 -0
  12. package/lib/api/soft-delete-sweep.d.ts +65 -0
  13. package/lib/api/soft-delete-sweep.js +124 -0
  14. package/lib/api/viewer-context.d.ts +29 -0
  15. package/lib/api/viewer-context.js +63 -0
  16. package/lib/core/query-filters.d.ts +263 -0
  17. package/lib/core/query-filters.js +4 -0
  18. package/lib/database/drizzle-schema.d.ts +7357 -0
  19. package/lib/database/drizzle-schema.js +66 -0
  20. package/lib/database/index.d.ts +5 -0
  21. package/lib/database/index.js +8 -0
  22. package/lib/database/migrator.d.ts +20 -0
  23. package/lib/database/migrator.js +80 -0
  24. package/lib/database/postgres-connection.d.ts +201 -0
  25. package/lib/database/postgres-connection.js +413 -0
  26. package/lib/database/retry-strategy.d.ts +68 -0
  27. package/lib/database/retry-strategy.js +122 -0
  28. package/lib/database/schema/alert.d.ts +588 -0
  29. package/lib/database/schema/alert.js +130 -0
  30. package/lib/database/schema/compliance.d.ts +3319 -0
  31. package/lib/database/schema/compliance.js +377 -0
  32. package/lib/database/schema/dashboard.d.ts +474 -0
  33. package/lib/database/schema/dashboard.js +129 -0
  34. package/lib/database/schema/message-attachment.d.ts +183 -0
  35. package/lib/database/schema/message-attachment.js +40 -0
  36. package/lib/database/schema/message.d.ts +411 -0
  37. package/lib/database/schema/message.js +114 -0
  38. package/lib/database/schema/pipeline-template.d.ts +466 -0
  39. package/lib/database/schema/pipeline-template.js +80 -0
  40. package/lib/database/schema/pipeline.d.ts +1613 -0
  41. package/lib/database/schema/pipeline.js +332 -0
  42. package/lib/database/schema/plugin.d.ts +749 -0
  43. package/lib/database/schema/plugin.js +166 -0
  44. package/lib/database/tenancy.d.ts +103 -0
  45. package/lib/database/tenancy.js +167 -0
  46. package/lib/index.d.ts +32 -0
  47. package/lib/index.js +38 -0
  48. package/package.json +161 -0
@@ -0,0 +1,66 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // Barrel for the Drizzle schema. The table/type definitions live in per-domain
5
+ // files under `./schema/*`; this module re-exports every one of them so the
6
+ // public API is byte-identical to the previous single-file schema. Existing
7
+ // `import { ... } from '.../drizzle-schema'` sites and the aggregate `schema`
8
+ // object below both continue to resolve exactly as before.
9
+ //
10
+ export * from './schema/plugin.js';
11
+ export * from './schema/pipeline.js';
12
+ export * from './schema/pipeline-template.js';
13
+ export * from './schema/message.js';
14
+ export * from './schema/message-attachment.js';
15
+ export * from './schema/compliance.js';
16
+ export * from './schema/dashboard.js';
17
+ export * from './schema/alert.js';
18
+ import { orgAlertDestination, orgAlertRule } from './schema/alert.js';
19
+ import { compliancePolicy, complianceRule, complianceRuleHistory, complianceAuditLog, complianceExemption, complianceRuleSubscription, complianceScan, complianceScanSchedule, complianceNotificationPreference, complianceNotificationLog, complianceRole, complianceReport, complianceReportSchedule, } from './schema/compliance.js';
20
+ import { dashboard, dashboardPanel } from './schema/dashboard.js';
21
+ import { messageAttachment } from './schema/message-attachment.js';
22
+ import { message } from './schema/message.js';
23
+ import { pipelineTemplate } from './schema/pipeline-template.js';
24
+ import { pipeline, pipelineRegistry, pipelineEvent, deploymentOutcome, ingestHealth, incident, doraSettings } from './schema/pipeline.js';
25
+ import { plugin } from './schema/plugin.js';
26
+ /**
27
+ * Complete Drizzle schema export
28
+ */
29
+ export const schema = {
30
+ plugin,
31
+ pipeline,
32
+ pipelineTemplate,
33
+ message,
34
+ messageAttachment,
35
+ pipelineRegistry,
36
+ pipelineEvent,
37
+ // DORA post-deploy outcome markers + per-org ingestion health
38
+ deploymentOutcome,
39
+ ingestHealth,
40
+ // Production incidents (webhook-ingested) → automated post-deploy CFR + MTTR
41
+ incident,
42
+ // Per-org DORA overrides (incident correlation window)
43
+ doraSettings,
44
+ // Observability dashboards (user-editable replacement for code-defined dashboards)
45
+ dashboard,
46
+ dashboardPanel,
47
+ // Per-org alert notification destinations (multi-tenant alerting)
48
+ orgAlertDestination,
49
+ // per-org operator-authored alert rules materialized into Prom YAML.
50
+ orgAlertRule,
51
+ // Compliance tables
52
+ compliancePolicy,
53
+ complianceRule,
54
+ complianceRuleHistory,
55
+ complianceAuditLog,
56
+ complianceExemption,
57
+ complianceRuleSubscription,
58
+ complianceScan,
59
+ complianceScanSchedule,
60
+ complianceNotificationPreference,
61
+ complianceNotificationLog,
62
+ complianceRole,
63
+ complianceReport,
64
+ complianceReportSchedule,
65
+ };
66
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJpenpsZS1zY2hlbWEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvZHJpenpsZS1zY2hlbWEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxFQUFFO0FBQ0YsK0VBQStFO0FBQy9FLDRFQUE0RTtBQUM1RSw0RUFBNEU7QUFDNUUsOEVBQThFO0FBQzlFLDJEQUEyRDtBQUMzRCxFQUFFO0FBRUYsY0FBYyxvQkFBb0IsQ0FBQztBQUNuQyxjQUFjLHNCQUFzQixDQUFDO0FBQ3JDLGNBQWMsK0JBQStCLENBQUM7QUFDOUMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGdDQUFnQyxDQUFDO0FBQy9DLGNBQWMsd0JBQXdCLENBQUM7QUFDdkMsY0FBYyx1QkFBdUIsQ0FBQztBQUN0QyxjQUFjLG1CQUFtQixDQUFDO0FBRWxDLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxZQUFZLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUN0RSxPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGNBQWMsRUFDZCxxQkFBcUIsRUFDckIsa0JBQWtCLEVBQ2xCLG1CQUFtQixFQUNuQiwwQkFBMEIsRUFDMUIsY0FBYyxFQUNkLHNCQUFzQixFQUN0QixnQ0FBZ0MsRUFDaEMseUJBQXlCLEVBQ3pCLGNBQWMsRUFDZCxnQkFBZ0IsRUFDaEIsd0JBQXdCLEdBQ3pCLE1BQU0sd0JBQXdCLENBQUM7QUFDaEMsT0FBTyxFQUFFLFNBQVMsRUFBRSxjQUFjLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUNsRSxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNuRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDOUMsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDakUsT0FBTyxFQUFFLFFBQVEsRUFBRSxnQkFBZ0IsRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxZQUFZLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUMxSSxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFFNUM7O0dBRUc7QUFDSCxNQUFNLENBQUMsTUFBTSxNQUFNLEdBQUc7SUFDcEIsTUFBTTtJQUNOLFFBQVE7SUFDUixnQkFBZ0I7SUFDaEIsT0FBTztJQUNQLGlCQUFpQjtJQUNqQixnQkFBZ0I7SUFDaEIsYUFBYTtJQUNiLDhEQUE4RDtJQUM5RCxpQkFBaUI7SUFDakIsWUFBWTtJQUNaLDZFQUE2RTtJQUM3RSxRQUFRO0lBQ1IsdURBQXVEO0lBQ3ZELFlBQVk7SUFDWixtRkFBbUY7SUFDbkYsU0FBUztJQUNULGNBQWM7SUFDZCxrRUFBa0U7SUFDbEUsbUJBQW1CO0lBQ25CLHNFQUFzRTtJQUN0RSxZQUFZO0lBQ1osb0JBQW9CO0lBQ3BCLGdCQUFnQjtJQUNoQixjQUFjO0lBQ2QscUJBQXFCO0lBQ3JCLGtCQUFrQjtJQUNsQixtQkFBbUI7SUFDbkIsMEJBQTBCO0lBQzFCLGNBQWM7SUFDZCxzQkFBc0I7SUFDdEIsZ0NBQWdDO0lBQ2hDLHlCQUF5QjtJQUN6QixjQUFjO0lBQ2QsZ0JBQWdCO0lBQ2hCLHdCQUF3QjtDQUNoQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8vXG4vLyBCYXJyZWwgZm9yIHRoZSBEcml6emxlIHNjaGVtYS4gVGhlIHRhYmxlL3R5cGUgZGVmaW5pdGlvbnMgbGl2ZSBpbiBwZXItZG9tYWluXG4vLyBmaWxlcyB1bmRlciBgLi9zY2hlbWEvKmA7IHRoaXMgbW9kdWxlIHJlLWV4cG9ydHMgZXZlcnkgb25lIG9mIHRoZW0gc28gdGhlXG4vLyBwdWJsaWMgQVBJIGlzIGJ5dGUtaWRlbnRpY2FsIHRvIHRoZSBwcmV2aW91cyBzaW5nbGUtZmlsZSBzY2hlbWEuIEV4aXN0aW5nXG4vLyBgaW1wb3J0IHsgLi4uIH0gZnJvbSAnLi4uL2RyaXp6bGUtc2NoZW1hJ2Agc2l0ZXMgYW5kIHRoZSBhZ2dyZWdhdGUgYHNjaGVtYWBcbi8vIG9iamVjdCBiZWxvdyBib3RoIGNvbnRpbnVlIHRvIHJlc29sdmUgZXhhY3RseSBhcyBiZWZvcmUuXG4vL1xuXG5leHBvcnQgKiBmcm9tICcuL3NjaGVtYS9wbHVnaW4uanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2hlbWEvcGlwZWxpbmUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2hlbWEvcGlwZWxpbmUtdGVtcGxhdGUuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2hlbWEvbWVzc2FnZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NjaGVtYS9tZXNzYWdlLWF0dGFjaG1lbnQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2hlbWEvY29tcGxpYW5jZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NjaGVtYS9kYXNoYm9hcmQuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zY2hlbWEvYWxlcnQuanMnO1xuXG5pbXBvcnQgeyBvcmdBbGVydERlc3RpbmF0aW9uLCBvcmdBbGVydFJ1bGUgfSBmcm9tICcuL3NjaGVtYS9hbGVydC5qcyc7XG5pbXBvcnQge1xuICBjb21wbGlhbmNlUG9saWN5LFxuICBjb21wbGlhbmNlUnVsZSxcbiAgY29tcGxpYW5jZVJ1bGVIaXN0b3J5LFxuICBjb21wbGlhbmNlQXVkaXRMb2csXG4gIGNvbXBsaWFuY2VFeGVtcHRpb24sXG4gIGNvbXBsaWFuY2VSdWxlU3Vic2NyaXB0aW9uLFxuICBjb21wbGlhbmNlU2NhbixcbiAgY29tcGxpYW5jZVNjYW5TY2hlZHVsZSxcbiAgY29tcGxpYW5jZU5vdGlmaWNhdGlvblByZWZlcmVuY2UsXG4gIGNvbXBsaWFuY2VOb3RpZmljYXRpb25Mb2csXG4gIGNvbXBsaWFuY2VSb2xlLFxuICBjb21wbGlhbmNlUmVwb3J0LFxuICBjb21wbGlhbmNlUmVwb3J0U2NoZWR1bGUsXG59IGZyb20gJy4vc2NoZW1hL2NvbXBsaWFuY2UuanMnO1xuaW1wb3J0IHsgZGFzaGJvYXJkLCBkYXNoYm9hcmRQYW5lbCB9IGZyb20gJy4vc2NoZW1hL2Rhc2hib2FyZC5qcyc7XG5pbXBvcnQgeyBtZXNzYWdlQXR0YWNobWVudCB9IGZyb20gJy4vc2NoZW1hL21lc3NhZ2UtYXR0YWNobWVudC5qcyc7XG5pbXBvcnQgeyBtZXNzYWdlIH0gZnJvbSAnLi9zY2hlbWEvbWVzc2FnZS5qcyc7XG5pbXBvcnQgeyBwaXBlbGluZVRlbXBsYXRlIH0gZnJvbSAnLi9zY2hlbWEvcGlwZWxpbmUtdGVtcGxhdGUuanMnO1xuaW1wb3J0IHsgcGlwZWxpbmUsIHBpcGVsaW5lUmVnaXN0cnksIHBpcGVsaW5lRXZlbnQsIGRlcGxveW1lbnRPdXRjb21lLCBpbmdlc3RIZWFsdGgsIGluY2lkZW50LCBkb3JhU2V0dGluZ3MgfSBmcm9tICcuL3NjaGVtYS9waXBlbGluZS5qcyc7XG5pbXBvcnQgeyBwbHVnaW4gfSBmcm9tICcuL3NjaGVtYS9wbHVnaW4uanMnO1xuXG4vKipcbiAqIENvbXBsZXRlIERyaXp6bGUgc2NoZW1hIGV4cG9ydFxuICovXG5leHBvcnQgY29uc3Qgc2NoZW1hID0ge1xuICBwbHVnaW4sXG4gIHBpcGVsaW5lLFxuICBwaXBlbGluZVRlbXBsYXRlLFxuICBtZXNzYWdlLFxuICBtZXNzYWdlQXR0YWNobWVudCxcbiAgcGlwZWxpbmVSZWdpc3RyeSxcbiAgcGlwZWxpbmVFdmVudCxcbiAgLy8gRE9SQSBwb3N0LWRlcGxveSBvdXRjb21lIG1hcmtlcnMgKyBwZXItb3JnIGluZ2VzdGlvbiBoZWFsdGhcbiAgZGVwbG95bWVudE91dGNvbWUsXG4gIGluZ2VzdEhlYWx0aCxcbiAgLy8gUHJvZHVjdGlvbiBpbmNpZGVudHMgKHdlYmhvb2staW5nZXN0ZWQpIOKGkiBhdXRvbWF0ZWQgcG9zdC1kZXBsb3kgQ0ZSICsgTVRUUlxuICBpbmNpZGVudCxcbiAgLy8gUGVyLW9yZyBET1JBIG92ZXJyaWRlcyAoaW5jaWRlbnQgY29ycmVsYXRpb24gd2luZG93KVxuICBkb3JhU2V0dGluZ3MsXG4gIC8vIE9ic2VydmFiaWxpdHkgZGFzaGJvYXJkcyAodXNlci1lZGl0YWJsZSByZXBsYWNlbWVudCBmb3IgY29kZS1kZWZpbmVkIGRhc2hib2FyZHMpXG4gIGRhc2hib2FyZCxcbiAgZGFzaGJvYXJkUGFuZWwsXG4gIC8vIFBlci1vcmcgYWxlcnQgbm90aWZpY2F0aW9uIGRlc3RpbmF0aW9ucyAobXVsdGktdGVuYW50IGFsZXJ0aW5nKVxuICBvcmdBbGVydERlc3RpbmF0aW9uLFxuICAvLyBwZXItb3JnIG9wZXJhdG9yLWF1dGhvcmVkIGFsZXJ0IHJ1bGVzICBtYXRlcmlhbGl6ZWQgaW50byBQcm9tIFlBTUwuXG4gIG9yZ0FsZXJ0UnVsZSxcbiAgLy8gQ29tcGxpYW5jZSB0YWJsZXNcbiAgY29tcGxpYW5jZVBvbGljeSxcbiAgY29tcGxpYW5jZVJ1bGUsXG4gIGNvbXBsaWFuY2VSdWxlSGlzdG9yeSxcbiAgY29tcGxpYW5jZUF1ZGl0TG9nLFxuICBjb21wbGlhbmNlRXhlbXB0aW9uLFxuICBjb21wbGlhbmNlUnVsZVN1YnNjcmlwdGlvbixcbiAgY29tcGxpYW5jZVNjYW4sXG4gIGNvbXBsaWFuY2VTY2FuU2NoZWR1bGUsXG4gIGNvbXBsaWFuY2VOb3RpZmljYXRpb25QcmVmZXJlbmNlLFxuICBjb21wbGlhbmNlTm90aWZpY2F0aW9uTG9nLFxuICBjb21wbGlhbmNlUm9sZSxcbiAgY29tcGxpYW5jZVJlcG9ydCxcbiAgY29tcGxpYW5jZVJlcG9ydFNjaGVkdWxlLFxufSBhcyBjb25zdDtcbiJdfQ==
@@ -0,0 +1,5 @@
1
+ export * from './drizzle-schema.js';
2
+ export * from './postgres-connection.js';
3
+ export * from './retry-strategy.js';
4
+ export * from './tenancy.js';
5
+ export { runMigrations, type MigrateOptions } from './migrator.js';
@@ -0,0 +1,8 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ export * from './drizzle-schema.js';
4
+ export * from './postgres-connection.js';
5
+ export * from './retry-strategy.js';
6
+ export * from './tenancy.js';
7
+ export { runMigrations } from './migrator.js';
8
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsMEJBQTBCLENBQUM7QUFDekMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGNBQWMsQ0FBQztBQUM3QixPQUFPLEVBQUUsYUFBYSxFQUF1QixNQUFNLGVBQWUsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5leHBvcnQgKiBmcm9tICcuL2RyaXp6bGUtc2NoZW1hLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vcG9zdGdyZXMtY29ubmVjdGlvbi5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3JldHJ5LXN0cmF0ZWd5LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vdGVuYW5jeS5qcyc7XG5leHBvcnQgeyBydW5NaWdyYXRpb25zLCB0eXBlIE1pZ3JhdGVPcHRpb25zIH0gZnJvbSAnLi9taWdyYXRvci5qcyc7XG4iXX0=
@@ -0,0 +1,20 @@
1
+ export interface MigrateOptions {
2
+ /** Absolute path to the migrations folder. Defaults to `<package>/drizzle`. */
3
+ migrationsFolder?: string;
4
+ /** Schema-qualified migrations table name. Defaults to `__drizzle_migrations`. */
5
+ migrationsTable?: string;
6
+ /** Skip the runner entirely (for tests or when a deploy uses an external migration tool). */
7
+ skip?: boolean;
8
+ }
9
+ /**
10
+ * Run any pending Drizzle migrations against the configured Postgres.
11
+ *
12
+ * No-ops gracefully when:
13
+ * - `options.skip` is true
14
+ * - `RUN_DB_MIGRATIONS` env var is set to a falsy value (`0`/`false`)
15
+ * - the migrations folder doesn't exist (fresh repo, nothing generated yet)
16
+ *
17
+ * Throws on any actual migration failure so the service refuses to start
18
+ * with a half-applied schema.
19
+ */
20
+ export declare function runMigrations(options?: MigrateOptions): Promise<void>;
@@ -0,0 +1,80 @@
1
+ // Copyright 2026 Pipeline Builder Contributors
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ /**
4
+ * Drizzle migration runner.
5
+ *
6
+ * Idempotent: safe to call on every service start. drizzle tracks applied
7
+ * migrations in the `__drizzle_migrations` table and skips ones already run.
8
+ *
9
+ * The migration files live at `packages/pipeline-data/drizzle/` and are
10
+ * generated from the `drizzle-schema.ts` source via `pnpm db:generate`
11
+ * (which invokes `drizzle-kit generate`).
12
+ *
13
+ * For brand-new deploys, `postgres-init.sql` still creates the baseline
14
+ * tables — the migration runner will skip its initial baseline migration
15
+ * because the tables already exist (drizzle uses CREATE TABLE IF NOT EXISTS
16
+ * by default for the snapshot-based generator). Future schema changes ship
17
+ * as additive migrations.
18
+ */
19
+ import * as fs from 'fs';
20
+ import * as path from 'path';
21
+ import { fileURLToPath } from 'url';
22
+ import { createLogger } from '@pipeline-builder/api-core';
23
+ import { migrate } from 'drizzle-orm/node-postgres/migrator';
24
+ import { getConnection } from './postgres-connection.js';
25
+ const logger = createLogger('migrator');
26
+ // ESM has no __dirname; derive it from this module's URL. Without this the
27
+ // migration runner threw `ReferenceError: __dirname is not defined` at startup
28
+ // (onBeforeStart → runMigrations), crash-looping every service that migrates.
29
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
30
+ /** Resolve the default migrations folder relative to this package. */
31
+ function defaultMigrationsFolder() {
32
+ // src/database/migrator.ts → up two levels → package root, then ./drizzle
33
+ return path.resolve(__dirname, '..', '..', 'drizzle');
34
+ }
35
+ /**
36
+ * Run any pending Drizzle migrations against the configured Postgres.
37
+ *
38
+ * No-ops gracefully when:
39
+ * - `options.skip` is true
40
+ * - `RUN_DB_MIGRATIONS` env var is set to a falsy value (`0`/`false`)
41
+ * - the migrations folder doesn't exist (fresh repo, nothing generated yet)
42
+ *
43
+ * Throws on any actual migration failure so the service refuses to start
44
+ * with a half-applied schema.
45
+ */
46
+ export async function runMigrations(options = {}) {
47
+ if (options.skip) {
48
+ logger.info('Migration runner skipped via options.skip');
49
+ return;
50
+ }
51
+ const envFlag = process.env.RUN_DB_MIGRATIONS;
52
+ if (envFlag !== undefined && (envFlag === '0' || envFlag.toLowerCase() === 'false')) {
53
+ logger.info('Migration runner skipped via RUN_DB_MIGRATIONS env');
54
+ return;
55
+ }
56
+ const migrationsFolder = options.migrationsFolder ?? defaultMigrationsFolder();
57
+ if (!fs.existsSync(migrationsFolder)) {
58
+ logger.info('No migrations folder found, nothing to run', { migrationsFolder });
59
+ return;
60
+ }
61
+ const journalPath = path.join(migrationsFolder, 'meta', '_journal.json');
62
+ if (!fs.existsSync(journalPath)) {
63
+ logger.info('No drizzle journal found, nothing to run', { journalPath });
64
+ return;
65
+ }
66
+ const conn = getConnection();
67
+ const migrationsTable = options.migrationsTable ?? '__drizzle_migrations';
68
+ logger.info('Running pending Drizzle migrations', { migrationsFolder, migrationsTable });
69
+ try {
70
+ await migrate(conn.db, { migrationsFolder, migrationsTable });
71
+ logger.info('Drizzle migrations complete');
72
+ }
73
+ catch (err) {
74
+ logger.error('Drizzle migration failed — refusing to start', {
75
+ error: err instanceof Error ? err.message : String(err),
76
+ });
77
+ throw err;
78
+ }
79
+ }
80
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlncmF0b3IuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGF0YWJhc2UvbWlncmF0b3IudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7O0dBZUc7QUFFSCxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEtBQUssSUFBSSxNQUFNLE1BQU0sQ0FBQztBQUM3QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sS0FBSyxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sb0NBQW9DLENBQUM7QUFDN0QsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRXpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxVQUFVLENBQUMsQ0FBQztBQUV4QywyRUFBMkU7QUFDM0UsK0VBQStFO0FBQy9FLDhFQUE4RTtBQUM5RSxNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGFBQWEsQ0FBQyxPQUFPLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO0FBVy9ELHNFQUFzRTtBQUN0RSxTQUFTLHVCQUF1QjtJQUM5QiwwRUFBMEU7SUFDMUUsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0FBQ3hELENBQUM7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxhQUFhLENBQUMsT0FBTyxHQUFtQixFQUFFO0lBQzlELElBQUksT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ2pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsMkNBQTJDLENBQUMsQ0FBQztRQUN6RCxPQUFPO0lBQ1QsQ0FBQztJQUVELE1BQU0sT0FBTyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUM7SUFDOUMsSUFBSSxPQUFPLEtBQUssU0FBUyxJQUFJLENBQUMsT0FBTyxLQUFLLEdBQUcsSUFBSSxPQUFPLENBQUMsV0FBVyxFQUFFLEtBQUssT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUNwRixNQUFNLENBQUMsSUFBSSxDQUFDLG9EQUFvRCxDQUFDLENBQUM7UUFDbEUsT0FBTztJQUNULENBQUM7SUFFRCxNQUFNLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSx1QkFBdUIsRUFBRSxDQUFDO0lBQy9FLElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsQ0FBQztRQUNyQyxNQUFNLENBQUMsSUFBSSxDQUFDLDRDQUE0QyxFQUFFLEVBQUUsZ0JBQWdCLEVBQUUsQ0FBQyxDQUFDO1FBQ2hGLE9BQU87SUFDVCxDQUFDO0lBRUQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxNQUFNLEVBQUUsZUFBZSxDQUFDLENBQUM7SUFDekUsSUFBSSxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztRQUNoQyxNQUFNLENBQUMsSUFBSSxDQUFDLDBDQUEwQyxFQUFFLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQztRQUN6RSxPQUFPO0lBQ1QsQ0FBQztJQUVELE1BQU0sSUFBSSxHQUFHLGFBQWEsRUFBRSxDQUFDO0lBQzdCLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxlQUFlLElBQUksc0JBQXNCLENBQUM7SUFFMUUsTUFBTSxDQUFDLElBQUksQ0FBQyxvQ0FBb0MsRUFBRSxFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7SUFDekYsSUFBSSxDQUFDO1FBQ0gsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLGdCQUFnQixFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDOUQsTUFBTSxDQUFDLElBQUksQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO0lBQzdDLENBQUM7SUFBQyxPQUFPLEdBQUcsRUFBRSxDQUFDO1FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQyw4Q0FBOEMsRUFBRTtZQUMzRCxLQUFLLEVBQUUsR0FBRyxZQUFZLEtBQUssQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztTQUN4RCxDQUFDLENBQUM7UUFDSCxNQUFNLEdBQUcsQ0FBQztJQUNaLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogRHJpenpsZSBtaWdyYXRpb24gcnVubmVyLlxuICpcbiAqIElkZW1wb3RlbnQ6IHNhZmUgdG8gY2FsbCBvbiBldmVyeSBzZXJ2aWNlIHN0YXJ0LiBkcml6emxlIHRyYWNrcyBhcHBsaWVkXG4gKiBtaWdyYXRpb25zIGluIHRoZSBgX19kcml6emxlX21pZ3JhdGlvbnNgIHRhYmxlIGFuZCBza2lwcyBvbmVzIGFscmVhZHkgcnVuLlxuICpcbiAqIFRoZSBtaWdyYXRpb24gZmlsZXMgbGl2ZSBhdCBgcGFja2FnZXMvcGlwZWxpbmUtZGF0YS9kcml6emxlL2AgYW5kIGFyZVxuICogZ2VuZXJhdGVkIGZyb20gdGhlIGBkcml6emxlLXNjaGVtYS50c2Agc291cmNlIHZpYSBgcG5wbSBkYjpnZW5lcmF0ZWBcbiAqICh3aGljaCBpbnZva2VzIGBkcml6emxlLWtpdCBnZW5lcmF0ZWApLlxuICpcbiAqIEZvciBicmFuZC1uZXcgZGVwbG95cywgYHBvc3RncmVzLWluaXQuc3FsYCBzdGlsbCBjcmVhdGVzIHRoZSBiYXNlbGluZVxuICogdGFibGVzIOKAlCB0aGUgbWlncmF0aW9uIHJ1bm5lciB3aWxsIHNraXAgaXRzIGluaXRpYWwgYmFzZWxpbmUgbWlncmF0aW9uXG4gKiBiZWNhdXNlIHRoZSB0YWJsZXMgYWxyZWFkeSBleGlzdCAoZHJpenpsZSB1c2VzIENSRUFURSBUQUJMRSBJRiBOT1QgRVhJU1RTXG4gKiBieSBkZWZhdWx0IGZvciB0aGUgc25hcHNob3QtYmFzZWQgZ2VuZXJhdG9yKS4gRnV0dXJlIHNjaGVtYSBjaGFuZ2VzIHNoaXBcbiAqIGFzIGFkZGl0aXZlIG1pZ3JhdGlvbnMuXG4gKi9cblxuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IGZpbGVVUkxUb1BhdGggfSBmcm9tICd1cmwnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnQHBpcGVsaW5lLWJ1aWxkZXIvYXBpLWNvcmUnO1xuaW1wb3J0IHsgbWlncmF0ZSB9IGZyb20gJ2RyaXp6bGUtb3JtL25vZGUtcG9zdGdyZXMvbWlncmF0b3InO1xuaW1wb3J0IHsgZ2V0Q29ubmVjdGlvbiB9IGZyb20gJy4vcG9zdGdyZXMtY29ubmVjdGlvbi5qcyc7XG5cbmNvbnN0IGxvZ2dlciA9IGNyZWF0ZUxvZ2dlcignbWlncmF0b3InKTtcblxuLy8gRVNNIGhhcyBubyBfX2Rpcm5hbWU7IGRlcml2ZSBpdCBmcm9tIHRoaXMgbW9kdWxlJ3MgVVJMLiBXaXRob3V0IHRoaXMgdGhlXG4vLyBtaWdyYXRpb24gcnVubmVyIHRocmV3IGBSZWZlcmVuY2VFcnJvcjogX19kaXJuYW1lIGlzIG5vdCBkZWZpbmVkYCBhdCBzdGFydHVwXG4vLyAob25CZWZvcmVTdGFydCDihpIgcnVuTWlncmF0aW9ucyksIGNyYXNoLWxvb3BpbmcgZXZlcnkgc2VydmljZSB0aGF0IG1pZ3JhdGVzLlxuY29uc3QgX19kaXJuYW1lID0gcGF0aC5kaXJuYW1lKGZpbGVVUkxUb1BhdGgoaW1wb3J0Lm1ldGEudXJsKSk7XG5cbmV4cG9ydCBpbnRlcmZhY2UgTWlncmF0ZU9wdGlvbnMge1xuICAvKiogQWJzb2x1dGUgcGF0aCB0byB0aGUgbWlncmF0aW9ucyBmb2xkZXIuIERlZmF1bHRzIHRvIGA8cGFja2FnZT4vZHJpenpsZWAuICovXG4gIG1pZ3JhdGlvbnNGb2xkZXI/OiBzdHJpbmc7XG4gIC8qKiBTY2hlbWEtcXVhbGlmaWVkIG1pZ3JhdGlvbnMgdGFibGUgbmFtZS4gRGVmYXVsdHMgdG8gYF9fZHJpenpsZV9taWdyYXRpb25zYC4gKi9cbiAgbWlncmF0aW9uc1RhYmxlPzogc3RyaW5nO1xuICAvKiogU2tpcCB0aGUgcnVubmVyIGVudGlyZWx5IChmb3IgdGVzdHMgb3Igd2hlbiBhIGRlcGxveSB1c2VzIGFuIGV4dGVybmFsIG1pZ3JhdGlvbiB0b29sKS4gKi9cbiAgc2tpcD86IGJvb2xlYW47XG59XG5cbi8qKiBSZXNvbHZlIHRoZSBkZWZhdWx0IG1pZ3JhdGlvbnMgZm9sZGVyIHJlbGF0aXZlIHRvIHRoaXMgcGFja2FnZS4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRNaWdyYXRpb25zRm9sZGVyKCk6IHN0cmluZyB7XG4gIC8vIHNyYy9kYXRhYmFzZS9taWdyYXRvci50cyDihpIgdXAgdHdvIGxldmVscyDihpIgcGFja2FnZSByb290LCB0aGVuIC4vZHJpenpsZVxuICByZXR1cm4gcGF0aC5yZXNvbHZlKF9fZGlybmFtZSwgJy4uJywgJy4uJywgJ2RyaXp6bGUnKTtcbn1cblxuLyoqXG4gKiBSdW4gYW55IHBlbmRpbmcgRHJpenpsZSBtaWdyYXRpb25zIGFnYWluc3QgdGhlIGNvbmZpZ3VyZWQgUG9zdGdyZXMuXG4gKlxuICogTm8tb3BzIGdyYWNlZnVsbHkgd2hlbjpcbiAqICAgLSBgb3B0aW9ucy5za2lwYCBpcyB0cnVlXG4gKiAgIC0gYFJVTl9EQl9NSUdSQVRJT05TYCBlbnYgdmFyIGlzIHNldCB0byBhIGZhbHN5IHZhbHVlIChgMGAvYGZhbHNlYClcbiAqICAgLSB0aGUgbWlncmF0aW9ucyBmb2xkZXIgZG9lc24ndCBleGlzdCAoZnJlc2ggcmVwbywgbm90aGluZyBnZW5lcmF0ZWQgeWV0KVxuICpcbiAqIFRocm93cyBvbiBhbnkgYWN0dWFsIG1pZ3JhdGlvbiBmYWlsdXJlIHNvIHRoZSBzZXJ2aWNlIHJlZnVzZXMgdG8gc3RhcnRcbiAqIHdpdGggYSBoYWxmLWFwcGxpZWQgc2NoZW1hLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcnVuTWlncmF0aW9ucyhvcHRpb25zOiBNaWdyYXRlT3B0aW9ucyA9IHt9KTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmIChvcHRpb25zLnNraXApIHtcbiAgICBsb2dnZXIuaW5mbygnTWlncmF0aW9uIHJ1bm5lciBza2lwcGVkIHZpYSBvcHRpb25zLnNraXAnKTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBlbnZGbGFnID0gcHJvY2Vzcy5lbnYuUlVOX0RCX01JR1JBVElPTlM7XG4gIGlmIChlbnZGbGFnICE9PSB1bmRlZmluZWQgJiYgKGVudkZsYWcgPT09ICcwJyB8fCBlbnZGbGFnLnRvTG93ZXJDYXNlKCkgPT09ICdmYWxzZScpKSB7XG4gICAgbG9nZ2VyLmluZm8oJ01pZ3JhdGlvbiBydW5uZXIgc2tpcHBlZCB2aWEgUlVOX0RCX01JR1JBVElPTlMgZW52Jyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgY29uc3QgbWlncmF0aW9uc0ZvbGRlciA9IG9wdGlvbnMubWlncmF0aW9uc0ZvbGRlciA/PyBkZWZhdWx0TWlncmF0aW9uc0ZvbGRlcigpO1xuICBpZiAoIWZzLmV4aXN0c1N5bmMobWlncmF0aW9uc0ZvbGRlcikpIHtcbiAgICBsb2dnZXIuaW5mbygnTm8gbWlncmF0aW9ucyBmb2xkZXIgZm91bmQsIG5vdGhpbmcgdG8gcnVuJywgeyBtaWdyYXRpb25zRm9sZGVyIH0pO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGpvdXJuYWxQYXRoID0gcGF0aC5qb2luKG1pZ3JhdGlvbnNGb2xkZXIsICdtZXRhJywgJ19qb3VybmFsLmpzb24nKTtcbiAgaWYgKCFmcy5leGlzdHNTeW5jKGpvdXJuYWxQYXRoKSkge1xuICAgIGxvZ2dlci5pbmZvKCdObyBkcml6emxlIGpvdXJuYWwgZm91bmQsIG5vdGhpbmcgdG8gcnVuJywgeyBqb3VybmFsUGF0aCB9KTtcbiAgICByZXR1cm47XG4gIH1cblxuICBjb25zdCBjb25uID0gZ2V0Q29ubmVjdGlvbigpO1xuICBjb25zdCBtaWdyYXRpb25zVGFibGUgPSBvcHRpb25zLm1pZ3JhdGlvbnNUYWJsZSA/PyAnX19kcml6emxlX21pZ3JhdGlvbnMnO1xuXG4gIGxvZ2dlci5pbmZvKCdSdW5uaW5nIHBlbmRpbmcgRHJpenpsZSBtaWdyYXRpb25zJywgeyBtaWdyYXRpb25zRm9sZGVyLCBtaWdyYXRpb25zVGFibGUgfSk7XG4gIHRyeSB7XG4gICAgYXdhaXQgbWlncmF0ZShjb25uLmRiLCB7IG1pZ3JhdGlvbnNGb2xkZXIsIG1pZ3JhdGlvbnNUYWJsZSB9KTtcbiAgICBsb2dnZXIuaW5mbygnRHJpenpsZSBtaWdyYXRpb25zIGNvbXBsZXRlJyk7XG4gIH0gY2F0Y2ggKGVycikge1xuICAgIGxvZ2dlci5lcnJvcignRHJpenpsZSBtaWdyYXRpb24gZmFpbGVkIOKAlCByZWZ1c2luZyB0byBzdGFydCcsIHtcbiAgICAgIGVycm9yOiBlcnIgaW5zdGFuY2VvZiBFcnJvciA/IGVyci5tZXNzYWdlIDogU3RyaW5nKGVyciksXG4gICAgfSk7XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG4iXX0=
@@ -0,0 +1,201 @@
1
+ import { drizzle } from 'drizzle-orm/node-postgres';
2
+ import { Pool } from 'pg';
3
+ /**
4
+ * Resolve the pg TLS/SSL config from an explicit option or the environment,
5
+ * following the same env-tunable pattern as the pool sizing above.
6
+ *
7
+ * Precedence:
8
+ * 1. An explicit `options.ssl` (constructor arg) always wins — including an
9
+ * explicit `false` to force plaintext.
10
+ * 2. `DB_SSL` (`true`/`1` on, `false`/`0` off) or Postgres' standard
11
+ * `PGSSLMODE` (`disable` = off, any other mode = on).
12
+ * 3. Default: ON in production (RDS connections must be encrypted in transit),
13
+ * OFF everywhere else so a local Postgres without TLS keeps working.
14
+ *
15
+ * When enabled, `rejectUnauthorized` follows `DB_SSL_REJECT_UNAUTHORIZED`
16
+ * (default `false`): AWS RDS presents a cert signed by the RDS CA, which is not
17
+ * in Node's default trust store unless the CA bundle is mounted, so certificate
18
+ * VERIFICATION is opt-in to avoid breaking a stock RDS deploy — the channel is
19
+ * still ENCRYPTED. Set `DB_SSL_REJECT_UNAUTHORIZED=true` once the RDS CA bundle
20
+ * is wired to get full verification.
21
+ */
22
+ export declare function getSslConfig(explicit?: ConnectionOptions['ssl']): boolean | {
23
+ rejectUnauthorized: boolean;
24
+ };
25
+ /**
26
+ * Database connection statistics for monitoring
27
+ */
28
+ export interface ConnectionStats {
29
+ totalCount: number;
30
+ idleCount: number;
31
+ waitingCount: number;
32
+ }
33
+ /**
34
+ * Options for configuring the database connection
35
+ */
36
+ export interface ConnectionOptions {
37
+ /** Whether to enable connection logging */
38
+ enableLogging?: boolean;
39
+ /** Whether to automatically retry failed connections */
40
+ enableAutoRetry?: boolean;
41
+ /** Maximum number of connection retry attempts */
42
+ maxRetries?: number;
43
+ /** Delay between retry attempts in milliseconds */
44
+ retryDelay?: number;
45
+ /** SSL configuration */
46
+ ssl?: boolean | {
47
+ rejectUnauthorized: boolean;
48
+ };
49
+ }
50
+ /**
51
+ * Singleton database connection class.
52
+ * Manages PostgreSQL connection pooling and Drizzle ORM instance.
53
+ *
54
+ * Features:
55
+ * - Singleton pattern for single connection pool
56
+ * - Automatic connection retry with backoff
57
+ * - Connection health monitoring
58
+ * - Graceful shutdown handling
59
+ * - Comprehensive error handling
60
+ * - Connection statistics tracking
61
+ *
62
+ * @example
63
+ * ```typescript
64
+ * import { Connection } from './connection';
65
+ *
66
+ * const connection = Connection.getInstance();
67
+ * const plugins = await connection.db.select().from(schema.plugin);
68
+ *
69
+ * // During shutdown
70
+ * await connection.close();
71
+ * ```
72
+ */
73
+ export declare class Connection {
74
+ private static instance;
75
+ /**
76
+ * Drizzle ORM database instance with schema
77
+ */
78
+ readonly db: ReturnType<typeof drizzle>;
79
+ private readonly pool;
80
+ private readonly options;
81
+ private readonly retryStrategy;
82
+ private isShuttingDown;
83
+ /**
84
+ * Private constructor to enforce singleton pattern.
85
+ * Initializes PostgreSQL connection pool and Drizzle ORM instance.
86
+ *
87
+ * @param options - Optional configuration for the connection
88
+ * @throws {Error} If database initialization fails after all retries
89
+ */
90
+ private constructor();
91
+ /**
92
+ * Gets the singleton instance of the Connection class.
93
+ * Creates a new instance if one doesn't exist.
94
+ *
95
+ * @param options - Optional configuration (only used on first call)
96
+ * @returns The singleton Connection instance
97
+ */
98
+ static getInstance(options?: ConnectionOptions): Connection;
99
+ /**
100
+ * Resets the singleton instance.
101
+ * Useful for testing or reconfiguring the connection.
102
+ *
103
+ * @param closeExisting - Whether to close existing connection before reset
104
+ */
105
+ static reset(closeExisting?: boolean): Promise<void>;
106
+ /**
107
+ * Tests the database connection
108
+ *
109
+ * @returns Promise that resolves to true if connection is healthy
110
+ */
111
+ testConnection(): Promise<boolean>;
112
+ /**
113
+ * Gets connection pool statistics
114
+ *
115
+ * @returns Current connection pool statistics
116
+ */
117
+ getStats(): ConnectionStats;
118
+ /**
119
+ * Closes the database connection pool gracefully.
120
+ * Should be called during application shutdown.
121
+ *
122
+ * @param timeout - Maximum time to wait for connections to close (ms)
123
+ * @returns Promise that resolves when pool is closed
124
+ */
125
+ close(timeout?: number): Promise<void>;
126
+ /**
127
+ * Checks if the connection is shutting down
128
+ *
129
+ * @returns true if connection is in shutdown state
130
+ */
131
+ isClosing(): boolean;
132
+ /**
133
+ * Sets up event handlers for the connection pool
134
+ */
135
+ private setupEventHandlers;
136
+ /**
137
+ * Logs connection configuration (sanitized)
138
+ */
139
+ private logConnectionConfig;
140
+ }
141
+ /**
142
+ * Proxy-based lazy database instance
143
+ * The actual connection is only created when first accessed
144
+ *
145
+ * @example
146
+ * ```typescript
147
+ * import { db } from './connection';
148
+ *
149
+ * // Connection is created here on first use, not on import
150
+ * const plugins = await db.select().from(schema.plugin);
151
+ * ```
152
+ */
153
+ export declare const db: import("drizzle-orm/node-postgres").NodePgDatabase<Record<string, unknown>> & {
154
+ $client: Pool;
155
+ };
156
+ /**
157
+ * Gets the Connection instance for advanced operations
158
+ *
159
+ * @example
160
+ * ```typescript
161
+ * import { getConnection } from './connection';
162
+ *
163
+ * const connection = getConnection();
164
+ * const stats = connection.getStats();
165
+ * console.log(`Active connections: ${stats.totalCount}`);
166
+ * ```
167
+ */
168
+ export declare function getConnection(): Connection;
169
+ /**
170
+ * Closes the database connection
171
+ * Should be called during application shutdown
172
+ *
173
+ * @example
174
+ * ```typescript
175
+ * import { closeConnection } from './connection';
176
+ *
177
+ * process.on('SIGTERM', async () => {
178
+ * await closeConnection();
179
+ * process.exit(0);
180
+ * });
181
+ * ```
182
+ */
183
+ export declare function closeConnection(): Promise<void>;
184
+ /**
185
+ * Tests the database connection
186
+ *
187
+ * @returns Promise that resolves to true if connection is healthy
188
+ *
189
+ * @example
190
+ * ```typescript
191
+ * import { testConnection } from './connection';
192
+ *
193
+ * if (await testConnection()) {
194
+ * console.log('Database is ready');
195
+ * } else {
196
+ * console.error('Database connection failed');
197
+ * process.exit(1);
198
+ * }
199
+ * ```
200
+ */
201
+ export declare function testConnection(): Promise<boolean>;