@noormdev/sdk 1.0.0-alpha.1 → 1.0.0-alpha.10

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.
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  // Generated by dts-bundle-generator v9.5.1
2
2
 
3
- import { Kysely } from 'kysely';
3
+ import { Generated, Kysely, Transaction } from 'kysely';
4
4
 
5
5
  /**
6
6
  * Supported database dialects.
@@ -45,6 +45,14 @@ export interface ConnectionConfig {
45
45
  key?: string;
46
46
  };
47
47
  }
48
+ /**
49
+ * Result of creating a connection.
50
+ */
51
+ export interface ConnectionResult {
52
+ db: Kysely<unknown>;
53
+ dialect: Dialect;
54
+ destroy: () => Promise<void>;
55
+ }
48
56
  /**
49
57
  * Full configuration object.
50
58
  *
@@ -377,6 +385,211 @@ export interface SettingsEvents {
377
385
  stageName?: string;
378
386
  };
379
387
  }
388
+ /**
389
+ * Version tracking table.
390
+ *
391
+ * Tracks noorm CLI version and all internal schema versions for migrations.
392
+ * See: plan/datamodel.md#__noorm_version__
393
+ */
394
+ export interface NoormVersionTable {
395
+ /** Primary key */
396
+ id: Generated<number>;
397
+ /** CLI semver (e.g., "1.2.3") */
398
+ cli_version: string;
399
+ /** Database tracking tables version */
400
+ noorm_version: number;
401
+ /** State file (state.enc) schema version */
402
+ state_version: number;
403
+ /** Settings file (settings.yml) schema version */
404
+ settings_version: number;
405
+ /** First installation timestamp */
406
+ installed_at: Generated<Date>;
407
+ /** Last upgrade timestamp */
408
+ upgraded_at: Generated<Date>;
409
+ }
410
+ /**
411
+ * Operation status values.
412
+ *
413
+ * - pending: Operation started but not finished
414
+ * - success: Operation completed successfully
415
+ * - failed: Operation failed with error
416
+ * - reverted: Operation was reverted
417
+ * - stale: Operation's schema objects were torn down (needs re-run)
418
+ */
419
+ export type OperationStatus = "pending" | "success" | "failed" | "reverted" | "stale";
420
+ /**
421
+ * Change type values.
422
+ */
423
+ export type ChangeType = "build" | "run" | "change";
424
+ /**
425
+ * Direction values.
426
+ */
427
+ export type Direction = "change" | "revert";
428
+ /**
429
+ * Change tracking table.
430
+ *
431
+ * Tracks all operation batches—changes, builds, and ad-hoc runs.
432
+ * See: plan/datamodel.md#__noorm_change__
433
+ */
434
+ export interface NoormChangeTable {
435
+ /** Primary key */
436
+ id: Generated<number>;
437
+ /** Operation identifier */
438
+ name: string;
439
+ /** 'build', 'run', or 'change' */
440
+ change_type: ChangeType;
441
+ /** 'change' or 'revert' */
442
+ direction: Direction;
443
+ /** SHA-256 of sorted file checksums */
444
+ checksum: Generated<string>;
445
+ /** When executed */
446
+ executed_at: Generated<Date>;
447
+ /** Identity string */
448
+ executed_by: Generated<string>;
449
+ /** Which config was used */
450
+ config_name: Generated<string>;
451
+ /** noorm version */
452
+ cli_version: Generated<string>;
453
+ /** 'pending', 'success', 'failed', 'reverted' */
454
+ status: OperationStatus;
455
+ /** Error details (empty = no error) */
456
+ error_message: Generated<string>;
457
+ /** Execution time (0 = never ran) */
458
+ duration_ms: Generated<number>;
459
+ }
460
+ /**
461
+ * File execution status values.
462
+ */
463
+ export type ExecutionStatus = "pending" | "success" | "failed" | "skipped";
464
+ /**
465
+ * File type values.
466
+ */
467
+ export type FileType = "sql" | "txt";
468
+ /**
469
+ * Executions tracking table.
470
+ *
471
+ * Tracks individual file executions within an operation.
472
+ * See: plan/datamodel.md#__noorm_executions__
473
+ */
474
+ export interface NoormExecutionsTable {
475
+ /** Primary key */
476
+ id: Generated<number>;
477
+ /** Parent operation (FK to __noorm_change__) */
478
+ change_id: number;
479
+ /** File that was executed */
480
+ filepath: string;
481
+ /** 'sql' or 'txt' */
482
+ file_type: FileType;
483
+ /** SHA-256 of file contents */
484
+ checksum: Generated<string>;
485
+ /** noorm version */
486
+ cli_version: Generated<string>;
487
+ /** 'pending', 'success', 'failed', 'skipped' */
488
+ status: ExecutionStatus;
489
+ /** Error details (empty = no error) */
490
+ error_message: Generated<string>;
491
+ /** 'unchanged', 'already-run', 'change failed' */
492
+ skip_reason: Generated<string>;
493
+ /** Execution time (0 = never ran) */
494
+ duration_ms: Generated<number>;
495
+ }
496
+ /**
497
+ * Lock table.
498
+ *
499
+ * Prevents concurrent operations on the same database.
500
+ * See: plan/datamodel.md#__noorm_lock__
501
+ */
502
+ export interface NoormLockTable {
503
+ /** Primary key */
504
+ id: Generated<number>;
505
+ /** Lock scope (config name) */
506
+ config_name: string;
507
+ /** Identity of holder */
508
+ locked_by: string;
509
+ /** When acquired */
510
+ locked_at: Generated<Date>;
511
+ /** Auto-expiry time */
512
+ expires_at: Date;
513
+ /** Lock reason (empty = none) */
514
+ reason: Generated<string>;
515
+ }
516
+ /**
517
+ * Identities table.
518
+ *
519
+ * Stores user identities for team discovery.
520
+ * Auto-populated on first connect when identity is set up.
521
+ * See: plan/datamodel.md#__noorm_identities__
522
+ */
523
+ export interface NoormIdentitiesTable {
524
+ /** Primary key */
525
+ id: Generated<number>;
526
+ /** SHA-256(email + name + machine + os) */
527
+ identity_hash: string;
528
+ /** User email */
529
+ email: string;
530
+ /** Display name */
531
+ name: string;
532
+ /** Machine hostname */
533
+ machine: string;
534
+ /** OS platform and version */
535
+ os: string;
536
+ /** X25519 public key (hex) */
537
+ public_key: string;
538
+ /** First registration */
539
+ registered_at: Generated<Date>;
540
+ /** Last activity */
541
+ last_seen_at: Generated<Date>;
542
+ /** Vault key encrypted with user's public key (nullable for users without vault access) */
543
+ encrypted_vault_key: string | null;
544
+ }
545
+ /**
546
+ * Vault secrets table.
547
+ *
548
+ * Stores encrypted secrets shared across the team.
549
+ * Secrets are encrypted with a vault key that is distributed
550
+ * to team members via their public keys.
551
+ */
552
+ export interface NoormVaultTable {
553
+ /** Primary key */
554
+ id: Generated<number>;
555
+ /** Secret key name (e.g., 'API_KEY', 'DB_PASSWORD') */
556
+ secret_key: string;
557
+ /** AES-256-GCM encrypted value (JSON: {iv, authTag, ciphertext}) */
558
+ encrypted_value: string;
559
+ /** Identity who set this secret */
560
+ set_by: string;
561
+ /** When created */
562
+ created_at: Generated<Date>;
563
+ /** When last updated */
564
+ updated_at: Generated<Date>;
565
+ }
566
+ /**
567
+ * Combined database interface for all noorm tracking tables.
568
+ *
569
+ * Use this with Kysely<NoormDatabase> for type-safe queries.
570
+ *
571
+ * @example
572
+ * ```typescript
573
+ * import { NoormDatabase, NOORM_TABLES } from './shared'
574
+ *
575
+ * const db = new Kysely<NoormDatabase>({ dialect })
576
+ *
577
+ * const version = await db
578
+ * .selectFrom(NOORM_TABLES.version)
579
+ * .selectAll()
580
+ * .orderBy('id', 'desc')
581
+ * .limit(1)
582
+ * .executeTakeFirst()
583
+ * ```
584
+ */
585
+ export interface NoormDatabase {
586
+ __noorm_version__: NoormVersionTable;
587
+ __noorm_change__: NoormChangeTable;
588
+ __noorm_executions__: NoormExecutionsTable;
589
+ __noorm_lock__: NoormLockTable;
590
+ __noorm_identities__: NoormIdentitiesTable;
591
+ __noorm_vault__: NoormVaultTable;
592
+ }
380
593
  /**
381
594
  * Identity types.
382
595
  *
@@ -410,24 +623,6 @@ export interface Identity {
410
623
  /** How the identity was resolved */
411
624
  source: IdentitySource;
412
625
  }
413
- /**
414
- * Operation status values.
415
- *
416
- * - pending: Operation started but not finished
417
- * - success: Operation completed successfully
418
- * - failed: Operation failed with error
419
- * - reverted: Operation was reverted
420
- * - stale: Operation's schema objects were torn down (needs re-run)
421
- */
422
- export type OperationStatus = "pending" | "success" | "failed" | "reverted" | "stale";
423
- /**
424
- * Direction values.
425
- */
426
- export type Direction = "change" | "revert";
427
- /**
428
- * File execution status values.
429
- */
430
- export type ExecutionStatus = "pending" | "success" | "failed" | "skipped";
431
626
  /**
432
627
  * Overview counts for all categories.
433
628
  */
@@ -669,6 +864,40 @@ export interface ChangeFile {
669
864
  /** Why the file was skipped */
670
865
  skipReason?: string;
671
866
  }
867
+ /**
868
+ * A change parsed from disk.
869
+ *
870
+ * Contains the folder structure with change and revert files.
871
+ *
872
+ * @example
873
+ * ```typescript
874
+ * const change: Change = {
875
+ * name: '2024-01-15-add-email-verification',
876
+ * path: '/project/changes/2024-01-15-add-email-verification',
877
+ * date: new Date('2024-01-15'),
878
+ * description: 'add-email-verification',
879
+ * changeFiles: [...],
880
+ * revertFiles: [...],
881
+ * hasChangelog: true,
882
+ * }
883
+ * ```
884
+ */
885
+ export interface Change {
886
+ /** Folder name (e.g., "2024-01-15-add-email-verification") */
887
+ name: string;
888
+ /** Absolute path to change folder */
889
+ path: string;
890
+ /** Date parsed from name (null if no date prefix) */
891
+ date: Date | null;
892
+ /** Human-readable description from name */
893
+ description: string;
894
+ /** Files in change/ folder */
895
+ changeFiles: ChangeFile[];
896
+ /** Files in revert/ folder */
897
+ revertFiles: ChangeFile[];
898
+ /** Whether changelog.md exists */
899
+ hasChangelog: boolean;
900
+ }
672
901
  /**
673
902
  * A change with merged disk and database information.
674
903
  *
@@ -745,6 +974,50 @@ export interface ChangeOptions {
745
974
  /** Write preview output to file. Default: null */
746
975
  output?: string | null;
747
976
  }
977
+ /**
978
+ * Options for batch operations (next, ff, rewind).
979
+ */
980
+ export interface BatchChangeOptions extends ChangeOptions {
981
+ /** Stop on first failure. Default: true */
982
+ abortOnError?: boolean;
983
+ }
984
+ /**
985
+ * Context required to execute changes.
986
+ *
987
+ * @example
988
+ * ```typescript
989
+ * const context: ChangeContext = {
990
+ * db,
991
+ * configName: 'dev',
992
+ * identity: { name: 'Alice', email: 'alice@example.com' },
993
+ * projectRoot: '/project',
994
+ * changesDir: '/project/changes',
995
+ * sqlDir: '/project/sql',
996
+ * }
997
+ * ```
998
+ */
999
+ export interface ChangeContext {
1000
+ /** Kysely database connection */
1001
+ db: Kysely<NoormDatabase>;
1002
+ /** Name of the active config */
1003
+ configName: string;
1004
+ /** User identity for tracking */
1005
+ identity: Identity;
1006
+ /** Project root for template resolution */
1007
+ projectRoot: string;
1008
+ /** Directory containing changes */
1009
+ changesDir: string;
1010
+ /** Schema directory for resolving .txt references */
1011
+ sqlDir: string;
1012
+ /** Config object for template context */
1013
+ config?: Record<string, unknown>;
1014
+ /** Secrets for template context */
1015
+ secrets?: Record<string, string>;
1016
+ /** Global secrets for template context */
1017
+ globalSecrets?: Record<string, string>;
1018
+ /** Database dialect for lock formatting. Default: 'postgres' */
1019
+ dialect?: "postgres" | "mysql" | "sqlite" | "mssql";
1020
+ }
748
1021
  /**
749
1022
  * Result of executing a single change.
750
1023
  *
@@ -834,6 +1107,119 @@ export interface ChangeHistoryRecord {
834
1107
  /** Checksum of files */
835
1108
  checksum: string;
836
1109
  }
1110
+ /**
1111
+ * File execution record from history.
1112
+ */
1113
+ export interface FileHistoryRecord {
1114
+ /** Record ID */
1115
+ id: number;
1116
+ /** Parent change ID */
1117
+ changeId: number;
1118
+ /** File path */
1119
+ filepath: string;
1120
+ /** File type */
1121
+ fileType: ChangeFileType;
1122
+ /** File checksum */
1123
+ checksum: string;
1124
+ /** Execution status */
1125
+ status: ExecutionStatus;
1126
+ /** Skip reason if skipped */
1127
+ skipReason: string | null;
1128
+ /** Error message if failed */
1129
+ errorMessage: string | null;
1130
+ /** Duration in milliseconds */
1131
+ durationMs: number;
1132
+ }
1133
+ declare class ChangeManager {
1134
+ #private;
1135
+ constructor(context: ChangeContext);
1136
+ /**
1137
+ * List all changes with status.
1138
+ *
1139
+ * Merges changes from disk with status from database.
1140
+ * Includes orphaned changes (in DB but not on disk).
1141
+ *
1142
+ * @returns Array of changes with merged status
1143
+ */
1144
+ list(): Promise<ChangeListItem[]>;
1145
+ /**
1146
+ * Run a specific change by name.
1147
+ *
1148
+ * @param name - Change name
1149
+ * @param options - Execution options
1150
+ * @returns Execution result
1151
+ */
1152
+ run(name: string, options?: ChangeOptions): Promise<ChangeResult>;
1153
+ /**
1154
+ * Run a change object directly.
1155
+ */
1156
+ runChange(change: Change, options?: ChangeOptions): Promise<ChangeResult>;
1157
+ /**
1158
+ * Revert a specific change by name.
1159
+ *
1160
+ * @param name - Change name
1161
+ * @param options - Execution options
1162
+ * @returns Execution result
1163
+ */
1164
+ revert(name: string, options?: ChangeOptions): Promise<ChangeResult>;
1165
+ /**
1166
+ * Revert a change object directly.
1167
+ */
1168
+ revertChange(change: Change, options?: ChangeOptions): Promise<ChangeResult>;
1169
+ /**
1170
+ * Run next N pending changes.
1171
+ *
1172
+ * @param count - Number of changes to run (default: 1)
1173
+ * @param options - Execution options
1174
+ * @returns Batch result
1175
+ */
1176
+ next(count?: number, options?: BatchChangeOptions): Promise<BatchChangeResult>;
1177
+ /**
1178
+ * Fast-forward: run all pending changes.
1179
+ *
1180
+ * @param options - Execution options
1181
+ * @returns Batch result
1182
+ */
1183
+ ff(options?: BatchChangeOptions): Promise<BatchChangeResult>;
1184
+ /**
1185
+ * Rewind: revert changes in reverse order.
1186
+ *
1187
+ * @param target - Number of changes to revert, or name to revert to
1188
+ * @param options - Execution options
1189
+ * @returns Batch result
1190
+ */
1191
+ rewind(target: number | string, options?: BatchChangeOptions): Promise<BatchChangeResult>;
1192
+ /**
1193
+ * Get execution history.
1194
+ *
1195
+ * @param name - Optional change name (all if not provided)
1196
+ * @param limit - Max records to return
1197
+ * @returns Array of history records
1198
+ */
1199
+ getHistory(name?: string, limit?: number): Promise<ChangeHistoryRecord[]>;
1200
+ /**
1201
+ * Get file execution history for an operation.
1202
+ */
1203
+ getFileHistory(operationId: number): Promise<FileHistoryRecord[]>;
1204
+ /**
1205
+ * Remove a change from disk, database, or both.
1206
+ *
1207
+ * @param name - Change name
1208
+ * @param options - What to remove
1209
+ */
1210
+ remove(name: string, options: {
1211
+ disk?: boolean;
1212
+ db?: boolean;
1213
+ }): Promise<void>;
1214
+ /**
1215
+ * Get a specific change by name.
1216
+ */
1217
+ get(name: string): Promise<ChangeListItem | null>;
1218
+ /**
1219
+ * Load a change from disk.
1220
+ */
1221
+ load(name: string): Promise<Change>;
1222
+ }
837
1223
  /**
838
1224
  * Lock manager types.
839
1225
  *
@@ -999,6 +1385,168 @@ interface ProcessResult {
999
1385
  */
1000
1386
  durationMs?: number;
1001
1387
  }
1388
+ /**
1389
+ * Simple types stored as native JSON values. No encoding tuple needed.
1390
+ */
1391
+ export type SimpleType = "string" | "int" | "bigint" | "float" | "decimal" | "bool" | "timestamp" | "date" | "uuid";
1392
+ /**
1393
+ * Encoded types that always use a `[value, encoding]` tuple in .dt files.
1394
+ */
1395
+ export type EncodedType = "json" | "binary" | "vector" | "array" | "text" | "custom";
1396
+ /**
1397
+ * All universal types recognized by the .dt format.
1398
+ */
1399
+ export type UniversalType = SimpleType | EncodedType;
1400
+ /**
1401
+ * Column definition within a .dt schema.
1402
+ *
1403
+ * @example
1404
+ * ```typescript
1405
+ * const col: DtColumn = {
1406
+ * name: 'embedding',
1407
+ * type: 'vector',
1408
+ * sourceType: 'vector(1536)',
1409
+ * nullable: false,
1410
+ * };
1411
+ * ```
1412
+ */
1413
+ export interface DtColumn {
1414
+ /** Column name as it appears in the source database. */
1415
+ name: string;
1416
+ /** Universal type classification. */
1417
+ type: UniversalType;
1418
+ /** Original database-specific type (e.g., `jsonb`, `vector(1536)`). */
1419
+ sourceType?: string;
1420
+ /** Whether NULL values are permitted. Default: true. */
1421
+ nullable?: boolean;
1422
+ }
1423
+ /**
1424
+ * Schema validation result.
1425
+ */
1426
+ export interface SchemaValidationResult {
1427
+ /** Whether the schema is compatible with the target. */
1428
+ valid: boolean;
1429
+ /** Blocking errors that prevent transfer. */
1430
+ errors: string[];
1431
+ /** Non-blocking warnings about potential issues. */
1432
+ warnings: string[];
1433
+ }
1434
+ /**
1435
+ * Strategy for handling primary key conflicts during transfer.
1436
+ *
1437
+ * - `fail`: Abort on first conflict (default)
1438
+ * - `skip`: Skip conflicting rows, continue transfer
1439
+ * - `update`: Update existing rows with source data
1440
+ * - `replace`: Delete and re-insert conflicting rows
1441
+ */
1442
+ export type ConflictStrategy = "fail" | "skip" | "update" | "replace";
1443
+ /**
1444
+ * Options for data transfer operations.
1445
+ *
1446
+ * @example
1447
+ * ```typescript
1448
+ * const options: TransferOptions = {
1449
+ * tables: ['users', 'posts'],
1450
+ * onConflict: 'skip',
1451
+ * batchSize: 5000,
1452
+ * truncateFirst: false,
1453
+ * };
1454
+ * ```
1455
+ */
1456
+ export interface TransferOptions {
1457
+ /** Tables to transfer. Empty = all user tables. */
1458
+ tables?: string[];
1459
+ /** How to handle primary key conflicts. Default: 'fail' */
1460
+ onConflict?: ConflictStrategy;
1461
+ /** Rows per batch for cross-server transfers. Default: 1000 */
1462
+ batchSize?: number;
1463
+ /** Disable foreign key checks during transfer. Default: true */
1464
+ disableForeignKeys?: boolean;
1465
+ /** Preserve identity/auto-increment values. Default: true */
1466
+ preserveIdentity?: boolean;
1467
+ /** Truncate destination tables before transfer. Default: false */
1468
+ truncateFirst?: boolean;
1469
+ /** Validate only, don't execute. Default: false */
1470
+ dryRun?: boolean;
1471
+ /** Export to .dt file instead of DB insert. */
1472
+ exportPath?: string;
1473
+ /** Passphrase for .dtzx export encryption. */
1474
+ passphrase?: string;
1475
+ }
1476
+ /**
1477
+ * Plan for a single table transfer.
1478
+ */
1479
+ export interface TransferTablePlan {
1480
+ /** Table name */
1481
+ name: string;
1482
+ /** Table schema (if applicable) */
1483
+ schema?: string;
1484
+ /** Estimated row count */
1485
+ rowCount: number;
1486
+ /** Whether table has identity/auto-increment column */
1487
+ hasIdentity: boolean;
1488
+ /** Identity column name if present */
1489
+ identityColumn?: string;
1490
+ /** Primary key columns */
1491
+ primaryKey: string[];
1492
+ /** All column names */
1493
+ columns: string[];
1494
+ /** Tables this table depends on (FK references) */
1495
+ dependsOn: string[];
1496
+ /** Column type definitions for cross-dialect transfers. */
1497
+ columnTypes?: DtColumn[];
1498
+ }
1499
+ /**
1500
+ * Complete transfer plan.
1501
+ *
1502
+ * Contains ordered list of tables and transfer metadata.
1503
+ */
1504
+ export interface TransferPlan {
1505
+ /** Tables in dependency order (parents before children) */
1506
+ tables: TransferTablePlan[];
1507
+ /** Whether source and destination are on same server */
1508
+ sameServer: boolean;
1509
+ /** Total estimated rows across all tables */
1510
+ estimatedRows: number;
1511
+ /** Warnings about potential issues */
1512
+ warnings: string[];
1513
+ /** Whether this is a cross-dialect transfer. */
1514
+ crossDialect: boolean;
1515
+ /** Source database dialect. */
1516
+ sourceDialect: Dialect;
1517
+ /** Destination database dialect. */
1518
+ destinationDialect: Dialect;
1519
+ }
1520
+ /**
1521
+ * Result for a single table transfer.
1522
+ */
1523
+ export interface TransferTableResult {
1524
+ /** Table name */
1525
+ table: string;
1526
+ /** Transfer status */
1527
+ status: "success" | "skipped" | "failed";
1528
+ /** Rows successfully transferred */
1529
+ rowsTransferred: number;
1530
+ /** Rows skipped due to conflicts */
1531
+ rowsSkipped: number;
1532
+ /** Duration in milliseconds */
1533
+ durationMs: number;
1534
+ /** Error message if failed */
1535
+ error?: string;
1536
+ }
1537
+ /**
1538
+ * Complete transfer result.
1539
+ */
1540
+ export interface TransferResult {
1541
+ /** Overall status */
1542
+ status: "success" | "partial" | "failed";
1543
+ /** Results per table */
1544
+ tables: TransferTableResult[];
1545
+ /** Total rows transferred */
1546
+ totalRows: number;
1547
+ /** Total duration in milliseconds */
1548
+ durationMs: number;
1549
+ }
1002
1550
  /**
1003
1551
  * SDK Types.
1004
1552
  *
@@ -1053,40 +1601,64 @@ export interface CreateContextOptions {
1053
1601
  stage?: string;
1054
1602
  }
1055
1603
  /**
1056
- * Result of an execute() call.
1604
+ * Options for build operations.
1057
1605
  */
1058
- export interface ExecuteResult {
1059
- /** Number of rows affected (if available) */
1060
- rowsAffected?: number;
1606
+ export interface BuildOptions {
1607
+ /** Skip checksum checks, rebuild everything. Default: false */
1608
+ force?: boolean;
1061
1609
  }
1062
1610
  /**
1063
- * Transaction context for use within transaction callbacks.
1611
+ * Options for exporting a table to a .dt file.
1612
+ *
1613
+ * Connection details (db, dialect) come from the context automatically.
1064
1614
  *
1065
1615
  * @example
1066
1616
  * ```typescript
1067
- * await ctx.transaction(async (tx) => {
1068
- * const [user] = await tx.query('SELECT * FROM users WHERE id = $1', [id])
1069
- * await tx.execute('UPDATE users SET login_count = login_count + 1 WHERE id = $1', [id])
1070
- * return user
1071
- * })
1617
+ * const [result, err] = await ctx.exportTable('users', './exports/users.dtz', {
1618
+ * passphrase: 'secret',
1619
+ * batchSize: 5000,
1620
+ * });
1072
1621
  * ```
1073
1622
  */
1074
- export interface TransactionContext {
1075
- /**
1076
- * Execute a SELECT query within the transaction.
1077
- */
1078
- query<T = Record<string, unknown>>(sql: string, params?: unknown[]): Promise<T[]>;
1079
- /**
1080
- * Execute an INSERT/UPDATE/DELETE within the transaction.
1081
- */
1082
- execute(sql: string, params?: unknown[]): Promise<ExecuteResult>;
1623
+ export interface ExportOptions {
1624
+ /** Passphrase for .dtzx encryption. */
1625
+ passphrase?: string;
1626
+ /** Schema/namespace (e.g., 'public' for PostgreSQL). */
1627
+ schema?: string;
1628
+ /** Rows per batch. Default: 1000. */
1629
+ batchSize?: number;
1083
1630
  }
1084
1631
  /**
1085
- * Options for build operations.
1632
+ * Options for importing a .dt file into the database.
1633
+ *
1634
+ * Connection details (db, dialect) come from the context automatically.
1635
+ *
1636
+ * @example
1637
+ * ```typescript
1638
+ * const [result, err] = await ctx.importFile('./exports/users.dtz', {
1639
+ * onConflict: 'skip',
1640
+ * truncate: true,
1641
+ * });
1642
+ * ```
1086
1643
  */
1087
- export interface BuildOptions {
1088
- /** Skip checksum checks, rebuild everything. Default: false */
1089
- force?: boolean;
1644
+ export interface ImportOptions {
1645
+ /** Passphrase for .dtzx decryption. */
1646
+ passphrase?: string;
1647
+ /** Rows per batch. Default: 1000. */
1648
+ batchSize?: number;
1649
+ /** Conflict strategy. Default: 'fail'. */
1650
+ onConflict?: "fail" | "skip" | "update" | "replace";
1651
+ /** Truncate target table before import. Default: false. */
1652
+ truncate?: boolean;
1653
+ }
1654
+ export interface ContextState {
1655
+ connection: ConnectionResult | null;
1656
+ config: Config;
1657
+ settings: Settings;
1658
+ identity: Identity;
1659
+ options: CreateContextOptions;
1660
+ projectRoot: string;
1661
+ changeManager: ChangeManager | null;
1090
1662
  }
1091
1663
  export type Events<Shape> = keyof Shape;
1092
1664
  declare namespace ObserverEngine {
@@ -1689,6 +2261,277 @@ export type ShutdownReason = "signal" | "user" | "error" | "programmatic";
1689
2261
  * Application mode.
1690
2262
  */
1691
2263
  export type AppMode = "tui" | "headless";
2264
+ /**
2265
+ * Type definitions for auto-update feature.
2266
+ *
2267
+ * Includes global settings structure and update check/result types.
2268
+ */
2269
+ /**
2270
+ * Dismissable alert preference.
2271
+ *
2272
+ * Controls how alerts are handled after user makes a choice:
2273
+ * - 'ask': Show the alert and ask user each time (default)
2274
+ * - 'always': Always perform the action without asking
2275
+ * - 'never': Never perform the action, auto-deny
2276
+ */
2277
+ export type DismissablePreference = "ask" | "always" | "never";
2278
+ /**
2279
+ * Global settings stored in ~/.noorm/settings.yml
2280
+ *
2281
+ * These are user-level settings, separate from project settings.
2282
+ * Used for preferences that apply across all projects.
2283
+ */
2284
+ export interface GlobalSettings {
2285
+ /** Check for updates on TUI launch (default: true) */
2286
+ checkUpdates: boolean;
2287
+ /** Auto-install updates without prompting (default: false) */
2288
+ autoUpdate: boolean;
2289
+ /** Last check timestamp (ISO string) */
2290
+ lastCheck?: string;
2291
+ /** Cached latest version from last check */
2292
+ cachedVersion?: string;
2293
+ /**
2294
+ * Dismissable alert preferences.
2295
+ *
2296
+ * Stores user decisions for alerts that can be permanently dismissed.
2297
+ * Keys are alert identifiers (e.g., 'majorVersionUpdate').
2298
+ */
2299
+ dismissable?: Record<string, DismissablePreference>;
2300
+ }
2301
+ /**
2302
+ * Events emitted by the update module.
2303
+ *
2304
+ * Used to integrate with the observer event system.
2305
+ */
2306
+ export interface UpdateEvents {
2307
+ "update:checking": Record<string, never>;
2308
+ "update:available": {
2309
+ currentVersion: string;
2310
+ latestVersion: string;
2311
+ };
2312
+ "update:major-available": {
2313
+ currentVersion: string;
2314
+ latestVersion: string;
2315
+ };
2316
+ "update:not-available": {
2317
+ currentVersion: string;
2318
+ };
2319
+ "update:check-failed": {
2320
+ error: string;
2321
+ };
2322
+ "update:installing": {
2323
+ version: string;
2324
+ };
2325
+ "update:complete": {
2326
+ previousVersion: string;
2327
+ newVersion: string;
2328
+ };
2329
+ "update:failed": {
2330
+ version: string;
2331
+ error: string;
2332
+ };
2333
+ "update:skipped": {
2334
+ version: string;
2335
+ reason: "user-denied" | "user-deferred";
2336
+ };
2337
+ "global-settings:loaded": {
2338
+ settings: GlobalSettings;
2339
+ };
2340
+ "global-settings:updated": {
2341
+ key: string;
2342
+ value: unknown;
2343
+ };
2344
+ }
2345
+ /**
2346
+ * Vault event types.
2347
+ *
2348
+ * All events emitted by the vault module. These are merged into
2349
+ * NoormEvents via the VaultEvents interface.
2350
+ */
2351
+ /**
2352
+ * Vault events for observer integration.
2353
+ *
2354
+ * Events follow the naming convention `vault:{operation}`.
2355
+ */
2356
+ export interface VaultEvents {
2357
+ /** Vault was initialized for the first time */
2358
+ "vault:initialized": {
2359
+ identityHash: string;
2360
+ };
2361
+ /** New vault secret was created */
2362
+ "vault:secret:created": {
2363
+ key: string;
2364
+ setBy: string;
2365
+ };
2366
+ /** Existing vault secret was updated */
2367
+ "vault:secret:updated": {
2368
+ key: string;
2369
+ setBy: string;
2370
+ };
2371
+ /** Vault secret was deleted */
2372
+ "vault:secret:deleted": {
2373
+ key: string;
2374
+ };
2375
+ /** Vault key was propagated to a user */
2376
+ "vault:propagated": {
2377
+ toIdentityHash: string;
2378
+ toEmail: string;
2379
+ };
2380
+ /** Vault copy operation started */
2381
+ "vault:copy:starting": {
2382
+ source: string;
2383
+ destination: string;
2384
+ keys: "all" | number;
2385
+ };
2386
+ /** Vault copy operation completed */
2387
+ "vault:copy:completed": {
2388
+ source: string;
2389
+ destination: string;
2390
+ copied: number;
2391
+ skipped: number;
2392
+ errors: number;
2393
+ };
2394
+ }
2395
+ /**
2396
+ * Transfer event types for observer integration.
2397
+ *
2398
+ * Events emitted during data transfer operations for CLI progress display.
2399
+ */
2400
+ /**
2401
+ * Events emitted by the transfer module.
2402
+ *
2403
+ * Subscribe to these events to track transfer progress in the CLI.
2404
+ */
2405
+ export interface TransferEvents {
2406
+ /** Emitted when transfer planning starts */
2407
+ "transfer:planning": {
2408
+ source: string;
2409
+ destination: string;
2410
+ };
2411
+ /** Emitted when transfer plan is ready */
2412
+ "transfer:plan:ready": {
2413
+ sameServer: boolean;
2414
+ tableCount: number;
2415
+ estimatedRows: number;
2416
+ warnings: string[];
2417
+ };
2418
+ /** Emitted when transfer execution starts */
2419
+ "transfer:starting": {
2420
+ tableCount: number;
2421
+ sameServer: boolean;
2422
+ };
2423
+ /** Emitted before transferring each table */
2424
+ "transfer:table:before": {
2425
+ table: string;
2426
+ index: number;
2427
+ total: number;
2428
+ rowCount: number;
2429
+ };
2430
+ /** Emitted during table transfer with progress */
2431
+ "transfer:table:progress": {
2432
+ table: string;
2433
+ rowsTransferred: number;
2434
+ rowsTotal: number;
2435
+ rowsSkipped: number;
2436
+ };
2437
+ /** Emitted after transferring each table */
2438
+ "transfer:table:after": {
2439
+ table: string;
2440
+ status: "success" | "skipped" | "failed";
2441
+ rowsTransferred: number;
2442
+ rowsSkipped: number;
2443
+ durationMs: number;
2444
+ error?: string;
2445
+ };
2446
+ /** Emitted when transfer completes */
2447
+ "transfer:complete": {
2448
+ status: "success" | "partial" | "failed";
2449
+ totalRows: number;
2450
+ tableCount: number;
2451
+ durationMs: number;
2452
+ };
2453
+ }
2454
+ /**
2455
+ * Events emitted by the dt module.
2456
+ *
2457
+ * Subscribe to these events to track .dt operation progress in the CLI.
2458
+ */
2459
+ export interface DtEvents {
2460
+ /** Export begins for a table. */
2461
+ "dt:export:start": {
2462
+ filepath: string;
2463
+ table: string;
2464
+ columnCount: number;
2465
+ };
2466
+ /** After each batch flush during export. */
2467
+ "dt:export:progress": {
2468
+ filepath: string;
2469
+ table: string;
2470
+ rowsWritten: number;
2471
+ bytesWritten: number;
2472
+ };
2473
+ /** Export finished for a table. */
2474
+ "dt:export:complete": {
2475
+ filepath: string;
2476
+ table: string;
2477
+ rowsWritten: number;
2478
+ bytesWritten: number;
2479
+ durationMs: number;
2480
+ };
2481
+ /** Import begins for a file. */
2482
+ "dt:import:start": {
2483
+ filepath: string;
2484
+ sourceDialect: string;
2485
+ sourceVersion: string;
2486
+ table: string;
2487
+ };
2488
+ /** Schema parsed and validated during import. */
2489
+ "dt:import:schema": {
2490
+ filepath: string;
2491
+ table: string;
2492
+ columns: number;
2493
+ validation: SchemaValidationResult;
2494
+ };
2495
+ /** After each batch insert during import. */
2496
+ "dt:import:progress": {
2497
+ filepath: string;
2498
+ table: string;
2499
+ rowsImported: number;
2500
+ rowsSkipped: number;
2501
+ };
2502
+ /** Import finished for a file. */
2503
+ "dt:import:complete": {
2504
+ filepath: string;
2505
+ table: string;
2506
+ rowsImported: number;
2507
+ rowsSkipped: number;
2508
+ durationMs: number;
2509
+ };
2510
+ /** Cross-dialect stream begins. */
2511
+ "dt:stream:start": {
2512
+ table: string;
2513
+ sourceDialect: string;
2514
+ targetDialect: string;
2515
+ };
2516
+ /** After each batch conversion during streaming. */
2517
+ "dt:stream:progress": {
2518
+ table: string;
2519
+ rowsConverted: number;
2520
+ };
2521
+ /** Cross-dialect stream finished. */
2522
+ "dt:stream:complete": {
2523
+ table: string;
2524
+ rowsConverted: number;
2525
+ durationMs: number;
2526
+ };
2527
+ /** Schema validation completed. */
2528
+ "dt:validate:result": {
2529
+ table: string;
2530
+ valid: boolean;
2531
+ errors: string[];
2532
+ warnings: string[];
2533
+ };
2534
+ }
1692
2535
  /**
1693
2536
  * All events emitted by noorm core modules.
1694
2537
  *
@@ -1706,9 +2549,12 @@ export type AppMode = "tui" | "headless";
1706
2549
  * - `identity:*` - Identity resolution
1707
2550
  * - `connection:*` - Database connections
1708
2551
  * - `settings:*` - Settings lifecycle and mutations
2552
+ * - `vault:*` - Vault operations
2553
+ * - `transfer:*` - Data transfer operations
2554
+ * - `dt:*` - .dt format export/import/stream operations
1709
2555
  * - `error` - Catch-all errors
1710
2556
  */
1711
- export interface NoormEvents extends SettingsEvents {
2557
+ export interface NoormEvents extends SettingsEvents, UpdateEvents, VaultEvents, TransferEvents, DtEvents {
1712
2558
  "file:before": {
1713
2559
  filepath: string;
1714
2560
  checksum: string;
@@ -1726,7 +2572,9 @@ export interface NoormEvents extends SettingsEvents {
1726
2572
  };
1727
2573
  "file:dry-run": {
1728
2574
  filepath: string;
1729
- outputPath: string;
2575
+ status: "success" | "failed";
2576
+ outputPath?: string;
2577
+ error?: string;
1730
2578
  };
1731
2579
  "change:created": {
1732
2580
  name: string;
@@ -1893,6 +2741,7 @@ export interface NoormEvents extends SettingsEvents {
1893
2741
  registered: boolean;
1894
2742
  knownUsersCount: number;
1895
2743
  };
2744
+ "identity:not-found": void;
1896
2745
  "connection:open": {
1897
2746
  configName: string;
1898
2747
  dialect: string;
@@ -1945,65 +2794,439 @@ export interface NoormEvents extends SettingsEvents {
1945
2794
  }
1946
2795
  export type NoormEventNames = Events<NoormEvents>;
1947
2796
  /**
1948
- * SDK Context implementation.
2797
+ * Noorm-specific operations accessed via ctx.noorm.
1949
2798
  *
1950
- * Provides programmatic access to all noorm operations.
2799
+ * All database management operations — schema, changes, locks,
2800
+ * runner, explore, transfer, DT — live here. The shared ContextState
2801
+ * keeps connection state in sync with the parent Context.
1951
2802
  *
1952
2803
  * @example
1953
2804
  * ```typescript
1954
2805
  * const ctx = await createContext({ config: 'dev' })
1955
2806
  * await ctx.connect()
1956
2807
  *
1957
- * // Run queries
1958
- * const users = await ctx.query('SELECT * FROM users')
1959
- *
1960
- * // Clean disconnect
1961
- * await ctx.disconnect()
2808
+ * await ctx.noorm.build()
2809
+ * await ctx.noorm.fastForward()
2810
+ * const tables = await ctx.noorm.listTables()
1962
2811
  * ```
1963
2812
  */
1964
- export declare class Context<DB = unknown> {
2813
+ export declare class NoormOps {
1965
2814
  #private;
1966
- constructor(config: Config, settings: Settings, identity: Identity, options: CreateContextOptions, projectRoot: string);
2815
+ constructor(state: ContextState);
1967
2816
  get config(): Config;
1968
2817
  get settings(): Settings;
1969
2818
  get identity(): Identity;
1970
- get dialect(): Dialect;
1971
- get connected(): boolean;
1972
2819
  get observer(): ObserverEngine<NoormEvents>;
1973
- get kysely(): Kysely<DB>;
1974
- connect(): Promise<void>;
1975
- disconnect(): Promise<void>;
1976
- query<T = Record<string, unknown>>(sqlStr: string, _params?: unknown[]): Promise<T[]>;
1977
- execute(sqlStr: string, _params?: unknown[]): Promise<ExecuteResult>;
1978
- transaction<T>(fn: (tx: TransactionContext) => Promise<T>): Promise<T>;
2820
+ /**
2821
+ * List all tables in the database.
2822
+ *
2823
+ * @example
2824
+ * ```typescript
2825
+ * const tables = await ctx.noorm.listTables()
2826
+ * ```
2827
+ */
1979
2828
  listTables(): Promise<TableSummary[]>;
2829
+ /**
2830
+ * Get detailed information about a table.
2831
+ *
2832
+ * @example
2833
+ * ```typescript
2834
+ * const detail = await ctx.noorm.describeTable('users')
2835
+ * ```
2836
+ */
1980
2837
  describeTable(name: string, schema?: string): Promise<TableDetail | null>;
2838
+ /**
2839
+ * Get database overview with counts of all object types.
2840
+ *
2841
+ * @example
2842
+ * ```typescript
2843
+ * const overview = await ctx.noorm.overview()
2844
+ * ```
2845
+ */
1981
2846
  overview(): Promise<ExploreOverview>;
2847
+ /**
2848
+ * Wipe all data, keeping the schema intact.
2849
+ *
2850
+ * @example
2851
+ * ```typescript
2852
+ * const result = await ctx.noorm.truncate()
2853
+ * ```
2854
+ */
1982
2855
  truncate(): Promise<TruncateResult>;
2856
+ /**
2857
+ * Drop all database objects except noorm tracking tables.
2858
+ *
2859
+ * @example
2860
+ * ```typescript
2861
+ * const result = await ctx.noorm.teardown()
2862
+ * ```
2863
+ */
1983
2864
  teardown(): Promise<TeardownResult>;
2865
+ /**
2866
+ * Execute all SQL files in the schema directory.
2867
+ *
2868
+ * @example
2869
+ * ```typescript
2870
+ * const result = await ctx.noorm.build({ force: true })
2871
+ * ```
2872
+ */
1984
2873
  build(options?: BuildOptions): Promise<BatchResult>;
2874
+ /**
2875
+ * Full rebuild: teardown + build.
2876
+ *
2877
+ * @example
2878
+ * ```typescript
2879
+ * await ctx.noorm.reset()
2880
+ * ```
2881
+ */
1985
2882
  reset(): Promise<void>;
2883
+ /**
2884
+ * Execute a single SQL file.
2885
+ *
2886
+ * @example
2887
+ * ```typescript
2888
+ * await ctx.noorm.runFile('seeds/test-data.sql')
2889
+ * ```
2890
+ */
1986
2891
  runFile(filepath: string, options?: RunOptions): Promise<FileResult>;
2892
+ /**
2893
+ * Execute multiple SQL files sequentially.
2894
+ *
2895
+ * @example
2896
+ * ```typescript
2897
+ * await ctx.noorm.runFiles(['functions/utils.sql', 'triggers/audit.sql'])
2898
+ * ```
2899
+ */
1987
2900
  runFiles(filepaths: string[], options?: RunOptions): Promise<BatchResult>;
2901
+ /**
2902
+ * Execute all SQL files in a directory.
2903
+ *
2904
+ * @example
2905
+ * ```typescript
2906
+ * await ctx.noorm.runDir('seeds/')
2907
+ * ```
2908
+ */
1988
2909
  runDir(dirpath: string, options?: RunOptions): Promise<BatchResult>;
2910
+ /**
2911
+ * Apply a specific change.
2912
+ *
2913
+ * @example
2914
+ * ```typescript
2915
+ * const result = await ctx.noorm.applyChange('2024-01-15-add-users')
2916
+ * ```
2917
+ */
1989
2918
  applyChange(name: string, options?: ChangeOptions): Promise<ChangeResult>;
2919
+ /**
2920
+ * Revert a specific change.
2921
+ *
2922
+ * @example
2923
+ * ```typescript
2924
+ * const result = await ctx.noorm.revertChange('2024-01-15-add-users')
2925
+ * ```
2926
+ */
1990
2927
  revertChange(name: string, options?: ChangeOptions): Promise<ChangeResult>;
2928
+ /**
2929
+ * Apply all pending changes.
2930
+ *
2931
+ * @example
2932
+ * ```typescript
2933
+ * const result = await ctx.noorm.fastForward()
2934
+ * ```
2935
+ */
1991
2936
  fastForward(): Promise<BatchChangeResult>;
2937
+ /**
2938
+ * Get status of all changes.
2939
+ *
2940
+ * @example
2941
+ * ```typescript
2942
+ * const changes = await ctx.noorm.getChangeStatus()
2943
+ * ```
2944
+ */
1992
2945
  getChangeStatus(): Promise<ChangeListItem[]>;
2946
+ /**
2947
+ * Get only pending changes.
2948
+ *
2949
+ * @example
2950
+ * ```typescript
2951
+ * const pending = await ctx.noorm.getPendingChanges()
2952
+ * ```
2953
+ */
1993
2954
  getPendingChanges(): Promise<ChangeListItem[]>;
2955
+ /**
2956
+ * Get a config-scoped secret.
2957
+ *
2958
+ * @example
2959
+ * ```typescript
2960
+ * const apiKey = ctx.noorm.getSecret('API_KEY')
2961
+ * ```
2962
+ */
1994
2963
  getSecret(key: string): string | undefined;
2964
+ /**
2965
+ * Acquire a database lock.
2966
+ *
2967
+ * @example
2968
+ * ```typescript
2969
+ * const lock = await ctx.noorm.acquireLock({ timeout: 60000 })
2970
+ * ```
2971
+ */
1995
2972
  acquireLock(options?: LockOptions$1): Promise<Lock$1>;
2973
+ /**
2974
+ * Release the current lock.
2975
+ *
2976
+ * @example
2977
+ * ```typescript
2978
+ * await ctx.noorm.releaseLock()
2979
+ * ```
2980
+ */
1996
2981
  releaseLock(): Promise<void>;
2982
+ /**
2983
+ * Get current lock status.
2984
+ *
2985
+ * @example
2986
+ * ```typescript
2987
+ * const status = await ctx.noorm.getLockStatus()
2988
+ * ```
2989
+ */
1997
2990
  getLockStatus(): Promise<LockStatus>;
2991
+ /**
2992
+ * Execute an operation with automatic lock acquisition and release.
2993
+ *
2994
+ * @example
2995
+ * ```typescript
2996
+ * await ctx.noorm.withLock(async () => {
2997
+ * await ctx.noorm.build()
2998
+ * await ctx.noorm.fastForward()
2999
+ * })
3000
+ * ```
3001
+ */
1998
3002
  withLock<T>(fn: () => Promise<T>, options?: LockOptions$1): Promise<T>;
3003
+ /**
3004
+ * Force release any database lock regardless of ownership.
3005
+ *
3006
+ * @example
3007
+ * ```typescript
3008
+ * await ctx.noorm.forceReleaseLock()
3009
+ * ```
3010
+ */
1999
3011
  forceReleaseLock(): Promise<boolean>;
3012
+ /**
3013
+ * Render a template file without executing.
3014
+ *
3015
+ * @example
3016
+ * ```typescript
3017
+ * const result = await ctx.noorm.renderTemplate('sql/001_users.sql.tmpl')
3018
+ * ```
3019
+ */
2000
3020
  renderTemplate(filepath: string): Promise<ProcessResult>;
3021
+ /**
3022
+ * Get execution history.
3023
+ *
3024
+ * @example
3025
+ * ```typescript
3026
+ * const history = await ctx.noorm.getHistory(10)
3027
+ * ```
3028
+ */
2001
3029
  getHistory(limit?: number): Promise<ChangeHistoryRecord[]>;
3030
+ /**
3031
+ * Compute SHA-256 checksum for a file.
3032
+ *
3033
+ * @example
3034
+ * ```typescript
3035
+ * const checksum = await ctx.noorm.computeChecksum('sql/001_users.sql')
3036
+ * ```
3037
+ */
2002
3038
  computeChecksum(filepath: string): Promise<string>;
3039
+ /**
3040
+ * Tests if the connection can be established.
3041
+ *
3042
+ * @example
3043
+ * ```typescript
3044
+ * const result = await ctx.noorm.testConnection()
3045
+ * ```
3046
+ */
2003
3047
  testConnection(): Promise<{
2004
3048
  ok: boolean;
2005
3049
  error?: string;
2006
3050
  }>;
3051
+ /**
3052
+ * Transfer data from this context's database to a destination context.
3053
+ *
3054
+ * Both contexts must be connected. Uses each context's config for
3055
+ * connection management.
3056
+ *
3057
+ * @example
3058
+ * ```typescript
3059
+ * const [result, err] = await source.noorm.transferTo(dest, {
3060
+ * tables: ['users', 'posts'],
3061
+ * onConflict: 'skip',
3062
+ * })
3063
+ * ```
3064
+ */
3065
+ transferTo(destConfig: Config, options?: TransferOptions): Promise<[
3066
+ TransferResult | null,
3067
+ Error | null
3068
+ ]>;
3069
+ /**
3070
+ * Generate a transfer plan without executing.
3071
+ *
3072
+ * @example
3073
+ * ```typescript
3074
+ * const [plan, err] = await source.noorm.transferPlan(destConfig)
3075
+ * ```
3076
+ */
3077
+ transferPlan(destConfig: Config, options?: TransferOptions): Promise<[
3078
+ TransferPlan | null,
3079
+ Error | null
3080
+ ]>;
3081
+ /**
3082
+ * Export a table to a .dt file.
3083
+ *
3084
+ * @example
3085
+ * ```typescript
3086
+ * const [result, err] = await ctx.noorm.exportTable('users', './exports/users.dtz')
3087
+ * ```
3088
+ */
3089
+ exportTable(tableName: string, filepath: string, options?: ExportOptions): Promise<[
3090
+ {
3091
+ rowsWritten: number;
3092
+ bytesWritten: number;
3093
+ } | null,
3094
+ Error | null
3095
+ ]>;
3096
+ /**
3097
+ * Import a .dt file into the connected database.
3098
+ *
3099
+ * @example
3100
+ * ```typescript
3101
+ * const [result, err] = await ctx.noorm.importFile('./exports/users.dtz', {
3102
+ * onConflict: 'skip',
3103
+ * })
3104
+ * ```
3105
+ */
3106
+ importFile(filepath: string, options?: ImportOptions): Promise<[
3107
+ {
3108
+ rowsImported: number;
3109
+ rowsSkipped: number;
3110
+ } | null,
3111
+ Error | null
3112
+ ]>;
3113
+ }
3114
+ /**
3115
+ * SDK Context implementation.
3116
+ *
3117
+ * Provides SQL-focused programmatic access to the database.
3118
+ * Noorm management operations are accessible via ctx.noorm.
3119
+ *
3120
+ * @example
3121
+ * ```typescript
3122
+ * const ctx = await createContext({ config: 'dev' })
3123
+ * await ctx.connect()
3124
+ *
3125
+ * // Top-level — SQL focused
3126
+ * const users = await ctx.kysely
3127
+ * .selectFrom('users')
3128
+ * .selectAll()
3129
+ * .execute()
3130
+ *
3131
+ * // Noorm operations — under namespace
3132
+ * await ctx.noorm.build()
3133
+ * await ctx.noorm.fastForward()
3134
+ *
3135
+ * await ctx.disconnect()
3136
+ * ```
3137
+ */
3138
+ export declare class Context<DB = unknown, Procs = object, Funcs = object> {
3139
+ #private;
3140
+ constructor(config: Config, settings: Settings, identity: Identity, options: CreateContextOptions, projectRoot: string);
3141
+ get dialect(): Dialect;
3142
+ get connected(): boolean;
3143
+ get kysely(): Kysely<DB>;
3144
+ /**
3145
+ * Noorm management operations.
3146
+ *
3147
+ * Lazily instantiated on first access. Returns the same instance
3148
+ * on repeated access (singleton per Context).
3149
+ *
3150
+ * @example
3151
+ * ```typescript
3152
+ * await ctx.noorm.build()
3153
+ * await ctx.noorm.fastForward()
3154
+ * const tables = await ctx.noorm.listTables()
3155
+ * ```
3156
+ */
3157
+ get noorm(): NoormOps;
3158
+ connect(): Promise<void>;
3159
+ disconnect(): Promise<void>;
3160
+ /**
3161
+ * Execute operations within a database transaction.
3162
+ *
3163
+ * The callback receives a full Kysely Transaction instance with
3164
+ * query builder, `sql` template literal, and all Kysely features.
3165
+ *
3166
+ * @example
3167
+ * ```typescript
3168
+ * await ctx.transaction(async (trx) => {
3169
+ * await trx
3170
+ * .updateTable('accounts')
3171
+ * .set({ balance: sql`balance - ${amount}` })
3172
+ * .where('id', '=', fromId)
3173
+ * .execute();
3174
+ * await trx
3175
+ * .updateTable('accounts')
3176
+ * .set({ balance: sql`balance + ${amount}` })
3177
+ * .where('id', '=', toId)
3178
+ * .execute();
3179
+ * });
3180
+ * ```
3181
+ */
3182
+ transaction<T>(fn: (trx: Transaction<DB>) => Promise<T>): Promise<T>;
3183
+ /**
3184
+ * Call a stored procedure and return the result set.
3185
+ *
3186
+ * Generates dialect-specific SQL: EXEC (MSSQL), CALL (PG/MySQL).
3187
+ * Named params use dialect-appropriate syntax; MySQL falls back
3188
+ * to positional. SQLite throws — no procedure support.
3189
+ *
3190
+ * @example
3191
+ * ```typescript
3192
+ * // Named params
3193
+ * const users = await ctx.proc<User>('get_users', { department_id: 1 });
3194
+ *
3195
+ * // Positional params
3196
+ * await ctx.proc('simple_proc', [42, 'hello']);
3197
+ *
3198
+ * // No params
3199
+ * await ctx.proc('refresh_cache');
3200
+ * ```
3201
+ */
3202
+ proc<T = unknown, N extends keyof Procs & string = keyof Procs & string>(name: N, ...args: Procs[N] extends void ? [
3203
+ ] : [
3204
+ params: Procs[N]
3205
+ ]): Promise<T[]>;
3206
+ /**
3207
+ * Call a database function and return the scalar result.
3208
+ *
3209
+ * Generates SELECT name(...) AS column. Named params only on PG;
3210
+ * other dialects fall back to positional. SQLite throws.
3211
+ *
3212
+ * @example
3213
+ * ```typescript
3214
+ * // Named params + column alias
3215
+ * const result = await ctx.func<{ total: number }>('calc_total', { order_id: 42 }, 'total');
3216
+ *
3217
+ * // Positional params + column alias
3218
+ * const sum = await ctx.func<{ result: number }>('add_numbers', [1, 2], 'result');
3219
+ *
3220
+ * // No params — just column alias
3221
+ * const ver = await ctx.func<{ v: string }>('get_version', 'v');
3222
+ * ```
3223
+ */
3224
+ func<T = unknown, N extends keyof Funcs & string = keyof Funcs & string>(name: N, ...args: Funcs[N] extends void ? [
3225
+ column: string
3226
+ ] : [
3227
+ params: Funcs[N],
3228
+ column: string
3229
+ ]): Promise<T>;
2007
3230
  }
2008
3231
  /**
2009
3232
  * Error thrown when requireTest is enabled but config.isTest is false.
@@ -2072,7 +3295,7 @@ export declare class ProtectedConfigError extends Error {
2072
3295
  * const ctx = await createContext()
2073
3296
  * ```
2074
3297
  */
2075
- export declare function createContext<DB = unknown>(options?: CreateContextOptions): Promise<Context<DB>>;
3298
+ export declare function createContext<DB = unknown, Procs = object, Funcs = object>(options?: CreateContextOptions): Promise<Context<DB, Procs, Funcs>>;
2076
3299
 
2077
3300
  export {
2078
3301
  Lock$1 as Lock,