@danceroutine/tango-orm 0.1.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.
Files changed (74) hide show
  1. package/dist/PostgresAdapter-DCF8T4vh.js +3 -0
  2. package/dist/PostgresAdapter-_X36-mLL.js +73 -0
  3. package/dist/PostgresAdapter-_X36-mLL.js.map +1 -0
  4. package/dist/QuerySet-BzR5QzGi.js +411 -0
  5. package/dist/QuerySet-BzR5QzGi.js.map +1 -0
  6. package/dist/SqliteAdapter-CBnxCznk.js +3 -0
  7. package/dist/SqliteAdapter-J03fEjmr.js +70 -0
  8. package/dist/SqliteAdapter-J03fEjmr.js.map +1 -0
  9. package/dist/chunk-DLY2FNSh.js +12 -0
  10. package/dist/connection/adapters/Adapter.d.ts +20 -0
  11. package/dist/connection/adapters/AdapterRegistry.d.ts +17 -0
  12. package/dist/connection/adapters/dialects/PostgresAdapter.d.ts +22 -0
  13. package/dist/connection/adapters/dialects/SqliteAdapter.d.ts +14 -0
  14. package/dist/connection/adapters/dialects/index.d.ts +5 -0
  15. package/dist/connection/adapters/index.d.ts +8 -0
  16. package/dist/connection/clients/DBClient.d.ts +9 -0
  17. package/dist/connection/clients/DBClient.js +1 -0
  18. package/dist/connection/clients/dialects/PostgresClient.d.ts +17 -0
  19. package/dist/connection/clients/dialects/PostgresClient.js +32 -0
  20. package/dist/connection/clients/dialects/SqliteClient.d.ts +17 -0
  21. package/dist/connection/clients/dialects/SqliteClient.js +44 -0
  22. package/dist/connection/clients/dialects/index.d.ts +5 -0
  23. package/dist/connection/clients/index.d.ts +7 -0
  24. package/dist/connection/index.d.ts +11 -0
  25. package/dist/connection/index.js +5 -0
  26. package/dist/connection-DytAsjC9.js +102 -0
  27. package/dist/connection-DytAsjC9.js.map +1 -0
  28. package/dist/index.d.ts +18 -0
  29. package/dist/index.js +9 -0
  30. package/dist/query/QBuilder.d.ts +11 -0
  31. package/dist/query/QuerySet.d.ts +64 -0
  32. package/dist/query/QuerySet.js +108 -0
  33. package/dist/query/compiler/QueryCompiler.d.ts +20 -0
  34. package/dist/query/compiler/QueryCompiler.js +183 -0
  35. package/dist/query/compiler/index.d.ts +4 -0
  36. package/dist/query/domain/CompiledQuery.d.ts +4 -0
  37. package/dist/query/domain/CompiledQuery.js +1 -0
  38. package/dist/query/domain/Dialect.d.ts +2 -0
  39. package/dist/query/domain/Direction.d.ts +2 -0
  40. package/dist/query/domain/FilterInput.d.ts +3 -0
  41. package/dist/query/domain/FilterKey.d.ts +2 -0
  42. package/dist/query/domain/FilterValue.d.ts +1 -0
  43. package/dist/query/domain/LookupType.d.ts +2 -0
  44. package/dist/query/domain/OrderSpec.d.ts +5 -0
  45. package/dist/query/domain/OrderToken.d.ts +1 -0
  46. package/dist/query/domain/QNode.d.ts +9 -0
  47. package/dist/query/domain/QueryResult.d.ts +4 -0
  48. package/dist/query/domain/QuerySetState.d.ts +13 -0
  49. package/dist/query/domain/RelationMeta.d.ts +10 -0
  50. package/dist/query/domain/RepositoryMeta.d.ts +7 -0
  51. package/dist/query/domain/WhereClause.d.ts +4 -0
  52. package/dist/query/domain/WhereClause.js +1 -0
  53. package/dist/query/domain/index.d.ts +18 -0
  54. package/dist/query/domain/internal/InternalDialect.d.ts +4 -0
  55. package/dist/query/domain/internal/InternalDirection.d.ts +4 -0
  56. package/dist/query/domain/internal/InternalLookupType.d.ts +15 -0
  57. package/dist/query/domain/internal/InternalQNodeType.d.ts +6 -0
  58. package/dist/query/domain/internal/InternalRelationKind.d.ts +5 -0
  59. package/dist/query/index.d.ts +12 -0
  60. package/dist/query/index.js +4 -0
  61. package/dist/query-CQbvLeuh.js +21 -0
  62. package/dist/query-CQbvLeuh.js.map +1 -0
  63. package/dist/repository/Repository.d.ts +40 -0
  64. package/dist/repository/Repository.js +100 -0
  65. package/dist/repository/index.d.ts +4 -0
  66. package/dist/repository/index.js +4 -0
  67. package/dist/repository-DaRvsfjs.js +78 -0
  68. package/dist/repository-DaRvsfjs.js.map +1 -0
  69. package/dist/transaction/UnitOfWork.d.ts +31 -0
  70. package/dist/transaction/index.d.ts +4 -0
  71. package/dist/transaction/index.js +3 -0
  72. package/dist/transaction-DIGJnp19.js +50 -0
  73. package/dist/transaction-DIGJnp19.js.map +1 -0
  74. package/package.json +82 -0
@@ -0,0 +1,20 @@
1
+ import type { DBClient } from '../clients/DBClient';
2
+ export interface AdapterConfig {
3
+ url?: string;
4
+ host?: string;
5
+ port?: number;
6
+ database?: string;
7
+ user?: string;
8
+ password?: string;
9
+ filename?: string;
10
+ maxConnections?: number;
11
+ }
12
+ export interface Adapter {
13
+ name: string;
14
+ connect(config: AdapterConfig): Promise<DBClient>;
15
+ features: {
16
+ transactionalDDL: boolean;
17
+ concurrentIndex: boolean;
18
+ validateForeignKeys: boolean;
19
+ };
20
+ }
@@ -0,0 +1,17 @@
1
+ import type { Adapter, AdapterConfig } from './Adapter';
2
+ import type { DBClient } from '../clients/DBClient';
3
+ export declare class AdapterRegistry {
4
+ static readonly BRAND: "tango.orm.adapter_registry";
5
+ readonly __tangoBrand: typeof AdapterRegistry.BRAND;
6
+ private static defaultRegistryInstance;
7
+ private adapters;
8
+ static isAdapterRegistry(value: unknown): value is AdapterRegistry;
9
+ static getDefaultRegistry(): Promise<AdapterRegistry>;
10
+ register(adapter: Adapter): this;
11
+ get(name: string): Adapter;
12
+ has(name: string): boolean;
13
+ }
14
+ export declare function connectDB(config: AdapterConfig & {
15
+ adapter: string;
16
+ }, registry?: AdapterRegistry): Promise<DBClient>;
17
+ export declare function getDefaultAdapterRegistry(): Promise<AdapterRegistry>;
@@ -0,0 +1,22 @@
1
+ import type { Adapter, AdapterConfig } from '../Adapter';
2
+ import type { DBClient } from '../../clients/DBClient';
3
+ export declare class PostgresAdapter implements Adapter {
4
+ static readonly BRAND: "tango.orm.postgres_adapter";
5
+ readonly __tangoBrand: typeof PostgresAdapter.BRAND;
6
+ readonly name = "postgres";
7
+ static isPostgresAdapter(value: unknown): value is PostgresAdapter;
8
+ /**
9
+ * Declares capabilities of this database adapter.
10
+ * Used by the migration runner and query compiler to determine which
11
+ * SQL features can be safely used:
12
+ * - transactionalDDL: Postgres supports DDL inside transactions (safe rollback of schema changes)
13
+ * - concurrentIndex: Supports CREATE INDEX CONCURRENTLY (non-blocking index builds)
14
+ * - validateForeignKeys: Supports deferred FK validation via NOT VALID + VALIDATE CONSTRAINT
15
+ */
16
+ readonly features: {
17
+ transactionalDDL: boolean;
18
+ concurrentIndex: boolean;
19
+ validateForeignKeys: boolean;
20
+ };
21
+ connect(config: AdapterConfig): Promise<DBClient>;
22
+ }
@@ -0,0 +1,14 @@
1
+ import type { Adapter, AdapterConfig } from '../Adapter';
2
+ import type { DBClient } from '../../clients/DBClient';
3
+ export declare class SqliteAdapter implements Adapter {
4
+ static readonly BRAND: "tango.orm.sqlite_adapter";
5
+ readonly __tangoBrand: typeof SqliteAdapter.BRAND;
6
+ readonly name = "sqlite";
7
+ readonly features: {
8
+ transactionalDDL: boolean;
9
+ concurrentIndex: boolean;
10
+ validateForeignKeys: boolean;
11
+ };
12
+ static isSqliteAdapter(value: unknown): value is SqliteAdapter;
13
+ connect(config: AdapterConfig): Promise<DBClient>;
14
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Domain boundary barrel: centralizes this subdomain's public contract.
3
+ */
4
+ export { PostgresAdapter } from './PostgresAdapter';
5
+ export { SqliteAdapter } from './SqliteAdapter';
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Domain boundary barrel: exposes namespaced exports for Django-style drill-down
3
+ * imports and curated flat exports for TS-native ergonomics.
4
+ */
5
+ export * as dialects from './dialects/index';
6
+ export { AdapterRegistry, connectDB, getDefaultAdapterRegistry } from './AdapterRegistry';
7
+ export type { Adapter, AdapterConfig } from './Adapter';
8
+ export { PostgresAdapter, SqliteAdapter } from './dialects/index';
@@ -0,0 +1,9 @@
1
+ export interface DBClient {
2
+ query<T = unknown>(sql: string, params?: readonly unknown[]): Promise<{
3
+ rows: T[];
4
+ }>;
5
+ begin(): Promise<void>;
6
+ commit(): Promise<void>;
7
+ rollback(): Promise<void>;
8
+ close(): Promise<void>;
9
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,17 @@
1
+ import type pg from 'pg';
2
+ import type { DBClient } from '../DBClient';
3
+ export declare class PostgresClient implements DBClient {
4
+ private pool;
5
+ private client;
6
+ static readonly BRAND: "tango.orm.postgres_client";
7
+ readonly __tangoBrand: typeof PostgresClient.BRAND;
8
+ static isPostgresClient(value: unknown): value is PostgresClient;
9
+ constructor(pool: pg.Pool, client: pg.PoolClient);
10
+ query<T = unknown>(sql: string, params?: readonly unknown[]): Promise<{
11
+ rows: T[];
12
+ }>;
13
+ begin(): Promise<void>;
14
+ commit(): Promise<void>;
15
+ rollback(): Promise<void>;
16
+ close(): Promise<void>;
17
+ }
@@ -0,0 +1,32 @@
1
+ export class PostgresClient {
2
+ pool;
3
+ client;
4
+ static BRAND = 'tango.orm.postgres_client';
5
+ __tangoBrand = PostgresClient.BRAND;
6
+ static isPostgresClient(value) {
7
+ return (typeof value === 'object' &&
8
+ value !== null &&
9
+ value.__tangoBrand === PostgresClient.BRAND);
10
+ }
11
+ constructor(pool, client) {
12
+ this.pool = pool;
13
+ this.client = client;
14
+ }
15
+ async query(sql, params) {
16
+ const result = await this.client.query(sql, params);
17
+ return { rows: result.rows };
18
+ }
19
+ async begin() {
20
+ await this.client.query('BEGIN');
21
+ }
22
+ async commit() {
23
+ await this.client.query('COMMIT');
24
+ }
25
+ async rollback() {
26
+ await this.client.query('ROLLBACK');
27
+ }
28
+ async close() {
29
+ this.client.release();
30
+ await this.pool.end();
31
+ }
32
+ }
@@ -0,0 +1,17 @@
1
+ import type Database from 'better-sqlite3';
2
+ import type { DBClient } from '../DBClient';
3
+ export declare class SqliteClient implements DBClient {
4
+ private db;
5
+ static readonly BRAND: "tango.orm.sqlite_client";
6
+ readonly __tangoBrand: typeof SqliteClient.BRAND;
7
+ private inTransaction;
8
+ static isSqliteClient(value: unknown): value is SqliteClient;
9
+ constructor(db: Database.Database);
10
+ query<T = unknown>(sql: string, params?: readonly unknown[]): Promise<{
11
+ rows: T[];
12
+ }>;
13
+ begin(): Promise<void>;
14
+ commit(): Promise<void>;
15
+ rollback(): Promise<void>;
16
+ close(): Promise<void>;
17
+ }
@@ -0,0 +1,44 @@
1
+ export class SqliteClient {
2
+ db;
3
+ static BRAND = 'tango.orm.sqlite_client';
4
+ __tangoBrand = SqliteClient.BRAND;
5
+ inTransaction = false;
6
+ static isSqliteClient(value) {
7
+ return (typeof value === 'object' &&
8
+ value !== null &&
9
+ value.__tangoBrand === SqliteClient.BRAND);
10
+ }
11
+ constructor(db) {
12
+ this.db = db;
13
+ }
14
+ async query(sql, params) {
15
+ const stmt = this.db.prepare(sql);
16
+ if (/^\s*(SELECT|PRAGMA)/i.test(sql)) {
17
+ const rows = params ? stmt.all(...params) : stmt.all();
18
+ return { rows: rows };
19
+ }
20
+ params ? stmt.run(...params) : stmt.run();
21
+ return { rows: [] };
22
+ }
23
+ async begin() {
24
+ if (!this.inTransaction) {
25
+ this.db.prepare('BEGIN').run();
26
+ this.inTransaction = true;
27
+ }
28
+ }
29
+ async commit() {
30
+ if (this.inTransaction) {
31
+ this.db.prepare('COMMIT').run();
32
+ this.inTransaction = false;
33
+ }
34
+ }
35
+ async rollback() {
36
+ if (this.inTransaction) {
37
+ this.db.prepare('ROLLBACK').run();
38
+ this.inTransaction = false;
39
+ }
40
+ }
41
+ async close() {
42
+ this.db.close();
43
+ }
44
+ }
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Domain boundary barrel: centralizes this subdomain's public contract.
3
+ */
4
+ export { PostgresClient } from './PostgresClient';
5
+ export { SqliteClient } from './SqliteClient';
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Domain boundary barrel: exposes namespaced exports for Django-style drill-down
3
+ * imports and curated flat exports for TS-native ergonomics.
4
+ */
5
+ export * as dialects from './dialects/index';
6
+ export type { DBClient } from './DBClient';
7
+ export { PostgresClient, SqliteClient } from './dialects/index';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Domain boundary barrel: exposes namespaced exports for Django-style drill-down
3
+ * imports and curated flat exports for TS-native ergonomics.
4
+ */
5
+ export * as adapters from './adapters/index';
6
+ export * as clients from './clients/index';
7
+ export { AdapterRegistry, connectDB, getDefaultAdapterRegistry } from './adapters/index';
8
+ export type { Adapter, AdapterConfig } from './adapters/index';
9
+ export type { DBClient } from './clients/DBClient';
10
+ export { PostgresAdapter, SqliteAdapter } from './adapters/index';
11
+ export { PostgresClient, SqliteClient } from './clients/index';
@@ -0,0 +1,5 @@
1
+ import { PostgresAdapter, PostgresClient } from "../PostgresAdapter-_X36-mLL.js";
2
+ import { SqliteAdapter, SqliteClient } from "../SqliteAdapter-J03fEjmr.js";
3
+ import { AdapterRegistry, adapters_exports, clients_exports, connectDB, getDefaultAdapterRegistry } from "../connection-DytAsjC9.js";
4
+
5
+ export { AdapterRegistry, PostgresAdapter, PostgresClient, SqliteAdapter, SqliteClient, adapters_exports as adapters, clients_exports as clients, connectDB, getDefaultAdapterRegistry };
@@ -0,0 +1,102 @@
1
+ import { __export } from "./chunk-DLY2FNSh.js";
2
+ import { PostgresAdapter, PostgresClient } from "./PostgresAdapter-_X36-mLL.js";
3
+ import { SqliteAdapter, SqliteClient } from "./SqliteAdapter-J03fEjmr.js";
4
+
5
+ //#region src/connection/adapters/dialects/index.ts
6
+ var dialects_exports$1 = {};
7
+ __export(dialects_exports$1, {
8
+ PostgresAdapter: () => PostgresAdapter,
9
+ SqliteAdapter: () => SqliteAdapter
10
+ });
11
+
12
+ //#endregion
13
+ //#region src/connection/adapters/AdapterRegistry.ts
14
+ var AdapterRegistry = class AdapterRegistry {
15
+ static BRAND = "tango.orm.adapter_registry";
16
+ __tangoBrand = AdapterRegistry.BRAND;
17
+ static defaultRegistryInstance;
18
+ adapters = new Map();
19
+ static isAdapterRegistry(value) {
20
+ return typeof value === "object" && value !== null && value.__tangoBrand === AdapterRegistry.BRAND;
21
+ }
22
+ static async getDefaultRegistry() {
23
+ if (AdapterRegistry.defaultRegistryInstance) return AdapterRegistry.defaultRegistryInstance;
24
+ AdapterRegistry.defaultRegistryInstance = new AdapterRegistry();
25
+ const { PostgresAdapter: PostgresAdapter$1 } = await import("./PostgresAdapter-DCF8T4vh.js");
26
+ const { SqliteAdapter: SqliteAdapter$1 } = await import("./SqliteAdapter-CBnxCznk.js");
27
+ AdapterRegistry.defaultRegistryInstance.register(new PostgresAdapter$1());
28
+ AdapterRegistry.defaultRegistryInstance.register(new SqliteAdapter$1());
29
+ return AdapterRegistry.defaultRegistryInstance;
30
+ }
31
+ register(adapter) {
32
+ this.adapters.set(adapter.name, adapter);
33
+ return this;
34
+ }
35
+ get(name) {
36
+ const adapter = this.adapters.get(name);
37
+ if (!adapter) {
38
+ const available = [...this.adapters.keys()].join(", ");
39
+ throw new Error(`Unknown adapter: ${name}. Available adapters: ${available || "none"}`);
40
+ }
41
+ return adapter;
42
+ }
43
+ has(name) {
44
+ return this.adapters.has(name);
45
+ }
46
+ };
47
+ async function connectDB(config, registry) {
48
+ const effectiveRegistry = registry ?? await AdapterRegistry.getDefaultRegistry();
49
+ const adapter = effectiveRegistry.get(config.adapter);
50
+ return adapter.connect(config);
51
+ }
52
+ async function getDefaultAdapterRegistry() {
53
+ return AdapterRegistry.getDefaultRegistry();
54
+ }
55
+
56
+ //#endregion
57
+ //#region src/connection/adapters/index.ts
58
+ var adapters_exports = {};
59
+ __export(adapters_exports, {
60
+ AdapterRegistry: () => AdapterRegistry,
61
+ PostgresAdapter: () => PostgresAdapter,
62
+ SqliteAdapter: () => SqliteAdapter,
63
+ connectDB: () => connectDB,
64
+ dialects: () => dialects_exports$1,
65
+ getDefaultAdapterRegistry: () => getDefaultAdapterRegistry
66
+ });
67
+
68
+ //#endregion
69
+ //#region src/connection/clients/dialects/index.ts
70
+ var dialects_exports = {};
71
+ __export(dialects_exports, {
72
+ PostgresClient: () => PostgresClient,
73
+ SqliteClient: () => SqliteClient
74
+ });
75
+
76
+ //#endregion
77
+ //#region src/connection/clients/index.ts
78
+ var clients_exports = {};
79
+ __export(clients_exports, {
80
+ PostgresClient: () => PostgresClient,
81
+ SqliteClient: () => SqliteClient,
82
+ dialects: () => dialects_exports
83
+ });
84
+
85
+ //#endregion
86
+ //#region src/connection/index.ts
87
+ var connection_exports = {};
88
+ __export(connection_exports, {
89
+ AdapterRegistry: () => AdapterRegistry,
90
+ PostgresAdapter: () => PostgresAdapter,
91
+ PostgresClient: () => PostgresClient,
92
+ SqliteAdapter: () => SqliteAdapter,
93
+ SqliteClient: () => SqliteClient,
94
+ adapters: () => adapters_exports,
95
+ clients: () => clients_exports,
96
+ connectDB: () => connectDB,
97
+ getDefaultAdapterRegistry: () => getDefaultAdapterRegistry
98
+ });
99
+
100
+ //#endregion
101
+ export { AdapterRegistry, adapters_exports, clients_exports, connectDB, connection_exports, getDefaultAdapterRegistry };
102
+ //# sourceMappingURL=connection-DytAsjC9.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-DytAsjC9.js","names":["value: unknown","adapter: Adapter","name: string","config: AdapterConfig & { adapter: string }","registry?: AdapterRegistry"],"sources":["../src/connection/adapters/dialects/index.ts","../src/connection/adapters/AdapterRegistry.ts","../src/connection/adapters/index.ts","../src/connection/clients/dialects/index.ts","../src/connection/clients/index.ts","../src/connection/index.ts"],"sourcesContent":["/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { PostgresAdapter } from './PostgresAdapter';\nexport { SqliteAdapter } from './SqliteAdapter';\n","import type { Adapter, AdapterConfig } from './Adapter';\nimport type { DBClient } from '../clients/DBClient';\nexport class AdapterRegistry {\n static readonly BRAND = 'tango.orm.adapter_registry' as const;\n readonly __tangoBrand: typeof AdapterRegistry.BRAND = AdapterRegistry.BRAND;\n private static defaultRegistryInstance: AdapterRegistry | undefined;\n\n private adapters = new Map<string, Adapter>();\n\n static isAdapterRegistry(value: unknown): value is AdapterRegistry {\n return (\n typeof value === 'object' &&\n value !== null &&\n (value as { __tangoBrand?: unknown }).__tangoBrand === AdapterRegistry.BRAND\n );\n }\n\n static async getDefaultRegistry(): Promise<AdapterRegistry> {\n if (AdapterRegistry.defaultRegistryInstance) {\n return AdapterRegistry.defaultRegistryInstance;\n }\n\n AdapterRegistry.defaultRegistryInstance = new AdapterRegistry();\n\n const { PostgresAdapter } = await import('./dialects/PostgresAdapter');\n const { SqliteAdapter } = await import('./dialects/SqliteAdapter');\n\n AdapterRegistry.defaultRegistryInstance.register(new PostgresAdapter());\n AdapterRegistry.defaultRegistryInstance.register(new SqliteAdapter());\n\n return AdapterRegistry.defaultRegistryInstance;\n }\n\n register(adapter: Adapter): this {\n this.adapters.set(adapter.name, adapter);\n return this;\n }\n\n get(name: string): Adapter {\n const adapter = this.adapters.get(name);\n if (!adapter) {\n const available = [...this.adapters.keys()].join(', ');\n throw new Error(`Unknown adapter: ${name}. Available adapters: ${available || 'none'}`);\n }\n return adapter;\n }\n\n has(name: string): boolean {\n return this.adapters.has(name);\n }\n}\n\nexport async function connectDB(\n config: AdapterConfig & { adapter: string },\n registry?: AdapterRegistry\n): Promise<DBClient> {\n const effectiveRegistry = registry ?? (await AdapterRegistry.getDefaultRegistry());\n const adapter = effectiveRegistry.get(config.adapter);\n return adapter.connect(config);\n}\n\nexport async function getDefaultAdapterRegistry(): Promise<AdapterRegistry> {\n return AdapterRegistry.getDefaultRegistry();\n}\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as dialects from './dialects/index';\n\nexport { AdapterRegistry, connectDB, getDefaultAdapterRegistry } from './AdapterRegistry';\nexport type { Adapter, AdapterConfig } from './Adapter';\nexport { PostgresAdapter, SqliteAdapter } from './dialects/index';\n","/**\n * Domain boundary barrel: centralizes this subdomain's public contract.\n */\n\nexport { PostgresClient } from './PostgresClient';\nexport { SqliteClient } from './SqliteClient';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as dialects from './dialects/index';\n\nexport type { DBClient } from './DBClient';\nexport { PostgresClient, SqliteClient } from './dialects/index';\n","/**\n * Domain boundary barrel: exposes namespaced exports for Django-style drill-down\n * imports and curated flat exports for TS-native ergonomics.\n */\n\nexport * as adapters from './adapters/index';\nexport * as clients from './clients/index';\n\nexport { AdapterRegistry, connectDB, getDefaultAdapterRegistry } from './adapters/index';\nexport type { Adapter, AdapterConfig } from './adapters/index';\nexport type { DBClient } from './clients/DBClient';\nexport { PostgresAdapter, SqliteAdapter } from './adapters/index';\nexport { PostgresClient, SqliteClient } from './clients/index';\n"],"mappings":";;;;;;;;;;;;;ICEa,kBAAN,MAAM,gBAAgB;CACzB,OAAgB,QAAQ;CACxB,eAAsD,gBAAgB;CACtE,OAAe;CAEf,WAAmB,IAAI;CAEvB,OAAO,kBAAkBA,OAA0C;AAC/D,gBACW,UAAU,YACjB,UAAU,QACT,MAAqC,iBAAiB,gBAAgB;CAE9E;CAED,aAAa,qBAA+C;AACxD,MAAI,gBAAgB,wBAChB,QAAO,gBAAgB;AAG3B,kBAAgB,0BAA0B,IAAI;EAE9C,MAAM,EAAE,oCAAiB,GAAG,MAAM,OAAO;EACzC,MAAM,EAAE,gCAAe,GAAG,MAAM,OAAO;AAEvC,kBAAgB,wBAAwB,SAAS,IAAI,oBAAkB;AACvE,kBAAgB,wBAAwB,SAAS,IAAI,kBAAgB;AAErE,SAAO,gBAAgB;CAC1B;CAED,SAASC,SAAwB;AAC7B,OAAK,SAAS,IAAI,QAAQ,MAAM,QAAQ;AACxC,SAAO;CACV;CAED,IAAIC,MAAuB;EACvB,MAAM,UAAU,KAAK,SAAS,IAAI,KAAK;AACvC,OAAK,SAAS;GACV,MAAM,YAAY,CAAC,GAAG,KAAK,SAAS,MAAM,AAAC,EAAC,KAAK,KAAK;AACtD,SAAM,IAAI,OAAO,mBAAmB,KAAK,wBAAwB,aAAa,OAAO;EACxF;AACD,SAAO;CACV;CAED,IAAIA,MAAuB;AACvB,SAAO,KAAK,SAAS,IAAI,KAAK;CACjC;AACJ;AAEM,eAAe,UAClBC,QACAC,UACiB;CACjB,MAAM,oBAAoB,YAAa,MAAM,gBAAgB,oBAAoB;CACjF,MAAM,UAAU,kBAAkB,IAAI,OAAO,QAAQ;AACrD,QAAO,QAAQ,QAAQ,OAAO;AACjC;AAEM,eAAe,4BAAsD;AACxE,QAAO,gBAAgB,oBAAoB;AAC9C"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Bundled exports for Django users who are used to Django domain-drill-down imports
3
+ */
4
+ export * as connection from './connection/index';
5
+ export * as query from './query/index';
6
+ export * as repository from './repository/index';
7
+ export * as transaction from './transaction/index';
8
+ /**
9
+ * Unbundled exports for more TS native developers
10
+ */
11
+ export { AdapterRegistry, connectDB, getDefaultAdapterRegistry } from './connection/index';
12
+ export type { Adapter, AdapterConfig, DBClient } from './connection/index';
13
+ export { PostgresAdapter, SqliteAdapter } from './connection/index';
14
+ export { Q, QBuilder, QueryCompiler, QuerySet } from './query/index';
15
+ export type { RepositoryLike } from './query/index';
16
+ export type { CompiledQuery, Dialect, Direction, FilterInput, FilterKey, FilterValue, LookupType, OrderSpec, OrderToken, QNode, QueryResult, QuerySetState, RelationMeta, RepoMeta, WhereClause, } from './query/domain/index';
17
+ export { Repository } from './repository/index';
18
+ export { UnitOfWork } from './transaction/index';
package/dist/index.js ADDED
@@ -0,0 +1,9 @@
1
+ import { PostgresAdapter } from "./PostgresAdapter-_X36-mLL.js";
2
+ import { SqliteAdapter } from "./SqliteAdapter-J03fEjmr.js";
3
+ import { AdapterRegistry, connectDB, connection_exports, getDefaultAdapterRegistry } from "./connection-DytAsjC9.js";
4
+ import { QBuilder, QueryCompiler, QuerySet } from "./QuerySet-BzR5QzGi.js";
5
+ import { query_exports } from "./query-CQbvLeuh.js";
6
+ import { Repository, repository_exports } from "./repository-DaRvsfjs.js";
7
+ import { UnitOfWork, transaction_exports } from "./transaction-DIGJnp19.js";
8
+
9
+ export { AdapterRegistry, PostgresAdapter, QBuilder as Q, QBuilder, QueryCompiler, QuerySet, Repository, SqliteAdapter, UnitOfWork, connectDB, connection_exports as connection, getDefaultAdapterRegistry, query_exports as query, repository_exports as repository, transaction_exports as transaction };
@@ -0,0 +1,11 @@
1
+ import type { QNode } from './domain/QNode';
2
+ import type { FilterInput } from './domain/FilterInput';
3
+ export declare class QBuilder {
4
+ static readonly BRAND: "tango.orm.q_builder";
5
+ readonly __tangoBrand: typeof QBuilder.BRAND;
6
+ static isQBuilder(value: unknown): value is QBuilder;
7
+ static and<T>(...nodes: Array<FilterInput<T> | QNode<T>>): QNode<T>;
8
+ static or<T>(...nodes: Array<FilterInput<T> | QNode<T>>): QNode<T>;
9
+ static not<T>(node: FilterInput<T> | QNode<T>): QNode<T>;
10
+ private static wrapNode;
11
+ }
@@ -0,0 +1,64 @@
1
+ import type { DBClient } from '../connection/clients/DBClient';
2
+ import type { Dialect } from './domain/Dialect';
3
+ import type { QuerySetState } from './domain/QuerySetState';
4
+ import type { RepositoryMeta } from './domain/RepositoryMeta';
5
+ import type { QNode } from './domain/QNode';
6
+ import type { QueryResult } from './domain/QueryResult';
7
+ import type { OrderToken } from './domain/OrderToken';
8
+ import type { FilterInput } from './domain/FilterInput';
9
+ /**
10
+ * Interface for repository-like objects that can execute queries.
11
+ * Used internally by QuerySet to remain decoupled from specific repository implementations.
12
+ *
13
+ * @template T - The model type
14
+ */
15
+ export interface RepositoryLike<T> {
16
+ meta: RepositoryMeta;
17
+ client: DBClient;
18
+ dialect: Dialect;
19
+ run(compiled: {
20
+ sql: string;
21
+ params: readonly unknown[];
22
+ }): Promise<T[]>;
23
+ }
24
+ /**
25
+ * Django-inspired query builder for constructing and executing database queries.
26
+ * Provides a fluent API for filtering, ordering, pagination, and eager loading.
27
+ *
28
+ * @template T - The model type being queried
29
+ *
30
+ * @example
31
+ * ```typescript
32
+ * const users = await repository
33
+ * .query()
34
+ * .filter({ active: true })
35
+ * .filter(Q.or({ role: 'admin' }, { role: 'moderator' }))
36
+ * .orderBy('-createdAt')
37
+ * .limit(10)
38
+ * .fetchAll();
39
+ * ```
40
+ */
41
+ export declare class QuerySet<T extends Record<string, unknown>> {
42
+ private repo;
43
+ private state;
44
+ static readonly BRAND: "tango.orm.query_set";
45
+ readonly __tangoBrand: typeof QuerySet.BRAND;
46
+ static isQuerySet<T extends Record<string, unknown>>(value: unknown): value is QuerySet<T>;
47
+ constructor(repo: RepositoryLike<T>, state?: QuerySetState<T>);
48
+ filter(q: FilterInput<T> | QNode<T>): QuerySet<T>;
49
+ exclude(q: FilterInput<T> | QNode<T>): QuerySet<T>;
50
+ orderBy(...tokens: OrderToken<T>[]): QuerySet<T>;
51
+ limit(n: number): QuerySet<T>;
52
+ offset(n: number): QuerySet<T>;
53
+ select(cols: (keyof T)[]): QuerySet<T>;
54
+ selectRelated(...rels: string[]): QuerySet<T>;
55
+ prefetchRelated(...rels: string[]): QuerySet<T>;
56
+ fetch<Out = T>(shape?: ((r: T) => Out) | {
57
+ parse: (r: T) => Out;
58
+ }): Promise<QueryResult<Out>>;
59
+ fetchOne<Out = T>(shape?: ((r: T) => Out) | {
60
+ parse: (r: T) => Out;
61
+ }): Promise<Out | null>;
62
+ count(): Promise<number>;
63
+ exists(): Promise<boolean>;
64
+ }
@@ -0,0 +1,108 @@
1
+ import { InternalQNodeType } from './domain/internal/InternalQNodeType';
2
+ import { InternalDirection } from './domain/internal/InternalDirection';
3
+ import { QBuilder as Q } from './QBuilder';
4
+ import { QueryCompiler } from './compiler';
5
+ /**
6
+ * Django-inspired query builder for constructing and executing database queries.
7
+ * Provides a fluent API for filtering, ordering, pagination, and eager loading.
8
+ *
9
+ * @template T - The model type being queried
10
+ *
11
+ * @example
12
+ * ```typescript
13
+ * const users = await repository
14
+ * .query()
15
+ * .filter({ active: true })
16
+ * .filter(Q.or({ role: 'admin' }, { role: 'moderator' }))
17
+ * .orderBy('-createdAt')
18
+ * .limit(10)
19
+ * .fetchAll();
20
+ * ```
21
+ */
22
+ export class QuerySet {
23
+ repo;
24
+ state;
25
+ static BRAND = 'tango.orm.query_set';
26
+ __tangoBrand = QuerySet.BRAND;
27
+ static isQuerySet(value) {
28
+ return (typeof value === 'object' &&
29
+ value !== null &&
30
+ value.__tangoBrand === QuerySet.BRAND);
31
+ }
32
+ constructor(repo, state = {}) {
33
+ this.repo = repo;
34
+ this.state = state;
35
+ }
36
+ filter(q) {
37
+ const wrapped = q.kind
38
+ ? q
39
+ : { kind: InternalQNodeType.ATOM, where: q };
40
+ const merged = this.state.q ? Q.and(this.state.q, wrapped) : wrapped;
41
+ return new QuerySet(this.repo, { ...this.state, q: merged });
42
+ }
43
+ exclude(q) {
44
+ const wrapped = q.kind
45
+ ? q
46
+ : { kind: InternalQNodeType.ATOM, where: q };
47
+ const excludes = [...(this.state.excludes ?? []), wrapped];
48
+ return new QuerySet(this.repo, { ...this.state, excludes });
49
+ }
50
+ orderBy(...tokens) {
51
+ const order = tokens.map((t) => {
52
+ const str = String(t);
53
+ if (str.startsWith('-')) {
54
+ return { by: str.slice(1), dir: InternalDirection.DESC };
55
+ }
56
+ return { by: t, dir: InternalDirection.ASC };
57
+ });
58
+ return new QuerySet(this.repo, { ...this.state, order });
59
+ }
60
+ limit(n) {
61
+ return new QuerySet(this.repo, { ...this.state, limit: n });
62
+ }
63
+ offset(n) {
64
+ return new QuerySet(this.repo, { ...this.state, offset: n });
65
+ }
66
+ select(cols) {
67
+ return new QuerySet(this.repo, { ...this.state, select: cols });
68
+ }
69
+ selectRelated(...rels) {
70
+ return new QuerySet(this.repo, { ...this.state, selectRelated: rels });
71
+ }
72
+ prefetchRelated(...rels) {
73
+ return new QuerySet(this.repo, { ...this.state, prefetchRelated: rels });
74
+ }
75
+ async fetch(shape) {
76
+ const compiler = new QueryCompiler(this.repo.meta, this.repo.dialect);
77
+ const compiled = compiler.compile(this.state);
78
+ const rows = await this.repo.run(compiled);
79
+ const results = !shape
80
+ ? rows
81
+ : typeof shape === 'function'
82
+ ? rows.map(shape)
83
+ : rows.map((r) => shape.parse(r));
84
+ return {
85
+ results,
86
+ nextCursor: null,
87
+ };
88
+ }
89
+ async fetchOne(shape) {
90
+ const limited = this.limit(1);
91
+ const result = await limited.fetch(shape);
92
+ return result.results[0] ?? null;
93
+ }
94
+ async count() {
95
+ const compiler = new QueryCompiler(this.repo.meta, this.repo.dialect);
96
+ const compiled = compiler.compile({
97
+ ...this.state,
98
+ select: ['COUNT(*) as count'],
99
+ });
100
+ const countQuery = compiled.sql.replace(/SELECT .+ FROM/, 'SELECT COUNT(*) as count FROM');
101
+ const rows = await this.repo.client.query(countQuery, compiled.params);
102
+ return Number(rows.rows[0]?.count ?? 0);
103
+ }
104
+ async exists() {
105
+ const count = await this.count();
106
+ return count > 0;
107
+ }
108
+ }
@@ -0,0 +1,20 @@
1
+ import type { QuerySetState } from '../domain/QuerySetState';
2
+ import type { RepositoryMeta } from '../domain/RepositoryMeta';
3
+ import type { CompiledQuery } from '../domain/CompiledQuery';
4
+ import type { Dialect } from '../domain/Dialect';
5
+ export declare class QueryCompiler {
6
+ private meta;
7
+ private dialect;
8
+ static readonly BRAND: "tango.orm.query_compiler";
9
+ readonly __tangoBrand: typeof QueryCompiler.BRAND;
10
+ static isQueryCompiler(value: unknown): value is QueryCompiler;
11
+ constructor(meta: RepositoryMeta, dialect?: Dialect);
12
+ compile<T>(state: QuerySetState<T>): CompiledQuery;
13
+ private compileQNode;
14
+ private compileAtom;
15
+ private compileAnd;
16
+ private compileOr;
17
+ private compileNot;
18
+ private lookupToSQL;
19
+ private normalizeParam;
20
+ }