@orpc/evlog 2.0.0-beta.30 → 2.0.0-beta.32
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 +29 -28
- package/dist/index.d.mts +12 -2
- package/dist/index.d.ts +12 -2
- package/dist/index.mjs +26 -11
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<a href="https://codecov.io/gh/middleapi/orpc">
|
|
5
5
|
<img alt="codecov" src="https://codecov.io/gh/middleapi/orpc/branch/main/graph/badge.svg">
|
|
6
6
|
</a>
|
|
7
|
-
<a href="https://
|
|
7
|
+
<a href="https://www.npmjs.com/package/@orpc/evlog">
|
|
8
8
|
<img alt="weekly downloads" src="https://img.shields.io/npm/dw/%40orpc%2Fevlog?logo=npm" />
|
|
9
9
|
</a>
|
|
10
10
|
<a href="https://app.codspeed.io/middleapi/orpc?utm_source=badge">
|
|
@@ -29,44 +29,44 @@ You can read the documentation [here](https://orpc.dev).
|
|
|
29
29
|
|
|
30
30
|
**Core**
|
|
31
31
|
|
|
32
|
-
- [@orpc/contract](https://
|
|
33
|
-
- [@orpc/server](https://
|
|
34
|
-
- [@orpc/client](https://
|
|
35
|
-
- [@orpc/openapi](https://
|
|
32
|
+
- [@orpc/contract](https://www.npmjs.com/package/@orpc/contract): Define API contract as the single source of truth.
|
|
33
|
+
- [@orpc/server](https://www.npmjs.com/package/@orpc/server): Build APIs or implement contracts.
|
|
34
|
+
- [@orpc/client](https://www.npmjs.com/package/@orpc/client): Consume APIs with end-to-end type safety.
|
|
35
|
+
- [@orpc/openapi](https://www.npmjs.com/package/@orpc/openapi): Add OpenAPI compatibility to APIs.
|
|
36
36
|
|
|
37
37
|
**Schema validation**
|
|
38
38
|
|
|
39
|
-
- [@orpc/zod](https://
|
|
40
|
-
- [@orpc/valibot](https://
|
|
41
|
-
- [@orpc/arktype](https://
|
|
39
|
+
- [@orpc/zod](https://www.npmjs.com/package/@orpc/zod): Integrate with [Zod](https://zod.dev/).
|
|
40
|
+
- [@orpc/valibot](https://www.npmjs.com/package/@orpc/valibot): Integrate with [Valibot](https://valibot.dev/).
|
|
41
|
+
- [@orpc/arktype](https://www.npmjs.com/package/@orpc/arktype): Integrate with [ArkType](https://arktype.io/).
|
|
42
42
|
|
|
43
43
|
**Built-in features**
|
|
44
44
|
|
|
45
|
-
- [@orpc/publisher](https://
|
|
46
|
-
- [@orpc/ratelimit](https://
|
|
47
|
-
- [@orpc/hibernation](https://
|
|
48
|
-
- [@orpc/json-schema](https://
|
|
45
|
+
- [@orpc/publisher](https://www.npmjs.com/package/@orpc/publisher): Pub/Sub with memory, Redis, and Upstash adapters.
|
|
46
|
+
- [@orpc/ratelimit](https://www.npmjs.com/package/@orpc/ratelimit): Rate limiting with memory, Redis, and Upstash adapters.
|
|
47
|
+
- [@orpc/hibernation](https://www.npmjs.com/package/@orpc/hibernation): Leverage Hibernation APIs like [Cloudflare's Hibernation WebSocket](https://developers.cloudflare.com/durable-objects/best-practices/websockets/#durable-objects-hibernation-websocket-api).
|
|
48
|
+
- [@orpc/json-schema](https://www.npmjs.com/package/@orpc/json-schema): Smart coercion for OpenAPI requests.
|
|
49
49
|
|
|
50
50
|
**Framework & ecosystem integrations**
|
|
51
51
|
|
|
52
|
-
- [@orpc/next](https://
|
|
53
|
-
- [@orpc/ai-sdk](https://
|
|
54
|
-
- [@orpc/tanstack-query](https://
|
|
55
|
-
- [@orpc/pinia-colada](https://
|
|
56
|
-
- [@orpc/swr](https://
|
|
57
|
-
- [@orpc/experimental-msw](https://
|
|
58
|
-
- [@orpc/experimental-effect](https://
|
|
59
|
-
- [@orpc/nest](https://
|
|
60
|
-
- [@orpc/node](https://
|
|
61
|
-
- [@orpc/bun](https://
|
|
62
|
-
- [@orpc/cloudflare](https://
|
|
63
|
-
- [@orpc/trpc](https://
|
|
52
|
+
- [@orpc/next](https://www.npmjs.com/package/@orpc/next): Integrate with [Next.js Server Functions](https://nextjs.org/docs/app/getting-started/mutating-data).
|
|
53
|
+
- [@orpc/ai-sdk](https://www.npmjs.com/package/@orpc/ai-sdk): Turn contracts and procedures into [AI SDK](https://ai-sdk.dev/) tools.
|
|
54
|
+
- [@orpc/tanstack-query](https://www.npmjs.com/package/@orpc/tanstack-query): Integrate with [TanStack Query](https://tanstack.com/query/latest).
|
|
55
|
+
- [@orpc/pinia-colada](https://www.npmjs.com/package/@orpc/pinia-colada): Integrate with [Pinia Colada](https://pinia-colada.esm.dev/).
|
|
56
|
+
- [@orpc/swr](https://www.npmjs.com/package/@orpc/swr): Integrate with [SWR](https://swr.vercel.app/).
|
|
57
|
+
- [@orpc/experimental-msw](https://www.npmjs.com/package/@orpc/experimental-msw): Mock procedures with [Mock Service Worker](https://mswjs.io/).
|
|
58
|
+
- [@orpc/experimental-effect](https://www.npmjs.com/package/@orpc/experimental-effect): Integrate with [Effect](https://effect.website/).
|
|
59
|
+
- [@orpc/nest](https://www.npmjs.com/package/@orpc/nest): Implement your contract with [NestJS](https://nestjs.com/).
|
|
60
|
+
- [@orpc/node](https://www.npmjs.com/package/@orpc/node): [Node.js](https://nodejs.org/) plugins for static file serving and large uploads.
|
|
61
|
+
- [@orpc/bun](https://www.npmjs.com/package/@orpc/bun): Adapters for [Bun's Redis](https://bun.sh/).
|
|
62
|
+
- [@orpc/cloudflare](https://www.npmjs.com/package/@orpc/cloudflare): Adapters for [Cloudflare's RateLimit and Durable Objects](https://developers.cloudflare.com/workers/).
|
|
63
|
+
- [@orpc/trpc](https://www.npmjs.com/package/@orpc/trpc): Reuse existing [tRPC](https://trpc.io/) routers within oRPC.
|
|
64
64
|
|
|
65
65
|
**Observability**
|
|
66
66
|
|
|
67
|
-
- [@orpc/opentelemetry](https://
|
|
68
|
-
- [@orpc/pino](https://
|
|
69
|
-
- [@orpc/evlog](https://
|
|
67
|
+
- [@orpc/opentelemetry](https://www.npmjs.com/package/@orpc/opentelemetry): Integrate with [OpenTelemetry](https://opentelemetry.io/) for distributed tracing.
|
|
68
|
+
- [@orpc/pino](https://www.npmjs.com/package/@orpc/pino): Integrate with [Pino](https://getpino.io/) for logging.
|
|
69
|
+
- [@orpc/evlog](https://www.npmjs.com/package/@orpc/evlog): Integrate with [Evlog](https://evlog.dev/) for logging.
|
|
70
70
|
|
|
71
71
|
## Sponsors
|
|
72
72
|
|
|
@@ -113,6 +113,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
113
113
|
<td align="center"><a href="https://github.com/itigoore01?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="shota"><img src="https://avatars.githubusercontent.com/u/11831107?u=c976a6dc7e055eb026304c46c99100ed22b0c8e0&v=4" width="139" alt="shota"/><br />shota</a></td>
|
|
114
114
|
<td align="center"><a href="https://github.com/ellis-driscoll?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Ellis Driscoll"><img src="https://avatars.githubusercontent.com/u/70685966?u=c5f95bc33b5991d9744abe00052542e4a2ed3cb9&v=4" width="139" alt="Ellis Driscoll"/><br />Ellis Driscoll</a></td>
|
|
115
115
|
<td align="center"><a href="https://github.com/hoangbn?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Hoang Nguyen"><img src="https://avatars.githubusercontent.com/u/38968280?u=c90084c6de65c56facabab7ba13a72a49ddbc3e4&v=4" width="139" alt="Hoang Nguyen"/><br />Hoang Nguyen</a></td>
|
|
116
|
+
<td align="center"><a href="https://opencollective.com/guest-ac41de3b?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Orestis Ioannou"><img src="https://images.opencollective.com/guest-ac41de3b/avatar/460.png" width="139" alt="Orestis Ioannou"/><br />Orestis Ioannou</a></td>
|
|
116
117
|
</tr>
|
|
117
118
|
</table>
|
|
118
119
|
|
|
@@ -135,7 +136,7 @@ Like what we build over at [middleapi](https://github.com/middleapi)? You can he
|
|
|
135
136
|
<td align="center"><a href="https://rigtch.fm/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Igor Makowski"><img src="https://avatars.githubusercontent.com/u/56691628?u=ee8c879478f7c151b9156aef6c74243fa3e247a8&v=4" width="119" alt="Igor Makowski"/><br />Igor Makowski</a></td>
|
|
136
137
|
<td align="center"><a href="https://blog.cwang.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="hanayashiki"><img src="https://avatars.githubusercontent.com/u/26056783?u=06c3b9205a16fd41a871e82da1cc2a09306d53f5&v=4" width="119" alt="hanayashiki"/><br />hanayashiki</a></td>
|
|
137
138
|
<td align="center"><a href="https://dubinets.io/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Lev Dubinets"><img src="https://avatars.githubusercontent.com/u/3114081?u=f547f5d5012cab54851f1b1ad72d10e537f78fc2&v=4" width="119" alt="Lev Dubinets"/><br />Lev Dubinets</a></td>
|
|
138
|
-
<td align="center"><a href="https://
|
|
139
|
+
<td align="center"><a href="https://kellychan.im/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Kelly Peilin Chan"><img src="https://avatars.githubusercontent.com/u/520852?u=6b0f7105f694e7b5cacf410a3f04c7044b469dc8&v=4" width="119" alt="Kelly Peilin Chan"/><br />Kelly Peilin Chan</a></td>
|
|
139
140
|
</tr>
|
|
140
141
|
<tr>
|
|
141
142
|
<td align="center"><a href="https://guyariely.com/?ref=middleapi&utm_source=middleapi&utm_medium=sponsor" target="_blank" rel="noopener sponsored" title="Guy Ariely"><img src="https://avatars.githubusercontent.com/u/42813496?u=edb6b7f563bf28e160a290832e7da57c0506f8ca&v=4" width="119" alt="Guy Ariely"/><br />Guy Ariely</a></td>
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestLogger } from 'evlog';
|
|
1
|
+
import { RequestLogger, LogLevel } from 'evlog';
|
|
2
2
|
import { Context } from '@orpc/server';
|
|
3
3
|
import { StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
|
|
4
4
|
import { StandardRequest } from '@standardserver/core';
|
|
@@ -33,6 +33,15 @@ interface EvlogHandlerPluginOptions<_T extends Context> extends BaseEvlogOptions
|
|
|
33
33
|
* @default false
|
|
34
34
|
*/
|
|
35
35
|
logAbort?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Customizes the log level for errors thrown from procedures;
|
|
38
|
+
* internal handler failures are always logged at error level.
|
|
39
|
+
* Receives the level applied by default; return it to keep the default behavior:
|
|
40
|
+
* 'info' for abort errors, 'warn' for ORPCError except INTERNAL_SERVER_ERROR, 'error' otherwise.
|
|
41
|
+
*
|
|
42
|
+
* @default (error, level) => level
|
|
43
|
+
*/
|
|
44
|
+
procedureErrorLevel?: (error: unknown, level: LogLevel) => LogLevel;
|
|
36
45
|
}
|
|
37
46
|
/**
|
|
38
47
|
* Instruments an oRPC handler with Evlog structured logging, request tracking,
|
|
@@ -50,9 +59,10 @@ declare class EvlogHandlerPlugin<T extends Context> implements StandardHandlerPl
|
|
|
50
59
|
*/
|
|
51
60
|
before: string[];
|
|
52
61
|
private readonly logAbort;
|
|
62
|
+
private readonly procedureErrorLevel;
|
|
53
63
|
private readonly integration;
|
|
54
64
|
private readonly evlogOptions;
|
|
55
|
-
constructor({ storage, logAbort, ...evlogOptions }?: EvlogHandlerPluginOptions<T>);
|
|
65
|
+
constructor({ storage, logAbort, procedureErrorLevel, ...evlogOptions }?: EvlogHandlerPluginOptions<T>);
|
|
56
66
|
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
57
67
|
}
|
|
58
68
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RequestLogger } from 'evlog';
|
|
1
|
+
import { RequestLogger, LogLevel } from 'evlog';
|
|
2
2
|
import { Context } from '@orpc/server';
|
|
3
3
|
import { StandardHandlerPlugin, StandardHandlerOptions } from '@orpc/server/standard';
|
|
4
4
|
import { StandardRequest } from '@standardserver/core';
|
|
@@ -33,6 +33,15 @@ interface EvlogHandlerPluginOptions<_T extends Context> extends BaseEvlogOptions
|
|
|
33
33
|
* @default false
|
|
34
34
|
*/
|
|
35
35
|
logAbort?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Customizes the log level for errors thrown from procedures;
|
|
38
|
+
* internal handler failures are always logged at error level.
|
|
39
|
+
* Receives the level applied by default; return it to keep the default behavior:
|
|
40
|
+
* 'info' for abort errors, 'warn' for ORPCError except INTERNAL_SERVER_ERROR, 'error' otherwise.
|
|
41
|
+
*
|
|
42
|
+
* @default (error, level) => level
|
|
43
|
+
*/
|
|
44
|
+
procedureErrorLevel?: (error: unknown, level: LogLevel) => LogLevel;
|
|
36
45
|
}
|
|
37
46
|
/**
|
|
38
47
|
* Instruments an oRPC handler with Evlog structured logging, request tracking,
|
|
@@ -50,9 +59,10 @@ declare class EvlogHandlerPlugin<T extends Context> implements StandardHandlerPl
|
|
|
50
59
|
*/
|
|
51
60
|
before: string[];
|
|
52
61
|
private readonly logAbort;
|
|
62
|
+
private readonly procedureErrorLevel;
|
|
53
63
|
private readonly integration;
|
|
54
64
|
private readonly evlogOptions;
|
|
55
|
-
constructor({ storage, logAbort, ...evlogOptions }?: EvlogHandlerPluginOptions<T>);
|
|
65
|
+
constructor({ storage, logAbort, procedureErrorLevel, ...evlogOptions }?: EvlogHandlerPluginOptions<T>);
|
|
56
66
|
init(options: StandardHandlerOptions<T>): StandardHandlerOptions<T>;
|
|
57
67
|
}
|
|
58
68
|
|
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { wrapAsyncIteratorPreservingEventMeta, ORPCError } from '@orpc/client';
|
|
2
2
|
import { ORPC_NAME, toArray, isAsyncIteratorObject, override, sleep, wrapReadableStream, isAbortError } from '@orpc/shared';
|
|
3
|
-
import { parseStandardUrl, flattenStandardHeader } from '@standardserver/core';
|
|
3
|
+
import { parseStandardUrl, flattenStandardHeader, ErrorEvent } from '@standardserver/core';
|
|
4
4
|
import { defineFrameworkIntegration } from 'evlog/toolkit';
|
|
5
5
|
|
|
6
6
|
const LOGGER_CONTEXT_SYMBOL = Symbol.for("ORPC_EVLOG_LOGGER_CONTEXT");
|
|
@@ -18,11 +18,13 @@ class EvlogHandlerPlugin {
|
|
|
18
18
|
*/
|
|
19
19
|
before = ["~opentelemetry", "~batch", "~hibernation"];
|
|
20
20
|
logAbort;
|
|
21
|
+
procedureErrorLevel;
|
|
21
22
|
integration;
|
|
22
23
|
evlogOptions;
|
|
23
|
-
constructor({ storage, logAbort, ...evlogOptions } = {}) {
|
|
24
|
+
constructor({ storage, logAbort, procedureErrorLevel, ...evlogOptions } = {}) {
|
|
24
25
|
this.evlogOptions = evlogOptions;
|
|
25
26
|
this.logAbort = logAbort ?? false;
|
|
27
|
+
this.procedureErrorLevel = procedureErrorLevel ?? ((_, level) => level);
|
|
26
28
|
this.integration = defineFrameworkIntegration({
|
|
27
29
|
name: ORPC_NAME,
|
|
28
30
|
storage,
|
|
@@ -66,7 +68,9 @@ class EvlogHandlerPlugin {
|
|
|
66
68
|
body: override(result.response.body, wrapAsyncIteratorPreservingEventMeta(result.response.body, {
|
|
67
69
|
runWith,
|
|
68
70
|
onError: (error) => {
|
|
69
|
-
|
|
71
|
+
if (!(error instanceof ErrorEvent)) {
|
|
72
|
+
logger.error(toErrorOrString(error));
|
|
73
|
+
}
|
|
70
74
|
},
|
|
71
75
|
onFinish: async () => {
|
|
72
76
|
await sleep(0);
|
|
@@ -135,7 +139,7 @@ class EvlogHandlerPlugin {
|
|
|
135
139
|
try {
|
|
136
140
|
return await next();
|
|
137
141
|
} catch (error) {
|
|
138
|
-
|
|
142
|
+
logProcedureError(logger, error, this.procedureErrorLevel);
|
|
139
143
|
throw error;
|
|
140
144
|
}
|
|
141
145
|
};
|
|
@@ -145,14 +149,14 @@ class EvlogHandlerPlugin {
|
|
|
145
149
|
if (isAsyncIteratorObject(output)) {
|
|
146
150
|
return override(output, wrapAsyncIteratorPreservingEventMeta(output, {
|
|
147
151
|
onError: (error) => {
|
|
148
|
-
|
|
152
|
+
logProcedureError(logger, error, this.procedureErrorLevel);
|
|
149
153
|
}
|
|
150
154
|
}));
|
|
151
155
|
}
|
|
152
156
|
if (output instanceof ReadableStream) {
|
|
153
157
|
return override(output, wrapReadableStream(output, {
|
|
154
158
|
onError: (error) => {
|
|
155
|
-
|
|
159
|
+
logProcedureError(logger, error, this.procedureErrorLevel);
|
|
156
160
|
}
|
|
157
161
|
}));
|
|
158
162
|
}
|
|
@@ -181,13 +185,24 @@ function toErrorOrString(error) {
|
|
|
181
185
|
}
|
|
182
186
|
return String(error);
|
|
183
187
|
}
|
|
184
|
-
function
|
|
185
|
-
logger
|
|
188
|
+
function logProcedureError(logger, error, procedureErrorLevel) {
|
|
189
|
+
if (!logger) {
|
|
190
|
+
return;
|
|
191
|
+
}
|
|
192
|
+
logger.error(toErrorOrString(error));
|
|
193
|
+
const level = procedureErrorLevel(error, defaultProcedureErrorLevel(error));
|
|
194
|
+
if (level !== "error") {
|
|
195
|
+
logger.setLevel(level);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
function defaultProcedureErrorLevel(error) {
|
|
186
199
|
if (isAbortError(error)) {
|
|
187
|
-
|
|
188
|
-
}
|
|
189
|
-
|
|
200
|
+
return "info";
|
|
201
|
+
}
|
|
202
|
+
if (error instanceof ORPCError && error.code !== "INTERNAL_SERVER_ERROR") {
|
|
203
|
+
return "warn";
|
|
190
204
|
}
|
|
205
|
+
return "error";
|
|
191
206
|
}
|
|
192
207
|
|
|
193
208
|
export { EvlogHandlerPlugin, LOGGER_CONTEXT_SYMBOL, getLogger };
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@orpc/evlog",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "2.0.0-beta.
|
|
4
|
+
"version": "2.0.0-beta.32",
|
|
5
5
|
"description": "Evlog integration for oRPC: wide-event logging for typesafe APIs",
|
|
6
6
|
"license": "MIT",
|
|
7
7
|
"funding": [
|
|
@@ -43,10 +43,10 @@
|
|
|
43
43
|
"evlog": ">=2.18.1"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@
|
|
47
|
-
"@orpc/
|
|
48
|
-
"@orpc/shared": "2.0.0-beta.
|
|
49
|
-
"@
|
|
46
|
+
"@orpc/client": "2.0.0-beta.32",
|
|
47
|
+
"@orpc/server": "2.0.0-beta.32",
|
|
48
|
+
"@orpc/shared": "2.0.0-beta.32",
|
|
49
|
+
"@standardserver/core": "^0.8.2"
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
52
|
"evlog": "^2.26.0"
|