@shivaedev/effect-prisma 0.6.3 → 0.7.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 (138) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/dist/bin/normalize-contract.js +1 -0
  3. package/dist/bin/normalize-contract.js.map +1 -1
  4. package/dist/database.d.ts +4 -4
  5. package/dist/database.d.ts.map +1 -1
  6. package/dist/database.js +12 -12
  7. package/dist/database.js.map +1 -1
  8. package/dist/error.d.ts +5 -5
  9. package/dist/error.d.ts.map +1 -1
  10. package/dist/error.js +5 -6
  11. package/dist/error.js.map +1 -1
  12. package/dist/index.d.ts +3 -3
  13. package/dist/internal/adapters/transaction-settlement.d.ts +10 -0
  14. package/dist/internal/adapters/transaction-settlement.d.ts.map +1 -0
  15. package/dist/internal/adapters/transaction-settlement.js +56 -0
  16. package/dist/internal/adapters/transaction-settlement.js.map +1 -0
  17. package/dist/internal/client-lifecycle.d.ts +2 -2
  18. package/dist/internal/client-lifecycle.d.ts.map +1 -1
  19. package/dist/internal/client-lifecycle.js.map +1 -1
  20. package/dist/internal/contract-normalization.d.ts +0 -4
  21. package/dist/internal/contract-normalization.d.ts.map +1 -1
  22. package/dist/internal/contract-normalization.js +5 -10
  23. package/dist/internal/contract-normalization.js.map +1 -1
  24. package/dist/internal/database-facade.d.ts +19 -0
  25. package/dist/internal/database-facade.d.ts.map +1 -0
  26. package/dist/internal/database-facade.js +79 -0
  27. package/dist/internal/database-facade.js.map +1 -0
  28. package/dist/internal/database-factory.d.ts +4 -48
  29. package/dist/internal/database-factory.d.ts.map +1 -1
  30. package/dist/internal/database-factory.js +11 -90
  31. package/dist/internal/database-factory.js.map +1 -1
  32. package/dist/internal/database-types.d.ts +33 -0
  33. package/dist/internal/database-types.d.ts.map +1 -0
  34. package/dist/internal/database-types.js +2 -0
  35. package/dist/internal/database-types.js.map +1 -0
  36. package/dist/internal/dynamic.d.ts +5 -0
  37. package/dist/internal/dynamic.d.ts.map +1 -0
  38. package/dist/internal/dynamic.js +12 -0
  39. package/dist/internal/dynamic.js.map +1 -0
  40. package/dist/internal/executor.d.ts +3 -7
  41. package/dist/internal/executor.d.ts.map +1 -1
  42. package/dist/internal/promise.d.ts +1 -1
  43. package/dist/internal/promise.d.ts.map +1 -1
  44. package/dist/internal/promise.js +2 -4
  45. package/dist/internal/promise.js.map +1 -1
  46. package/dist/internal/query-execution.d.ts +2 -2
  47. package/dist/internal/query-execution.d.ts.map +1 -1
  48. package/dist/internal/query-execution.js +2 -6
  49. package/dist/internal/query-execution.js.map +1 -1
  50. package/dist/internal/recipe.d.ts +3 -3
  51. package/dist/internal/recipe.d.ts.map +1 -1
  52. package/dist/internal/recipe.js +9 -20
  53. package/dist/internal/recipe.js.map +1 -1
  54. package/dist/internal/relation-plan.d.ts +1 -1
  55. package/dist/internal/relation-result.d.ts +4 -0
  56. package/dist/internal/relation-result.d.ts.map +1 -0
  57. package/dist/internal/relation-result.js +19 -0
  58. package/dist/internal/relation-result.js.map +1 -0
  59. package/dist/internal/relation-runtime.d.ts +3 -3
  60. package/dist/internal/relation-runtime.d.ts.map +1 -1
  61. package/dist/internal/relation-runtime.js +12 -37
  62. package/dist/internal/relation-runtime.js.map +1 -1
  63. package/dist/internal/relation-stream.d.ts +3 -3
  64. package/dist/internal/relation-stream.d.ts.map +1 -1
  65. package/dist/internal/relation-stream.js +20 -24
  66. package/dist/internal/relation-stream.js.map +1 -1
  67. package/dist/internal/sqlite-datetime.d.ts +1 -27
  68. package/dist/internal/sqlite-datetime.d.ts.map +1 -1
  69. package/dist/internal/sqlite-datetime.js +16 -35
  70. package/dist/internal/sqlite-datetime.js.map +1 -1
  71. package/dist/internal/sqlite-pragmas.d.ts +1 -13
  72. package/dist/internal/sqlite-pragmas.d.ts.map +1 -1
  73. package/dist/internal/sqlite-pragmas.js +2 -12
  74. package/dist/internal/sqlite-pragmas.js.map +1 -1
  75. package/dist/internal/testing.d.ts +1 -1
  76. package/dist/internal/testing.d.ts.map +1 -1
  77. package/dist/internal/testing.js +5 -2
  78. package/dist/internal/testing.js.map +1 -1
  79. package/dist/internal/transaction.d.ts +5 -5
  80. package/dist/internal/transaction.d.ts.map +1 -1
  81. package/dist/internal/transaction.js +5 -53
  82. package/dist/internal/transaction.js.map +1 -1
  83. package/dist/relation/include-metadata.d.ts +1 -1
  84. package/dist/relation/include-metadata.d.ts.map +1 -1
  85. package/dist/relation/include.d.ts +8 -5
  86. package/dist/relation/include.d.ts.map +1 -1
  87. package/dist/relation/prisma-methods.d.ts +17 -17
  88. package/dist/relation/prisma-methods.d.ts.map +1 -1
  89. package/dist/relation.d.ts +4 -4
  90. package/dist/relation.d.ts.map +1 -1
  91. package/dist/sqlite.d.ts +5 -10
  92. package/dist/sqlite.d.ts.map +1 -1
  93. package/dist/sqlite.js +14 -12
  94. package/dist/sqlite.js.map +1 -1
  95. package/dist/testing/transaction.d.ts +6 -7
  96. package/dist/testing/transaction.d.ts.map +1 -1
  97. package/dist/testing/transaction.js +2 -2
  98. package/dist/testing/transaction.js.map +1 -1
  99. package/dist/testing/types.d.ts +7 -7
  100. package/dist/testing/types.d.ts.map +1 -1
  101. package/dist/testing/vitest.d.ts +3 -3
  102. package/dist/testing/vitest.d.ts.map +1 -1
  103. package/dist/testing/vitest.js +2 -2
  104. package/dist/testing/vitest.js.map +1 -1
  105. package/dist/testing.d.ts +3 -3
  106. package/package.json +35 -37
  107. package/src/bin/normalize-contract.ts +2 -1
  108. package/src/database.ts +49 -67
  109. package/src/error.ts +13 -23
  110. package/src/index.ts +3 -3
  111. package/src/internal/adapters/transaction-settlement.ts +70 -0
  112. package/src/internal/client-lifecycle.ts +4 -11
  113. package/src/internal/contract-normalization.ts +6 -14
  114. package/src/internal/database-facade.ts +138 -0
  115. package/src/internal/database-factory.ts +34 -306
  116. package/src/internal/database-types.ts +65 -0
  117. package/src/internal/dynamic.ts +16 -0
  118. package/src/internal/executor.ts +4 -11
  119. package/src/internal/promise.ts +4 -12
  120. package/src/internal/query-execution.ts +4 -8
  121. package/src/internal/recipe.ts +24 -89
  122. package/src/internal/relation-plan.ts +1 -1
  123. package/src/internal/relation-result.ts +27 -0
  124. package/src/internal/relation-runtime.ts +45 -135
  125. package/src/internal/relation-stream.ts +24 -51
  126. package/src/internal/sqlite-datetime.ts +20 -54
  127. package/src/internal/sqlite-pragmas.ts +3 -16
  128. package/src/internal/testing.ts +13 -15
  129. package/src/internal/transaction.ts +16 -109
  130. package/src/relation/include-metadata.ts +11 -43
  131. package/src/relation/include.ts +46 -140
  132. package/src/relation/prisma-methods.ts +36 -122
  133. package/src/relation.ts +20 -48
  134. package/src/sqlite.ts +59 -85
  135. package/src/testing/transaction.ts +20 -33
  136. package/src/testing/types.ts +15 -34
  137. package/src/testing/vitest.ts +14 -28
  138. package/src/testing.ts +3 -3
@@ -2,11 +2,7 @@ import { DatabaseSync } from "node:sqlite";
2
2
 
3
3
  export const MEMORY_PATH = ":memory:";
4
4
 
5
- /**
6
- * Prisma Next's SQLite driver opens a fresh `node:sqlite` connection for every
7
- * `RuntimeConnection`, so an in-memory database would give each transaction its
8
- * own empty database.
9
- */
5
+ // Prisma Next's SQLite driver opens a fresh `node:sqlite` connection per `RuntimeConnection`, so each transaction would get its own empty in-memory database.
10
6
  export const assertFileBackedPath = (path: string): void => {
11
7
  if (path === MEMORY_PATH || path.trim().length === 0) {
12
8
  throw new TypeError(
@@ -15,17 +11,8 @@ export const assertFileBackedPath = (path: string): void => {
15
11
  }
16
12
  };
17
13
 
18
- /**
19
- * Apply connect-time pragmas.
20
- *
21
- * The driver already sets `foreign_keys` and `busy_timeout` on every connection
22
- * it opens, but it has no hook for anything else, so durable pragmas such as
23
- * `journal_mode` are applied once against the database file itself.
24
- */
25
- export const applySqlitePragmas = (
26
- path: string,
27
- pragmas: ReadonlyArray<string>,
28
- ): void => {
14
+ // The driver has no hook for pragmas beyond `foreign_keys` and `busy_timeout`, so durable ones such as `journal_mode` go to the file once.
15
+ export const applySqlitePragmas = (path: string, pragmas: readonly string[]): void => {
29
16
  if (pragmas.length === 0) {
30
17
  return;
31
18
  }
@@ -1,9 +1,7 @@
1
1
  import type { Effect } from "effect";
2
- import type { PrismaError } from "../error.js";
2
+ import type { PrismaError } from "../error.ts";
3
3
 
4
- export const DatabaseTestingTypeId: unique symbol = Symbol.for(
5
- "@shivaedev/effect-prisma/DatabaseTesting",
6
- );
4
+ export const DatabaseTestingTypeId: unique symbol = Symbol.for("@shivaedev/effect-prisma/DatabaseTesting");
7
5
 
8
6
  export interface DatabaseTesting<DatabaseId> {
9
7
  readonly withTestTransaction: <A, E, R>(
@@ -15,18 +13,18 @@ export interface DatabaseWithTesting<DatabaseId> {
15
13
  readonly [DatabaseTestingTypeId]: DatabaseTesting<DatabaseId>;
16
14
  }
17
15
 
18
- export const getDatabaseTesting = <DatabaseId>(
19
- database: object,
20
- ): DatabaseTesting<DatabaseId> => {
21
- const testing = Reflect.get(database, DatabaseTestingTypeId) as
22
- | DatabaseTesting<DatabaseId>
23
- | undefined;
16
+ // makeSqlDatabase installs the testing hooks for the database's own service identifier.
17
+ function testingFor<DatabaseId>(testing: object): DatabaseTesting<DatabaseId>;
18
+ function testingFor(testing: object): unknown {
19
+ return testing;
20
+ }
24
21
 
25
- if (testing === undefined) {
26
- throw new TypeError(
27
- "The database was not created by this copy of @shivaedev/effect-prisma",
28
- );
22
+ export const getDatabaseTesting = <DatabaseId>(database: object): DatabaseTesting<DatabaseId> => {
23
+ const testing: unknown = Reflect.get(database, DatabaseTestingTypeId);
24
+
25
+ if (typeof testing !== "object" || testing === null || typeof Reflect.get(testing, "withTestTransaction") !== "function") {
26
+ throw new TypeError("The database was not created by this copy of @shivaedev/effect-prisma");
29
27
  }
30
28
 
31
- return testing;
29
+ return testingFor<DatabaseId>(testing);
32
30
  };
@@ -1,45 +1,26 @@
1
1
  import { orm } from "@prisma-next/sql-orm-client";
2
- import type {
3
- RuntimeConnection,
4
- RuntimeTransaction,
5
- } from "@prisma-next/sql-runtime";
6
2
  import { Effect, Exit, Semaphore } from "effect";
7
- import type { PrismaError } from "../error.js";
8
- import type { AnySqlContract, DatabaseExecutor } from "./executor.js";
9
- import { fromPrismaPromise } from "./promise.js";
3
+ import type { PrismaError } from "../error.ts";
4
+ import { type SettledConnection, type SettledTransaction, settleConnection } from "./adapters/transaction-settlement.ts";
5
+ import type { AnySqlContract, DatabaseExecutor } from "./executor.ts";
6
+ import { fromPrismaPromise } from "./promise.ts";
10
7
 
11
- export type TransactionOrm<Contract extends AnySqlContract> = ReturnType<
12
- typeof orm<Contract>
13
- >;
8
+ export type TransactionOrm<Contract extends AnySqlContract> = ReturnType<typeof orm<Contract>>;
14
9
 
15
10
  export const withTransactionSemaphore = <A, E, R>(
16
11
  semaphore: Semaphore.Semaphore | undefined,
17
12
  transaction: Effect.Effect<A, E, R>,
18
- ): Effect.Effect<A, E, R> =>
19
- semaphore === undefined ? transaction : semaphore.withPermit(transaction);
13
+ ): Effect.Effect<A, E, R> => (semaphore === undefined ? transaction : semaphore.withPermit(transaction));
20
14
 
21
- export interface TransactionResource<
22
- Models extends object,
23
- Contract extends AnySqlContract,
24
- > {
25
- readonly connection: RuntimeConnection;
26
- readonly transaction: RuntimeTransaction;
15
+ export interface TransactionResource<Models extends object, Contract extends AnySqlContract> {
16
+ readonly connection: SettledConnection;
27
17
  readonly executor: DatabaseExecutor<Models, Contract> & {
28
18
  readonly querySemaphore: Semaphore.Semaphore;
29
19
  };
20
+ readonly transaction: SettledTransaction;
30
21
  }
31
22
 
32
- const runtimeFailure = (
33
- code: string,
34
- cause: unknown,
35
- details?: Readonly<Record<string, unknown>>,
36
- ): Error & { readonly code: string } =>
37
- Object.assign(new Error(code, { cause }), { code, ...details });
38
-
39
- export const acquireTransaction = <
40
- Models extends object,
41
- Contract extends AnySqlContract,
42
- >(
23
+ export const acquireTransaction = <Models extends object, Contract extends AnySqlContract>(
43
24
  current: DatabaseExecutor<Models, Contract>,
44
25
  models: (orm: TransactionOrm<Contract>) => Models,
45
26
  mode: "test" | "transaction",
@@ -50,13 +31,12 @@ export const acquireTransaction = <
50
31
  try {
51
32
  const transaction = await connection.transaction();
52
33
  const transactionOrm = orm({
53
- runtime: transaction,
54
34
  context: current.client.context,
35
+ runtime: transaction,
55
36
  });
56
37
 
57
38
  return {
58
39
  connection,
59
- transaction,
60
40
  executor: {
61
41
  client: current.client,
62
42
  identity: current.identity,
@@ -70,6 +50,7 @@ export const acquireTransaction = <
70
50
  transactionIdentity: {},
71
51
  transactionSemaphore: current.transactionSemaphore,
72
52
  },
53
+ transaction,
73
54
  };
74
55
  } catch (error) {
75
56
  await connection.destroy(error).catch(() => undefined);
@@ -77,32 +58,17 @@ export const acquireTransaction = <
77
58
  }
78
59
  });
79
60
 
80
- export const releaseTransaction = <
81
- Models extends object,
82
- Contract extends AnySqlContract,
83
- A,
84
- E,
85
- >(
61
+ export const releaseTransaction = <Models extends object, Contract extends AnySqlContract, A, E>(
86
62
  resource: TransactionResource<Models, Contract>,
87
63
  exit: Exit.Exit<A, E>,
88
64
  ): Effect.Effect<void, PrismaError> => settleTransaction(resource, exit, true);
89
65
 
90
- export const releaseTestTransaction = <
91
- Models extends object,
92
- Contract extends AnySqlContract,
93
- A,
94
- E,
95
- >(
66
+ export const releaseTestTransaction = <Models extends object, Contract extends AnySqlContract, A, E>(
96
67
  resource: TransactionResource<Models, Contract>,
97
68
  exit: Exit.Exit<A, E>,
98
69
  ): Effect.Effect<void, PrismaError> => settleTransaction(resource, exit, false);
99
70
 
100
- const settleTransaction = <
101
- Models extends object,
102
- Contract extends AnySqlContract,
103
- A,
104
- E,
105
- >(
71
+ const settleTransaction = <Models extends object, Contract extends AnySqlContract, A, E>(
106
72
  resource: TransactionResource<Models, Contract>,
107
73
  exit: Exit.Exit<A, E>,
108
74
  commitOnSuccess: boolean,
@@ -112,66 +78,7 @@ const settleTransaction = <
112
78
  resource.executor.liveness.open = false;
113
79
  }).pipe(
114
80
  Effect.andThen(
115
- resource.executor.querySemaphore.withPermit(
116
- fromPrismaPromise(async () => {
117
- let disposed = false;
118
- let failure: unknown;
119
-
120
- const destroy = async (reason: unknown): Promise<void> => {
121
- if (disposed) {
122
- return;
123
- }
124
- disposed = true;
125
- await resource.connection.destroy(reason).catch(() => undefined);
126
- };
127
-
128
- if (commitOnSuccess && Exit.isSuccess(exit)) {
129
- try {
130
- await resource.transaction.commit();
131
- } catch (commitError) {
132
- try {
133
- await resource.transaction.rollback();
134
- } catch {
135
- await destroy(commitError);
136
- }
137
- failure = runtimeFailure(
138
- "RUNTIME.TRANSACTION_COMMIT_FAILED",
139
- commitError,
140
- );
141
- }
142
- } else {
143
- try {
144
- await resource.transaction.rollback();
145
- } catch (rollbackError) {
146
- await destroy(rollbackError);
147
- failure = runtimeFailure(
148
- "RUNTIME.TRANSACTION_ROLLBACK_FAILED",
149
- rollbackError,
150
- );
151
- }
152
- }
153
-
154
- if (!disposed) {
155
- try {
156
- await resource.connection.release();
157
- } catch (releaseError) {
158
- await destroy(releaseError);
159
- if (failure !== undefined) {
160
- throw runtimeFailure(
161
- "RUNTIME.TRANSACTION_RELEASE_FAILED",
162
- failure,
163
- { releaseError },
164
- );
165
- }
166
- throw releaseError;
167
- }
168
- }
169
-
170
- if (failure !== undefined) {
171
- throw failure;
172
- }
173
- }),
174
- ),
81
+ resource.executor.querySemaphore.withPermit(fromPrismaPromise(() => settleConnection(resource, commitOnSuccess && Exit.isSuccess(exit)))),
175
82
  ),
176
83
  ),
177
84
  );
@@ -8,46 +8,26 @@ type RelationDefinition<
8
8
  Contract extends AnyPostgresContract,
9
9
  Model extends string,
10
10
  RelationName extends string,
11
- > = RelationName extends keyof RelationsOf<Contract, Model>
12
- ? RelationsOf<Contract, Model>[RelationName]
13
- : never;
11
+ > = RelationName extends keyof RelationsOf<Contract, Model> ? RelationsOf<Contract, Model>[RelationName] : never;
14
12
 
15
- type RelationCardinalityOf<
16
- Contract extends AnyPostgresContract,
17
- Model extends string,
18
- RelationName extends string,
19
- > =
13
+ type RelationCardinalityOf<Contract extends AnyPostgresContract, Model extends string, RelationName extends string> =
20
14
  RelationDefinition<Contract, Model, RelationName> extends {
21
15
  readonly cardinality: infer Cardinality extends string;
22
16
  }
23
17
  ? Cardinality
24
18
  : never;
25
19
 
26
- export type IsToManyRelation<
27
- Contract extends AnyPostgresContract,
28
- Model extends string,
29
- RelationName extends string,
30
- > =
31
- RelationCardinalityOf<Contract, Model, RelationName> extends "1:N" | "N:M"
32
- ? true
33
- : false;
20
+ export type IsToManyRelation<Contract extends AnyPostgresContract, Model extends string, RelationName extends string> =
21
+ RelationCardinalityOf<Contract, Model, RelationName> extends "1:N" | "N:M" ? true : false;
34
22
 
35
- export type RelatedModelNameOf<
36
- Contract extends AnyPostgresContract,
37
- Model extends string,
38
- RelationName extends string,
39
- > =
23
+ export type RelatedModelNameOf<Contract extends AnyPostgresContract, Model extends string, RelationName extends string> =
40
24
  RelationDefinition<Contract, Model, RelationName> extends {
41
25
  readonly to: { readonly model: infer Related extends string };
42
26
  }
43
27
  ? Related
44
28
  : never;
45
29
 
46
- type RelationLocalFields<
47
- Contract extends AnyPostgresContract,
48
- Model extends string,
49
- RelationName extends string,
50
- > =
30
+ type RelationLocalFields<Contract extends AnyPostgresContract, Model extends string, RelationName extends string> =
51
31
  RelationDefinition<Contract, Model, RelationName> extends {
52
32
  readonly on: {
53
33
  readonly localFields: infer Fields extends readonly string[];
@@ -56,8 +36,7 @@ type RelationLocalFields<
56
36
  ? Fields
57
37
  : readonly [];
58
38
 
59
- type DefaultNamespace<Contract extends AnyPostgresContract> =
60
- Contract["domain"]["namespaces"][keyof Contract["domain"]["namespaces"]];
39
+ type DefaultNamespace<Contract extends AnyPostgresContract> = Contract["domain"]["namespaces"][keyof Contract["domain"]["namespaces"]];
61
40
 
62
41
  type ModelFields<Contract extends AnyPostgresContract, Model extends string> =
63
42
  DefaultNamespace<Contract> extends {
@@ -70,10 +49,7 @@ type ModelFields<Contract extends AnyPostgresContract, Model extends string> =
70
49
  : never
71
50
  : never;
72
51
 
73
- type AnyNullableField<
74
- Fields,
75
- Names extends readonly string[],
76
- > = Names extends readonly [
52
+ type AnyNullableField<Fields, Names extends readonly string[]> = Names extends readonly [
77
53
  infer Head extends string,
78
54
  ...infer Tail extends readonly string[],
79
55
  ]
@@ -84,19 +60,11 @@ type AnyNullableField<
84
60
  : true
85
61
  : false;
86
62
 
87
- export type IncludedRelationValue<
88
- Contract extends AnyPostgresContract,
89
- Model extends string,
90
- RelationName extends string,
91
- Value,
92
- > =
63
+ export type IncludedRelationValue<Contract extends AnyPostgresContract, Model extends string, RelationName extends string, Value> =
93
64
  RelationCardinalityOf<Contract, Model, RelationName> extends "1:N" | "N:M"
94
- ? Array<Value>
65
+ ? Value[]
95
66
  : RelationCardinalityOf<Contract, Model, RelationName> extends "N:1"
96
- ? AnyNullableField<
97
- ModelFields<Contract, Model>,
98
- RelationLocalFields<Contract, Model, RelationName>
99
- > extends true
67
+ ? AnyNullableField<ModelFields<Contract, Model>, RelationLocalFields<Contract, Model, RelationName>> extends true
100
68
  ? Value | null
101
69
  : Value
102
70
  : Value | null;
@@ -1,40 +1,13 @@
1
- import type {
2
- DefaultModelRow,
3
- Collection as PrismaCollection,
4
- RelationNames,
5
- } from "@prisma-next/sql-orm-client";
6
- import type { Relation, RelationQuery } from "../relation.js";
7
- import type {
8
- AnyPostgresContract,
9
- IncludedRelationValue,
10
- IsToManyRelation,
11
- RelatedModelNameOf,
12
- } from "./include-metadata.js";
1
+ import type { DefaultModelRow, Collection as PrismaCollection, RelationNames } from "@prisma-next/sql-orm-client";
2
+ import type { Relation, RelationQuery } from "../relation.ts";
3
+ import type { AnyPostgresContract, IncludedRelationValue, IsToManyRelation, RelatedModelNameOf } from "./include-metadata.ts";
13
4
 
14
5
  type Simplify<Value> = { [Key in keyof Value]: Value[Key] };
15
6
 
16
- type QueryValue<Query> =
17
- Query extends RelationQuery<
18
- infer Value,
19
- infer _Contract,
20
- infer _Model,
21
- infer _DatabaseId
22
- >
23
- ? Value
24
- : never;
7
+ type QueryValue<Query> = Query extends RelationQuery<infer Value, infer _Contract, infer _Model, infer _DatabaseId> ? Value : never;
25
8
 
26
- type AcceptRelatedQuery<
27
- Query,
28
- Contract extends AnyPostgresContract,
29
- Model extends string,
30
- DatabaseId,
31
- > = [Query] extends [
32
- RelationQuery<
33
- infer _Value,
34
- infer QueryContract,
35
- infer QueryModel,
36
- infer QueryDatabaseId
37
- >,
9
+ type AcceptRelatedQuery<Query, Contract extends AnyPostgresContract, Model extends string, DatabaseId> = [Query] extends [
10
+ RelationQuery<infer _Value, infer QueryContract, infer QueryModel, infer QueryDatabaseId>,
38
11
  ]
39
12
  ? [QueryContract] extends [Contract]
40
13
  ? [Contract] extends [QueryContract]
@@ -49,15 +22,8 @@ type AcceptRelatedQuery<
49
22
  : never
50
23
  : never;
51
24
 
52
- type IncludedQueryValue<
53
- Query,
54
- Contract extends AnyPostgresContract,
55
- Model extends string,
56
- RelationName extends string,
57
- > =
58
- QueryValue<Query> extends ReadonlyArray<infer Row>
59
- ? IncludedRelationValue<Contract, Model, RelationName, Row>
60
- : QueryValue<Query>;
25
+ type IncludedQueryValue<Query, Contract extends AnyPostgresContract, Model extends string, RelationName extends string> =
26
+ QueryValue<Query> extends ReadonlyArray<infer Row> ? IncludedRelationValue<Contract, Model, RelationName, Row> : QueryValue<Query>;
61
27
 
62
28
  type QueryShapeValue<Shape extends Readonly<Record<string, unknown>>> = {
63
29
  readonly [Key in keyof Shape]: QueryValue<Shape[Key]>;
@@ -69,110 +35,50 @@ type AcceptRelatedQueryShape<
69
35
  Model extends string,
70
36
  DatabaseId,
71
37
  > = {
72
- readonly [Key in keyof Shape]: Shape[Key] &
73
- AcceptRelatedQuery<Shape[Key], Contract, Model, DatabaseId>;
38
+ readonly [Key in keyof Shape]: Shape[Key] & AcceptRelatedQuery<Shape[Key], Contract, Model, DatabaseId>;
74
39
  };
75
40
 
76
- type WithIncludedRelation<
77
- Collection,
78
- Contract extends AnyPostgresContract,
79
- Model extends string,
80
- RelationName extends string,
81
- Value,
82
- > =
41
+ type WithIncludedRelation<Collection, Contract extends AnyPostgresContract, Model extends string, RelationName extends string, Value> =
83
42
  Collection extends PrismaCollection<Contract, Model, infer Row, infer State>
84
- ? PrismaCollection<
85
- Contract,
86
- Model,
87
- Simplify<Row & { readonly [Key in RelationName]: Value }>,
88
- State
89
- >
43
+ ? PrismaCollection<Contract, Model, Simplify<Row & { readonly [Key in RelationName]: Value }>, State>
90
44
  : never;
91
45
 
92
- export type IncludeMethod<
93
- Collection,
94
- Contract,
95
- Model extends string,
96
- DatabaseId,
97
- > = Contract extends AnyPostgresContract
98
- ? Collection extends PrismaCollection<
46
+ interface IncludeOverloads<Collection, Contract extends AnyPostgresContract, Model extends string, DatabaseId> {
47
+ <RelationName extends RelationNames<Contract, Model>>(
48
+ relationName: RelationName,
49
+ ): Relation<
50
+ WithIncludedRelation<
51
+ Collection,
99
52
  Contract,
100
53
  Model,
101
- infer _Row,
102
- infer _State
103
- >
104
- ? {
105
- include<RelationName extends RelationNames<Contract, Model>>(
106
- relationName: RelationName,
107
- ): Relation<
108
- WithIncludedRelation<
109
- Collection,
110
- Contract,
111
- Model,
112
- RelationName,
113
- IncludedRelationValue<
114
- Contract,
115
- Model,
116
- RelationName,
117
- DefaultModelRow<
118
- Contract,
119
- RelatedModelNameOf<Contract, Model, RelationName>
120
- >
121
- >
122
- >,
123
- Contract,
124
- Model,
125
- DatabaseId
126
- >;
127
- include<RelationName extends RelationNames<Contract, Model>, Query>(
128
- relationName: RelationName,
129
- query: Query &
130
- AcceptRelatedQuery<
131
- Query,
132
- Contract,
133
- RelatedModelNameOf<Contract, Model, RelationName>,
134
- DatabaseId
135
- >,
136
- ): Relation<
137
- WithIncludedRelation<
138
- Collection,
139
- Contract,
140
- Model,
141
- RelationName,
142
- IncludedQueryValue<Query, Contract, Model, RelationName>
143
- >,
144
- Contract,
145
- Model,
146
- DatabaseId
147
- >;
148
- include<
149
- RelationName extends RelationNames<Contract, Model>,
150
- Shape extends Readonly<Record<string, unknown>>,
151
- >(
152
- relationName: RelationName,
153
- shape: IsToManyRelation<Contract, Model, RelationName> extends true
154
- ? keyof Shape extends never
155
- ? never
156
- : Shape &
157
- AcceptRelatedQueryShape<
158
- Shape,
159
- Contract,
160
- RelatedModelNameOf<Contract, Model, RelationName>,
161
- DatabaseId
162
- >
163
- : never,
164
- ): Relation<
165
- WithIncludedRelation<
166
- Collection,
167
- Contract,
168
- Model,
169
- RelationName,
170
- QueryShapeValue<Shape>
171
- >,
172
- Contract,
173
- Model,
174
- DatabaseId
175
- >;
176
- }
54
+ RelationName,
55
+ IncludedRelationValue<Contract, Model, RelationName, DefaultModelRow<Contract, RelatedModelNameOf<Contract, Model, RelationName>>>
56
+ >,
57
+ Contract,
58
+ Model,
59
+ DatabaseId
60
+ >;
61
+ <RelationName extends RelationNames<Contract, Model>, Query>(
62
+ relationName: RelationName,
63
+ query: Query & AcceptRelatedQuery<Query, Contract, RelatedModelNameOf<Contract, Model, RelationName>, DatabaseId>,
64
+ ): Relation<
65
+ WithIncludedRelation<Collection, Contract, Model, RelationName, IncludedQueryValue<Query, Contract, Model, RelationName>>,
66
+ Contract,
67
+ Model,
68
+ DatabaseId
69
+ >;
70
+ <RelationName extends RelationNames<Contract, Model>, Shape extends Readonly<Record<string, unknown>>>(
71
+ relationName: RelationName,
72
+ shape: IsToManyRelation<Contract, Model, RelationName> extends true
73
+ ? keyof Shape extends never
74
+ ? never
75
+ : Shape & AcceptRelatedQueryShape<Shape, Contract, RelatedModelNameOf<Contract, Model, RelationName>, DatabaseId>
76
+ : never,
77
+ ): Relation<WithIncludedRelation<Collection, Contract, Model, RelationName, QueryShapeValue<Shape>>, Contract, Model, DatabaseId>;
78
+ }
79
+
80
+ export type IncludeMethod<Collection, Contract, Model extends string, DatabaseId> = Contract extends AnyPostgresContract
81
+ ? Collection extends PrismaCollection<Contract, Model, infer _Row, infer _State>
82
+ ? { include: IncludeOverloads<Collection, Contract, Model, DatabaseId> }
177
83
  : Record<never, never>
178
84
  : Record<never, never>;