@btravstack/prisma 0.4.0 → 0.6.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/README.md +5 -5
- package/dist/index.cjs +35 -14
- package/dist/index.d.cts +15 -13
- package/dist/index.d.mts +15 -13
- package/dist/index.mjs +37 -16
- package/package.json +9 -9
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@ pnpm add @btravstack/prisma @btravstack/core @btravstack/config @btravstack/di u
|
|
|
15
15
|
Five peer dependencies — install every one, so the application holds a single
|
|
16
16
|
copy of each. Your own `@prisma/client`, `prisma` and (if you want the `try*`
|
|
17
17
|
twins) `@unthrown/prisma` are yours, not this package's: the client is
|
|
18
|
-
generated from your schema. Node `>=
|
|
18
|
+
generated from your schema. Node `>=22`.
|
|
19
19
|
|
|
20
20
|
## A worked example
|
|
21
21
|
|
|
@@ -32,6 +32,7 @@ import { PrismaPg } from "@prisma/adapter-pg";
|
|
|
32
32
|
declare class PrismaClient {
|
|
33
33
|
constructor(options: { readonly adapter: PrismaPg });
|
|
34
34
|
$disconnect(): Promise<void>;
|
|
35
|
+
$queryRaw(query: TemplateStringsArray, ...values: unknown[]): Promise<unknown>;
|
|
35
36
|
$extends(extension: unknown): this;
|
|
36
37
|
}
|
|
37
38
|
declare const unthrownPrisma: unknown;
|
|
@@ -88,10 +89,9 @@ package's.
|
|
|
88
89
|
|
|
89
90
|
## Options
|
|
90
91
|
|
|
91
|
-
| Option | Default
|
|
92
|
-
| -------- |
|
|
93
|
-
| `client` | —
|
|
94
|
-
| `urlVar` | `"DATABASE_URL"` | The variable the connection string is read from. |
|
|
92
|
+
| Option | Default | What it does |
|
|
93
|
+
| -------- | ------- | -------------------------------------------------- |
|
|
94
|
+
| `client` | — | Builds the client from the driver adapter and URL. |
|
|
95
95
|
|
|
96
96
|
## License
|
|
97
97
|
|
package/dist/index.cjs
CHANGED
|
@@ -60,7 +60,12 @@ const instrument = (client, logger, meter) => {
|
|
|
60
60
|
/** Injected so a spec can drive the arm where the optional peer is absent. */
|
|
61
61
|
const defaultLoader = async () => (await import("@prisma/instrumentation")).PrismaInstrumentation;
|
|
62
62
|
/**
|
|
63
|
-
* Prisma's own OpenTelemetry instrumentation,
|
|
63
|
+
* Prisma's own OpenTelemetry instrumentation, loaded if it is installed.
|
|
64
|
+
*
|
|
65
|
+
* Handed to `@btravstack/observability/otel` through the `Instrumentations`
|
|
66
|
+
* set port rather than registered here: a graph with no SDK collects nothing
|
|
67
|
+
* and this is never called, so engine tracing follows from composing `otel()`
|
|
68
|
+
* instead of from importing this package.
|
|
64
69
|
*
|
|
65
70
|
* **A dynamic import, and it has to be**: `@prisma/instrumentation` is an
|
|
66
71
|
* OPTIONAL peer, so a static import would make every consumer install it. The
|
|
@@ -79,7 +84,7 @@ const defaultLoader = async () => (await import("@prisma/instrumentation")).Pris
|
|
|
79
84
|
* is worse than none, so the one path that quietly produces no spans says so at
|
|
80
85
|
* `debug` — the level for something that is a choice rather than a fault.
|
|
81
86
|
*/
|
|
82
|
-
const
|
|
87
|
+
const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
83
88
|
try {
|
|
84
89
|
const instrumentation = new (await (load()))();
|
|
85
90
|
instrumentation.enable();
|
|
@@ -109,19 +114,18 @@ const enableTracing = async (logger, load = defaultLoader) => {
|
|
|
109
114
|
* against this same URL *before the process starts*; an application that
|
|
110
115
|
* migrates itself at boot races every other replica.
|
|
111
116
|
*/
|
|
112
|
-
const prismaDatabase = (name) => ({ client,
|
|
113
|
-
const config = _btravstack_config.Config.provider(`${name}Config`)(_btravstack_config.Config.object({ url: _btravstack_config.Config.string(
|
|
117
|
+
const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
118
|
+
const config = _btravstack_config.Config.provider(`${name}Config`)(_btravstack_config.Config.object({ url: _btravstack_config.Config.string("DATABASE_URL") }));
|
|
114
119
|
const DatabasePort = (0, _btravstack_di.Port)(name);
|
|
115
|
-
const open = (url) => client(new _prisma_adapter_pg.PrismaPg({ connectionString: url })
|
|
120
|
+
const open = (url) => client(new _prisma_adapter_pg.PrismaPg({ connectionString: url }));
|
|
116
121
|
const port = DatabasePort;
|
|
117
122
|
const instrumentedProvider = (0, _btravstack_di.Provider)(port)({
|
|
118
123
|
settings: config.port,
|
|
119
124
|
logger: _btravstack_core.Logger,
|
|
120
|
-
tracer: _btravstack_core.Tracer,
|
|
121
125
|
meter: _btravstack_core.Meter
|
|
122
126
|
}, {
|
|
123
|
-
acquire: ({ settings, logger,
|
|
124
|
-
return (0, unthrown.fromSafePromise)(
|
|
127
|
+
acquire: ({ settings, logger, meter }) => {
|
|
128
|
+
return (0, unthrown.fromSafePromise)(Promise.resolve(instrument(open(settings.url), logger, meter)));
|
|
125
129
|
},
|
|
126
130
|
release: (db) => db.$disconnect()
|
|
127
131
|
});
|
|
@@ -129,20 +133,37 @@ const prismaDatabase = (name) => ({ client, urlVar = "DATABASE_URL", instrumente
|
|
|
129
133
|
acquire: ({ settings }) => (0, unthrown.OkAsync)(open(settings.url)),
|
|
130
134
|
release: (db) => db.$disconnect()
|
|
131
135
|
});
|
|
136
|
+
const healthCheck = _btravstack_di.Provider.member(_btravstack_core.HealthChecks)({ db: port }, { sync: ({ db }) => ({
|
|
137
|
+
name,
|
|
138
|
+
check: () => (0, unthrown.fromPromise)(db.$queryRaw`SELECT 1`, (cause) => new _btravstack_core.HealthCheckFailed({ reason: cause instanceof Error ? cause.message : "database unreachable" })).map(() => void 0)
|
|
139
|
+
}) });
|
|
140
|
+
const instrumentation = _btravstack_di.Provider.member(_btravstack_core.Instrumentations)({ logger: _btravstack_core.Logger }, { sync: ({ logger }) => () => loadPrismaInstrumentation(logger) });
|
|
132
141
|
const instrumentedModule = (0, _btravstack_di.Module)(name)({
|
|
133
142
|
needs: [
|
|
134
143
|
_btravstack_config.Env,
|
|
135
144
|
_btravstack_core.Logger,
|
|
136
|
-
_btravstack_core.Meter
|
|
137
|
-
|
|
145
|
+
_btravstack_core.Meter
|
|
146
|
+
],
|
|
147
|
+
provides: [
|
|
148
|
+
config,
|
|
149
|
+
instrumentedProvider,
|
|
150
|
+
healthCheck,
|
|
151
|
+
instrumentation
|
|
138
152
|
],
|
|
139
|
-
|
|
140
|
-
|
|
153
|
+
exports: [
|
|
154
|
+
DatabasePort,
|
|
155
|
+
_btravstack_core.HealthChecks,
|
|
156
|
+
_btravstack_core.Instrumentations
|
|
157
|
+
]
|
|
141
158
|
});
|
|
142
159
|
const plainModule = (0, _btravstack_di.Module)(name)({
|
|
143
160
|
needs: [_btravstack_config.Env],
|
|
144
|
-
provides: [
|
|
145
|
-
|
|
161
|
+
provides: [
|
|
162
|
+
config,
|
|
163
|
+
plainProvider,
|
|
164
|
+
healthCheck
|
|
165
|
+
],
|
|
166
|
+
exports: [DatabasePort, _btravstack_core.HealthChecks]
|
|
146
167
|
});
|
|
147
168
|
return Object.assign(instrumented !== false ? instrumentedModule : plainModule, { port: DatabasePort });
|
|
148
169
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Env } from "@btravstack/config";
|
|
2
|
-
import { Logger, Meter
|
|
2
|
+
import { HealthChecks, Instrumentations, Logger, Meter } from "@btravstack/core";
|
|
3
3
|
import { Module, PortClassOf } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
5
|
//#region src/prisma.d.ts
|
|
@@ -11,22 +11,26 @@ import { PrismaPg } from "@prisma/adapter-pg";
|
|
|
11
11
|
*/
|
|
12
12
|
type PrismaLike = {
|
|
13
13
|
readonly $disconnect: () => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* What the health check asks. Part of the contract rather than optional
|
|
16
|
+
* because every generated Prisma client has it, and a probe that has to
|
|
17
|
+
* feature-detect its own client cannot report the difference between "the
|
|
18
|
+
* database is down" and "this client cannot be asked".
|
|
19
|
+
*/
|
|
20
|
+
readonly $queryRaw: (query: TemplateStringsArray, ...values: unknown[]) => Promise<unknown>;
|
|
14
21
|
};
|
|
15
22
|
/** What {@link prismaDatabase} is handed. */
|
|
16
23
|
type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
17
24
|
/**
|
|
18
|
-
* Builds the client
|
|
19
|
-
* environment's URL
|
|
20
|
-
* it directly.
|
|
25
|
+
* Builds the client from the driver adapter, which is already constructed
|
|
26
|
+
* from the environment's URL.
|
|
21
27
|
*
|
|
22
28
|
* This is the one thing the starter cannot own: a Prisma client is
|
|
23
29
|
* **generated per application** from its own schema, so there is no client
|
|
24
30
|
* type to ship. Applying `@unthrown/prisma`'s extension belongs here too, so
|
|
25
31
|
* the returned type is exactly the one the application will hold.
|
|
26
32
|
*/
|
|
27
|
-
readonly client: (adapter: PrismaPg
|
|
28
|
-
/** The variable the connection string is read from. `DATABASE_URL` by 12-factor convention. */
|
|
29
|
-
readonly urlVar?: string;
|
|
33
|
+
readonly client: (adapter: PrismaPg) => C;
|
|
30
34
|
/**
|
|
31
35
|
* Span, count and log every query. **Default `true`**, `false` opts out — the
|
|
32
36
|
* same shape as `cache`, `mailer` and `storage`, and as `StartOptions`'
|
|
@@ -59,15 +63,13 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
59
63
|
* against this same URL *before the process starts*; an application that
|
|
60
64
|
* migrates itself at boot races every other replica.
|
|
61
65
|
*/
|
|
62
|
-
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike, Instrumented extends boolean = true>({ client,
|
|
63
|
-
readonly url: string;
|
|
64
|
-
}>> | Exclude<Logger, import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
66
|
+
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike, Instrumented extends boolean = true>({ client, instrumented }: PrismaOptions<C, Instrumented>) => (Instrumented extends true ? Module<HealthChecks | Instrumentations | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
65
67
|
readonly url: string;
|
|
66
|
-
}>> | Exclude<
|
|
68
|
+
}>> | Exclude<Logger, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
67
69
|
readonly url: string;
|
|
68
|
-
}>> | Exclude<
|
|
70
|
+
}>> | Exclude<Meter, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
69
71
|
readonly url: string;
|
|
70
|
-
}>>> : Module<PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never, import("@btravstack/config").ConfigInvalid, Exclude<Env, import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
72
|
+
}>>> : Module<HealthChecks | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
71
73
|
readonly url: string;
|
|
72
74
|
}>>>) & {
|
|
73
75
|
readonly port: PortClassOf<N, C>;
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Env } from "@btravstack/config";
|
|
2
|
-
import { Logger, Meter
|
|
2
|
+
import { HealthChecks, Instrumentations, Logger, Meter } from "@btravstack/core";
|
|
3
3
|
import { Module, PortClassOf } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
5
|
//#region src/prisma.d.ts
|
|
@@ -11,22 +11,26 @@ import { PrismaPg } from "@prisma/adapter-pg";
|
|
|
11
11
|
*/
|
|
12
12
|
type PrismaLike = {
|
|
13
13
|
readonly $disconnect: () => Promise<void>;
|
|
14
|
+
/**
|
|
15
|
+
* What the health check asks. Part of the contract rather than optional
|
|
16
|
+
* because every generated Prisma client has it, and a probe that has to
|
|
17
|
+
* feature-detect its own client cannot report the difference between "the
|
|
18
|
+
* database is down" and "this client cannot be asked".
|
|
19
|
+
*/
|
|
20
|
+
readonly $queryRaw: (query: TemplateStringsArray, ...values: unknown[]) => Promise<unknown>;
|
|
14
21
|
};
|
|
15
22
|
/** What {@link prismaDatabase} is handed. */
|
|
16
23
|
type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
17
24
|
/**
|
|
18
|
-
* Builds the client
|
|
19
|
-
* environment's URL
|
|
20
|
-
* it directly.
|
|
25
|
+
* Builds the client from the driver adapter, which is already constructed
|
|
26
|
+
* from the environment's URL.
|
|
21
27
|
*
|
|
22
28
|
* This is the one thing the starter cannot own: a Prisma client is
|
|
23
29
|
* **generated per application** from its own schema, so there is no client
|
|
24
30
|
* type to ship. Applying `@unthrown/prisma`'s extension belongs here too, so
|
|
25
31
|
* the returned type is exactly the one the application will hold.
|
|
26
32
|
*/
|
|
27
|
-
readonly client: (adapter: PrismaPg
|
|
28
|
-
/** The variable the connection string is read from. `DATABASE_URL` by 12-factor convention. */
|
|
29
|
-
readonly urlVar?: string;
|
|
33
|
+
readonly client: (adapter: PrismaPg) => C;
|
|
30
34
|
/**
|
|
31
35
|
* Span, count and log every query. **Default `true`**, `false` opts out — the
|
|
32
36
|
* same shape as `cache`, `mailer` and `storage`, and as `StartOptions`'
|
|
@@ -59,15 +63,13 @@ type PrismaOptions<C extends PrismaLike, Instrumented extends boolean> = {
|
|
|
59
63
|
* against this same URL *before the process starts*; an application that
|
|
60
64
|
* migrates itself at boot races every other replica.
|
|
61
65
|
*/
|
|
62
|
-
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike, Instrumented extends boolean = true>({ client,
|
|
63
|
-
readonly url: string;
|
|
64
|
-
}>> | Exclude<Logger, import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
66
|
+
declare const prismaDatabase: <const N extends string>(name: N) => <C extends PrismaLike, Instrumented extends boolean = true>({ client, instrumented }: PrismaOptions<C, Instrumented>) => (Instrumented extends true ? Module<HealthChecks | Instrumentations | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
65
67
|
readonly url: string;
|
|
66
|
-
}>> | Exclude<
|
|
68
|
+
}>> | Exclude<Logger, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
67
69
|
readonly url: string;
|
|
68
|
-
}>> | Exclude<
|
|
70
|
+
}>> | Exclude<Meter, HealthChecks | Instrumentations | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
69
71
|
readonly url: string;
|
|
70
|
-
}>>> : Module<PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never, import("@btravstack/config").ConfigInvalid, Exclude<Env, import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
72
|
+
}>>> : Module<HealthChecks | (PortClassOf<N, C> extends (infer T) ? T extends PortClassOf<N, C> ? T extends import("@btravstack/di").AnyPort ? InstanceType<T> : T extends import("@btravstack/di").AnyProvider ? InstanceType<T["port"]> : never : never : never), import("@btravstack/config").ConfigInvalid, Exclude<Env, HealthChecks | import("@btravstack/di").PortInstance<string, C> | import("@btravstack/di").PortInstance<`${N}Config`, {
|
|
71
73
|
readonly url: string;
|
|
72
74
|
}>>>) & {
|
|
73
75
|
readonly port: PortClassOf<N, C>;
|
package/dist/index.mjs
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Config, Env } from "@btravstack/config";
|
|
2
|
-
import { Logger, Meter
|
|
2
|
+
import { HealthCheckFailed, HealthChecks, Instrumentations, Logger, Meter } from "@btravstack/core";
|
|
3
3
|
import { Module, Port, Provider } from "@btravstack/di";
|
|
4
4
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
5
|
-
import { OkAsync, fromSafePromise } from "unthrown";
|
|
5
|
+
import { OkAsync, fromPromise, fromSafePromise } from "unthrown";
|
|
6
6
|
//#region src/instrument.ts
|
|
7
7
|
/**
|
|
8
8
|
* Every query, wrapped: a span around it, a count of how it came out, and a log
|
|
@@ -59,7 +59,12 @@ const instrument = (client, logger, meter) => {
|
|
|
59
59
|
/** Injected so a spec can drive the arm where the optional peer is absent. */
|
|
60
60
|
const defaultLoader = async () => (await import("@prisma/instrumentation")).PrismaInstrumentation;
|
|
61
61
|
/**
|
|
62
|
-
* Prisma's own OpenTelemetry instrumentation,
|
|
62
|
+
* Prisma's own OpenTelemetry instrumentation, loaded if it is installed.
|
|
63
|
+
*
|
|
64
|
+
* Handed to `@btravstack/observability/otel` through the `Instrumentations`
|
|
65
|
+
* set port rather than registered here: a graph with no SDK collects nothing
|
|
66
|
+
* and this is never called, so engine tracing follows from composing `otel()`
|
|
67
|
+
* instead of from importing this package.
|
|
63
68
|
*
|
|
64
69
|
* **A dynamic import, and it has to be**: `@prisma/instrumentation` is an
|
|
65
70
|
* OPTIONAL peer, so a static import would make every consumer install it. The
|
|
@@ -78,7 +83,7 @@ const defaultLoader = async () => (await import("@prisma/instrumentation")).Pris
|
|
|
78
83
|
* is worse than none, so the one path that quietly produces no spans says so at
|
|
79
84
|
* `debug` — the level for something that is a choice rather than a fault.
|
|
80
85
|
*/
|
|
81
|
-
const
|
|
86
|
+
const loadPrismaInstrumentation = async (logger, load = defaultLoader) => {
|
|
82
87
|
try {
|
|
83
88
|
const instrumentation = new (await (load()))();
|
|
84
89
|
instrumentation.enable();
|
|
@@ -108,19 +113,18 @@ const enableTracing = async (logger, load = defaultLoader) => {
|
|
|
108
113
|
* against this same URL *before the process starts*; an application that
|
|
109
114
|
* migrates itself at boot races every other replica.
|
|
110
115
|
*/
|
|
111
|
-
const prismaDatabase = (name) => ({ client,
|
|
112
|
-
const config = Config.provider(`${name}Config`)(Config.object({ url: Config.string(
|
|
116
|
+
const prismaDatabase = (name) => ({ client, instrumented }) => {
|
|
117
|
+
const config = Config.provider(`${name}Config`)(Config.object({ url: Config.string("DATABASE_URL") }));
|
|
113
118
|
const DatabasePort = Port(name);
|
|
114
|
-
const open = (url) => client(new PrismaPg({ connectionString: url })
|
|
119
|
+
const open = (url) => client(new PrismaPg({ connectionString: url }));
|
|
115
120
|
const port = DatabasePort;
|
|
116
121
|
const instrumentedProvider = Provider(port)({
|
|
117
122
|
settings: config.port,
|
|
118
123
|
logger: Logger,
|
|
119
|
-
tracer: Tracer,
|
|
120
124
|
meter: Meter
|
|
121
125
|
}, {
|
|
122
|
-
acquire: ({ settings, logger,
|
|
123
|
-
return fromSafePromise(
|
|
126
|
+
acquire: ({ settings, logger, meter }) => {
|
|
127
|
+
return fromSafePromise(Promise.resolve(instrument(open(settings.url), logger, meter)));
|
|
124
128
|
},
|
|
125
129
|
release: (db) => db.$disconnect()
|
|
126
130
|
});
|
|
@@ -128,20 +132,37 @@ const prismaDatabase = (name) => ({ client, urlVar = "DATABASE_URL", instrumente
|
|
|
128
132
|
acquire: ({ settings }) => OkAsync(open(settings.url)),
|
|
129
133
|
release: (db) => db.$disconnect()
|
|
130
134
|
});
|
|
135
|
+
const healthCheck = Provider.member(HealthChecks)({ db: port }, { sync: ({ db }) => ({
|
|
136
|
+
name,
|
|
137
|
+
check: () => fromPromise(db.$queryRaw`SELECT 1`, (cause) => new HealthCheckFailed({ reason: cause instanceof Error ? cause.message : "database unreachable" })).map(() => void 0)
|
|
138
|
+
}) });
|
|
139
|
+
const instrumentation = Provider.member(Instrumentations)({ logger: Logger }, { sync: ({ logger }) => () => loadPrismaInstrumentation(logger) });
|
|
131
140
|
const instrumentedModule = Module(name)({
|
|
132
141
|
needs: [
|
|
133
142
|
Env,
|
|
134
143
|
Logger,
|
|
135
|
-
Meter
|
|
136
|
-
|
|
144
|
+
Meter
|
|
145
|
+
],
|
|
146
|
+
provides: [
|
|
147
|
+
config,
|
|
148
|
+
instrumentedProvider,
|
|
149
|
+
healthCheck,
|
|
150
|
+
instrumentation
|
|
137
151
|
],
|
|
138
|
-
|
|
139
|
-
|
|
152
|
+
exports: [
|
|
153
|
+
DatabasePort,
|
|
154
|
+
HealthChecks,
|
|
155
|
+
Instrumentations
|
|
156
|
+
]
|
|
140
157
|
});
|
|
141
158
|
const plainModule = Module(name)({
|
|
142
159
|
needs: [Env],
|
|
143
|
-
provides: [
|
|
144
|
-
|
|
160
|
+
provides: [
|
|
161
|
+
config,
|
|
162
|
+
plainProvider,
|
|
163
|
+
healthCheck
|
|
164
|
+
],
|
|
165
|
+
exports: [DatabasePort, HealthChecks]
|
|
145
166
|
});
|
|
146
167
|
return Object.assign(instrumented !== false ? instrumentedModule : plainModule, { port: DatabasePort });
|
|
147
168
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@btravstack/prisma",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "The Prisma starter for @btravstack/core: DATABASE_URL through Config, the Postgres driver adapter, and a client whose pool is the application scope's",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"database",
|
|
@@ -53,17 +53,17 @@
|
|
|
53
53
|
"typescript": "7.0.2",
|
|
54
54
|
"unthrown": "5.7.0",
|
|
55
55
|
"vitest": "4.1.11",
|
|
56
|
-
"@btravstack/config": "0.
|
|
57
|
-
"@btravstack/core": "0.
|
|
58
|
-
"@btravstack/di": "0.
|
|
56
|
+
"@btravstack/config": "0.6.0",
|
|
57
|
+
"@btravstack/core": "0.6.0",
|
|
58
|
+
"@btravstack/di": "0.6.0"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
61
|
"@prisma/adapter-pg": "^7.0.0",
|
|
62
62
|
"@prisma/instrumentation": "^7.0.0",
|
|
63
63
|
"unthrown": "^5.0.0",
|
|
64
|
-
"@btravstack/config": "^0.
|
|
65
|
-
"@btravstack/core": "^0.
|
|
66
|
-
"@btravstack/di": "^0.
|
|
64
|
+
"@btravstack/config": "^0.6.0",
|
|
65
|
+
"@btravstack/core": "^0.6.0",
|
|
66
|
+
"@btravstack/di": "^0.6.0"
|
|
67
67
|
},
|
|
68
68
|
"peerDependenciesMeta": {
|
|
69
69
|
"@prisma/instrumentation": {
|
|
@@ -71,13 +71,13 @@
|
|
|
71
71
|
}
|
|
72
72
|
},
|
|
73
73
|
"engines": {
|
|
74
|
-
"node": ">=
|
|
74
|
+
"node": ">=22"
|
|
75
75
|
},
|
|
76
76
|
"scripts": {
|
|
77
77
|
"build": "tsdown src/index.ts --format cjs,esm --dts --clean",
|
|
78
78
|
"dev": "tsdown src/index.ts --format cjs,esm --dts --watch",
|
|
79
79
|
"test": "vitest run --coverage",
|
|
80
80
|
"test:types": "tsc -p tsconfig.test-d.json --noEmit",
|
|
81
|
-
"typecheck": "tsc --noEmit"
|
|
81
|
+
"typecheck": "tsc --noEmit && tsc --noEmit -p tsconfig.test-d.json"
|
|
82
82
|
}
|
|
83
83
|
}
|