@gl-life/gl-life-database 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/API.md +1486 -0
- package/LICENSE +190 -0
- package/README.md +480 -0
- package/dist/cache/index.d.ts +4 -0
- package/dist/cache/index.d.ts.map +1 -0
- package/dist/cache/invalidation.d.ts +156 -0
- package/dist/cache/invalidation.d.ts.map +1 -0
- package/dist/cache/kv-cache.d.ts +79 -0
- package/dist/cache/kv-cache.d.ts.map +1 -0
- package/dist/cache/memory-cache.d.ts +68 -0
- package/dist/cache/memory-cache.d.ts.map +1 -0
- package/dist/cloudforge/d1-adapter.d.ts +67 -0
- package/dist/cloudforge/d1-adapter.d.ts.map +1 -0
- package/dist/cloudforge/do-storage.d.ts +51 -0
- package/dist/cloudforge/do-storage.d.ts.map +1 -0
- package/dist/cloudforge/index.d.ts +4 -0
- package/dist/cloudforge/index.d.ts.map +1 -0
- package/dist/cloudforge/r2-backup.d.ts +38 -0
- package/dist/cloudforge/r2-backup.d.ts.map +1 -0
- package/dist/connection/index.d.ts +2 -0
- package/dist/connection/index.d.ts.map +1 -0
- package/dist/connection/manager.d.ts +54 -0
- package/dist/connection/manager.d.ts.map +1 -0
- package/dist/index.cjs +4762 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4701 -0
- package/dist/index.js.map +1 -0
- package/dist/migration/index.d.ts +4 -0
- package/dist/migration/index.d.ts.map +1 -0
- package/dist/migration/loader.d.ts +88 -0
- package/dist/migration/loader.d.ts.map +1 -0
- package/dist/migration/runner.d.ts +91 -0
- package/dist/migration/runner.d.ts.map +1 -0
- package/dist/migration/seeder.d.ts +95 -0
- package/dist/migration/seeder.d.ts.map +1 -0
- package/dist/query/builder.d.ts +47 -0
- package/dist/query/builder.d.ts.map +1 -0
- package/dist/query/index.d.ts +3 -0
- package/dist/query/index.d.ts.map +1 -0
- package/dist/query/raw.d.ts +92 -0
- package/dist/query/raw.d.ts.map +1 -0
- package/dist/tenant/context.d.ts +52 -0
- package/dist/tenant/context.d.ts.map +1 -0
- package/dist/tenant/index.d.ts +4 -0
- package/dist/tenant/index.d.ts.map +1 -0
- package/dist/tenant/query-wrapper.d.ts +96 -0
- package/dist/tenant/query-wrapper.d.ts.map +1 -0
- package/dist/tenant/schema-manager.d.ts +185 -0
- package/dist/tenant/schema-manager.d.ts.map +1 -0
- package/dist/transaction/index.d.ts +2 -0
- package/dist/transaction/index.d.ts.map +1 -0
- package/dist/transaction/transaction.d.ts +51 -0
- package/dist/transaction/transaction.d.ts.map +1 -0
- package/dist/types/cache.d.ts +214 -0
- package/dist/types/cache.d.ts.map +1 -0
- package/dist/types/cloudforge.d.ts +753 -0
- package/dist/types/cloudforge.d.ts.map +1 -0
- package/dist/types/connection.d.ts +91 -0
- package/dist/types/connection.d.ts.map +1 -0
- package/dist/types/index.d.ts +10 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/migration.d.ts +225 -0
- package/dist/types/migration.d.ts.map +1 -0
- package/dist/types/plugin.d.ts +432 -0
- package/dist/types/plugin.d.ts.map +1 -0
- package/dist/types/query-builder.d.ts +217 -0
- package/dist/types/query-builder.d.ts.map +1 -0
- package/dist/types/seed.d.ts +187 -0
- package/dist/types/seed.d.ts.map +1 -0
- package/dist/types/tenant.d.ts +140 -0
- package/dist/types/tenant.d.ts.map +1 -0
- package/dist/types/transaction.d.ts +144 -0
- package/dist/types/transaction.d.ts.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/migration/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { Migration, MigrationConfig, MigrationError } from '../types/migration.js';
|
|
3
|
+
/**
|
|
4
|
+
* Migration file loader
|
|
5
|
+
*
|
|
6
|
+
* Discovers and loads migration files from a directory,
|
|
7
|
+
* validates migration structure, and orders by version.
|
|
8
|
+
*
|
|
9
|
+
* Migration file format:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* export const version = 1;
|
|
12
|
+
* export const name = 'create_users_table';
|
|
13
|
+
*
|
|
14
|
+
* export async function up(context) {
|
|
15
|
+
* return context.execute('CREATE TABLE users (id INTEGER PRIMARY KEY)');
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* export async function down(context) {
|
|
19
|
+
* return context.execute('DROP TABLE users');
|
|
20
|
+
* }
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* Usage:
|
|
24
|
+
* ```typescript
|
|
25
|
+
* const loader = new MigrationLoader(config, logger);
|
|
26
|
+
* const result = await loader.loadMigrations();
|
|
27
|
+
* if (result.isOk()) {
|
|
28
|
+
* const migrations = result.unwrap();
|
|
29
|
+
* // migrations are ordered by version
|
|
30
|
+
* }
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export declare class MigrationLoader {
|
|
34
|
+
private readonly config;
|
|
35
|
+
private readonly logger;
|
|
36
|
+
private readonly filePattern;
|
|
37
|
+
constructor(config: MigrationConfig, logger: Logger);
|
|
38
|
+
/**
|
|
39
|
+
* Load all migrations from the configured directory
|
|
40
|
+
*
|
|
41
|
+
* @returns Result with array of migrations ordered by version
|
|
42
|
+
*/
|
|
43
|
+
loadMigrations(): Promise<Result<Migration[], MigrationError>>;
|
|
44
|
+
/**
|
|
45
|
+
* Load a single migration file
|
|
46
|
+
*
|
|
47
|
+
* @param filePath - Path to migration file
|
|
48
|
+
* @returns Result with Migration or MigrationError
|
|
49
|
+
*/
|
|
50
|
+
private loadMigrationFile;
|
|
51
|
+
/**
|
|
52
|
+
* Validate migration module structure
|
|
53
|
+
*
|
|
54
|
+
* @param module - Migration module
|
|
55
|
+
* @param filePath - File path for error messages
|
|
56
|
+
* @returns Result with void on success or MigrationError
|
|
57
|
+
*/
|
|
58
|
+
private validateMigration;
|
|
59
|
+
/**
|
|
60
|
+
* Find duplicate version numbers in migrations
|
|
61
|
+
*
|
|
62
|
+
* @param migrations - Array of migrations
|
|
63
|
+
* @returns Array of duplicate version numbers
|
|
64
|
+
*/
|
|
65
|
+
private findDuplicateVersions;
|
|
66
|
+
/**
|
|
67
|
+
* Generate unique migration ID from version and name
|
|
68
|
+
*
|
|
69
|
+
* @param version - Migration version
|
|
70
|
+
* @param name - Migration name
|
|
71
|
+
* @returns Migration ID
|
|
72
|
+
*/
|
|
73
|
+
private generateMigrationId;
|
|
74
|
+
/**
|
|
75
|
+
* Compute SHA-256 checksum of migration content
|
|
76
|
+
*
|
|
77
|
+
* @param content - Migration file content
|
|
78
|
+
* @returns Checksum string
|
|
79
|
+
*/
|
|
80
|
+
private computeChecksum;
|
|
81
|
+
/**
|
|
82
|
+
* Get SQL schema for migration tracking table
|
|
83
|
+
*
|
|
84
|
+
* @returns SQL CREATE TABLE statement
|
|
85
|
+
*/
|
|
86
|
+
getMigrationTableSchema(): string;
|
|
87
|
+
}
|
|
88
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/migration/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIvD,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EACf,cAAc,EACf,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;gBAEzB,MAAM,EAAE,eAAe,EAAE,MAAM,EAAE,MAAM;IAQnD;;;;OAIG;IACG,cAAc,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,cAAc,CAAC,CAAC;IA4DpE;;;;;OAKG;YACW,iBAAiB;IA8C/B;;;;;;OAMG;IACH,OAAO,CAAC,iBAAiB;IAqDzB;;;;;OAKG;IACH,OAAO,CAAC,qBAAqB;IAkB7B;;;;;;OAMG;IACH,OAAO,CAAC,mBAAmB;IAI3B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAIvB;;;;OAIG;IACH,uBAAuB,IAAI,MAAM;CAmBlC"}
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { MigrationLoader } from './loader.js';
|
|
3
|
+
import type { Migration, MigrationConfig, MigrationMetadata, MigrationError, MigrationRunner as IMigrationRunner } from '../types/migration.js';
|
|
4
|
+
/**
|
|
5
|
+
* Migration runner implementation
|
|
6
|
+
*
|
|
7
|
+
* Manages database migrations with version control, transaction support,
|
|
8
|
+
* and rollback capabilities. Tracks migration state in the database.
|
|
9
|
+
*
|
|
10
|
+
* Usage:
|
|
11
|
+
* ```typescript
|
|
12
|
+
* const runner = new MigrationRunner(connection, loader, config, logger);
|
|
13
|
+
*
|
|
14
|
+
* // Run all pending migrations
|
|
15
|
+
* const result = await runner.migrate();
|
|
16
|
+
*
|
|
17
|
+
* // Rollback last migration
|
|
18
|
+
* const rollbackResult = await runner.rollback();
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare class MigrationRunner implements IMigrationRunner {
|
|
22
|
+
private readonly connection;
|
|
23
|
+
private readonly loader;
|
|
24
|
+
readonly config: MigrationConfig;
|
|
25
|
+
private readonly logger;
|
|
26
|
+
constructor(connection: any, loader: MigrationLoader, config: MigrationConfig, logger: Logger);
|
|
27
|
+
/**
|
|
28
|
+
* Create migration table if it doesn't exist
|
|
29
|
+
*/
|
|
30
|
+
createMigrationTable(): Promise<Result<void, MigrationError>>;
|
|
31
|
+
/**
|
|
32
|
+
* Get all available migrations
|
|
33
|
+
*/
|
|
34
|
+
getMigrations(): Promise<Result<Migration[], MigrationError>>;
|
|
35
|
+
/**
|
|
36
|
+
* Get migration history from database
|
|
37
|
+
*/
|
|
38
|
+
getHistory(): Promise<Result<MigrationMetadata[], MigrationError>>;
|
|
39
|
+
/**
|
|
40
|
+
* Get pending migrations
|
|
41
|
+
*/
|
|
42
|
+
getPending(): Promise<Result<Migration[], MigrationError>>;
|
|
43
|
+
/**
|
|
44
|
+
* Run all pending migrations
|
|
45
|
+
*/
|
|
46
|
+
migrate(): Promise<Result<MigrationMetadata[], MigrationError>>;
|
|
47
|
+
/**
|
|
48
|
+
* Run migrations up to a specific version
|
|
49
|
+
*/
|
|
50
|
+
migrateTo(targetVersion: number): Promise<Result<MigrationMetadata[], MigrationError>>;
|
|
51
|
+
/**
|
|
52
|
+
* Rollback the last migration
|
|
53
|
+
*/
|
|
54
|
+
rollback(): Promise<Result<MigrationMetadata, MigrationError>>;
|
|
55
|
+
/**
|
|
56
|
+
* Rollback to a specific version
|
|
57
|
+
*/
|
|
58
|
+
rollbackTo(targetVersion: number): Promise<Result<MigrationMetadata[], MigrationError>>;
|
|
59
|
+
/**
|
|
60
|
+
* Reset database by rolling back all migrations
|
|
61
|
+
*/
|
|
62
|
+
reset(): Promise<Result<MigrationMetadata[], MigrationError>>;
|
|
63
|
+
/**
|
|
64
|
+
* Refresh database by resetting and re-running all migrations
|
|
65
|
+
*/
|
|
66
|
+
refresh(): Promise<Result<{
|
|
67
|
+
rolledBack: MigrationMetadata[];
|
|
68
|
+
applied: MigrationMetadata[];
|
|
69
|
+
}, MigrationError>>;
|
|
70
|
+
/**
|
|
71
|
+
* Get current migration version
|
|
72
|
+
*/
|
|
73
|
+
getCurrentVersion(): Promise<Result<number, MigrationError>>;
|
|
74
|
+
/**
|
|
75
|
+
* Validate migration checksums
|
|
76
|
+
*/
|
|
77
|
+
validateChecksums(): Promise<Result<boolean, MigrationError>>;
|
|
78
|
+
/**
|
|
79
|
+
* Load migration from file
|
|
80
|
+
*/
|
|
81
|
+
loadMigration(filePath: string): Promise<Result<Migration, MigrationError>>;
|
|
82
|
+
/**
|
|
83
|
+
* Run a single migration in a transaction
|
|
84
|
+
*/
|
|
85
|
+
private runMigration;
|
|
86
|
+
/**
|
|
87
|
+
* Update migration status in database
|
|
88
|
+
*/
|
|
89
|
+
private updateMigrationStatus;
|
|
90
|
+
}
|
|
91
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../../src/migration/runner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AACnD,OAAO,KAAK,EACV,SAAS,EACT,eAAe,EAEf,iBAAiB,EACjB,cAAc,EACd,eAAe,IAAI,gBAAgB,EACpC,MAAM,uBAAuB,CAAC;AAE/B;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,eAAgB,YAAW,gBAAgB;IACtD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAkB;IACzC,QAAQ,CAAC,MAAM,EAAE,eAAe,CAAC;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAG9B,UAAU,EAAE,GAAG,EACf,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,eAAe,EACvB,MAAM,EAAE,MAAM;IAQhB;;OAEG;IACG,oBAAoB,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,cAAc,CAAC,CAAC;IAyBnE;;OAEG;IACG,aAAa,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,cAAc,CAAC,CAAC;IAInE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,cAAc,CAAC,CAAC;IAoCxE;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,EAAE,cAAc,CAAC,CAAC;IAqChE;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,cAAc,CAAC,CAAC;IAwCrE;;OAEG;IACG,SAAS,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,cAAc,CAAC,CAAC;IAoD5F;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,cAAc,CAAC,CAAC;IAyDpE;;OAEG;IACG,UAAU,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,cAAc,CAAC,CAAC;IAoD7F;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,EAAE,cAAc,CAAC,CAAC;IAInE;;OAEG;IACG,OAAO,IAAI,OAAO,CACtB,MAAM,CAAC;QAAE,UAAU,EAAE,iBAAiB,EAAE,CAAC;QAAC,OAAO,EAAE,iBAAiB,EAAE,CAAA;KAAE,EAAE,cAAc,CAAC,CAC1F;IAkCD;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IA2BlE;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,cAAc,CAAC,CAAC;IAkDnE;;OAEG;IACG,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,CAAC;IAWjF;;OAEG;YACW,YAAY;IA8G1B;;OAEG;YACW,qBAAqB;CAqDpC"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { Seed, SeedConfig, SeedMetadata, SeedError, Seeder } from '../types/seed.js';
|
|
3
|
+
/**
|
|
4
|
+
* Data seeder implementation
|
|
5
|
+
*
|
|
6
|
+
* Manages database seeding with environment-specific support and idempotent execution.
|
|
7
|
+
* Seeds are executed only once per environment unless explicitly re-run.
|
|
8
|
+
*
|
|
9
|
+
* Usage:
|
|
10
|
+
* ```typescript
|
|
11
|
+
* const seeder = new DataSeeder(connection, config, logger);
|
|
12
|
+
*
|
|
13
|
+
* // Run all pending seeds
|
|
14
|
+
* const result = await seeder.seed();
|
|
15
|
+
*
|
|
16
|
+
* // Reset all seeds
|
|
17
|
+
* const resetResult = await seeder.reset();
|
|
18
|
+
* ```
|
|
19
|
+
*/
|
|
20
|
+
export declare class DataSeeder implements Seeder {
|
|
21
|
+
private readonly connection;
|
|
22
|
+
readonly config: SeedConfig;
|
|
23
|
+
private readonly logger;
|
|
24
|
+
private seedsCache;
|
|
25
|
+
constructor(connection: any, config: SeedConfig, logger: Logger);
|
|
26
|
+
/**
|
|
27
|
+
* Create seed table if it doesn't exist
|
|
28
|
+
*/
|
|
29
|
+
createSeedTable(): Promise<Result<void, SeedError>>;
|
|
30
|
+
/**
|
|
31
|
+
* Get all available seeds
|
|
32
|
+
*/
|
|
33
|
+
getSeeds(): Promise<Result<Seed[], SeedError>>;
|
|
34
|
+
/**
|
|
35
|
+
* Get seed history from database
|
|
36
|
+
*/
|
|
37
|
+
getHistory(): Promise<Result<SeedMetadata[], SeedError>>;
|
|
38
|
+
/**
|
|
39
|
+
* Get pending seeds for current environment
|
|
40
|
+
*/
|
|
41
|
+
getPending(): Promise<Result<Seed[], SeedError>>;
|
|
42
|
+
/**
|
|
43
|
+
* Run all pending seeds for current environment
|
|
44
|
+
*/
|
|
45
|
+
seed(): Promise<Result<SeedMetadata[], SeedError>>;
|
|
46
|
+
/**
|
|
47
|
+
* Run a specific seed by ID
|
|
48
|
+
*/
|
|
49
|
+
runSeed(seedId: string): Promise<Result<SeedMetadata, SeedError>>;
|
|
50
|
+
/**
|
|
51
|
+
* Reset all seeds (clear history)
|
|
52
|
+
*/
|
|
53
|
+
reset(): Promise<Result<void, SeedError>>;
|
|
54
|
+
/**
|
|
55
|
+
* Validate seed checksums
|
|
56
|
+
*/
|
|
57
|
+
validateChecksums(): Promise<Result<boolean, SeedError>>;
|
|
58
|
+
/**
|
|
59
|
+
* Load seed from file
|
|
60
|
+
*/
|
|
61
|
+
loadSeed(filePath: string): Promise<Result<Seed, SeedError>>;
|
|
62
|
+
/**
|
|
63
|
+
* Load seeds from directory
|
|
64
|
+
*/
|
|
65
|
+
private loadSeedsFromDirectory;
|
|
66
|
+
/**
|
|
67
|
+
* Load a single seed file
|
|
68
|
+
*/
|
|
69
|
+
private loadSeedFile;
|
|
70
|
+
/**
|
|
71
|
+
* Validate seed module structure
|
|
72
|
+
*/
|
|
73
|
+
private validateSeed;
|
|
74
|
+
/**
|
|
75
|
+
* Check if seed matches current environment
|
|
76
|
+
*/
|
|
77
|
+
private matchesEnvironment;
|
|
78
|
+
/**
|
|
79
|
+
* Execute a single seed
|
|
80
|
+
*/
|
|
81
|
+
private executeSeed;
|
|
82
|
+
/**
|
|
83
|
+
* Update seed status in database
|
|
84
|
+
*/
|
|
85
|
+
private updateSeedStatus;
|
|
86
|
+
/**
|
|
87
|
+
* Compute SHA-256 checksum of seed content
|
|
88
|
+
*/
|
|
89
|
+
private computeChecksum;
|
|
90
|
+
/**
|
|
91
|
+
* Get SQL schema for seed tracking table
|
|
92
|
+
*/
|
|
93
|
+
private getSeedTableSchema;
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=seeder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"seeder.d.ts","sourceRoot":"","sources":["../../src/migration/seeder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAIvD,OAAO,KAAK,EACV,IAAI,EACJ,UAAU,EAEV,YAAY,EACZ,SAAS,EACT,MAAM,EAEP,MAAM,kBAAkB,CAAC;AAE1B;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,UAAW,YAAW,MAAM;IACvC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAM;IACjC,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,UAAU,CAAuB;gBAE7B,UAAU,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM;IAM/D;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAyBzD;;OAEG;IACG,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;IAIpD;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC;IAoC9D;;OAEG;IACG,UAAU,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,SAAS,CAAC,CAAC;IAwCtD;;OAEG;IACG,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,EAAE,SAAS,CAAC,CAAC;IAwCxD;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;IA+BvE;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAyB/C;;OAEG;IACG,iBAAiB,IAAI,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,SAAS,CAAC,CAAC;IAkD9D;;OAEG;IACG,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAIlE;;OAEG;YACW,sBAAsB;IA8DpC;;OAEG;YACW,YAAY;IA0C1B;;OAEG;IACH,OAAO,CAAC,YAAY;IAoCpB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IAU1B;;OAEG;YACW,WAAW;IAyFzB;;OAEG;YACW,gBAAgB;IAkD9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,kBAAkB;CAmB3B"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { QueryBuilder as IQueryBuilder, QueryBuilderError, WhereOperator, JoinType, OrderDirection } from '../types/query-builder.js';
|
|
3
|
+
/**
|
|
4
|
+
* Type-safe query builder wrapper for gl-life-data
|
|
5
|
+
*
|
|
6
|
+
* Wraps gl-life-data QueryBuilder with:
|
|
7
|
+
* - Type safety using TypeScript generics
|
|
8
|
+
* - Result<T, E> pattern for error handling
|
|
9
|
+
* - Fluent chainable API
|
|
10
|
+
* - Complex joins, aggregations, subqueries support
|
|
11
|
+
*/
|
|
12
|
+
export declare class TypeSafeQueryBuilder<T = unknown> implements IQueryBuilder<T> {
|
|
13
|
+
private tableName;
|
|
14
|
+
private metaDataService;
|
|
15
|
+
private logger;
|
|
16
|
+
private selectedColumns;
|
|
17
|
+
private whereConditions;
|
|
18
|
+
private joinClauses;
|
|
19
|
+
private orderByClauses;
|
|
20
|
+
private groupByFields;
|
|
21
|
+
private havingCondition;
|
|
22
|
+
private limitValue;
|
|
23
|
+
private offsetValue;
|
|
24
|
+
constructor(tableName: string, metaDataService: any, logger: Logger);
|
|
25
|
+
table(table: string): IQueryBuilder<T>;
|
|
26
|
+
select(...columns: string[]): IQueryBuilder<T>;
|
|
27
|
+
where(field: string, operator: WhereOperator, value?: unknown): IQueryBuilder<T>;
|
|
28
|
+
orWhere(field: string, operator: WhereOperator, value?: unknown): IQueryBuilder<T>;
|
|
29
|
+
whereIn(field: string, values: unknown[]): IQueryBuilder<T>;
|
|
30
|
+
join(table: string, leftField: string, rightField: string, type?: JoinType): IQueryBuilder<T>;
|
|
31
|
+
orderBy(field: string, direction?: OrderDirection): IQueryBuilder<T>;
|
|
32
|
+
groupBy(...fields: string[]): IQueryBuilder<T>;
|
|
33
|
+
having(condition: string): IQueryBuilder<T>;
|
|
34
|
+
limit(limit: number): IQueryBuilder<T>;
|
|
35
|
+
offset(offset: number): IQueryBuilder<T>;
|
|
36
|
+
insert(data: Partial<T>): Promise<Result<T, QueryBuilderError>>;
|
|
37
|
+
insertMany(data: Partial<T>[]): Promise<Result<T[], QueryBuilderError>>;
|
|
38
|
+
update(data: Partial<T>): Promise<Result<number, QueryBuilderError>>;
|
|
39
|
+
delete(): Promise<Result<number, QueryBuilderError>>;
|
|
40
|
+
first(): Promise<Result<T | null, QueryBuilderError>>;
|
|
41
|
+
get(): Promise<Result<T[], QueryBuilderError>>;
|
|
42
|
+
count(field?: string): Promise<Result<number, QueryBuilderError>>;
|
|
43
|
+
toSQL(): string;
|
|
44
|
+
getBindings(): unknown[];
|
|
45
|
+
clone(): IQueryBuilder<T>;
|
|
46
|
+
}
|
|
47
|
+
//# sourceMappingURL=builder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"builder.d.ts","sourceRoot":"","sources":["../../src/query/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/query/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { DatabaseConnection, DatabaseConnectionError } from '../types/connection.js';
|
|
3
|
+
/**
|
|
4
|
+
* Raw SQL execution error types
|
|
5
|
+
*/
|
|
6
|
+
export type RawSQLError = {
|
|
7
|
+
type: 'INVALID_SQL';
|
|
8
|
+
message: string;
|
|
9
|
+
} | {
|
|
10
|
+
type: 'PARAMETER_MISMATCH';
|
|
11
|
+
message: string;
|
|
12
|
+
} | {
|
|
13
|
+
type: 'EXECUTION_FAILED';
|
|
14
|
+
message: string;
|
|
15
|
+
cause?: unknown;
|
|
16
|
+
} | {
|
|
17
|
+
type: 'VALIDATION_FAILED';
|
|
18
|
+
message: string;
|
|
19
|
+
} | DatabaseConnectionError;
|
|
20
|
+
/**
|
|
21
|
+
* Query with parameters for batch execution
|
|
22
|
+
*/
|
|
23
|
+
export interface SQLQuery {
|
|
24
|
+
sql: string;
|
|
25
|
+
params?: unknown[];
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Execution options
|
|
29
|
+
*/
|
|
30
|
+
export interface ExecutionOptions {
|
|
31
|
+
transaction?: boolean;
|
|
32
|
+
timeout?: number;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Raw SQL Executor
|
|
36
|
+
*
|
|
37
|
+
* Provides safe raw SQL execution with:
|
|
38
|
+
* - Parameterized queries to prevent SQL injection
|
|
39
|
+
* - Result type mapping
|
|
40
|
+
* - Query validation
|
|
41
|
+
* - Batch execution support
|
|
42
|
+
* - Error handling with Result pattern
|
|
43
|
+
*/
|
|
44
|
+
export declare class RawSQLExecutor {
|
|
45
|
+
private readonly connection;
|
|
46
|
+
private readonly logger;
|
|
47
|
+
constructor(connection: DatabaseConnection, logger: Logger);
|
|
48
|
+
/**
|
|
49
|
+
* Execute a raw SQL query with parameters
|
|
50
|
+
*
|
|
51
|
+
* Uses parameterized queries to prevent SQL injection.
|
|
52
|
+
* All parameter values are properly escaped by the database driver.
|
|
53
|
+
*
|
|
54
|
+
* @param sql - SQL query string with ? placeholders
|
|
55
|
+
* @param params - Parameter values to bind to placeholders
|
|
56
|
+
* @param options - Execution options
|
|
57
|
+
* @returns Result containing array of rows or error
|
|
58
|
+
*/
|
|
59
|
+
execute<T = unknown>(sql: string, params?: unknown[], options?: ExecutionOptions): Promise<Result<T[], RawSQLError>>;
|
|
60
|
+
/**
|
|
61
|
+
* Execute a query and return the first row or null
|
|
62
|
+
*
|
|
63
|
+
* @param sql - SQL query string
|
|
64
|
+
* @param params - Parameter values
|
|
65
|
+
* @param options - Execution options
|
|
66
|
+
* @returns Result containing single row or null
|
|
67
|
+
*/
|
|
68
|
+
executeOne<T = unknown>(sql: string, params?: unknown[], options?: ExecutionOptions): Promise<Result<T | null, RawSQLError>>;
|
|
69
|
+
/**
|
|
70
|
+
* Execute multiple queries in batch
|
|
71
|
+
*
|
|
72
|
+
* All queries execute sequentially. If any query fails, execution stops
|
|
73
|
+
* and an error is returned.
|
|
74
|
+
*
|
|
75
|
+
* @param queries - Array of SQL queries with parameters
|
|
76
|
+
* @returns Result containing array of results or error
|
|
77
|
+
*/
|
|
78
|
+
executeBatch<T = unknown>(queries: SQLQuery[]): Promise<Result<T[][], RawSQLError>>;
|
|
79
|
+
/**
|
|
80
|
+
* Validate SQL query and parameters
|
|
81
|
+
*
|
|
82
|
+
* Checks for:
|
|
83
|
+
* - Empty/whitespace-only queries
|
|
84
|
+
* - Parameter count matching placeholder count
|
|
85
|
+
*
|
|
86
|
+
* @param sql - SQL query string
|
|
87
|
+
* @param params - Parameter values
|
|
88
|
+
* @returns Result indicating validation success or error
|
|
89
|
+
*/
|
|
90
|
+
private validateSQL;
|
|
91
|
+
}
|
|
92
|
+
//# sourceMappingURL=raw.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"raw.d.ts","sourceRoot":"","sources":["../../src/query/raw.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,kBAAkB,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAE1F;;GAEG;AACH,MAAM,MAAM,WAAW,GACnB;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACxC;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC/C;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,mBAAmB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC9C,uBAAuB,CAAC;AAE5B;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;GASG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAqB;IAChD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;gBAEpB,UAAU,EAAE,kBAAkB,EAAE,MAAM,EAAE,MAAM;IAK1D;;;;;;;;;;OAUG;IACG,OAAO,CAAC,CAAC,GAAG,OAAO,EACvB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;IAyDpC;;;;;;;OAOG;IACG,UAAU,CAAC,CAAC,GAAG,OAAO,EAC1B,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,EACtB,OAAO,CAAC,EAAE,gBAAgB,GACzB,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAC;IAWzC;;;;;;;;OAQG;IACG,YAAY,CAAC,CAAC,GAAG,OAAO,EAC5B,OAAO,EAAE,QAAQ,EAAE,GAClB,OAAO,CAAC,MAAM,CAAC,CAAC,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;IAsCtC;;;;;;;;;;OAUG;IACH,OAAO,CAAC,WAAW;CAsBpB"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { Option, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { TenantContext, TenantMetadata, TenantContextConfig } from '../types/tenant.js';
|
|
3
|
+
/**
|
|
4
|
+
* Tenant Context Manager
|
|
5
|
+
*
|
|
6
|
+
* Manages multi-tenancy context using AsyncLocalStorage for request isolation.
|
|
7
|
+
* Supports multiple isolation strategies: DATABASE, SCHEMA, ROW, and HYBRID.
|
|
8
|
+
*
|
|
9
|
+
* Features:
|
|
10
|
+
* - AsyncLocalStorage for context isolation (Cloudflare Workers compatible)
|
|
11
|
+
* - Multiple isolation strategies
|
|
12
|
+
* - Automatic SQL query modification for tenant isolation
|
|
13
|
+
* - Tenant validation
|
|
14
|
+
* - Scoped execution with withTenant()
|
|
15
|
+
*/
|
|
16
|
+
export declare class TenantContextManager implements TenantContext {
|
|
17
|
+
private readonly storage;
|
|
18
|
+
private readonly _config;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
private currentTenant;
|
|
21
|
+
constructor(config: TenantContextConfig, logger: Logger);
|
|
22
|
+
get tenant(): Option<TenantMetadata>;
|
|
23
|
+
get config(): TenantContextConfig;
|
|
24
|
+
get hasTenant(): boolean;
|
|
25
|
+
setTenant(tenantId: string): Promise<void>;
|
|
26
|
+
setTenantWithMetadata(metadata: TenantMetadata): Promise<void>;
|
|
27
|
+
clearTenant(): Promise<void>;
|
|
28
|
+
getTenantId(): Option<string>;
|
|
29
|
+
getTenant(): Option<TenantMetadata>;
|
|
30
|
+
shouldIsolateTable(table: string): boolean;
|
|
31
|
+
applyTenantIsolation(sql: string, params?: unknown[]): {
|
|
32
|
+
sql: string;
|
|
33
|
+
params: unknown[];
|
|
34
|
+
};
|
|
35
|
+
getTenantDatabase(): Option<string>;
|
|
36
|
+
getTenantSchema(): Option<string>;
|
|
37
|
+
withTenant<T>(tenantId: string, callback: () => Promise<T>): Promise<T>;
|
|
38
|
+
clone(): TenantContext;
|
|
39
|
+
/**
|
|
40
|
+
* Validate tenant ID format
|
|
41
|
+
*/
|
|
42
|
+
private validateTenantId;
|
|
43
|
+
/**
|
|
44
|
+
* Apply ROW-level tenant isolation to SQL query
|
|
45
|
+
*/
|
|
46
|
+
private applyRowLevelIsolation;
|
|
47
|
+
/**
|
|
48
|
+
* Apply SCHEMA-level tenant isolation to SQL query
|
|
49
|
+
*/
|
|
50
|
+
private applySchemaIsolation;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/tenant/context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EACV,aAAa,EACb,cAAc,EACd,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAS5B;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAqB,YAAW,aAAa;IACxD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwC;IAChE,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAsB;IAC9C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,aAAa,CAA+B;gBAExC,MAAM,EAAE,mBAAmB,EAAE,MAAM,EAAE,MAAM;IAMvD,IAAI,MAAM,IAAI,MAAM,CAAC,cAAc,CAAC,CAEnC;IAED,IAAI,MAAM,IAAI,mBAAmB,CAEhC;IAED,IAAI,SAAS,IAAI,OAAO,CAEvB;IAEK,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiB1C,qBAAqB,CAAC,QAAQ,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IAW9D,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC;IAKlC,WAAW,IAAI,MAAM,CAAC,MAAM,CAAC;IAO7B,SAAS,IAAI,MAAM,CAAC,cAAc,CAAC;IAOnC,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO;IAc1C,oBAAoB,CAClB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,OAAO,EAAO,GACrB;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,EAAE,CAAA;KAAE;IA0CrC,iBAAiB,IAAI,MAAM,CAAC,MAAM,CAAC;IAiBnC,eAAe,IAAI,MAAM,CAAC,MAAM,CAAC;IAiB3B,UAAU,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;IAsB7E,KAAK,IAAI,aAAa;IAItB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAexB;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAiE9B;;OAEG;IACH,OAAO,CAAC,oBAAoB;CA2B7B"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tenant/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,oBAAoB,CAAC;AACnC,cAAc,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { Result, Logger } from '@gl-life/gl-life-core';
|
|
2
|
+
import type { QueryBuilder, QueryBuilderError, WhereOperator, JoinType, OrderDirection } from '../types/query-builder.js';
|
|
3
|
+
import type { TenantContext } from '../types/tenant.js';
|
|
4
|
+
/**
|
|
5
|
+
* Tenant-Aware Query Builder
|
|
6
|
+
*
|
|
7
|
+
* Wraps a QueryBuilder to automatically inject tenant filters and prevent
|
|
8
|
+
* cross-tenant data access. Provides:
|
|
9
|
+
* - Automatic tenant_id filter injection for all queries
|
|
10
|
+
* - Cross-tenant access prevention
|
|
11
|
+
* - Admin override mechanism via asAdmin()
|
|
12
|
+
* - Tenant filter enforcement (cannot be accidentally removed)
|
|
13
|
+
* - Support for excluded tables (migrations, system tables)
|
|
14
|
+
*
|
|
15
|
+
* Security:
|
|
16
|
+
* - All queries automatically scoped to current tenant
|
|
17
|
+
* - Tenant context validated before query execution
|
|
18
|
+
* - Manual tenant_id in WHERE clauses are overridden
|
|
19
|
+
* - INSERT operations always use current tenant_id
|
|
20
|
+
*
|
|
21
|
+
* Usage:
|
|
22
|
+
* ```typescript
|
|
23
|
+
* const builder = new TenantAwareQueryBuilder(baseBuilder, tenantContext, logger);
|
|
24
|
+
*
|
|
25
|
+
* // Normal tenant-scoped query
|
|
26
|
+
* const users = await builder.select('id', 'name').get();
|
|
27
|
+
*
|
|
28
|
+
* // Admin query (bypasses tenant filter)
|
|
29
|
+
* const allUsers = await builder.asAdmin().select('id', 'name').get();
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export declare class TenantAwareQueryBuilder<T = unknown> implements QueryBuilder<T> {
|
|
33
|
+
private readonly baseBuilder;
|
|
34
|
+
private readonly tenantContext;
|
|
35
|
+
private readonly logger;
|
|
36
|
+
private isAdminMode;
|
|
37
|
+
constructor(baseBuilder: QueryBuilder<T>, tenantContext: TenantContext, logger: Logger);
|
|
38
|
+
/**
|
|
39
|
+
* Switch to admin mode - bypasses tenant filtering
|
|
40
|
+
*
|
|
41
|
+
* Use with caution! Only for administrative queries that need
|
|
42
|
+
* to access data across all tenants.
|
|
43
|
+
*
|
|
44
|
+
* @returns QueryBuilder in admin mode
|
|
45
|
+
*/
|
|
46
|
+
asAdmin(): TenantAwareQueryBuilder<T>;
|
|
47
|
+
/**
|
|
48
|
+
* Switch back to tenant mode from admin mode
|
|
49
|
+
*
|
|
50
|
+
* Re-enables automatic tenant filtering
|
|
51
|
+
*
|
|
52
|
+
* @returns QueryBuilder in tenant mode
|
|
53
|
+
*/
|
|
54
|
+
asTenant(): TenantAwareQueryBuilder<T>;
|
|
55
|
+
/**
|
|
56
|
+
* Validate that tenant context is set (unless admin mode or excluded table)
|
|
57
|
+
*/
|
|
58
|
+
private validateTenantContext;
|
|
59
|
+
/**
|
|
60
|
+
* Get table name from base builder
|
|
61
|
+
*/
|
|
62
|
+
private getTableName;
|
|
63
|
+
/**
|
|
64
|
+
* Inject tenant filter into query builder
|
|
65
|
+
*
|
|
66
|
+
* This method ensures the correct tenant filter is present.
|
|
67
|
+
* If a manual tenant_id filter exists, it will be overridden.
|
|
68
|
+
*/
|
|
69
|
+
private injectTenantFilter;
|
|
70
|
+
/**
|
|
71
|
+
* Override tenant_id in data object for INSERT operations
|
|
72
|
+
*/
|
|
73
|
+
private enforceTenantInData;
|
|
74
|
+
table(table: string): QueryBuilder<T>;
|
|
75
|
+
select(...columns: string[]): QueryBuilder<T>;
|
|
76
|
+
where(field: string, operator: WhereOperator, value?: unknown): QueryBuilder<T>;
|
|
77
|
+
orWhere(field: string, operator: WhereOperator, value?: unknown): QueryBuilder<T>;
|
|
78
|
+
whereIn(field: string, values: unknown[]): QueryBuilder<T>;
|
|
79
|
+
join(table: string, leftField: string, rightField: string, type?: JoinType): QueryBuilder<T>;
|
|
80
|
+
orderBy(field: string, direction?: OrderDirection): QueryBuilder<T>;
|
|
81
|
+
groupBy(...fields: string[]): QueryBuilder<T>;
|
|
82
|
+
having(condition: string): QueryBuilder<T>;
|
|
83
|
+
limit(limit: number): QueryBuilder<T>;
|
|
84
|
+
offset(offset: number): QueryBuilder<T>;
|
|
85
|
+
insert(data: Partial<T>): Promise<Result<T, QueryBuilderError>>;
|
|
86
|
+
insertMany(data: Partial<T>[]): Promise<Result<T[], QueryBuilderError>>;
|
|
87
|
+
update(data: Partial<T>): Promise<Result<number, QueryBuilderError>>;
|
|
88
|
+
delete(): Promise<Result<number, QueryBuilderError>>;
|
|
89
|
+
first(): Promise<Result<T | null, QueryBuilderError>>;
|
|
90
|
+
get(): Promise<Result<T[], QueryBuilderError>>;
|
|
91
|
+
count(field?: string): Promise<Result<number, QueryBuilderError>>;
|
|
92
|
+
toSQL(): string;
|
|
93
|
+
getBindings(): unknown[];
|
|
94
|
+
clone(): QueryBuilder<T>;
|
|
95
|
+
}
|
|
96
|
+
//# sourceMappingURL=query-wrapper.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"query-wrapper.d.ts","sourceRoot":"","sources":["../../src/tenant/query-wrapper.ts"],"names":[],"mappings":"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"}
|