@danceroutine/tango-orm 1.11.1 → 1.11.3

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 (131) hide show
  1. package/dist/Adapter-DKxAaL4l.d.ts +73 -0
  2. package/dist/DBClient-DuYcXolQ.d.ts +27 -0
  3. package/dist/{InternalDialect-ClSaUNso.js → InternalDialect-U3mwJjKA.js} +3 -4
  4. package/dist/InternalDialect-U3mwJjKA.js.map +1 -0
  5. package/dist/QuerySetState-CjyvAUBs.d.ts +1310 -0
  6. package/dist/SqliteAdapter-6oyUmoJf.js +279 -0
  7. package/dist/SqliteAdapter-6oyUmoJf.js.map +1 -0
  8. package/dist/chunk-8H4AJuhK.js +14 -0
  9. package/dist/connection/index.d.ts +4 -11
  10. package/dist/connection/index.js +3 -6
  11. package/dist/{connection-Dmhgx31M.js → connection-D-E6_Yf1.js} +28 -30
  12. package/dist/connection-D-E6_Yf1.js.map +1 -0
  13. package/dist/{defaultRuntime-DzqBQ9Hb.js → defaultRuntime-CdTX8cXm.js} +41 -35
  14. package/dist/defaultRuntime-CdTX8cXm.js.map +1 -0
  15. package/dist/index-B-aibguC.d.ts +226 -0
  16. package/dist/index-D9B6gKez.d.ts +70 -0
  17. package/dist/index-rjKca3U_.d.ts +31 -0
  18. package/dist/index-uuG57Y7C.d.ts +97 -0
  19. package/dist/index.d.ts +9 -22
  20. package/dist/index.js +9 -12
  21. package/dist/manager/index.d.ts +4 -12
  22. package/dist/manager/index.js +3 -9
  23. package/dist/{manager-DrDTiCAz.js → manager-CiYqAYpn.js} +7 -11
  24. package/dist/{manager-DrDTiCAz.js.map → manager-CiYqAYpn.js.map} +1 -1
  25. package/dist/query/index.d.ts +3 -14
  26. package/dist/query/index.js +2 -4
  27. package/dist/{query-DUZnBFhf.js → query-CP1UMIX6.js} +163 -121
  28. package/dist/query-CP1UMIX6.js.map +1 -0
  29. package/dist/registerModelObjects-C-MliIiM.d.ts +229 -0
  30. package/dist/{registerModelObjects-22ZJKoit.js → registerModelObjects-DZfZ20fa.js} +119 -69
  31. package/dist/registerModelObjects-DZfZ20fa.js.map +1 -0
  32. package/dist/runtime/index.d.ts +3 -15
  33. package/dist/runtime/index.js +15 -8
  34. package/dist/runtime/index.js.map +1 -0
  35. package/dist/transaction/index.d.ts +2 -6
  36. package/dist/transaction/index.js +2 -7
  37. package/dist/{transaction-ZhfDf-f8.js → transaction-2_2m7VUo.js} +26 -10
  38. package/dist/transaction-2_2m7VUo.js.map +1 -0
  39. package/package.json +7 -7
  40. package/dist/InternalDialect-ClSaUNso.js.map +0 -1
  41. package/dist/PostgresAdapter-CXKdKBG-.js +0 -4
  42. package/dist/PostgresAdapter-DySFW6vy.js +0 -128
  43. package/dist/PostgresAdapter-DySFW6vy.js.map +0 -1
  44. package/dist/SqliteAdapter-CDdOjRmW.js +0 -151
  45. package/dist/SqliteAdapter-CDdOjRmW.js.map +0 -1
  46. package/dist/SqliteAdapter-mjtXuVTg.js +0 -4
  47. package/dist/chunk-DLY2FNSh.js +0 -12
  48. package/dist/connection/adapters/Adapter.d.ts +0 -60
  49. package/dist/connection/adapters/AdapterRegistry.d.ts +0 -44
  50. package/dist/connection/adapters/dialects/PostgresAdapter.d.ts +0 -30
  51. package/dist/connection/adapters/dialects/SqliteAdapter.d.ts +0 -22
  52. package/dist/connection/adapters/dialects/index.d.ts +0 -5
  53. package/dist/connection/adapters/index.d.ts +0 -8
  54. package/dist/connection/clients/DBClient.d.ts +0 -23
  55. package/dist/connection/clients/dialects/PostgresClient.d.ts +0 -54
  56. package/dist/connection/clients/dialects/SqliteClient.d.ts +0 -54
  57. package/dist/connection/clients/dialects/index.d.ts +0 -5
  58. package/dist/connection/clients/index.d.ts +0 -7
  59. package/dist/connection-Dmhgx31M.js.map +0 -1
  60. package/dist/defaultRuntime-DzqBQ9Hb.js.map +0 -1
  61. package/dist/manager/ManagerLike.d.ts +0 -34
  62. package/dist/manager/ModelManager.d.ts +0 -106
  63. package/dist/manager/internal/MutationCompiler.d.ts +0 -23
  64. package/dist/manager/internal/RuntimeBoundClient.d.ts +0 -20
  65. package/dist/manager/registerModelObjects.d.ts +0 -5
  66. package/dist/manager/relations/ManyToManyRelatedManager.d.ts +0 -181
  67. package/dist/manager/relations/ManyToManyRelatedQuerySet.d.ts +0 -62
  68. package/dist/manager/relations/MaterializedModelRecord.d.ts +0 -28
  69. package/dist/manager/relations/index.d.ts +0 -9
  70. package/dist/manager/relations/internal/ThroughTableManager.d.ts +0 -85
  71. package/dist/query/ModelQuerySet.d.ts +0 -20
  72. package/dist/query/QBuilder.d.ts +0 -29
  73. package/dist/query/QuerySet.d.ts +0 -215
  74. package/dist/query/compiler/QueryCompiler.d.ts +0 -49
  75. package/dist/query/compiler/index.d.ts +0 -4
  76. package/dist/query/domain/CompiledQuery.d.ts +0 -209
  77. package/dist/query/domain/Dialect.d.ts +0 -2
  78. package/dist/query/domain/Direction.d.ts +0 -2
  79. package/dist/query/domain/FilterInput.d.ts +0 -3
  80. package/dist/query/domain/FilterKey.d.ts +0 -4
  81. package/dist/query/domain/FilterValue.d.ts +0 -1
  82. package/dist/query/domain/LookupType.d.ts +0 -2
  83. package/dist/query/domain/OrderSpec.d.ts +0 -5
  84. package/dist/query/domain/OrderToken.d.ts +0 -1
  85. package/dist/query/domain/QNode.d.ts +0 -9
  86. package/dist/query/domain/QueryResult.d.ts +0 -35
  87. package/dist/query/domain/QuerySetState.d.ts +0 -13
  88. package/dist/query/domain/RelationMeta.d.ts +0 -56
  89. package/dist/query/domain/RelationTyping.d.ts +0 -163
  90. package/dist/query/domain/TableMeta.d.ts +0 -16
  91. package/dist/query/domain/TableMetaFactory.d.ts +0 -10
  92. package/dist/query/domain/WhereClause.d.ts +0 -4
  93. package/dist/query/domain/index.d.ts +0 -21
  94. package/dist/query/domain/internal/InternalDialect.d.ts +0 -4
  95. package/dist/query/domain/internal/InternalDirection.d.ts +0 -4
  96. package/dist/query/domain/internal/InternalLookupType.d.ts +0 -15
  97. package/dist/query/domain/internal/InternalPrefetchQueryKind.d.ts +0 -20
  98. package/dist/query/domain/internal/InternalQNodeType.d.ts +0 -6
  99. package/dist/query/domain/internal/InternalRelationKind.d.ts +0 -6
  100. package/dist/query/internal/isQNodeLike.d.ts +0 -3
  101. package/dist/query/planning/QueryPlanner.d.ts +0 -16
  102. package/dist/query/planning/domain/QueryHydrationPlan.d.ts +0 -20
  103. package/dist/query/planning/index.d.ts +0 -2
  104. package/dist/query-DUZnBFhf.js.map +0 -1
  105. package/dist/registerModelObjects-22ZJKoit.js.map +0 -1
  106. package/dist/runtime/TangoRuntime.d.ts +0 -56
  107. package/dist/runtime/defaultRuntime.d.ts +0 -13
  108. package/dist/runtime/internal/DBClientProvider.d.ts +0 -12
  109. package/dist/runtime/internal/PostgresDBClientProvider.d.ts +0 -12
  110. package/dist/runtime/internal/SqliteDBClientProvider.d.ts +0 -19
  111. package/dist/runtime/internal/createDBClientProvider.d.ts +0 -5
  112. package/dist/runtime-1H88J3nN.js +0 -18
  113. package/dist/runtime-1H88J3nN.js.map +0 -1
  114. package/dist/transaction/AtomicTransaction.d.ts +0 -32
  115. package/dist/transaction/UnitOfWork.d.ts +0 -52
  116. package/dist/transaction/atomic.d.ts +0 -2
  117. package/dist/transaction/internal/context/AsyncLocalTransactionEngine.d.ts +0 -21
  118. package/dist/transaction/internal/context/CallbackRecord.d.ts +0 -5
  119. package/dist/transaction/internal/context/FrameBoundTransaction.d.ts +0 -20
  120. package/dist/transaction/internal/context/FrameTransactionHandle.d.ts +0 -4
  121. package/dist/transaction/internal/context/TransactionEngine.d.ts +0 -16
  122. package/dist/transaction/internal/context/TransactionFrame.d.ts +0 -7
  123. package/dist/transaction/internal/context/TransactionState.d.ts +0 -10
  124. package/dist/transaction/internal/context/index.d.ts +0 -1
  125. package/dist/transaction-ZhfDf-f8.js.map +0 -1
  126. package/dist/validation/OrmSqlSafetyAdapter.d.ts +0 -22
  127. package/dist/validation/SQLValidationEngine.d.ts +0 -68
  128. package/dist/validation/SqlValidationPlan.d.ts +0 -43
  129. package/dist/validation/index.d.ts +0 -3
  130. package/dist/validation/internal/InternalSqlValidationPlanKind.d.ts +0 -25
  131. package/dist/validation/internal/InternalValidatedFilterDescriptorKind.d.ts +0 -4
@@ -1,34 +0,0 @@
1
- import type { QNode } from '../query/domain/QNode';
2
- import type { FilterInput } from '../query/domain/FilterInput';
3
- import type { QuerySet } from '../query/index';
4
- import type { TableMeta } from '../query/domain/index';
5
- /**
6
- * Public manager contract consumed by Tango resources and applications.
7
- */
8
- export interface ManagerLike<TModelRow extends Record<string, unknown>, TSourceModel = unknown> {
9
- readonly meta: TableMeta;
10
- query(): QuerySet<TModelRow, TModelRow, TSourceModel>;
11
- all(): QuerySet<TModelRow, TModelRow, TSourceModel>;
12
- getOrCreate(args: {
13
- where: FilterInput<TModelRow> | QNode<TModelRow>;
14
- defaults?: Partial<TModelRow>;
15
- }): Promise<{
16
- record: TModelRow;
17
- created: boolean;
18
- }>;
19
- updateOrCreate(args: {
20
- where: FilterInput<TModelRow> | QNode<TModelRow>;
21
- defaults?: Partial<TModelRow>;
22
- update?: Partial<TModelRow>;
23
- }): Promise<{
24
- record: TModelRow;
25
- created: boolean;
26
- updated: boolean;
27
- }>;
28
- findById(id: TModelRow[keyof TModelRow]): Promise<TModelRow | null>;
29
- getOrThrow(id: TModelRow[keyof TModelRow]): Promise<TModelRow>;
30
- create(input: Partial<TModelRow>): Promise<TModelRow>;
31
- update(id: TModelRow[keyof TModelRow], patch: Partial<TModelRow>): Promise<TModelRow>;
32
- delete(id: TModelRow[keyof TModelRow]): Promise<void>;
33
- bulkCreate(inputs: Partial<TModelRow>[]): Promise<TModelRow[]>;
34
- }
@@ -1,106 +0,0 @@
1
- import type { ModelWriteHooks } from '@danceroutine/tango-schema';
2
- import type { Model as SchemaModel } from '@danceroutine/tango-schema/domain';
3
- import type { QNode } from '../query/domain/QNode';
4
- import type { FilterInput, TableMeta } from '../query/domain/index';
5
- import type { QuerySet } from '../query/index';
6
- import type { TangoRuntime } from '../runtime/TangoRuntime';
7
- import type { ManagerLike } from './ManagerLike';
8
- import { ManyToManyRelatedManager } from './relations/ManyToManyRelatedManager';
9
- type ModelMetadataLike = Omit<SchemaModel['metadata'], 'key' | 'namespace' | 'fields'> & {
10
- key?: string;
11
- namespace?: string;
12
- fields: Array<{
13
- name: string;
14
- type: string;
15
- primaryKey?: boolean;
16
- }>;
17
- };
18
- type ModelLike<TModelRow extends Record<string, unknown>> = {
19
- metadata: ModelMetadataLike;
20
- schema: {
21
- parse(input: unknown): TModelRow;
22
- };
23
- hooks?: ModelWriteHooks<TModelRow>;
24
- };
25
- /**
26
- * Model-backed data access API exposed as `Model.objects`.
27
- */
28
- export declare class ModelManager<TModelRow extends Record<string, unknown>, TSourceModel = unknown> implements ManagerLike<TModelRow, TSourceModel> {
29
- static readonly BRAND: "tango.orm.model_manager";
30
- readonly __tangoBrand: typeof ModelManager.BRAND;
31
- private readonly queryExecutor;
32
- private readonly mutationCompiler;
33
- private readonly model;
34
- private readonly client;
35
- private readonly adapter;
36
- private readonly runtime;
37
- constructor(model: ModelLike<TModelRow>, runtime: TangoRuntime);
38
- get meta(): TableMeta;
39
- /**
40
- * Narrow an unknown value to `ModelManager`.
41
- */
42
- static isModelManager<TModelRow extends Record<string, unknown>>(value: unknown): value is ModelManager<TModelRow>;
43
- private static createTableMeta;
44
- private static mergeCreatePayloadFromWhere;
45
- private static countDefinedValues;
46
- private static collectPlainFieldsFromQNode;
47
- private static omitLookupKeysFromAtom;
48
- private static mergeCompatiblePartials;
49
- query(): QuerySet<TModelRow, TModelRow, TSourceModel>;
50
- all(): QuerySet<TModelRow, TModelRow, TSourceModel>;
51
- findById(id: TModelRow[keyof TModelRow]): Promise<TModelRow | null>;
52
- getOrThrow(id: TModelRow[keyof TModelRow]): Promise<TModelRow>;
53
- getOrCreate(args: {
54
- where: FilterInput<TModelRow> | QNode<TModelRow>;
55
- defaults?: Partial<TModelRow>;
56
- }): Promise<{
57
- record: TModelRow;
58
- created: boolean;
59
- }>;
60
- updateOrCreate(args: {
61
- where: FilterInput<TModelRow> | QNode<TModelRow>;
62
- defaults?: Partial<TModelRow>;
63
- update?: Partial<TModelRow>;
64
- }): Promise<{
65
- record: TModelRow;
66
- created: boolean;
67
- updated: boolean;
68
- }>;
69
- create(input: Partial<TModelRow>): Promise<TModelRow>;
70
- update(id: TModelRow[keyof TModelRow], patch: Partial<TModelRow>): Promise<TModelRow>;
71
- delete(id: TModelRow[keyof TModelRow]): Promise<void>;
72
- /**
73
- * Build a {@link ManyToManyRelatedManager} bound to a single owner record
74
- * for the supplied many-to-many relation. The returned manager performs
75
- * its INSERT/DELETE writes through the shared runtime-bound client, so
76
- * mutations enroll in any active `transaction.atomic(...)` boundary.
77
- */
78
- createManyToManyRelatedManager<TTarget extends Record<string, unknown>>(relationName: string, ownerPrimaryKey: unknown): ManyToManyRelatedManager<TTarget>;
79
- /**
80
- * Insert multiple rows in a single multi-row INSERT statement.
81
- *
82
- * All rows must share the same field set after hook processing. Rows with
83
- * extra or missing fields relative to the first row will cause an error.
84
- * If you need to insert rows with different field sets, use individual
85
- * {@link create} calls instead.
86
- */
87
- bulkCreate(inputs: Partial<TModelRow>[]): Promise<TModelRow[]>;
88
- /**
89
- * Attach a {@link ManyToManyRelatedManager} as a non-enumerable property
90
- * for every persisted many-to-many relation declared on the supplied
91
- * record's model. Existing properties are left untouched so that prior
92
- * hydration writes (such as prefetched arrays) survive the attach pass
93
- * during the incremental rollout of related-manager hydration.
94
- */
95
- private attachOwnRelatedManagers;
96
- private attachManyToManyRelatedManagers;
97
- private resolveManagerForModelKey;
98
- private resolveTargetExecutor;
99
- private resolveTargetManager;
100
- private requireManyToManyEdge;
101
- private runBeforeCreate;
102
- private runBeforeUpdate;
103
- private getHookTransaction;
104
- private assertUniformRowShape;
105
- }
106
- export {};
@@ -1,23 +0,0 @@
1
- import type { CompiledQuery } from '../../query/domain/index';
2
- import type { Adapter } from '../../connection/adapters/Adapter';
3
- import type { ValidatedDeleteSqlPlan, ValidatedInsertSqlPlan, ValidatedSelectSqlPlan, ValidatedUpdateSqlPlan } from '../../validation/SQLValidationEngine';
4
- export declare const InternalDuplicateInsertPolicy: {
5
- readonly ERROR: "error";
6
- readonly IGNORE: "ignore";
7
- };
8
- export type DuplicateInsertPolicy = (typeof InternalDuplicateInsertPolicy)[keyof typeof InternalDuplicateInsertPolicy];
9
- /**
10
- * Internal compiler for manager-owned INSERT/UPDATE/DELETE statements.
11
- */
12
- export declare class MutationCompiler {
13
- private readonly adapter;
14
- private readonly placeholders;
15
- constructor(adapter: Adapter);
16
- compileInsert(plan: ValidatedInsertSqlPlan, values: readonly unknown[]): CompiledQuery;
17
- compileUpdate(plan: ValidatedUpdateSqlPlan, values: readonly unknown[], id: unknown): CompiledQuery;
18
- compileDelete(plan: ValidatedDeleteSqlPlan, id: unknown): CompiledQuery;
19
- compileDeleteByJoinKeys(plan: ValidatedSelectSqlPlan, leftFilterKey: string, rightFilterKey: string, leftValue: unknown, rightValue: unknown): CompiledQuery;
20
- compileBulkInsert(plan: ValidatedInsertSqlPlan, valueRows: ReadonlyArray<ReadonlyArray<unknown>>): CompiledQuery;
21
- compileInsertJoinLinks(plan: ValidatedInsertSqlPlan, sourceKey: string, targetKey: string, ownerValue: unknown, targetValues: readonly unknown[], duplicatePolicy: DuplicateInsertPolicy): CompiledQuery;
22
- compileDeleteJoinLinks(plan: ValidatedSelectSqlPlan, leftFilterKey: string, rightFilterKey: string, leftValue: unknown, rightValues: readonly unknown[]): CompiledQuery;
23
- }
@@ -1,20 +0,0 @@
1
- import type { DBClient } from '../../connection/index';
2
- import type { TangoRuntime } from '../../runtime/index';
3
- /**
4
- * DB client proxy that resolves either the active transaction lease or the
5
- * runtime autocommit path lazily.
6
- */
7
- export declare class RuntimeBoundClient implements DBClient {
8
- private readonly runtime;
9
- constructor(runtime: TangoRuntime);
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
- createSavepoint(_name: string): Promise<void>;
17
- releaseSavepoint(_name: string): Promise<void>;
18
- rollbackToSavepoint(_name: string): Promise<void>;
19
- close(): Promise<void>;
20
- }
@@ -1,5 +0,0 @@
1
- /**
2
- * Install the schema model augmentor that exposes `Model.objects`.
3
- * This registration is idempotent so multiple Tango entrypoints can safely call it.
4
- */
5
- export declare function registerModelObjects(): void;
@@ -1,181 +0,0 @@
1
- import type { DBClient } from '../../connection/clients/DBClient';
2
- import type { TableMeta } from '../../query/domain/index';
3
- import type { Adapter } from '../../connection/adapters/Adapter';
4
- import type { QueryExecutor, QuerySet } from '../../query/index';
5
- import type { OrmSqlSafetyAdapter } from '../../validation/OrmSqlSafetyAdapter';
6
- import type { MutationCompiler } from '../internal/MutationCompiler';
7
- import { ThroughTableManager } from './internal/ThroughTableManager';
8
- /**
9
- * Accepted target reference shapes for {@link ManyToManyRelatedManager.add},
10
- * {@link ManyToManyRelatedManager.remove}, and
11
- * {@link ManyToManyRelatedManager.set}.
12
- *
13
- * Application code may pass a target record, a primary-key carrier object, or
14
- * a bare primary-key value.
15
- *
16
- * @template TTarget - The persisted target record shape.
17
- */
18
- export type ManyToManyTargetRef<TTarget extends Record<string, unknown>> = TTarget | {
19
- readonly [pk: string]: unknown;
20
- } | string | number;
21
- /**
22
- * Inputs accepted by the {@link ManyToManyRelatedManager.create} factory. The
23
- * factory owns the wiring between relation metadata, the SQL safety adapter,
24
- * and the {@link ThroughTableManager}, so callers only supply context they
25
- * already have on hand.
26
- */
27
- export interface ManyToManyRelatedManagerCreateInputs<TTarget extends Record<string, unknown>> {
28
- /** Persisted primary-key value of the owning record. */
29
- ownerPrimaryKey: unknown;
30
- /** Relation name on the owning model (for error messages). */
31
- relationName: string;
32
- /** Display name of the owning model (for error messages). */
33
- ownerModelLabel: string;
34
- /** Resolved relation edge metadata for the many-to-many relation. */
35
- relation: NonNullable<TableMeta['relations']>[string];
36
- /** Through-model column metadata used to derive the join-table descriptor. */
37
- throughModelFields: ReadonlyArray<{
38
- name: string;
39
- type: string;
40
- primaryKey?: boolean;
41
- }>;
42
- /** Runtime-bound database client shared with the owning manager. */
43
- client: DBClient;
44
- /** Shared {@link MutationCompiler} configured for the active dialect. */
45
- mutationCompiler: MutationCompiler;
46
- /** Active database adapter. Supplies placeholder formatting and dialect flags. */
47
- adapter: Adapter;
48
- /** SQL safety adapter shared with the owning manager. */
49
- sqlSafetyAdapter: OrmSqlSafetyAdapter;
50
- /** Lazy resolver returning the target model's {@link QueryExecutor}. */
51
- targetExecutorProvider: () => QueryExecutor<TTarget> | null;
52
- /** Model-manager-backed create path for new target records. */
53
- createTarget: (input: Partial<TTarget>) => Promise<TTarget>;
54
- /** Internal transaction runner used for multi-target membership writes. */
55
- runAtomic: <T>(work: () => Promise<T>) => Promise<T>;
56
- }
57
- interface ManyToManyRelatedManagerInternalInputs<TTarget extends Record<string, unknown>> {
58
- ownerPrimaryKey: unknown;
59
- relationName: string;
60
- ownerModelLabel: string;
61
- targetPrimaryKeyField: string;
62
- throughTableManager: ThroughTableManager;
63
- targetExecutorProvider: () => QueryExecutor<TTarget> | null;
64
- createTarget: (input: Partial<TTarget>) => Promise<TTarget>;
65
- runAtomic: <T>(work: () => Promise<T>) => Promise<T>;
66
- }
67
- /**
68
- * Django-style related manager exposed on materialized model records for each
69
- * many-to-many relation.
70
- *
71
- * Use the manager to add or remove join-table membership and to query the
72
- * related target rows. The owning record's primary key and the relation name
73
- * are bound when the manager is attached, so application code does not need
74
- * to pass them on every call.
75
- *
76
- * Prefetched memberships seed an internal cache that the queryset returned
77
- * from `all()` short-circuits to without re-querying. Mutations through
78
- * `add`, `remove`, `set`, `clear`, and `create` invalidate the cache so
79
- * subsequent reads observe the updated membership. `set(...)` applies
80
- * Django-shaped replacement semantics:
81
- * it diffs the current relation membership against the supplied targets,
82
- * removes any missing links, and inserts any new links inside one atomic
83
- * write boundary. `clear()` removes every join row for the owner, and
84
- * `create(...)` persists a new target row plus its join-row link inside one
85
- * atomic boundary.
86
- *
87
- * @template TTarget - The persisted target record shape returned by `all()`.
88
- */
89
- export declare class ManyToManyRelatedManager<TTarget extends Record<string, unknown>> {
90
- private readonly inputs;
91
- private static readonly BRAND;
92
- readonly __tangoBrand: typeof ManyToManyRelatedManager.BRAND;
93
- private prefetchCache;
94
- /**
95
- * Constructor is internal. Application and ORM code must build instances
96
- * through {@link ManyToManyRelatedManager.create}, which owns the wiring
97
- * between relation metadata and the backing through-table mutator. The
98
- * testing package exposes a fixture for unit tests that need a custom
99
- * mutator.
100
- */
101
- constructor(inputs: ManyToManyRelatedManagerInternalInputs<TTarget>);
102
- /**
103
- * Narrow an unknown value to {@link ManyToManyRelatedManager}.
104
- */
105
- static isManyToManyRelatedManager<TTarget extends Record<string, unknown>>(value: unknown): value is ManyToManyRelatedManager<TTarget>;
106
- /**
107
- * Build a {@link ManyToManyRelatedManager} bound to a single owner record.
108
- * The factory derives the join-table descriptor from the relation edge and
109
- * through-model fields, wires a {@link ThroughTableManager} against the
110
- * supplied runtime-bound client, and returns a manager whose `add`,
111
- * `remove`, `clear`, `create`, and `all` methods enroll in any active
112
- * `transaction.atomic(...)` boundary.
113
- */
114
- static create<TTarget extends Record<string, unknown>>(inputs: ManyToManyRelatedManagerCreateInputs<TTarget>): ManyToManyRelatedManager<TTarget>;
115
- /**
116
- * Insert join-table rows linking the owning record to the supplied
117
- * targets. Duplicate links are ignored so repeated `add(...)` calls are
118
- * idempotent. When multiple targets are supplied, Tango performs the
119
- * membership write inside one `transaction.atomic(...)` boundary.
120
- */
121
- add(...targets: ManyToManyTargetRef<TTarget>[]): Promise<void>;
122
- /**
123
- * Delete join-table rows linking the owning record to the supplied
124
- * targets. When multiple targets are supplied, Tango performs the
125
- * membership write inside one `transaction.atomic(...)` boundary.
126
- */
127
- remove(...targets: ManyToManyTargetRef<TTarget>[]): Promise<void>;
128
- /**
129
- * Delete every join-table row linked to the owning record and invalidate
130
- * any prefetched membership cache after the delete succeeds.
131
- */
132
- clear(): Promise<void>;
133
- /**
134
- * Create a new target record through the related model's manager and link
135
- * it to the owning record inside one `transaction.atomic(...)` boundary.
136
- * This preserves target-manager hooks and defaults while preventing a
137
- * created target row from leaking if the join-row insert fails.
138
- */
139
- create(input: Partial<TTarget>): Promise<TTarget>;
140
- /**
141
- * Replace the current relation membership with exactly the supplied
142
- * targets. Duplicate inputs are collapsed before diffing against the
143
- * current through-table rows, so repeated values do not trigger extra
144
- * writes. Calling `set()` with no targets clears the relation.
145
- *
146
- * When replacement requires writes, Tango performs the delete/insert
147
- * sequence inside one `transaction.atomic(...)` boundary.
148
- */
149
- set(...targets: ManyToManyTargetRef<TTarget>[]): Promise<void>;
150
- /**
151
- * Return a {@link QuerySet} for the related target rows of this many-to-many
152
- * relation. When the relation was already loaded by `prefetchRelated(...)`,
153
- * the first `fetch()` resolves with the cached materialization without
154
- * re-querying. Mutating the membership through `add`/`remove`/`set`/
155
- * `clear`/`create` invalidates that cache.
156
- */
157
- all(): QuerySet<TTarget>;
158
- /**
159
- * Replace the prefetch cache with the supplied target rows. Called by the
160
- * many-to-many prefetch path so a follow-up `all()` resolves without an
161
- * extra database round-trip.
162
- */
163
- primePrefetchCache(targets: readonly TTarget[]): void;
164
- /**
165
- * Drop any cached prefetch results. Mutating helpers call this so reads
166
- * after an `add`/`remove`/`set`/`clear`/`create` go back to the database.
167
- */
168
- invalidateCache(): void;
169
- /**
170
- * Snapshot of the current prefetch cache, exposed for diagnostics and
171
- * focused unit testing. Returns a fresh array copy so callers cannot
172
- * mutate the manager's internal state.
173
- */
174
- snapshotCache(): readonly TTarget[] | null;
175
- private insertTargetPrimaryKeys;
176
- private deleteTargetPrimaryKeys;
177
- private resolveTargetPrimaryKeys;
178
- private resolveTargetPrimaryKey;
179
- private canonicalizePrimaryKey;
180
- }
181
- export {};
@@ -1,62 +0,0 @@
1
- import type { QueryResult } from '../../query/domain/QueryResult';
2
- import type { QuerySetState } from '../../query/domain/QuerySetState';
3
- import type { QueryExecutor } from '../../query/index';
4
- import { QuerySet } from '../../query/index';
5
- /**
6
- * Hooks supplied by {@link ManyToManyRelatedManager} so the queryset returned
7
- * from `all()` can short-circuit to the prefetch cache, scope the SQL query
8
- * to the owner via the join table, and filter targets by the resolved primary
9
- * keys.
10
- *
11
- * Application code does not construct this bridge directly; it is wired by
12
- * the related manager when `all()` is called.
13
- */
14
- export interface ManyToManyRelatedQuerySetBridge<TTarget extends Record<string, unknown>> {
15
- getCache(): readonly TTarget[] | null;
16
- fetchTargetIds(): Promise<readonly (string | number)[]>;
17
- targetPrimaryKeyField: string;
18
- }
19
- type ShapeFunction<TInput, Out> = (row: TInput) => Out;
20
- type ShapeParser<TInput, Out> = {
21
- parse: (row: TInput) => Out;
22
- };
23
- /**
24
- * {@link QuerySet} returned by `post.tags.all()` on a many-to-many related
25
- * manager.
26
- *
27
- * Behaves like a normal `QuerySet` over the target model from an application
28
- * developer's perspective: you can chain `filter`, `exclude`, `orderBy`,
29
- * `limit`, `offset`, and terminate with `fetch`, `fetchOne`, or `count`.
30
- * Each chainable call returns another `ManyToManyRelatedQuerySet` so the
31
- * chain keeps the membership scoping of the owning record.
32
- *
33
- * Two behaviors differ from a plain `QuerySet` and matter to application
34
- * developers:
35
- *
36
- * - When the relation was loaded by `prefetchRelated(...)` and no chainable
37
- * state has been added (no `filter`, `orderBy`, etc.), `fetch()` and
38
- * `count()` resolve from the prefetch cache without issuing SQL.
39
- * - Mutating the membership via `post.tags.add(tag)` or
40
- * `post.tags.remove(tag)` invalidates that cache so follow-up reads go
41
- * back to the database.
42
- *
43
- * @example
44
- * ```ts
45
- * const post = await PostModel.objects.getOrThrow(postId);
46
- * await post.tags.add(tag);
47
- * const tags = await post.tags.all().filter({ color: 'red' }).orderBy('name').fetch();
48
- * ```
49
- *
50
- * @template TTarget - The persisted target record shape (e.g. `Tag`).
51
- */
52
- export declare class ManyToManyRelatedQuerySet<TTarget extends Record<string, unknown>> extends QuerySet<TTarget> {
53
- private readonly bridge;
54
- constructor(executor: QueryExecutor<TTarget>, bridge: ManyToManyRelatedQuerySetBridge<TTarget>, state?: QuerySetState<TTarget>);
55
- fetch<Out>(shape?: ShapeFunction<TTarget, Out> | ShapeParser<TTarget, Out>): Promise<QueryResult<TTarget | Out>>;
56
- fetchOne<Out>(shape?: ShapeFunction<TTarget, Out> | ShapeParser<TTarget, Out>): Promise<TTarget | Out | null>;
57
- count(): Promise<number>;
58
- protected spawn<TNextBaseResult extends Record<string, unknown>, TNextHydrated extends Record<string, unknown>>(state: QuerySetState<TTarget>): QuerySet<TTarget, TNextBaseResult, unknown, TNextHydrated>;
59
- private isStateTrivial;
60
- private scopedState;
61
- }
62
- export {};
@@ -1,28 +0,0 @@
1
- import type { z } from 'zod';
2
- import type { Model, PersistedModelOutput } from '@danceroutine/tango-schema/domain';
3
- import type { DecoratedFieldKind, InternalDecoratedFieldKind, RelationDecoratedSchema } from '@danceroutine/tango-schema/model';
4
- import type { ManyToManyRelatedManager } from './ManyToManyRelatedManager';
5
- type IsAny<TValue> = 0 extends 1 & TValue ? true : false;
6
- type AnyModel = Model<z.ZodObject<z.ZodRawShape>, string>;
7
- type SchemaShape<TSchema> = TSchema extends z.ZodObject<infer TShape> ? TShape : never;
8
- type RelationKindOf<TField> = TField extends RelationDecoratedSchema<z.ZodTypeAny, infer TKind extends DecoratedFieldKind, AnyModel, string | undefined, string | undefined> ? TKind : never;
9
- type RelationTarget<TField> = TField extends RelationDecoratedSchema<z.ZodTypeAny, DecoratedFieldKind, infer TTarget, string | undefined, string | undefined> ? TTarget : never;
10
- type RelationPublishedName<TField, TFallback extends string> = TField extends RelationDecoratedSchema<z.ZodTypeAny, DecoratedFieldKind, AnyModel, infer TName extends string | undefined, string | undefined> ? TName extends string ? TName : TFallback : TFallback;
11
- type ModelRow<TTarget> = TTarget extends Model<infer TSchema extends z.ZodObject<z.ZodRawShape>, string> ? PersistedModelOutput<TSchema> : never;
12
- type ManyToManyKeysOfShape<TShape extends z.ZodRawShape> = Extract<{
13
- [K in keyof TShape]: IsAny<TShape[K]> extends true ? never : [RelationKindOf<TShape[K]>] extends [never] ? never : [RelationKindOf<TShape[K]>] extends [typeof InternalDecoratedFieldKind.MANY_TO_MANY] ? K : never;
14
- }[keyof TShape], string>;
15
- type ManyToManyManagers<TShape extends z.ZodRawShape> = {
16
- readonly [K in ManyToManyKeysOfShape<TShape> as K extends keyof TShape ? RelationPublishedName<TShape[K], K> : never]: K extends keyof TShape ? RelationTarget<TShape[K]> extends AnyModel ? ManyToManyRelatedManager<ModelRow<RelationTarget<TShape[K]>>> : never : never;
17
- };
18
- /**
19
- * Persisted model record shape returned by ORM read and write paths.
20
- *
21
- * Combines the column-level {@link PersistedModelOutput} with a per-relation
22
- * {@link ManyToManyRelatedManager} for every many-to-many field declared on the
23
- * source schema. The manager properties are attached as non-enumerable accessors
24
- * at runtime, so `JSON.stringify` and structural equality checks only see the
25
- * column data.
26
- */
27
- export type MaterializedModelRecord<TSchema extends z.ZodObject<z.ZodRawShape>> = PersistedModelOutput<TSchema> & ManyToManyManagers<SchemaShape<TSchema>>;
28
- export {};
@@ -1,9 +0,0 @@
1
- /**
2
- * Domain boundary barrel: centralizes ORM relation managers attached to
3
- * materialized model records.
4
- */
5
- export { ManyToManyRelatedQuerySet } from './ManyToManyRelatedQuerySet';
6
- export type { ManyToManyRelatedQuerySetBridge } from './ManyToManyRelatedQuerySet';
7
- export { ManyToManyRelatedManager } from './ManyToManyRelatedManager';
8
- export type { ManyToManyRelatedManagerCreateInputs, ManyToManyTargetRef } from './ManyToManyRelatedManager';
9
- export type { MaterializedModelRecord } from './MaterializedModelRecord';
@@ -1,85 +0,0 @@
1
- import type { DBClient } from '../../../connection/clients/DBClient';
2
- import type { TableMeta } from '../../../query/domain/index';
3
- import type { Adapter } from '../../../connection/adapters/Adapter';
4
- import { OrmSqlSafetyAdapter } from '../../../validation/OrmSqlSafetyAdapter';
5
- import { MutationCompiler, type DuplicateInsertPolicy } from '../../internal/MutationCompiler';
6
- /**
7
- * Resolved through-table descriptor used by {@link ThroughTableManager}. The
8
- * descriptor is derived once from a relation edge plus its through-model
9
- * metadata, then reused for every link insert, delete, and read.
10
- */
11
- export interface ThroughTableLinkDescriptor {
12
- /** Physical join-table name validated against SQL identifier safety rules. */
13
- table: string;
14
- /** Primary-key column name on the join table. */
15
- primaryKey: string;
16
- /** Full column map for the join table, used by the SQL safety adapter. */
17
- columns: Record<string, string>;
18
- /** Join-table column that stores the owner-side primary-key value. */
19
- sourceColumn: string;
20
- /** Join-table column that stores the target-side primary-key value. */
21
- targetColumn: string;
22
- }
23
- /**
24
- * Inputs accepted by {@link ThroughTableManager.fromRelation}.
25
- */
26
- export interface ThroughTableManagerFromRelationInputs {
27
- relation: NonNullable<TableMeta['relations']>[string];
28
- throughModelFields: ReadonlyArray<{
29
- name: string;
30
- type: string;
31
- primaryKey?: boolean;
32
- }>;
33
- client: DBClient;
34
- mutationCompiler: MutationCompiler;
35
- adapter: Adapter;
36
- sqlSafetyAdapter: OrmSqlSafetyAdapter;
37
- }
38
- export interface InsertLinkOptions {
39
- onDuplicate?: DuplicateInsertPolicy;
40
- }
41
- /**
42
- * Internal helper that issues the INSERT, DELETE, and SELECT statements for
43
- * a single many-to-many join table. Centralizes SQL safety validation and
44
- * compilation so {@link ManyToManyRelatedManager} implementations only deal
45
- * in primary-key values.
46
- */
47
- export declare class ThroughTableManager {
48
- private readonly client;
49
- private readonly mutationCompiler;
50
- private readonly descriptor;
51
- private readonly adapter;
52
- private readonly sqlSafetyAdapter;
53
- constructor(client: DBClient, mutationCompiler: MutationCompiler, descriptor: ThroughTableLinkDescriptor, adapter: Adapter, sqlSafetyAdapter?: OrmSqlSafetyAdapter);
54
- /**
55
- * Derive a {@link ThroughTableLinkDescriptor} from the through-model
56
- * metadata exposed by a many-to-many relation edge.
57
- */
58
- static buildLinkDescriptor(relation: NonNullable<TableMeta['relations']>[string], throughModelFields: ReadonlyArray<{
59
- name: string;
60
- type: string;
61
- primaryKey?: boolean;
62
- }>): ThroughTableLinkDescriptor;
63
- /**
64
- * Convenience factory that derives the join-table descriptor from the
65
- * relation edge and instantiates a {@link ThroughTableManager} in one
66
- * step.
67
- */
68
- static fromRelation(inputs: ThroughTableManagerFromRelationInputs): ThroughTableManager;
69
- /**
70
- * Read every target primary-key value linked to the supplied owner via
71
- * the join table. Used by ManyToManyRelatedManager.all to scope
72
- * follow-up target queries to the current owner.
73
- */
74
- selectTargetIdsForOwner(ownerPrimaryKey: unknown): Promise<readonly (string | number)[]>;
75
- insertLink(ownerPrimaryKey: unknown, targetPrimaryKey: unknown, options?: InsertLinkOptions): Promise<void>;
76
- insertLinks(ownerPrimaryKey: unknown, targetPrimaryKeys: readonly unknown[], options?: InsertLinkOptions): Promise<void>;
77
- deleteLink(ownerPrimaryKey: unknown, targetPrimaryKey: unknown): Promise<void>;
78
- deleteLinks(ownerPrimaryKey: unknown, targetPrimaryKeys: readonly unknown[]): Promise<void>;
79
- /**
80
- * Delete every join-table row linked to one owner record. Used by
81
- * `ManyToManyRelatedManager.clear()` so the related manager can clear a
82
- * relation without first loading the current target ids.
83
- */
84
- deleteAllLinksForOwner(ownerPrimaryKey: unknown): Promise<void>;
85
- }
@@ -1,20 +0,0 @@
1
- /**
2
- * Maintainer note: model-backed and specialized relation-backed querysets
3
- * share the fluent API through `QuerySet.spawn(...)`. This concrete class
4
- * owns the direct "compile the accumulated state and execute it" path, while
5
- * subclasses preserve specialized execution behavior by returning their own
6
- * queryset family from `spawn(...)`.
7
- */
8
- import type { QuerySetState } from './domain/QuerySetState';
9
- import type { QueryExecutor } from './QuerySet';
10
- import { QuerySet } from './QuerySet';
11
- /**
12
- * Concrete `QuerySet` implementation returned by `Model.objects.query()`.
13
- *
14
- * It executes the accumulated queryset state directly against the bound
15
- * model executor.
16
- */
17
- export declare class ModelQuerySet<TModel extends Record<string, unknown>, TBaseResult extends Record<string, unknown> = TModel, TSourceModel = unknown, THydrated extends Record<string, unknown> = Record<never, never>> extends QuerySet<TModel, TBaseResult, TSourceModel, THydrated> {
18
- constructor(executor: QueryExecutor<TModel>, state?: QuerySetState<TModel, TSourceModel>);
19
- protected spawn<TNextBaseResult extends Record<string, unknown> = TBaseResult, TNextHydrated extends Record<string, unknown> = THydrated>(state: QuerySetState<TModel, TSourceModel>): ModelQuerySet<TModel, TNextBaseResult, TSourceModel, TNextHydrated>;
20
- }
@@ -1,29 +0,0 @@
1
- import type { QNode } from './domain/QNode';
2
- import type { FilterInput } from './domain/FilterInput';
3
- /**
4
- * Static builder for composing boolean query expressions.
5
- *
6
- * This mirrors Django's `Q(...)` composition patterns and is intended
7
- * for ergonomic construction of nested `AND`/`OR`/`NOT` trees.
8
- */
9
- export declare class QBuilder {
10
- static readonly BRAND: "tango.orm.q_builder";
11
- readonly __tangoBrand: typeof QBuilder.BRAND;
12
- /**
13
- * Narrow an unknown value to `QBuilder`.
14
- */
15
- static isQBuilder(value: unknown): value is QBuilder;
16
- /**
17
- * Combine multiple filter fragments using logical `AND`.
18
- */
19
- static and<T, TSourceModel = unknown>(...nodes: Array<FilterInput<T, TSourceModel> | QNode<T, TSourceModel>>): QNode<T, TSourceModel>;
20
- /**
21
- * Combine multiple filter fragments using logical `OR`.
22
- */
23
- static or<T, TSourceModel = unknown>(...nodes: Array<FilterInput<T, TSourceModel> | QNode<T, TSourceModel>>): QNode<T, TSourceModel>;
24
- /**
25
- * Negate a filter fragment using logical `NOT`.
26
- */
27
- static not<T, TSourceModel = unknown>(node: FilterInput<T, TSourceModel> | QNode<T, TSourceModel>): QNode<T, TSourceModel>;
28
- private static wrapNode;
29
- }