@shivaedev/effect-prisma 0.4.3 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/README.md +37 -0
- package/dist/database.d.ts +8 -27
- package/dist/database.d.ts.map +1 -1
- package/dist/database.js +29 -78
- package/dist/database.js.map +1 -1
- package/dist/internal/database-factory.d.ts +46 -0
- package/dist/internal/database-factory.d.ts.map +1 -0
- package/dist/internal/database-factory.js +56 -0
- package/dist/internal/database-factory.js.map +1 -0
- package/dist/internal/executor.d.ts +16 -5
- package/dist/internal/executor.d.ts.map +1 -1
- package/dist/internal/sqlite-datetime.d.ts +31 -0
- package/dist/internal/sqlite-datetime.d.ts.map +1 -0
- package/dist/internal/sqlite-datetime.js +66 -0
- package/dist/internal/sqlite-datetime.js.map +1 -0
- package/dist/internal/sqlite-pragmas.d.ts +16 -0
- package/dist/internal/sqlite-pragmas.d.ts.map +1 -0
- package/dist/internal/sqlite-pragmas.js +34 -0
- package/dist/internal/sqlite-pragmas.js.map +1 -0
- package/dist/internal/transaction.d.ts +7 -6
- package/dist/internal/transaction.d.ts.map +1 -1
- package/dist/internal/transaction.js.map +1 -1
- package/dist/sqlite.d.ts +28 -0
- package/dist/sqlite.d.ts.map +1 -0
- package/dist/sqlite.js +41 -0
- package/dist/sqlite.js.map +1 -0
- package/package.json +11 -2
- package/src/database.ts +54 -204
- package/src/internal/database-factory.ts +209 -0
- package/src/internal/executor.ts +17 -5
- package/src/internal/sqlite-datetime.ts +95 -0
- package/src/internal/sqlite-pragmas.ts +41 -0
- package/src/internal/transaction.ts +11 -8
- package/src/sqlite.ts +108 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/internal/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,
|
|
1
|
+
{"version":3,"file":"transaction.d.ts","sourceRoot":"","sources":["../../src/internal/transaction.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,6BAA6B,CAAC;AAClD,OAAO,KAAK,EACX,iBAAiB,EACjB,kBAAkB,EAClB,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAa,MAAM,QAAQ,CAAC;AACjD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtE,MAAM,MAAM,cAAc,CAAC,QAAQ,SAAS,cAAc,IAAI,UAAU,CACvE,OAAO,GAAG,CAAC,QAAQ,CAAC,CACpB,CAAC;AAEF,MAAM,WAAW,mBAAmB,CACnC,MAAM,SAAS,MAAM,EACrB,QAAQ,SAAS,cAAc;IAE/B,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAC;IACvC,QAAQ,CAAC,WAAW,EAAE,kBAAkB,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACtD;AASD,eAAO,MAAM,kBAAkB,GAC9B,MAAM,SAAS,MAAM,EACrB,QAAQ,SAAS,cAAc,EAE/B,SAAS,gBAAgB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC3C,QAAQ,CAAC,GAAG,EAAE,cAAc,CAAC,QAAQ,CAAC,KAAK,MAAM,KAC/C,MAAM,CAAC,MAAM,CAAC,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,WAAW,CAyBhE,CAAC;AAEJ,eAAO,MAAM,kBAAkB,GAC9B,MAAM,SAAS,MAAM,EACrB,QAAQ,SAAS,cAAc,EAC/B,CAAC,EACD,CAAC,EAED,UAAU,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC/C,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAA4C,CAAC;AAE/E,eAAO,MAAM,sBAAsB,GAClC,MAAM,SAAS,MAAM,EACrB,QAAQ,SAAS,cAAc,EAC/B,CAAC,EACD,CAAC,EAED,UAAU,mBAAmB,CAAC,MAAM,EAAE,QAAQ,CAAC,EAC/C,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC,KACnB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,CAA6C,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/internal/transaction.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"transaction.js","sourceRoot":"","sources":["../../src/internal/transaction.ts"],"names":[],"mappings":"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"}
|
package/dist/sqlite.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { type SqliteOptionsBase } from "@prisma-next/sqlite/runtime";
|
|
2
|
+
import type { Layer } from "effect";
|
|
3
|
+
import type { PrismaError } from "./error.js";
|
|
4
|
+
import { type DatabaseIdentifier, type DatabaseServiceHolder, type DefaultModels } from "./internal/database-factory.js";
|
|
5
|
+
import type { AnySqlContract, ExecutorIdentifier } from "./internal/executor.js";
|
|
6
|
+
export declare const defaultSqlitePragmas: ReadonlyArray<string>;
|
|
7
|
+
export interface SqliteDatabaseLayerOptions extends SqliteOptionsBase {
|
|
8
|
+
/** Path to the database file. In-memory databases are not supported. */
|
|
9
|
+
readonly path: string;
|
|
10
|
+
/**
|
|
11
|
+
* Pragmas applied once when the Layer connects. Defaults to
|
|
12
|
+
* {@link defaultSqlitePragmas}; pass `[]` to skip them.
|
|
13
|
+
*/
|
|
14
|
+
readonly pragmas?: ReadonlyArray<string>;
|
|
15
|
+
}
|
|
16
|
+
type SqliteFactoryOptions<Contract extends AnySqlContract> = {
|
|
17
|
+
readonly contract: Contract;
|
|
18
|
+
readonly contractJson?: never;
|
|
19
|
+
} | {
|
|
20
|
+
readonly contractJson: unknown;
|
|
21
|
+
readonly contract?: never;
|
|
22
|
+
};
|
|
23
|
+
export interface SqliteDatabaseDefinition<Contract extends AnySqlContract, Requirement = ExecutorIdentifier<DefaultModels<Contract>>> extends DatabaseServiceHolder<Contract, Requirement> {
|
|
24
|
+
readonly layer: (options: SqliteDatabaseLayerOptions) => Layer.Layer<DatabaseIdentifier<Contract> | Requirement, PrismaError>;
|
|
25
|
+
}
|
|
26
|
+
export declare const makeSqliteDatabase: <const Contract extends AnySqlContract>(identifier: string, options: SqliteFactoryOptions<Contract>) => SqliteDatabaseDefinition<Contract>;
|
|
27
|
+
export {};
|
|
28
|
+
//# sourceMappingURL=sqlite.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.d.ts","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAe,EAEd,KAAK,iBAAiB,EACtB,MAAM,6BAA6B,CAAC;AACrC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAK9C,OAAO,EACN,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,aAAa,EAElB,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EACX,cAAc,EACd,kBAAkB,EAClB,MAAM,wBAAwB,CAAC;AAQhC,eAAO,MAAM,oBAAoB,EAAE,aAAa,CAAC,MAAM,CAAwB,CAAC;AAEhF,MAAM,WAAW,0BAA2B,SAAQ,iBAAiB;IACpE,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,QAAQ,CAAC,OAAO,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;CACzC;AAED,KAAK,oBAAoB,CAAC,QAAQ,SAAS,cAAc,IACtD;IACA,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAC5B,QAAQ,CAAC,YAAY,CAAC,EAAE,KAAK,CAAC;CAC7B,GACD;IACA,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;CACzB,CAAC;AAEL,MAAM,WAAW,wBAAwB,CACxC,QAAQ,SAAS,cAAc,EAC/B,WAAW,GAAG,kBAAkB,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CACxD,SAAQ,qBAAqB,CAAC,QAAQ,EAAE,WAAW,CAAC;IACrD,QAAQ,CAAC,KAAK,EAAE,CACf,OAAO,EAAE,0BAA0B,KAC/B,KAAK,CAAC,KAAK,CAAC,kBAAkB,CAAC,QAAQ,CAAC,GAAG,WAAW,EAAE,WAAW,CAAC,CAAC;CAC1E;AAED,eAAO,MAAM,kBAAkB,GAAI,KAAK,CAAC,QAAQ,SAAS,cAAc,EACvE,YAAY,MAAM,EAClB,SAAS,oBAAoB,CAAC,QAAQ,CAAC,KACrC,wBAAwB,CAAC,QAAQ,CA8CnC,CAAC"}
|
package/dist/sqlite.js
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import sqlite, {} from "@prisma-next/sqlite/runtime";
|
|
2
|
+
import { acquireConnectedClient, assertAvailableModelNames, } from "./internal/client-lifecycle.js";
|
|
3
|
+
import { makeSqlDatabase, } from "./internal/database-factory.js";
|
|
4
|
+
import { fromPrismaPromise } from "./internal/promise.js";
|
|
5
|
+
import { decodeSqliteDatetimesAsUtc } from "./internal/sqlite-datetime.js";
|
|
6
|
+
import { applySqlitePragmas, assertFileBackedPath, } from "./internal/sqlite-pragmas.js";
|
|
7
|
+
export const defaultSqlitePragmas = ["journal_mode=WAL"];
|
|
8
|
+
export const makeSqliteDatabase = (identifier, options) => {
|
|
9
|
+
return makeSqlDatabase(identifier, (layerOptions) => {
|
|
10
|
+
assertFileBackedPath(layerOptions.path);
|
|
11
|
+
applySqlitePragmas(layerOptions.path, layerOptions.pragmas ?? defaultSqlitePragmas);
|
|
12
|
+
const clientOptions = {
|
|
13
|
+
path: layerOptions.path,
|
|
14
|
+
extensions: layerOptions.extensions,
|
|
15
|
+
middleware: layerOptions.middleware,
|
|
16
|
+
verifyMarker: layerOptions.verifyMarker,
|
|
17
|
+
};
|
|
18
|
+
const client = options.contract === undefined
|
|
19
|
+
? sqlite({
|
|
20
|
+
...clientOptions,
|
|
21
|
+
contractJson: options.contractJson,
|
|
22
|
+
})
|
|
23
|
+
: sqlite({
|
|
24
|
+
...clientOptions,
|
|
25
|
+
contract: options.contract,
|
|
26
|
+
});
|
|
27
|
+
decodeSqliteDatetimesAsUtc(client.context);
|
|
28
|
+
return fromPrismaPromise(() => acquireConnectedClient(client, () => {
|
|
29
|
+
// The SQLite client already exposes the unbound namespace.
|
|
30
|
+
const models = client.orm;
|
|
31
|
+
assertAvailableModelNames(Object.keys(models));
|
|
32
|
+
return {
|
|
33
|
+
client,
|
|
34
|
+
models,
|
|
35
|
+
querySemaphore: undefined,
|
|
36
|
+
transactional: false,
|
|
37
|
+
};
|
|
38
|
+
}));
|
|
39
|
+
});
|
|
40
|
+
};
|
|
41
|
+
//# sourceMappingURL=sqlite.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlite.js","sourceRoot":"","sources":["../src/sqlite.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,EAAE,EAGd,MAAM,6BAA6B,CAAC;AAGrC,OAAO,EACN,sBAAsB,EACtB,yBAAyB,GACzB,MAAM,gCAAgC,CAAC;AACxC,OAAO,EAIN,eAAe,GACf,MAAM,gCAAgC,CAAC;AAKxC,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAC1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,+BAA+B,CAAC;AAC3E,OAAO,EACN,kBAAkB,EAClB,oBAAoB,GACpB,MAAM,8BAA8B,CAAC;AAEtC,MAAM,CAAC,MAAM,oBAAoB,GAA0B,CAAC,kBAAkB,CAAC,CAAC;AA+BhF,MAAM,CAAC,MAAM,kBAAkB,GAAG,CACjC,UAAkB,EAClB,OAAuC,EACF,EAAE;IAGvC,OAAO,eAAe,CACrB,UAAU,EACV,CAAC,YAAY,EAAE,EAAE;QAChB,oBAAoB,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QACxC,kBAAkB,CACjB,YAAY,CAAC,IAAI,EACjB,YAAY,CAAC,OAAO,IAAI,oBAAoB,CAC5C,CAAC;QAEF,MAAM,aAAa,GAAG;YACrB,IAAI,EAAE,YAAY,CAAC,IAAI;YACvB,UAAU,EAAE,YAAY,CAAC,UAAU;YACnC,UAAU,EAAE,YAAY,CAAC,UAAU;YACnC,YAAY,EAAE,YAAY,CAAC,YAAY;SACvC,CAAC;QACF,MAAM,MAAM,GACX,OAAO,CAAC,QAAQ,KAAK,SAAS;YAC7B,CAAC,CAAC,MAAM,CAAW;gBACjB,GAAG,aAAa;gBAChB,YAAY,EAAE,OAAO,CAAC,YAAY;aAClC,CAAC;YACH,CAAC,CAAC,MAAM,CAAW;gBACjB,GAAG,aAAa;gBAChB,QAAQ,EAAE,OAAO,CAAC,QAAQ;aAC1B,CAAC,CAAC;QAEN,0BAA0B,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QAE3C,OAAO,iBAAiB,CAAC,GAAG,EAAE,CAC7B,sBAAsB,CAAC,MAAM,EAAE,GAAG,EAAE;YACnC,2DAA2D;YAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,GAAa,CAAC;YACpC,yBAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;YAC/C,OAAO;gBACN,MAAM;gBACN,MAAM;gBACN,cAAc,EAAE,SAAS;gBACzB,aAAa,EAAE,KAAK;aACpB,CAAC;QACH,CAAC,CAAC,CACF,CAAC;IACH,CAAC,CACqC,CAAC;AACzC,CAAC,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@shivaedev/effect-prisma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Effect-native PostgreSQL queries and transactions for Prisma Next",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -33,6 +33,12 @@
|
|
|
33
33
|
"import": "./dist/index.js",
|
|
34
34
|
"default": "./dist/index.js"
|
|
35
35
|
},
|
|
36
|
+
"./sqlite": {
|
|
37
|
+
"types": "./dist/sqlite.d.ts",
|
|
38
|
+
"source": "./src/sqlite.ts",
|
|
39
|
+
"import": "./dist/sqlite.js",
|
|
40
|
+
"default": "./dist/sqlite.js"
|
|
41
|
+
},
|
|
36
42
|
"./testing": {
|
|
37
43
|
"types": "./dist/testing.d.ts",
|
|
38
44
|
"source": "./src/testing.ts",
|
|
@@ -51,7 +57,8 @@
|
|
|
51
57
|
"@prisma-next/sql-contract": "0.15.0",
|
|
52
58
|
"@prisma-next/sql-orm-client": "0.15.0",
|
|
53
59
|
"@prisma-next/sql-relational-core": "0.15.0",
|
|
54
|
-
"@prisma-next/sql-runtime": "0.15.0"
|
|
60
|
+
"@prisma-next/sql-runtime": "0.15.0",
|
|
61
|
+
"@prisma-next/sqlite": "0.15.0"
|
|
55
62
|
},
|
|
56
63
|
"peerDependencies": {
|
|
57
64
|
"@effect/vitest": "4.0.0-beta.102",
|
|
@@ -65,8 +72,10 @@
|
|
|
65
72
|
"devDependencies": {
|
|
66
73
|
"@effect/vitest": "4.0.0-beta.102",
|
|
67
74
|
"@prisma-next/adapter-postgres": "0.15.0",
|
|
75
|
+
"@prisma-next/adapter-sqlite": "0.15.0",
|
|
68
76
|
"@prisma-next/cli": "0.15.0",
|
|
69
77
|
"@prisma-next/target-postgres": "0.15.0",
|
|
78
|
+
"@prisma-next/target-sqlite": "0.15.0",
|
|
70
79
|
"@types/node": "24.10.1",
|
|
71
80
|
"@types/pg": "8.20.0",
|
|
72
81
|
"@typescript/native": "npm:typescript@7.0.2",
|
package/src/database.ts
CHANGED
|
@@ -2,69 +2,34 @@ import postgres, {
|
|
|
2
2
|
type PostgresClient,
|
|
3
3
|
type PostgresOptionsBase,
|
|
4
4
|
} from "@prisma-next/postgres/runtime";
|
|
5
|
-
import {
|
|
5
|
+
import { type Layer, Redacted } from "effect";
|
|
6
6
|
import type { PrismaError } from "./error.js";
|
|
7
|
+
import { acquireConnectedClient } from "./internal/client-lifecycle.js";
|
|
7
8
|
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
type DatabaseIdentifier,
|
|
10
|
+
type DatabaseServiceHolder,
|
|
11
|
+
type DefaultModels,
|
|
12
|
+
makeSqlDatabase,
|
|
13
|
+
namespaceModels,
|
|
14
|
+
} from "./internal/database-factory.js";
|
|
11
15
|
import type {
|
|
12
|
-
|
|
13
|
-
DatabaseExecutor,
|
|
16
|
+
AnySqlContract,
|
|
14
17
|
ExecutorIdentifier,
|
|
15
18
|
} from "./internal/executor.js";
|
|
16
19
|
import { fromPrismaPromise } from "./internal/promise.js";
|
|
17
|
-
import { makeModelRelation } from "./internal/relation-runtime.js";
|
|
18
|
-
import { DatabaseTestingTypeId } from "./internal/testing.js";
|
|
19
|
-
import {
|
|
20
|
-
acquireTransaction,
|
|
21
|
-
releaseTestTransaction,
|
|
22
|
-
releaseTransaction,
|
|
23
|
-
} from "./internal/transaction.js";
|
|
24
|
-
import type { Relation } from "./relation.js";
|
|
25
|
-
|
|
26
|
-
type ClientFor<Contract extends AnyPostgresContract> = PostgresClient<Contract>;
|
|
27
|
-
type OrmFor<Contract extends AnyPostgresContract> = ClientFor<Contract>["orm"];
|
|
28
|
-
type DefaultNamespaceId<Contract extends AnyPostgresContract> =
|
|
29
|
-
"__unbound__" extends keyof OrmFor<Contract>
|
|
30
|
-
? "__unbound__"
|
|
31
|
-
: "public" extends keyof OrmFor<Contract>
|
|
32
|
-
? "public"
|
|
33
|
-
: keyof OrmFor<Contract>;
|
|
34
|
-
type DefaultModels<Contract extends AnyPostgresContract> =
|
|
35
|
-
OrmFor<Contract>[DefaultNamespaceId<Contract>] extends infer Models extends
|
|
36
|
-
object
|
|
37
|
-
? Models
|
|
38
|
-
: never;
|
|
39
|
-
|
|
40
|
-
interface DatabaseIdentifier<Contract extends AnyPostgresContract> {
|
|
41
|
-
readonly _contract: Contract;
|
|
42
|
-
readonly _databaseIdentifier: unique symbol;
|
|
43
|
-
}
|
|
44
20
|
|
|
45
|
-
type
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
>;
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export type DatabaseService<
|
|
55
|
-
Contract extends AnyPostgresContract,
|
|
56
|
-
Requirement,
|
|
57
|
-
> = DatabaseModels<Contract, Requirement> & {
|
|
58
|
-
transaction<A, E, R>(
|
|
59
|
-
program: Effect.Effect<A, E, R>,
|
|
60
|
-
): Effect.Effect<A, E | PrismaError, R | Requirement>;
|
|
61
|
-
};
|
|
21
|
+
export type {
|
|
22
|
+
AnyDatabase,
|
|
23
|
+
DatabaseRequirement,
|
|
24
|
+
DatabaseService,
|
|
25
|
+
DatabaseServiceOf,
|
|
26
|
+
} from "./internal/database-factory.js";
|
|
62
27
|
|
|
63
28
|
export interface DatabaseLayerOptions extends PostgresOptionsBase {
|
|
64
29
|
readonly url: string | Redacted.Redacted<string>;
|
|
65
30
|
}
|
|
66
31
|
|
|
67
|
-
type DatabaseFactoryOptions<Contract extends
|
|
32
|
+
type DatabaseFactoryOptions<Contract extends AnySqlContract> =
|
|
68
33
|
| {
|
|
69
34
|
readonly contract: Contract;
|
|
70
35
|
readonly contractJson?: never;
|
|
@@ -75,171 +40,56 @@ type DatabaseFactoryOptions<Contract extends AnyPostgresContract> =
|
|
|
75
40
|
};
|
|
76
41
|
|
|
77
42
|
export interface DatabaseDefinition<
|
|
78
|
-
Contract extends
|
|
43
|
+
Contract extends AnySqlContract,
|
|
79
44
|
Requirement = ExecutorIdentifier<DefaultModels<Contract>>,
|
|
80
|
-
> extends
|
|
81
|
-
DatabaseIdentifier<Contract>,
|
|
82
|
-
DatabaseService<Contract, Requirement>
|
|
83
|
-
> {
|
|
45
|
+
> extends DatabaseServiceHolder<Contract, Requirement> {
|
|
84
46
|
readonly layer: (
|
|
85
47
|
options: DatabaseLayerOptions,
|
|
86
48
|
) => Layer.Layer<DatabaseIdentifier<Contract> | Requirement, PrismaError>;
|
|
87
49
|
}
|
|
88
50
|
|
|
89
|
-
|
|
90
|
-
readonly layer: (...arguments_: ReadonlyArray<never>) => Layer.Any;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
export type DatabaseRequirement<Database> =
|
|
94
|
-
Database extends DatabaseDefinition<AnyPostgresContract, infer Requirement>
|
|
95
|
-
? Requirement
|
|
96
|
-
: never;
|
|
97
|
-
|
|
98
|
-
export type DatabaseServiceOf<Database extends AnyDatabase> =
|
|
99
|
-
Effect.Success<Database>;
|
|
100
|
-
|
|
101
|
-
const defaultModels = <
|
|
102
|
-
Contract extends AnyPostgresContract,
|
|
103
|
-
Models extends object,
|
|
104
|
-
>(
|
|
51
|
+
const defaultModels = <Contract extends AnySqlContract, Models extends object>(
|
|
105
52
|
client: Pick<PostgresClient<Contract>, "contract" | "orm">,
|
|
106
|
-
): Models =>
|
|
107
|
-
const namespaces = Object.keys(client.contract.domain.namespaces);
|
|
108
|
-
if (namespaces.length !== 1 || namespaces[0] === undefined) {
|
|
109
|
-
throw new TypeError(
|
|
110
|
-
"Effect Prisma currently requires exactly one domain namespace",
|
|
111
|
-
);
|
|
112
|
-
}
|
|
113
|
-
assertAvailableModelNames(
|
|
114
|
-
Object.keys(client.contract.domain.namespaces[namespaces[0]].models),
|
|
115
|
-
);
|
|
116
|
-
return Reflect.get(client.orm, namespaces[0]) as Models;
|
|
117
|
-
};
|
|
53
|
+
): Models => namespaceModels<Contract, Models>(client.contract, client.orm);
|
|
118
54
|
|
|
119
|
-
export const makeDatabase = <const Contract extends
|
|
55
|
+
export const makeDatabase = <const Contract extends AnySqlContract>(
|
|
120
56
|
identifier: string,
|
|
121
57
|
options: DatabaseFactoryOptions<Contract>,
|
|
122
58
|
): DatabaseDefinition<Contract> => {
|
|
123
59
|
type Models = DefaultModels<Contract>;
|
|
124
|
-
type ExecutorId = ExecutorIdentifier<Models>;
|
|
125
|
-
type DatabaseId = DatabaseIdentifier<Contract>;
|
|
126
|
-
|
|
127
|
-
const Executor = Context.Service<
|
|
128
|
-
ExecutorId,
|
|
129
|
-
DatabaseExecutor<Models, Contract>
|
|
130
|
-
>(`${identifier}/Executor`);
|
|
131
|
-
const Service = Context.Service<
|
|
132
|
-
DatabaseId,
|
|
133
|
-
DatabaseService<Contract, ExecutorId>
|
|
134
|
-
>(identifier);
|
|
135
|
-
|
|
136
|
-
const transaction = <A, E, R>(
|
|
137
|
-
program: Effect.Effect<A, E, R>,
|
|
138
|
-
): Effect.Effect<A, E | PrismaError, R | ExecutorId> =>
|
|
139
|
-
Effect.flatMap(Executor, (current) => {
|
|
140
|
-
if (current.transactional) {
|
|
141
|
-
return program;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return Effect.acquireUseRelease(
|
|
145
|
-
acquireTransaction(current, (transactionOrm) =>
|
|
146
|
-
defaultModels<Contract, Models>({
|
|
147
|
-
contract: current.client.contract,
|
|
148
|
-
orm: transactionOrm,
|
|
149
|
-
}),
|
|
150
|
-
),
|
|
151
|
-
(resource) =>
|
|
152
|
-
program.pipe(Effect.provideService(Executor, resource.executor)),
|
|
153
|
-
releaseTransaction,
|
|
154
|
-
).pipe(Effect.withSpan("prisma.transaction", { kind: "client" }));
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
const withTestTransaction = <A, E, R>(
|
|
158
|
-
program: Effect.Effect<A, E, R>,
|
|
159
|
-
): Effect.Effect<A, E | PrismaError, R | ExecutorId> =>
|
|
160
|
-
Effect.flatMap(Executor, (current) => {
|
|
161
|
-
if (current.transactional) {
|
|
162
|
-
return program;
|
|
163
|
-
}
|
|
164
60
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
61
|
+
return makeSqlDatabase<Contract, DatabaseLayerOptions>(
|
|
62
|
+
identifier,
|
|
63
|
+
(layerOptions) => {
|
|
64
|
+
const clientOptions = {
|
|
65
|
+
url:
|
|
66
|
+
typeof layerOptions.url === "string"
|
|
67
|
+
? layerOptions.url
|
|
68
|
+
: Redacted.value(layerOptions.url),
|
|
69
|
+
extensions: layerOptions.extensions,
|
|
70
|
+
middleware: layerOptions.middleware,
|
|
71
|
+
poolOptions: layerOptions.poolOptions,
|
|
72
|
+
verifyMarker: layerOptions.verifyMarker,
|
|
73
|
+
};
|
|
74
|
+
const client =
|
|
75
|
+
options.contract === undefined
|
|
76
|
+
? postgres<Contract>({
|
|
77
|
+
...clientOptions,
|
|
78
|
+
contractJson: options.contractJson,
|
|
79
|
+
})
|
|
80
|
+
: postgres<Contract>({
|
|
81
|
+
...clientOptions,
|
|
82
|
+
contract: options.contract,
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
return fromPrismaPromise(() =>
|
|
86
|
+
acquireConnectedClient(client, () => ({
|
|
87
|
+
client,
|
|
88
|
+
models: defaultModels<Contract, Models>(client),
|
|
89
|
+
querySemaphore: undefined,
|
|
90
|
+
transactional: false,
|
|
91
|
+
})),
|
|
92
|
+
);
|
|
192
93
|
},
|
|
193
|
-
)
|
|
194
|
-
|
|
195
|
-
const layer = (
|
|
196
|
-
layerOptions: DatabaseLayerOptions,
|
|
197
|
-
): Layer.Layer<DatabaseId | ExecutorId, PrismaError> => {
|
|
198
|
-
const acquire = Effect.acquireRelease(
|
|
199
|
-
Effect.suspend(() => {
|
|
200
|
-
const clientOptions = {
|
|
201
|
-
url:
|
|
202
|
-
typeof layerOptions.url === "string"
|
|
203
|
-
? layerOptions.url
|
|
204
|
-
: Redacted.value(layerOptions.url),
|
|
205
|
-
extensions: layerOptions.extensions,
|
|
206
|
-
middleware: layerOptions.middleware,
|
|
207
|
-
poolOptions: layerOptions.poolOptions,
|
|
208
|
-
verifyMarker: layerOptions.verifyMarker,
|
|
209
|
-
};
|
|
210
|
-
const client =
|
|
211
|
-
options.contract === undefined
|
|
212
|
-
? postgres<Contract>({
|
|
213
|
-
...clientOptions,
|
|
214
|
-
contractJson: options.contractJson,
|
|
215
|
-
})
|
|
216
|
-
: postgres<Contract>({
|
|
217
|
-
...clientOptions,
|
|
218
|
-
contract: options.contract,
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
return fromPrismaPromise(() =>
|
|
222
|
-
acquireConnectedClient(client, () => ({
|
|
223
|
-
client,
|
|
224
|
-
models: defaultModels<Contract, Models>(client),
|
|
225
|
-
querySemaphore: undefined,
|
|
226
|
-
transactional: false,
|
|
227
|
-
})),
|
|
228
|
-
);
|
|
229
|
-
}),
|
|
230
|
-
(executor) =>
|
|
231
|
-
Effect.promise(() => executor.client.close()).pipe(Effect.orDie),
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
return Layer.effectContext(
|
|
235
|
-
Effect.map(acquire, (executor) =>
|
|
236
|
-
Context.make(Executor, executor).pipe(Context.add(Service, facade)),
|
|
237
|
-
),
|
|
238
|
-
);
|
|
239
|
-
};
|
|
240
|
-
|
|
241
|
-
return Object.assign(Service, {
|
|
242
|
-
layer,
|
|
243
|
-
[DatabaseTestingTypeId]: { withTestTransaction },
|
|
244
|
-
}) as DatabaseDefinition<Contract>;
|
|
94
|
+
) as DatabaseDefinition<Contract>;
|
|
245
95
|
};
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import type { orm } from "@prisma-next/sql-orm-client";
|
|
2
|
+
import { Context, Effect, Layer } from "effect";
|
|
3
|
+
import type { PrismaError } from "../error.js";
|
|
4
|
+
import type { Relation } from "../relation.js";
|
|
5
|
+
import { assertAvailableModelNames } from "./client-lifecycle.js";
|
|
6
|
+
import type {
|
|
7
|
+
AnySqlContract,
|
|
8
|
+
DatabaseExecutor,
|
|
9
|
+
ExecutorIdentifier,
|
|
10
|
+
} from "./executor.js";
|
|
11
|
+
import { makeModelRelation } from "./relation-runtime.js";
|
|
12
|
+
import { DatabaseTestingTypeId } from "./testing.js";
|
|
13
|
+
import {
|
|
14
|
+
acquireTransaction,
|
|
15
|
+
releaseTestTransaction,
|
|
16
|
+
releaseTransaction,
|
|
17
|
+
type TransactionOrm,
|
|
18
|
+
} from "./transaction.js";
|
|
19
|
+
|
|
20
|
+
type OrmFor<Contract extends AnySqlContract> = ReturnType<typeof orm<Contract>>;
|
|
21
|
+
type DefaultNamespaceId<Contract extends AnySqlContract> =
|
|
22
|
+
"__unbound__" extends keyof OrmFor<Contract>
|
|
23
|
+
? "__unbound__"
|
|
24
|
+
: "public" extends keyof OrmFor<Contract>
|
|
25
|
+
? "public"
|
|
26
|
+
: keyof OrmFor<Contract>;
|
|
27
|
+
export type DefaultModels<Contract extends AnySqlContract> =
|
|
28
|
+
OrmFor<Contract>[DefaultNamespaceId<Contract>] extends infer Models extends
|
|
29
|
+
object
|
|
30
|
+
? Models
|
|
31
|
+
: never;
|
|
32
|
+
|
|
33
|
+
export interface DatabaseIdentifier<Contract extends AnySqlContract> {
|
|
34
|
+
readonly _contract: Contract;
|
|
35
|
+
readonly _databaseIdentifier: unique symbol;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
type DatabaseModels<Contract extends AnySqlContract, Requirement> = {
|
|
39
|
+
readonly [Model in keyof DefaultModels<Contract>]: Relation<
|
|
40
|
+
DefaultModels<Contract>[Model],
|
|
41
|
+
Requirement,
|
|
42
|
+
Contract,
|
|
43
|
+
Model & string
|
|
44
|
+
>;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type DatabaseService<
|
|
48
|
+
Contract extends AnySqlContract,
|
|
49
|
+
Requirement,
|
|
50
|
+
> = DatabaseModels<Contract, Requirement> & {
|
|
51
|
+
transaction<A, E, R>(
|
|
52
|
+
program: Effect.Effect<A, E, R>,
|
|
53
|
+
): Effect.Effect<A, E | PrismaError, R | Requirement>;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* The driver-independent part of a database definition: the Context service
|
|
58
|
+
* carrying the typed facade. Driver entrypoints add their own `layer` options.
|
|
59
|
+
*/
|
|
60
|
+
export interface DatabaseServiceHolder<
|
|
61
|
+
Contract extends AnySqlContract,
|
|
62
|
+
Requirement = ExecutorIdentifier<DefaultModels<Contract>>,
|
|
63
|
+
> extends Context.Service<
|
|
64
|
+
DatabaseIdentifier<Contract>,
|
|
65
|
+
DatabaseService<Contract, Requirement>
|
|
66
|
+
> {}
|
|
67
|
+
|
|
68
|
+
export type AnyDatabase = Effect.Effect<unknown, never, unknown> & {
|
|
69
|
+
readonly layer: (...arguments_: ReadonlyArray<never>) => Layer.Any;
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export type DatabaseRequirement<Database> =
|
|
73
|
+
Database extends DatabaseServiceHolder<AnySqlContract, infer Requirement>
|
|
74
|
+
? Requirement
|
|
75
|
+
: never;
|
|
76
|
+
|
|
77
|
+
export type DatabaseServiceOf<Database extends AnyDatabase> =
|
|
78
|
+
Effect.Success<Database>;
|
|
79
|
+
|
|
80
|
+
export interface SqlDatabase<Contract extends AnySqlContract, Options>
|
|
81
|
+
extends DatabaseServiceHolder<Contract> {
|
|
82
|
+
readonly layer: (
|
|
83
|
+
options: Options,
|
|
84
|
+
) => Layer.Layer<
|
|
85
|
+
DatabaseIdentifier<Contract> | ExecutorIdentifier<DefaultModels<Contract>>,
|
|
86
|
+
PrismaError
|
|
87
|
+
>;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Resolve the models of the single domain namespace from a namespaced ORM
|
|
92
|
+
* client. Prisma Next namespaces PostgreSQL models under their schema and
|
|
93
|
+
* SQLite models under the unbound namespace.
|
|
94
|
+
*/
|
|
95
|
+
export const namespaceModels = <
|
|
96
|
+
Contract extends AnySqlContract,
|
|
97
|
+
Models extends object,
|
|
98
|
+
>(
|
|
99
|
+
contract: Contract,
|
|
100
|
+
namespacedOrm: TransactionOrm<Contract>,
|
|
101
|
+
): Models => {
|
|
102
|
+
const namespaces = Object.keys(contract.domain.namespaces);
|
|
103
|
+
if (namespaces.length !== 1 || namespaces[0] === undefined) {
|
|
104
|
+
throw new TypeError(
|
|
105
|
+
"Effect Prisma currently requires exactly one domain namespace",
|
|
106
|
+
);
|
|
107
|
+
}
|
|
108
|
+
assertAvailableModelNames(
|
|
109
|
+
Object.keys(contract.domain.namespaces[namespaces[0]].models),
|
|
110
|
+
);
|
|
111
|
+
return Reflect.get(namespacedOrm, namespaces[0]) as Models;
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Assemble the database service, its Executor service, and its Layer around a
|
|
116
|
+
* driver-specific executor acquisition.
|
|
117
|
+
*/
|
|
118
|
+
export const makeSqlDatabase = <const Contract extends AnySqlContract, Options>(
|
|
119
|
+
identifier: string,
|
|
120
|
+
acquireExecutor: (
|
|
121
|
+
options: Options,
|
|
122
|
+
) => Effect.Effect<
|
|
123
|
+
DatabaseExecutor<DefaultModels<Contract>, Contract>,
|
|
124
|
+
PrismaError
|
|
125
|
+
>,
|
|
126
|
+
): SqlDatabase<Contract, Options> => {
|
|
127
|
+
type Models = DefaultModels<Contract>;
|
|
128
|
+
type ExecutorId = ExecutorIdentifier<Models>;
|
|
129
|
+
type DatabaseId = DatabaseIdentifier<Contract>;
|
|
130
|
+
|
|
131
|
+
const Executor = Context.Service<
|
|
132
|
+
ExecutorId,
|
|
133
|
+
DatabaseExecutor<Models, Contract>
|
|
134
|
+
>(`${identifier}/Executor`);
|
|
135
|
+
const Service = Context.Service<
|
|
136
|
+
DatabaseId,
|
|
137
|
+
DatabaseService<Contract, ExecutorId>
|
|
138
|
+
>(identifier);
|
|
139
|
+
|
|
140
|
+
const scopedTransaction =
|
|
141
|
+
(release: typeof releaseTransaction, span: string) =>
|
|
142
|
+
<A, E, R>(
|
|
143
|
+
program: Effect.Effect<A, E, R>,
|
|
144
|
+
): Effect.Effect<A, E | PrismaError, R | ExecutorId> =>
|
|
145
|
+
Effect.flatMap(Executor, (current) => {
|
|
146
|
+
if (current.transactional) {
|
|
147
|
+
return program;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return Effect.acquireUseRelease(
|
|
151
|
+
acquireTransaction(current, (transactionOrm) =>
|
|
152
|
+
namespaceModels<Contract, Models>(
|
|
153
|
+
current.client.contract,
|
|
154
|
+
transactionOrm,
|
|
155
|
+
),
|
|
156
|
+
),
|
|
157
|
+
(resource) =>
|
|
158
|
+
program.pipe(Effect.provideService(Executor, resource.executor)),
|
|
159
|
+
release,
|
|
160
|
+
).pipe(Effect.withSpan(span, { kind: "client" }));
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
const transaction = scopedTransaction(
|
|
164
|
+
releaseTransaction,
|
|
165
|
+
"prisma.transaction",
|
|
166
|
+
);
|
|
167
|
+
const withTestTransaction = scopedTransaction(
|
|
168
|
+
releaseTestTransaction,
|
|
169
|
+
"prisma.testTransaction",
|
|
170
|
+
);
|
|
171
|
+
|
|
172
|
+
const facade = new Proxy(
|
|
173
|
+
Object.assign(Object.create(null), {
|
|
174
|
+
transaction,
|
|
175
|
+
}) as DatabaseService<Contract, ExecutorId>,
|
|
176
|
+
{
|
|
177
|
+
get(target, property, receiver) {
|
|
178
|
+
if (Reflect.has(target, property)) {
|
|
179
|
+
return Reflect.get(target, property, receiver);
|
|
180
|
+
}
|
|
181
|
+
if (typeof property !== "string") {
|
|
182
|
+
return undefined;
|
|
183
|
+
}
|
|
184
|
+
return makeModelRelation(Executor, property);
|
|
185
|
+
},
|
|
186
|
+
},
|
|
187
|
+
);
|
|
188
|
+
|
|
189
|
+
const layer = (
|
|
190
|
+
layerOptions: Options,
|
|
191
|
+
): Layer.Layer<DatabaseId | ExecutorId, PrismaError> => {
|
|
192
|
+
const acquire = Effect.acquireRelease(
|
|
193
|
+
Effect.suspend(() => acquireExecutor(layerOptions)),
|
|
194
|
+
(executor) =>
|
|
195
|
+
Effect.promise(() => executor.client.close()).pipe(Effect.orDie),
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
return Layer.effectContext(
|
|
199
|
+
Effect.map(acquire, (executor) =>
|
|
200
|
+
Context.make(Executor, executor).pipe(Context.add(Service, facade)),
|
|
201
|
+
),
|
|
202
|
+
);
|
|
203
|
+
};
|
|
204
|
+
|
|
205
|
+
return Object.assign(Service, {
|
|
206
|
+
layer,
|
|
207
|
+
[DatabaseTestingTypeId]: { withTestTransaction },
|
|
208
|
+
}) as SqlDatabase<Contract, Options>;
|
|
209
|
+
};
|