relq 1.0.5 → 1.0.7

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 (86) hide show
  1. package/dist/cjs/cli/commands/add.cjs +257 -17
  2. package/dist/cjs/cli/commands/commit.cjs +13 -2
  3. package/dist/cjs/cli/commands/export.cjs +25 -19
  4. package/dist/cjs/cli/commands/import.cjs +219 -100
  5. package/dist/cjs/cli/commands/init.cjs +86 -14
  6. package/dist/cjs/cli/commands/pull.cjs +104 -23
  7. package/dist/cjs/cli/commands/push.cjs +38 -3
  8. package/dist/cjs/cli/index.cjs +9 -1
  9. package/dist/cjs/cli/utils/ast/codegen/builder.cjs +297 -0
  10. package/dist/cjs/cli/utils/ast/codegen/constraints.cjs +185 -0
  11. package/dist/cjs/cli/utils/ast/codegen/defaults.cjs +311 -0
  12. package/dist/cjs/cli/utils/ast/codegen/index.cjs +24 -0
  13. package/dist/cjs/cli/utils/ast/codegen/type-map.cjs +116 -0
  14. package/dist/cjs/cli/utils/ast/codegen/utils.cjs +69 -0
  15. package/dist/cjs/cli/utils/ast/index.cjs +19 -0
  16. package/dist/cjs/cli/utils/ast/transformer/helpers.cjs +154 -0
  17. package/dist/cjs/cli/utils/ast/transformer/index.cjs +25 -0
  18. package/dist/cjs/cli/utils/ast/types.cjs +2 -0
  19. package/dist/cjs/cli/utils/ast-codegen.cjs +949 -0
  20. package/dist/cjs/cli/utils/ast-transformer.cjs +916 -0
  21. package/dist/cjs/cli/utils/change-tracker.cjs +50 -1
  22. package/dist/cjs/cli/utils/cli-utils.cjs +151 -0
  23. package/dist/cjs/cli/utils/fast-introspect.cjs +149 -23
  24. package/dist/cjs/cli/utils/pg-parser.cjs +1 -0
  25. package/dist/cjs/cli/utils/repo-manager.cjs +121 -4
  26. package/dist/cjs/cli/utils/schema-comparator.cjs +98 -14
  27. package/dist/cjs/cli/utils/schema-introspect.cjs +56 -19
  28. package/dist/cjs/cli/utils/snapshot-manager.cjs +0 -1
  29. package/dist/cjs/cli/utils/sql-generator.cjs +353 -64
  30. package/dist/cjs/cli/utils/type-generator.cjs +114 -15
  31. package/dist/cjs/config/config.cjs +29 -10
  32. package/dist/cjs/core/relq-client.cjs +22 -6
  33. package/dist/cjs/schema-definition/column-types.cjs +149 -13
  34. package/dist/cjs/schema-definition/defaults.cjs +72 -0
  35. package/dist/cjs/schema-definition/index.cjs +15 -1
  36. package/dist/cjs/schema-definition/introspection.cjs +7 -3
  37. package/dist/cjs/schema-definition/pg-relations.cjs +169 -0
  38. package/dist/cjs/schema-definition/pg-view.cjs +30 -0
  39. package/dist/cjs/schema-definition/table-definition.cjs +110 -4
  40. package/dist/cjs/types/config-types.cjs +13 -4
  41. package/dist/cjs/utils/aws-dsql.cjs +177 -0
  42. package/dist/config.d.ts +147 -2
  43. package/dist/esm/cli/commands/add.js +255 -18
  44. package/dist/esm/cli/commands/commit.js +13 -2
  45. package/dist/esm/cli/commands/export.js +25 -19
  46. package/dist/esm/cli/commands/import.js +221 -102
  47. package/dist/esm/cli/commands/init.js +86 -14
  48. package/dist/esm/cli/commands/pull.js +106 -25
  49. package/dist/esm/cli/commands/push.js +39 -4
  50. package/dist/esm/cli/index.js +9 -1
  51. package/dist/esm/cli/utils/ast/codegen/builder.js +291 -0
  52. package/dist/esm/cli/utils/ast/codegen/constraints.js +176 -0
  53. package/dist/esm/cli/utils/ast/codegen/defaults.js +305 -0
  54. package/dist/esm/cli/utils/ast/codegen/index.js +6 -0
  55. package/dist/esm/cli/utils/ast/codegen/type-map.js +111 -0
  56. package/dist/esm/cli/utils/ast/codegen/utils.js +60 -0
  57. package/dist/esm/cli/utils/ast/index.js +3 -0
  58. package/dist/esm/cli/utils/ast/transformer/helpers.js +141 -0
  59. package/dist/esm/cli/utils/ast/transformer/index.js +2 -0
  60. package/dist/esm/cli/utils/ast/types.js +1 -0
  61. package/dist/esm/cli/utils/ast-codegen.js +945 -0
  62. package/dist/esm/cli/utils/ast-transformer.js +907 -0
  63. package/dist/esm/cli/utils/change-tracker.js +50 -1
  64. package/dist/esm/cli/utils/cli-utils.js +147 -0
  65. package/dist/esm/cli/utils/fast-introspect.js +149 -23
  66. package/dist/esm/cli/utils/pg-parser.js +1 -0
  67. package/dist/esm/cli/utils/repo-manager.js +114 -4
  68. package/dist/esm/cli/utils/schema-comparator.js +98 -14
  69. package/dist/esm/cli/utils/schema-introspect.js +56 -19
  70. package/dist/esm/cli/utils/snapshot-manager.js +0 -1
  71. package/dist/esm/cli/utils/sql-generator.js +353 -64
  72. package/dist/esm/cli/utils/type-generator.js +114 -15
  73. package/dist/esm/config/config.js +29 -10
  74. package/dist/esm/core/relq-client.js +23 -7
  75. package/dist/esm/schema-definition/column-types.js +146 -12
  76. package/dist/esm/schema-definition/defaults.js +69 -0
  77. package/dist/esm/schema-definition/index.js +3 -0
  78. package/dist/esm/schema-definition/introspection.js +7 -3
  79. package/dist/esm/schema-definition/pg-relations.js +161 -0
  80. package/dist/esm/schema-definition/pg-view.js +24 -0
  81. package/dist/esm/schema-definition/table-definition.js +110 -4
  82. package/dist/esm/types/config-types.js +12 -4
  83. package/dist/esm/utils/aws-dsql.js +139 -0
  84. package/dist/index.d.ts +159 -1
  85. package/dist/schema-builder.d.ts +1314 -32
  86. package/package.json +1 -1
@@ -0,0 +1,177 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.getAwsDsqlToken = getAwsDsqlToken;
37
+ exports.clearAwsDsqlToken = clearAwsDsqlToken;
38
+ exports.isAwsDsql = isAwsDsql;
39
+ const node_fs_1 = require("node:fs");
40
+ const node_path_1 = require("node:path");
41
+ const node_os_1 = require("node:os");
42
+ const node_crypto_1 = require("node:crypto");
43
+ const node_constants_1 = require("node:constants");
44
+ const relq_errors_1 = require("../errors/relq-errors.cjs");
45
+ const tokenCache = new Map();
46
+ function getCacheKey(config) {
47
+ const hash = (0, node_crypto_1.createHash)('md5')
48
+ .update(`${config.secretAccessKey ?? ''}-${config.accessKeyId ?? ''}-${config.region}-${config.hostname}`)
49
+ .digest('hex');
50
+ return hash;
51
+ }
52
+ function getTempFolder() {
53
+ return (0, node_path_1.join)((0, node_os_1.tmpdir)(), '.dsql_');
54
+ }
55
+ function isTempFolderAvailable() {
56
+ const tempFolder = getTempFolder();
57
+ try {
58
+ (0, node_fs_1.mkdirSync)(tempFolder, { recursive: true });
59
+ (0, node_fs_1.accessSync)(tempFolder, node_constants_1.F_OK | node_constants_1.R_OK | node_constants_1.W_OK);
60
+ return true;
61
+ }
62
+ catch {
63
+ return false;
64
+ }
65
+ }
66
+ function getFromCache(cacheKey) {
67
+ const memoryToken = tokenCache.get(cacheKey);
68
+ if (memoryToken && memoryToken.expiresAt > Date.now()) {
69
+ return memoryToken;
70
+ }
71
+ const envName = `DSQL_TOKEN_${cacheKey}`;
72
+ const envToken = process.env[envName];
73
+ if (envToken) {
74
+ try {
75
+ const parsed = JSON.parse(envToken);
76
+ if (parsed.expiresAt > Date.now()) {
77
+ tokenCache.set(cacheKey, parsed);
78
+ return parsed;
79
+ }
80
+ }
81
+ catch { }
82
+ }
83
+ if (isTempFolderAvailable()) {
84
+ const tokenFile = (0, node_path_1.join)(getTempFolder(), `${cacheKey}.json`);
85
+ if ((0, node_fs_1.existsSync)(tokenFile)) {
86
+ try {
87
+ const parsed = JSON.parse((0, node_fs_1.readFileSync)(tokenFile, 'utf8'));
88
+ if (parsed.expiresAt > Date.now()) {
89
+ tokenCache.set(cacheKey, parsed);
90
+ process.env[envName] = JSON.stringify(parsed);
91
+ return parsed;
92
+ }
93
+ }
94
+ catch { }
95
+ }
96
+ }
97
+ return null;
98
+ }
99
+ function saveToCache(cacheKey, token) {
100
+ tokenCache.set(cacheKey, token);
101
+ const envName = `DSQL_TOKEN_${cacheKey}`;
102
+ process.env[envName] = JSON.stringify(token);
103
+ if (isTempFolderAvailable()) {
104
+ const tokenFile = (0, node_path_1.join)(getTempFolder(), `${cacheKey}.json`);
105
+ try {
106
+ (0, node_fs_1.writeFileSync)(tokenFile, JSON.stringify(token));
107
+ }
108
+ catch { }
109
+ }
110
+ }
111
+ let DsqlSigner = null;
112
+ async function loadAwsSdk() {
113
+ if (!DsqlSigner) {
114
+ try {
115
+ const sdk = await Promise.resolve().then(() => __importStar(require('@aws-sdk/dsql-signer')));
116
+ DsqlSigner = sdk.DsqlSigner;
117
+ }
118
+ catch (error) {
119
+ throw new relq_errors_1.RelqConfigError('AWS DSQL requires @aws-sdk/dsql-signer package.\n\n' +
120
+ 'Install it with:\n' +
121
+ ' npm install @aws-sdk/dsql-signer\n' +
122
+ ' # or\n' +
123
+ ' bun add @aws-sdk/dsql-signer', { field: '@aws-sdk/dsql-signer', value: 'not installed' });
124
+ }
125
+ }
126
+ return DsqlSigner;
127
+ }
128
+ async function getAwsDsqlToken(config) {
129
+ const cacheKey = getCacheKey(config);
130
+ const cached = getFromCache(cacheKey);
131
+ if (cached) {
132
+ return cached.token;
133
+ }
134
+ if (!config.useDefaultCredentials && (!config.accessKeyId || !config.secretAccessKey)) {
135
+ throw new relq_errors_1.RelqConfigError('AWS DSQL requires credentials. Either provide accessKeyId + secretAccessKey, ' +
136
+ 'or set useDefaultCredentials: true to use AWS credential chain.', { field: 'aws.credentials', value: 'missing' });
137
+ }
138
+ const SignerClass = await loadAwsSdk();
139
+ const expiresIn = config.tokenExpiresIn ?? 604800;
140
+ const signerConfig = {
141
+ hostname: config.hostname,
142
+ region: config.region,
143
+ expiresIn,
144
+ };
145
+ if (!config.useDefaultCredentials) {
146
+ signerConfig.credentials = {
147
+ accessKeyId: config.accessKeyId,
148
+ secretAccessKey: config.secretAccessKey,
149
+ };
150
+ }
151
+ const signer = new SignerClass(signerConfig);
152
+ const token = await signer.getDbConnectAdminAuthToken();
153
+ const cachedToken = {
154
+ token,
155
+ expiresAt: Date.now() + ((expiresIn - 30) * 1000)
156
+ };
157
+ saveToCache(cacheKey, cachedToken);
158
+ return token;
159
+ }
160
+ function clearAwsDsqlToken(config) {
161
+ const cacheKey = getCacheKey(config);
162
+ tokenCache.delete(cacheKey);
163
+ const envName = `DSQL_TOKEN_${cacheKey}`;
164
+ delete process.env[envName];
165
+ if (isTempFolderAvailable()) {
166
+ const tokenFile = (0, node_path_1.join)(getTempFolder(), `${cacheKey}.json`);
167
+ try {
168
+ if ((0, node_fs_1.existsSync)(tokenFile)) {
169
+ (0, node_fs_1.writeFileSync)(tokenFile, '');
170
+ }
171
+ }
172
+ catch { }
173
+ }
174
+ }
175
+ function isAwsDsql(config) {
176
+ return !!config.aws?.hostname && !!config.aws?.region;
177
+ }
package/dist/config.d.ts CHANGED
@@ -253,6 +253,14 @@ declare class ClientBase extends events.EventEmitter {
253
253
  getTypeParser: typeof getTypeParser;
254
254
  on<E extends "drain" | "error" | "notice" | "notification" | "end">(event: E, listener: E extends "drain" | "end" ? () => void : E extends "error" ? (err: Error) => void : E extends "notice" ? (notice: NoticeMessage) => void : (message: Notification) => void): this;
255
255
  }
256
+ /**
257
+ * Type-safe PostgreSQL DEFAULT value helpers
258
+ * Covers all PostgreSQL default value types with 100% typed output
259
+ */
260
+ export interface DefaultValue {
261
+ readonly $sql: string;
262
+ readonly $isDefault: true;
263
+ }
256
264
  declare const EMPTY_OBJECT: unique symbol;
257
265
  declare const EMPTY_ARRAY: unique symbol;
258
266
  export interface ColumnConfig<T = unknown> {
@@ -260,7 +268,7 @@ export interface ColumnConfig<T = unknown> {
260
268
  $sqlType?: string;
261
269
  $tsType?: T;
262
270
  $nullable?: boolean;
263
- $default?: T | (() => T) | string | object | typeof EMPTY_OBJECT | typeof EMPTY_ARRAY;
271
+ $default?: T | (() => T) | string | object | typeof EMPTY_OBJECT | typeof EMPTY_ARRAY | DefaultValue;
264
272
  $primaryKey?: boolean;
265
273
  $unique?: boolean;
266
274
  $references?: {
@@ -282,6 +290,7 @@ export interface ColumnConfig<T = unknown> {
282
290
  $scale?: number;
283
291
  $withTimezone?: boolean;
284
292
  $columnName?: string;
293
+ $trackingId?: string;
285
294
  }
286
295
  /**
287
296
  * Partition Types and Builders
@@ -332,6 +341,58 @@ export interface IndexDefinition {
332
341
  include?: string[];
333
342
  /** Expression for expression-based indexes */
334
343
  expression?: string;
344
+ /**
345
+ * Generate CREATE INDEX IF NOT EXISTS instead of CREATE INDEX.
346
+ *
347
+ * When true, the generated SQL will be:
348
+ * `CREATE INDEX IF NOT EXISTS index_name ON table_name (...)`
349
+ *
350
+ * This makes index creation idempotent - if the index already exists,
351
+ * PostgreSQL will skip creation instead of throwing an error.
352
+ *
353
+ * Use cases:
354
+ * - Idempotent migrations that can be run multiple times safely
355
+ * - Manual schema management where you want to avoid errors on re-runs
356
+ * - Incremental schema updates in development environments
357
+ * - CI/CD pipelines where schema might already exist
358
+ *
359
+ * @default false
360
+ */
361
+ ifNotExists?: boolean;
362
+ /**
363
+ * Use ON ONLY clause for partitioned tables.
364
+ *
365
+ * When true, the generated SQL will be:
366
+ * `CREATE INDEX index_name ON ONLY table_name (...)`
367
+ *
368
+ * This creates an index on the parent partitioned table only, without
369
+ * automatically creating matching indexes on child partitions. Each
370
+ * partition must have its own index created separately.
371
+ *
372
+ * Use cases:
373
+ * - When you want different index configurations per partition
374
+ * - When partitions have different access patterns
375
+ * - When you want to control index creation timing per partition
376
+ * - For declarative partitioning with custom index strategies
377
+ * - When some partitions don't need certain indexes (e.g., archive partitions)
378
+ *
379
+ * @default false
380
+ * @see https://www.postgresql.org/docs/current/ddl-partitioning.html#DDL-PARTITIONING-DECLARATIVE-MAINTENANCE
381
+ */
382
+ tableOnly?: boolean;
383
+ /** Index comment/description */
384
+ comment?: string;
385
+ /** Tracking ID for rename detection */
386
+ trackingId?: string;
387
+ }
388
+ /** Constraint definition result */
389
+ export interface ConstraintDef {
390
+ readonly $type: "PRIMARY KEY" | "UNIQUE" | "EXCLUDE";
391
+ readonly $name: string;
392
+ readonly $columns: string[];
393
+ readonly $expression?: string;
394
+ /** Tracking ID for rename detection */
395
+ readonly $trackingId?: string;
335
396
  }
336
397
  export type IsSerialType<T extends string> = T extends "SERIAL" | "BIGSERIAL" | "SMALLSERIAL" | "SERIAL4" | "SERIAL2" | "SERIAL8" ? true : false;
337
398
  export type HasDefault<C> = C extends {
@@ -417,6 +478,8 @@ export interface TableDefinition<T extends Record<string, ColumnConfig>> {
417
478
  expression: string;
418
479
  name?: string;
419
480
  }>;
481
+ /** Table-level constraints (composite PKs, etc.) */
482
+ $constraints?: ConstraintDef[];
420
483
  $foreignKeys?: Array<{
421
484
  columns: string[];
422
485
  references: {
@@ -426,17 +489,93 @@ export interface TableDefinition<T extends Record<string, ColumnConfig>> {
426
489
  onDelete?: string;
427
490
  onUpdate?: string;
428
491
  name?: string;
492
+ /** Tracking ID for rename detection */
493
+ trackingId?: string;
429
494
  }>;
430
495
  $indexes?: IndexDefinition[];
431
496
  $inherits?: string[];
432
497
  $partitionBy?: PartitionStrategyDef;
433
498
  $tablespace?: string;
434
499
  $withOptions?: Record<string, unknown>;
500
+ /** Whether to use CREATE TABLE IF NOT EXISTS */
501
+ $ifNotExists?: boolean;
502
+ /** Tracking ID for rename detection */
503
+ $trackingId?: string;
435
504
  $inferSelect: BuildSelectType<T>;
436
505
  $inferInsert: BuildInsertType<T>;
437
506
  toSQL(): string;
438
507
  toCreateIndexSQL(): string[];
439
508
  }
509
+ /**
510
+ * AWS regions with autocomplete support
511
+ * Includes all standard AWS regions that may support DSQL
512
+ */
513
+ export type AwsRegion = "us-east-1" | "us-east-2" | "us-west-1" | "us-west-2" | "eu-west-1" | "eu-west-2" | "eu-west-3" | "eu-central-1" | "eu-central-2" | "eu-north-1" | "eu-south-1" | "eu-south-2" | "ap-east-1" | "ap-south-1" | "ap-south-2" | "ap-northeast-1" | "ap-northeast-2" | "ap-northeast-3" | "ap-southeast-1" | "ap-southeast-2" | "ap-southeast-3" | "ap-southeast-4" | "me-south-1" | "me-central-1" | "af-south-1" | "il-central-1" | "sa-east-1" | "ca-central-1" | "ca-west-1" | "us-gov-east-1" | "us-gov-west-1" | (string & {});
514
+ /**
515
+ * AWS DSQL (Aurora Serverless) configuration
516
+ * When provided, Relq automatically handles IAM token generation and caching
517
+ *
518
+ * @example
519
+ * ```typescript
520
+ * const db = new Relq(schema, {
521
+ * database: 'postgres',
522
+ * aws: {
523
+ * hostname: 'abc123.dsql.us-east-1.on.aws',
524
+ * region: 'us-east-1', // Autocomplete supported!
525
+ * accessKeyId: 'AKIA...',
526
+ * secretAccessKey: '...'
527
+ * }
528
+ * });
529
+ * ```
530
+ */
531
+ export interface AwsDbConfig {
532
+ /**
533
+ * DSQL cluster hostname
534
+ * @example "7btnrhwkzis7lsxg24cqdyzsm4.dsql.us-east-1.on.aws"
535
+ */
536
+ hostname: string;
537
+ /**
538
+ * AWS region with autocomplete support
539
+ * @example "us-east-1"
540
+ */
541
+ region: AwsRegion;
542
+ /**
543
+ * AWS Access Key ID
544
+ * Required unless useDefaultCredentials is true
545
+ */
546
+ accessKeyId?: string;
547
+ /**
548
+ * AWS Secret Access Key
549
+ * Required unless useDefaultCredentials is true
550
+ */
551
+ secretAccessKey?: string;
552
+ /**
553
+ * Database port (inherited from root config if not specified)
554
+ * @default 5432
555
+ */
556
+ port?: number;
557
+ /**
558
+ * Database user (inherited from root config if not specified)
559
+ * @default 'admin'
560
+ */
561
+ user?: string;
562
+ /**
563
+ * Enable SSL/TLS for connection
564
+ * @default true (DSQL typically requires SSL)
565
+ */
566
+ ssl?: boolean;
567
+ /**
568
+ * Use AWS default credential provider chain
569
+ * (env vars, IAM role, ~/.aws/credentials)
570
+ * @default false
571
+ */
572
+ useDefaultCredentials?: boolean;
573
+ /**
574
+ * Token expiration time in seconds
575
+ * @default 604800 (7 days)
576
+ */
577
+ tokenExpiresIn?: number;
578
+ }
440
579
  export interface RelqMigrationConfig {
441
580
  directory: string;
442
581
  tableName?: string;
@@ -466,6 +605,12 @@ export interface RelqCacheConfig {
466
605
  export interface RelqConnectionConfig extends Omit<PoolConfig, "ssl"> {
467
606
  url?: string;
468
607
  ssl?: boolean | "require" | "prefer" | "allow" | "disable" | PoolConfig["ssl"];
608
+ /**
609
+ * AWS DSQL configuration
610
+ * When provided, enables first-class AWS Aurora DSQL support
611
+ * with automatic IAM token generation and caching
612
+ */
613
+ aws?: AwsDbConfig;
469
614
  }
470
615
  export interface RelqGenerateConfig {
471
616
  outDir: string;
@@ -635,7 +780,7 @@ export interface RelqPlugin {
635
780
  };
636
781
  }
637
782
  export declare function defineConfig<TTables extends Record<string, TableDefinition<Record<string, ColumnConfig>>> = Record<string, TableDefinition<Record<string, ColumnConfig>>>>(config: RelqConfig<TTables>): RelqConfig<TTables>;
638
- export declare function loadConfig(path?: string): Promise<RelqConfig>;
783
+ export declare function loadConfig(startPath?: string): Promise<RelqConfig>;
639
784
  export declare function parseConnectionUrl(url: string): RelqConnectionConfig;
640
785
  export declare function mergeConfigs(...configs: Partial<RelqConfig>[]): RelqConfig;
641
786
  export declare function validateConfig(config: RelqConfig): {