@effect-app/infra 0.73.0 → 0.74.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 +20 -0
- package/_cjs/RequestContext.cjs +2 -4
- package/_cjs/RequestContext.cjs.map +1 -1
- package/_cjs/api/authorization.jwt.cjs +1 -2
- package/_cjs/api/authorization.jwt.cjs.map +1 -1
- package/_cjs/api/codec.cjs +4 -3
- package/_cjs/api/codec.cjs.map +1 -1
- package/_cjs/api/defaultErrorHandler.cjs +6 -8
- package/_cjs/api/defaultErrorHandler.cjs.map +1 -1
- package/_cjs/api/express/makeJsonSchema.test.cjs +2 -2
- package/_cjs/api/express/makeJsonSchema.test.cjs.map +1 -1
- package/_cjs/api/express/schema/jwt.cjs +8 -10
- package/_cjs/api/express/schema/jwt.cjs.map +1 -1
- package/_cjs/api/express/schema/requestHandler.cjs +7 -6
- package/_cjs/api/express/schema/requestHandler.cjs.map +1 -1
- package/_cjs/api/express/schema/routing.cjs +20 -5
- package/_cjs/api/express/schema/routing.cjs.map +1 -1
- package/_cjs/api/reportError.cjs +7 -8
- package/_cjs/api/reportError.cjs.map +1 -1
- package/_cjs/api/routing.cjs +26 -25
- package/_cjs/api/routing.cjs.map +1 -1
- package/_cjs/api/setupRequest.cjs +3 -4
- package/_cjs/api/setupRequest.cjs.map +1 -1
- package/_cjs/api/writeDocs.cjs +3 -4
- package/_cjs/api/writeDocs.cjs.map +1 -1
- package/_cjs/errorReporter.cjs +10 -11
- package/_cjs/errorReporter.cjs.map +1 -1
- package/_cjs/errors.cjs +1 -1
- package/_cjs/errors.cjs.map +1 -1
- package/_cjs/filter.cjs +14 -28
- package/_cjs/filter.cjs.map +1 -1
- package/_cjs/instrument.cjs +1 -2
- package/_cjs/instrument.cjs.map +1 -1
- package/_cjs/logger/jsonLogger.cjs +17 -12
- package/_cjs/logger/jsonLogger.cjs.map +1 -1
- package/_cjs/logger/logFmtLogger.cjs +7 -6
- package/_cjs/logger/logFmtLogger.cjs.map +1 -1
- package/_cjs/rateLimit.cjs +13 -5
- package/_cjs/rateLimit.cjs.map +1 -1
- package/_cjs/services/Emailer/Sendgrid.cjs +10 -9
- package/_cjs/services/Emailer/Sendgrid.cjs.map +1 -1
- package/_cjs/services/Emailer/fake.cjs +3 -3
- package/_cjs/services/Emailer/fake.cjs.map +1 -1
- package/_cjs/services/Operations/live.cjs +4 -6
- package/_cjs/services/Operations/live.cjs.map +1 -1
- package/_cjs/services/Operations/service.cjs +5 -7
- package/_cjs/services/Operations/service.cjs.map +1 -1
- package/_cjs/services/QueueMaker/errors.cjs +5 -3
- package/_cjs/services/QueueMaker/errors.cjs.map +1 -1
- package/_cjs/services/QueueMaker/memQueue.cjs +5 -6
- package/_cjs/services/QueueMaker/memQueue.cjs.map +1 -1
- package/_cjs/services/QueueMaker/sbqueue.cjs +9 -10
- package/_cjs/services/QueueMaker/sbqueue.cjs.map +1 -1
- package/_cjs/services/QueueMaker/service.cjs +1 -2
- package/_cjs/services/QueueMaker/service.cjs.map +1 -1
- package/_cjs/services/Repository.cjs +18 -30
- package/_cjs/services/Repository.cjs.map +1 -1
- package/_cjs/services/RepositoryBase.cjs +7 -5
- package/_cjs/services/RepositoryBase.cjs.map +1 -1
- package/_cjs/services/RequestContextContainer.cjs +1 -2
- package/_cjs/services/RequestContextContainer.cjs.map +1 -1
- package/_cjs/services/Store/Cosmos.cjs +68 -58
- package/_cjs/services/Store/Cosmos.cjs.map +1 -1
- package/_cjs/services/Store/Disk.cjs +2 -1
- package/_cjs/services/Store/Disk.cjs.map +1 -1
- package/_cjs/services/Store/Memory.cjs +15 -19
- package/_cjs/services/Store/Memory.cjs.map +1 -1
- package/_cjs/services/Store/Redis.cjs +2 -1
- package/_cjs/services/Store/Redis.cjs.map +1 -1
- package/_cjs/services/Store/index.cjs +4 -3
- package/_cjs/services/Store/index.cjs.map +1 -1
- package/_cjs/services/Store/service.cjs +1 -2
- package/_cjs/services/Store/service.cjs.map +1 -1
- package/_cjs/services/simpledb/cosmosdb.cjs +25 -23
- package/_cjs/services/simpledb/cosmosdb.cjs.map +1 -1
- package/_cjs/services/simpledb/diskdb.cjs +16 -7
- package/_cjs/services/simpledb/diskdb.cjs.map +1 -1
- package/_cjs/services/simpledb/memdb.cjs +1 -1
- package/_cjs/services/simpledb/memdb.cjs.map +1 -1
- package/_cjs/services/simpledb/mongodb.cjs +26 -22
- package/_cjs/services/simpledb/mongodb.cjs.map +1 -1
- package/_cjs/services/simpledb/redisdb.cjs +35 -28
- package/_cjs/services/simpledb/redisdb.cjs.map +1 -1
- package/_cjs/services/simpledb/simpledb.cjs +25 -17
- package/_cjs/services/simpledb/simpledb.cjs.map +1 -1
- package/_cjs/test.arbs.cjs +5 -4
- package/_cjs/test.arbs.cjs.map +1 -1
- package/_src/api/defaultErrorHandler.ts +33 -37
- package/_src/api/express/makeJsonSchema.test.ts +2 -2
- package/_src/api/express/routing.ts.bak +1 -1
- package/_src/api/express/schema/routing.ts +20 -20
- package/_src/api/reportError.ts +15 -19
- package/_src/api/routing.ts +96 -95
- package/_src/api/setupRequest.ts +4 -6
- package/_src/api/writeDocs.ts +1 -1
- package/_src/errorReporter.ts +25 -29
- package/_src/errors.ts +1 -1
- package/_src/instrument.ts +4 -5
- package/_src/logger/jsonLogger.ts +5 -6
- package/_src/logger/logFmtLogger.ts +5 -4
- package/_src/rateLimit.ts +10 -9
- package/_src/services/Emailer/Sendgrid.ts +3 -3
- package/_src/services/Emailer/fake.ts +1 -1
- package/_src/services/Operations/live.ts +1 -1
- package/_src/services/Operations/service.ts +32 -38
- package/_src/services/QueueMaker/errors.ts +1 -2
- package/_src/services/QueueMaker/memQueue.ts +1 -1
- package/_src/services/QueueMaker/sbqueue.ts +3 -3
- package/_src/services/Repository.ts +10 -13
- package/_src/services/RepositoryBase.ts +10 -8
- package/_src/services/Store/Cosmos.ts +66 -62
- package/_src/services/Store/Memory.ts +1 -1
- package/_src/services/simpledb/cosmosdb.ts +45 -43
- package/_src/services/simpledb/diskdb.ts +9 -10
- package/_src/services/simpledb/mongodb.ts +33 -31
- package/_src/services/simpledb/redisdb.ts +42 -40
- package/_src/services/simpledb/simpledb.ts +6 -7
- package/dist/RequestContext.d.ts +4 -4
- package/dist/RequestContext.js +5 -3
- package/dist/api/defaultErrorHandler.d.ts.map +1 -1
- package/dist/api/defaultErrorHandler.js +7 -9
- package/dist/api/express/schema/routing.js +21 -6
- package/dist/api/reportError.d.ts.map +1 -1
- package/dist/api/reportError.js +9 -10
- package/dist/api/routing.d.ts +1 -1
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +35 -33
- package/dist/api/setupRequest.d.ts.map +1 -1
- package/dist/api/setupRequest.js +4 -5
- package/dist/api/writeDocs.js +4 -5
- package/dist/errorReporter.d.ts.map +1 -1
- package/dist/errorReporter.js +11 -12
- package/dist/errors.js +2 -2
- package/dist/instrument.d.ts.map +1 -1
- package/dist/instrument.js +2 -3
- package/dist/logger/jsonLogger.d.ts +1 -1
- package/dist/logger/jsonLogger.d.ts.map +1 -1
- package/dist/logger/jsonLogger.js +9 -11
- package/dist/logger/logFmtLogger.d.ts +1 -1
- package/dist/logger/logFmtLogger.d.ts.map +1 -1
- package/dist/logger/logFmtLogger.js +5 -4
- package/dist/rateLimit.d.ts.map +1 -1
- package/dist/rateLimit.js +6 -6
- package/dist/services/Emailer/Sendgrid.d.ts +1 -1
- package/dist/services/Emailer/Sendgrid.d.ts.map +1 -1
- package/dist/services/Emailer/Sendgrid.js +11 -10
- package/dist/services/Emailer/fake.js +4 -3
- package/dist/services/Emailer/service.d.ts +1 -1
- package/dist/services/Operations/live.js +5 -6
- package/dist/services/Operations/service.d.ts.map +1 -1
- package/dist/services/Operations/service.js +8 -9
- package/dist/services/QueueMaker/errors.d.ts.map +1 -1
- package/dist/services/QueueMaker/errors.js +2 -2
- package/dist/services/QueueMaker/memQueue.js +6 -7
- package/dist/services/QueueMaker/sbqueue.js +10 -11
- package/dist/services/Repository.d.ts +19 -18
- package/dist/services/Repository.d.ts.map +1 -1
- package/dist/services/Repository.js +8 -9
- package/dist/services/RepositoryBase.d.ts +7 -7
- package/dist/services/RepositoryBase.d.ts.map +1 -1
- package/dist/services/RepositoryBase.js +5 -4
- package/dist/services/Store/Cosmos.d.ts +1 -1
- package/dist/services/Store/Cosmos.d.ts.map +1 -1
- package/dist/services/Store/Cosmos.js +64 -55
- package/dist/services/Store/Disk.d.ts +1 -1
- package/dist/services/Store/Disk.d.ts.map +1 -1
- package/dist/services/Store/Disk.js +3 -2
- package/dist/services/Store/Memory.js +13 -14
- package/dist/services/Store/Redis.d.ts +1 -1
- package/dist/services/Store/Redis.d.ts.map +1 -1
- package/dist/services/Store/Redis.js +3 -2
- package/dist/services/Store/index.d.ts +1 -1
- package/dist/services/Store/index.d.ts.map +1 -1
- package/dist/services/Store/index.js +5 -4
- package/dist/services/Store/service.d.ts +1 -1
- package/dist/services/simpledb/cosmosdb.d.ts.map +1 -1
- package/dist/services/simpledb/cosmosdb.js +29 -27
- package/dist/services/simpledb/diskdb.d.ts.map +1 -1
- package/dist/services/simpledb/diskdb.js +10 -4
- package/dist/services/simpledb/memdb.d.ts +2 -2
- package/dist/services/simpledb/memdb.js +1 -1
- package/dist/services/simpledb/mongodb.d.ts.map +1 -1
- package/dist/services/simpledb/mongodb.js +18 -15
- package/dist/services/simpledb/redisdb.d.ts.map +1 -1
- package/dist/services/simpledb/redisdb.js +30 -23
- package/dist/services/simpledb/simpledb.d.ts.map +1 -1
- package/dist/services/simpledb/simpledb.js +16 -12
- package/package.json +22 -22
- package/tsconfig.json +1 -1
|
@@ -100,34 +100,34 @@ export function makeFromSchema<ResA>(
|
|
|
100
100
|
// TODO EffectOption.fromNullable(Req.Headers).flatMapOpt(jsonSchema)
|
|
101
101
|
// TODO: use the path vs body etc serialisation also in the Client.
|
|
102
102
|
const makeReqQuerySchema = Effect(Option.fromNullable(Req.Query)).flatMap((_) =>
|
|
103
|
-
_.match(
|
|
104
|
-
() => Effect(Option.none),
|
|
105
|
-
(_) => jsonSchema(_).map(Option.some)
|
|
106
|
-
)
|
|
103
|
+
_.match({
|
|
104
|
+
onNone: () => Effect(Option.none),
|
|
105
|
+
onSome: (_) => jsonSchema(_).map(Option.some)
|
|
106
|
+
})
|
|
107
107
|
)
|
|
108
108
|
const makeReqHeadersSchema = Effect(Option.fromNullable(Req.Headers)).flatMap((_) =>
|
|
109
|
-
_.match(
|
|
110
|
-
() => Effect(Option.none),
|
|
111
|
-
(_) => jsonSchema(_).map(Option.some)
|
|
112
|
-
)
|
|
109
|
+
_.match({
|
|
110
|
+
onNone: () => Effect(Option.none),
|
|
111
|
+
onSome: (_) => jsonSchema(_).map(Option.some)
|
|
112
|
+
})
|
|
113
113
|
)
|
|
114
114
|
const makeReqCookieSchema = Effect(Option.fromNullable(Req.Cookie)).flatMap((_) =>
|
|
115
|
-
_.match(
|
|
116
|
-
() => Effect(Option.none),
|
|
117
|
-
(_) => jsonSchema(_).map(Option.some)
|
|
118
|
-
)
|
|
115
|
+
_.match({
|
|
116
|
+
onNone: () => Effect(Option.none),
|
|
117
|
+
onSome: (_) => jsonSchema(_).map(Option.some)
|
|
118
|
+
})
|
|
119
119
|
)
|
|
120
120
|
const makeReqPathSchema = Effect(Option.fromNullable(Req.Path)).flatMap((_) =>
|
|
121
|
-
_.match(
|
|
122
|
-
() => Effect(Option.none),
|
|
123
|
-
(_) => jsonSchema(_).map(Option.some)
|
|
124
|
-
)
|
|
121
|
+
_.match({
|
|
122
|
+
onNone: () => Effect(Option.none),
|
|
123
|
+
onSome: (_) => jsonSchema(_).map(Option.some)
|
|
124
|
+
})
|
|
125
125
|
)
|
|
126
126
|
const makeReqBodySchema = Effect(Option.fromNullable(Req.Body)).flatMap((_) =>
|
|
127
|
-
_.match(
|
|
128
|
-
() => Effect(Option.none),
|
|
129
|
-
(_) => jsonSchema(_).map(Option.some)
|
|
130
|
-
)
|
|
127
|
+
_.match({
|
|
128
|
+
onNone: () => Effect(Option.none),
|
|
129
|
+
onSome: (_) => jsonSchema(_).map(Option.some)
|
|
130
|
+
})
|
|
131
131
|
)
|
|
132
132
|
// const makeReqSchema = schema(Req)
|
|
133
133
|
|
package/_src/api/reportError.ts
CHANGED
|
@@ -15,17 +15,17 @@ export class FatalMainException<E> extends CauseException<E> {
|
|
|
15
15
|
const reportMainError_ = reportError((cause) => new FatalMainException(cause))
|
|
16
16
|
|
|
17
17
|
export const reportMainError = <E>(cause: Cause<E>, extras?: Record<string, unknown> | undefined) =>
|
|
18
|
-
|
|
18
|
+
reportMainError_(cause, extras)
|
|
19
19
|
|
|
20
20
|
const reportRequestError_ = reportError((cause) => new RequestException(cause))
|
|
21
21
|
|
|
22
22
|
export const reportRequestError = <E>(cause: Cause<E>, extras?: Record<string, unknown> | undefined) =>
|
|
23
|
-
|
|
23
|
+
reportRequestError_(cause, extras)
|
|
24
24
|
|
|
25
25
|
const logRequestError_ = logError((cause) => new RequestException(cause))
|
|
26
26
|
|
|
27
27
|
export const logRequestError = <E>(cause: Cause<E>, extras?: Record<string, unknown> | undefined) =>
|
|
28
|
-
|
|
28
|
+
logRequestError_(cause, extras)
|
|
29
29
|
|
|
30
30
|
/**
|
|
31
31
|
* Forks the effect into a new fiber attached to the global scope. Because the
|
|
@@ -37,12 +37,10 @@ export const logRequestError = <E>(cause: Cause<E>, extras?: Record<string, unkn
|
|
|
37
37
|
* @tsplus getter effect/io/Effect forkDaemonReportRequest
|
|
38
38
|
*/
|
|
39
39
|
export function forkDaemonReportRequest<R, E, A>(self: Effect<R, E, A>) {
|
|
40
|
-
return
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
.daemonChildren
|
|
45
|
-
)
|
|
40
|
+
return self
|
|
41
|
+
.tapErrorCause(reportRequestError)
|
|
42
|
+
.fork
|
|
43
|
+
.daemonChildren
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
/**
|
|
@@ -55,14 +53,12 @@ export function forkDaemonReportRequest<R, E, A>(self: Effect<R, E, A>) {
|
|
|
55
53
|
* @tsplus getter effect/io/Effect forkDaemonReportRequestUnexpected
|
|
56
54
|
*/
|
|
57
55
|
export function forkDaemonReportRequestUnexpected<R, E, A>(self: Effect<R, E, A>) {
|
|
58
|
-
return
|
|
59
|
-
|
|
60
|
-
.
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
.daemonChildren
|
|
67
|
-
)
|
|
56
|
+
return self
|
|
57
|
+
.tapErrorCause((cause) =>
|
|
58
|
+
cause.isInterruptedOnly() || cause.isDie()
|
|
59
|
+
? reportRequestError(cause)
|
|
60
|
+
: logRequestError(cause)
|
|
61
|
+
)
|
|
62
|
+
.fork
|
|
63
|
+
.daemonChildren
|
|
68
64
|
}
|
package/_src/api/routing.ts
CHANGED
|
@@ -309,77 +309,77 @@ export function makeRequestHandler<
|
|
|
309
309
|
}
|
|
310
310
|
|
|
311
311
|
return (req: express.Request, res: express.Response) => {
|
|
312
|
-
return
|
|
313
|
-
|
|
314
|
-
.
|
|
315
|
-
requestContext
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
Effect.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
: undefined
|
|
343
|
-
})
|
|
344
|
-
)
|
|
345
|
-
)
|
|
346
|
-
.zipRight(
|
|
347
|
-
Effect.suspend(() => {
|
|
348
|
-
const handleRequest = parseRequest(req)
|
|
349
|
-
.map(({ body, path, query }) => {
|
|
350
|
-
const hn = {
|
|
351
|
-
...body.value,
|
|
352
|
-
...query.value,
|
|
353
|
-
...path.value
|
|
354
|
-
} as unknown as ReqA
|
|
355
|
-
return hn
|
|
356
|
-
})
|
|
357
|
-
.flatMap((parsedReq) =>
|
|
358
|
-
restore(() => handle(parsedReq as any))()
|
|
359
|
-
.flatMap((r) => respond(parsedReq, res, r))
|
|
360
|
-
)
|
|
361
|
-
|
|
362
|
-
// Commands should not be interruptable.
|
|
363
|
-
const r = req.method !== "GET" ? handleRequest.uninterruptible : handleRequest // .instrument("Performance.RequestResponse")
|
|
364
|
-
// the first log entry should be of the request start.
|
|
365
|
-
const r2 = makeMiddlewareContext
|
|
366
|
-
? restoreFromRequestContext
|
|
367
|
-
.zipRight(r
|
|
368
|
-
// the db namespace must be restored, before calling provide here
|
|
369
|
-
.provideSomeContextEffect(makeMiddlewareContext(req, res)))
|
|
370
|
-
: restoreFromRequestContext
|
|
371
|
-
// PR is not relevant here
|
|
372
|
-
.zipRight(r) as Effect<R, E | ValidationError, void>
|
|
373
|
-
return errorHandler(
|
|
374
|
-
req,
|
|
375
|
-
res,
|
|
376
|
-
r2
|
|
377
|
-
)
|
|
312
|
+
return Effect
|
|
313
|
+
.all({
|
|
314
|
+
requestContext: Effect.sync(() => {
|
|
315
|
+
const requestContext = makeContext(req)
|
|
316
|
+
if (req.method === "GET") {
|
|
317
|
+
res.setHeader("Cache-Control", "no-store")
|
|
318
|
+
}
|
|
319
|
+
res.setHeader("Content-Language", requestContext.locale)
|
|
320
|
+
return requestContext
|
|
321
|
+
}),
|
|
322
|
+
pars: getParams(req)
|
|
323
|
+
})
|
|
324
|
+
.flatMap(({ pars, requestContext }) =>
|
|
325
|
+
RequestSettings
|
|
326
|
+
.get
|
|
327
|
+
.flatMap((s) =>
|
|
328
|
+
// TODO: we don;t have access to user id here cause context is not yet created
|
|
329
|
+
Effect.logInfo("Incoming request").apply(
|
|
330
|
+
Effect.annotateLogs({
|
|
331
|
+
method: req.method,
|
|
332
|
+
path: req.originalUrl,
|
|
333
|
+
...s.verbose
|
|
334
|
+
? {
|
|
335
|
+
reqPath: pars.path.$$.pretty,
|
|
336
|
+
reqQuery: pars.query.$$.pretty,
|
|
337
|
+
reqBody: pretty(pars.body),
|
|
338
|
+
reqCookies: pretty(pars.cookies),
|
|
339
|
+
reqHeaders: pars.headers.$$.pretty
|
|
340
|
+
}
|
|
341
|
+
: undefined
|
|
378
342
|
})
|
|
379
343
|
)
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
344
|
+
)
|
|
345
|
+
.zipRight(
|
|
346
|
+
Effect.suspend(() => {
|
|
347
|
+
const handleRequest = parseRequest(req)
|
|
348
|
+
.map(({ body, path, query }) => {
|
|
349
|
+
const hn = {
|
|
350
|
+
...body.value,
|
|
351
|
+
...query.value,
|
|
352
|
+
...path.value
|
|
353
|
+
} as unknown as ReqA
|
|
354
|
+
return hn
|
|
355
|
+
})
|
|
356
|
+
.flatMap((parsedReq) =>
|
|
357
|
+
handle(parsedReq as any)
|
|
358
|
+
.flatMap((r) => respond(parsedReq, res, r))
|
|
359
|
+
)
|
|
360
|
+
|
|
361
|
+
// Commands should not be interruptable.
|
|
362
|
+
const r = req.method !== "GET" ? handleRequest.uninterruptible : handleRequest // .instrument("Performance.RequestResponse")
|
|
363
|
+
// the first log entry should be of the request start.
|
|
364
|
+
const r2 = makeMiddlewareContext
|
|
365
|
+
? restoreFromRequestContext
|
|
366
|
+
.zipRight(r
|
|
367
|
+
// the db namespace must be restored, before calling provide here
|
|
368
|
+
.provideSomeContextEffect(makeMiddlewareContext(req, res)))
|
|
369
|
+
: restoreFromRequestContext
|
|
370
|
+
// PR is not relevant here
|
|
371
|
+
.zipRight(r) as Effect<R, E | ValidationError, void>
|
|
372
|
+
return errorHandler(
|
|
373
|
+
req,
|
|
374
|
+
res,
|
|
375
|
+
r2
|
|
376
|
+
)
|
|
377
|
+
})
|
|
378
|
+
)
|
|
379
|
+
.tapErrorCause((cause) =>
|
|
380
|
+
Effect
|
|
381
|
+
.all(
|
|
382
|
+
[
|
|
383
383
|
Effect(res.status(500).send()),
|
|
384
384
|
Effect(
|
|
385
385
|
reportRequestError(cause, {
|
|
@@ -390,11 +390,11 @@ export function makeRequestHandler<
|
|
|
390
390
|
Effect.suspend(() => {
|
|
391
391
|
const headers = res.getHeaders()
|
|
392
392
|
return Effect
|
|
393
|
-
.
|
|
393
|
+
.logError(
|
|
394
394
|
"Finished request",
|
|
395
395
|
cause
|
|
396
396
|
)
|
|
397
|
-
.apply(Effect.
|
|
397
|
+
.apply(Effect.annotateLogs({
|
|
398
398
|
method: req.method,
|
|
399
399
|
path: req.originalUrl,
|
|
400
400
|
statusCode: res.statusCode.toString(),
|
|
@@ -415,30 +415,31 @@ export function makeRequestHandler<
|
|
|
415
415
|
.pretty
|
|
416
416
|
}))
|
|
417
417
|
})
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
:
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
418
|
+
],
|
|
419
|
+
{ concurrency: "inherit" }
|
|
420
|
+
)
|
|
421
|
+
.tapErrorCause((cause) => Effect(console.error("Error occurred while reporting error", cause)))
|
|
422
|
+
)
|
|
423
|
+
.tap(() =>
|
|
424
|
+
RequestSettings
|
|
425
|
+
.get
|
|
426
|
+
.flatMap((s) => {
|
|
427
|
+
const headers = res.getHeaders()
|
|
428
|
+
return Effect.logInfo("Finished request").apply(Effect.annotateLogs({
|
|
429
|
+
method: req.method,
|
|
430
|
+
path: req.originalUrl,
|
|
431
|
+
statusCode: res.statusCode.toString(),
|
|
432
|
+
...s.verbose
|
|
433
|
+
? {
|
|
434
|
+
resHeaders: headers.$$.pretty
|
|
435
|
+
}
|
|
436
|
+
: undefined
|
|
437
|
+
}))
|
|
438
|
+
})
|
|
439
|
+
)
|
|
440
|
+
.withSpan("request")
|
|
441
|
+
.provideService(RequestContextContainer, new RequestContextContainerImpl(requestContext)) // otherwise external error reporter breaks.
|
|
442
|
+
)
|
|
442
443
|
}
|
|
443
444
|
}
|
|
444
445
|
|
package/_src/api/setupRequest.ts
CHANGED
|
@@ -6,12 +6,10 @@ import { RequestContextContainer, RequestContextContainerImpl } from "../service
|
|
|
6
6
|
* @tsplus fluent effect/io/Effect setupRequestFromWith
|
|
7
7
|
*/
|
|
8
8
|
export function setupReq3<R, E, A>(self: Effect<R, E, A>, name: string) {
|
|
9
|
-
return
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
.provideService(RequestContextContainer, new RequestContextContainerImpl(rc))
|
|
14
|
-
)
|
|
9
|
+
return makeInternalRequestContext(name).flatMap((rc) =>
|
|
10
|
+
self
|
|
11
|
+
.withSpan("request")
|
|
12
|
+
.provideService(RequestContextContainer, new RequestContextContainerImpl(rc))
|
|
15
13
|
)
|
|
16
14
|
}
|
|
17
15
|
|
package/_src/api/writeDocs.ts
CHANGED
|
@@ -8,7 +8,7 @@ export function writeOpenapiDocs(rdescs: Record<string, Record<string, RouteDesc
|
|
|
8
8
|
return makeOpenApiSpecs(
|
|
9
9
|
typedValuesOf(rdescs)
|
|
10
10
|
.reduce((prev, cur) => prev.concat(typedValuesOf(cur)), [] as readonly RouteDescriptorAny[])
|
|
11
|
-
.sortWith(Order.string.
|
|
11
|
+
.sortWith(Order.string.mapInput((a: RouteDescriptorAny) => a.path)),
|
|
12
12
|
Plutus.info({
|
|
13
13
|
title: "api",
|
|
14
14
|
version: "X",
|
package/_src/errorReporter.ts
CHANGED
|
@@ -6,22 +6,20 @@ export function reportError<E, E2 extends CauseException<unknown>>(
|
|
|
6
6
|
makeError: (cause: Cause<E>) => E2
|
|
7
7
|
) {
|
|
8
8
|
return (cause: Cause<E>, extras?: Record<string, unknown>) =>
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
JSON.stringify({ ...extras, __error__: { _tag: error._tag, message: error.message } })
|
|
21
|
-
)
|
|
9
|
+
Effect.gen(function*($) {
|
|
10
|
+
if (cause.isInterrupted()) {
|
|
11
|
+
yield* $(Effect.logDebug("Interrupted").annotateLogs("extras", JSON.stringify(extras ?? {})))
|
|
12
|
+
return
|
|
13
|
+
}
|
|
14
|
+
const error = makeError(cause)
|
|
15
|
+
yield* $(reportSentry(error, extras))
|
|
16
|
+
yield* $(
|
|
17
|
+
cause.logError.annotateLogs(
|
|
18
|
+
"extras",
|
|
19
|
+
JSON.stringify({ ...extras, __error__: { _tag: error._tag, message: error.message } })
|
|
22
20
|
)
|
|
23
|
-
|
|
24
|
-
)
|
|
21
|
+
)
|
|
22
|
+
})
|
|
25
23
|
}
|
|
26
24
|
|
|
27
25
|
function reportSentry<E2 extends CauseException<unknown>>(
|
|
@@ -42,21 +40,19 @@ export function logError<E, E2 extends CauseException<unknown>>(
|
|
|
42
40
|
makeError: (cause: Cause<E>) => E2
|
|
43
41
|
) {
|
|
44
42
|
return (cause: Cause<E>, extras?: Record<string, unknown>) =>
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
JSON.stringify({ ...extras, __error__: { _tag: error._tag, message: error.message } })
|
|
56
|
-
)
|
|
43
|
+
Effect.gen(function*($) {
|
|
44
|
+
if (cause.isInterrupted()) {
|
|
45
|
+
yield* $(Effect.logDebug("Interrupted").annotateLogs("extras", JSON.stringify(extras ?? {})))
|
|
46
|
+
return
|
|
47
|
+
}
|
|
48
|
+
const error = makeError(cause)
|
|
49
|
+
yield* $(
|
|
50
|
+
cause.logWarning.annotateLogs(
|
|
51
|
+
"extras",
|
|
52
|
+
JSON.stringify({ ...extras, __error__: { _tag: error._tag, message: error.message } })
|
|
57
53
|
)
|
|
58
|
-
|
|
59
|
-
)
|
|
54
|
+
)
|
|
55
|
+
})
|
|
60
56
|
}
|
|
61
57
|
|
|
62
58
|
export function captureException(error: unknown) {
|
package/_src/errors.ts
CHANGED
package/_src/instrument.ts
CHANGED
|
@@ -2,10 +2,9 @@
|
|
|
2
2
|
* @tsplus fluent effect/io/Effect instrument
|
|
3
3
|
*/
|
|
4
4
|
export function instr<R, E, A>(self: Effect<R, E, A>, name: string, properties?: Record<string, string>) {
|
|
5
|
-
return
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
)
|
|
5
|
+
return self
|
|
6
|
+
.tap(() => Effect.logDebug(`instrumented`).annotateLogs("properties", (properties || {}).$$.pretty))
|
|
7
|
+
.withSpan(name)
|
|
8
|
+
|
|
10
9
|
// trackMetric(name, time, properties))
|
|
11
10
|
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
+
import type { AnnotationValue } from "@effect/io/Logger"
|
|
1
2
|
import { getRequestContext } from "./shared.js"
|
|
2
3
|
|
|
3
|
-
export const jsonLogger = Logger.make<
|
|
4
|
-
(
|
|
4
|
+
export const jsonLogger = Logger.make<unknown, void>(
|
|
5
|
+
({ annotations, cause, context, fiberId, logLevel, message, spans }) => {
|
|
5
6
|
const now = new Date()
|
|
6
7
|
const nowMillis = now.getTime()
|
|
7
8
|
|
|
@@ -14,14 +15,12 @@ export const jsonLogger = Logger.make<string, void>(
|
|
|
14
15
|
message,
|
|
15
16
|
request: c.value,
|
|
16
17
|
cause: cause != null && cause != Cause.empty ? cause.pretty : undefined,
|
|
17
|
-
spans:
|
|
18
|
-
? spans.map((_) => ({ label: _.label, timing: nowMillis - _.startTime })).toArray
|
|
19
|
-
: undefined,
|
|
18
|
+
spans: spans.map((_) => ({ label: _.label, timing: nowMillis - _.startTime })).toReadonlyArray,
|
|
20
19
|
annotations: annotations.size > 0
|
|
21
20
|
? [...annotations].reduce((prev, [k, v]) => {
|
|
22
21
|
prev[k] = v
|
|
23
22
|
return prev
|
|
24
|
-
}, {} as Record<string,
|
|
23
|
+
}, {} as Record<string, AnnotationValue>)
|
|
25
24
|
: undefined
|
|
26
25
|
}
|
|
27
26
|
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { getRequestContext } from "./shared.js"
|
|
2
2
|
|
|
3
|
-
export const logfmtLogger = Logger.make<
|
|
4
|
-
(
|
|
5
|
-
|
|
3
|
+
export const logfmtLogger = Logger.make<unknown, void>(
|
|
4
|
+
(_) => {
|
|
5
|
+
let { annotations } = _
|
|
6
|
+
const c = getRequestContext(_.context)
|
|
6
7
|
const requestContext = c.value
|
|
7
8
|
if (requestContext) {
|
|
8
9
|
annotations = HashMap.make(...[
|
|
@@ -17,7 +18,7 @@ export const logfmtLogger = Logger.make<string, void>(
|
|
|
17
18
|
.entries
|
|
18
19
|
])
|
|
19
20
|
}
|
|
20
|
-
const formatted = Logger.logfmtLogger.log(
|
|
21
|
+
const formatted = Logger.logfmtLogger.log(_)
|
|
21
22
|
globalThis.console.log(formatted)
|
|
22
23
|
}
|
|
23
24
|
)
|
package/_src/rateLimit.ts
CHANGED
|
@@ -60,10 +60,12 @@ export function batchPar<R, E, A, R2, E2, A2, T>(
|
|
|
60
60
|
return (items: Iterable<T>) =>
|
|
61
61
|
items
|
|
62
62
|
.chunk(n)
|
|
63
|
-
.
|
|
64
|
-
_
|
|
65
|
-
|
|
66
|
-
|
|
63
|
+
.forEachEffect(
|
|
64
|
+
(_, i) =>
|
|
65
|
+
_
|
|
66
|
+
.forEachEffect((_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
67
|
+
.flatMap((_) => forEachBatch(_ as NonEmptyArray<A>, i)),
|
|
68
|
+
{ concurrency: "inherit" }
|
|
67
69
|
)
|
|
68
70
|
}
|
|
69
71
|
|
|
@@ -79,9 +81,9 @@ export function batch<R, E, A, R2, E2, A2, T>(
|
|
|
79
81
|
return (items: Iterable<T>) =>
|
|
80
82
|
items
|
|
81
83
|
.chunk(n)
|
|
82
|
-
.
|
|
84
|
+
.forEachEffect((_, i) =>
|
|
83
85
|
_
|
|
84
|
-
.
|
|
86
|
+
.forEachEffect((_, j) => forEachItem(_, j, i), { concurrency: "inherit" })
|
|
85
87
|
.flatMap((_) => forEachBatch(_ as NonEmptyArray<A>, i))
|
|
86
88
|
)
|
|
87
89
|
}
|
|
@@ -121,12 +123,11 @@ export function naiveRateLimit(
|
|
|
121
123
|
) =>
|
|
122
124
|
items
|
|
123
125
|
.chunk(n)
|
|
124
|
-
.
|
|
126
|
+
.forEachEffect((batch, i) =>
|
|
125
127
|
((i === 0) ? Effect.unit : Effect.sleep(d))
|
|
126
128
|
.zipRight(
|
|
127
129
|
batch
|
|
128
|
-
.
|
|
129
|
-
.withParallelism(n)
|
|
130
|
+
.forEachEffect(forEachItem, { concurrency: n })
|
|
130
131
|
.flatMap(forEachBatch)
|
|
131
132
|
)
|
|
132
133
|
))
|
|
@@ -20,7 +20,7 @@ const makeLiveSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subje
|
|
|
20
20
|
|
|
21
21
|
const renderedMsg_ = render(msg)
|
|
22
22
|
const renderedMsg = { ...renderedMsg_, subject: `${subjectPrefix}${renderedMsg_.subject}` }
|
|
23
|
-
yield* $(Effect.logDebug("Sending email").
|
|
23
|
+
yield* $(Effect.logDebug("Sending email").annotateLogs("msg", inspect(renderedMsg, false, 5)))
|
|
24
24
|
|
|
25
25
|
const ret = yield* $(
|
|
26
26
|
Effect.async<
|
|
@@ -42,7 +42,7 @@ const makeLiveSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subje
|
|
|
42
42
|
// templateId: msg.templateId
|
|
43
43
|
// }
|
|
44
44
|
// }
|
|
45
|
-
// yield* $(Effect.logDebug("Tracking email event").
|
|
45
|
+
// yield* $(Effect.logDebug("Tracking email event").annotateLogs("event", event.$$.pretty))
|
|
46
46
|
// const { trackEvent } = yield* $(AiContextService)
|
|
47
47
|
// trackEvent(event)
|
|
48
48
|
return ret
|
|
@@ -100,7 +100,7 @@ function renderFake(addr: EmailData | EmailData[], makeId: () => number) {
|
|
|
100
100
|
email: `test+${makeId()}@nomizz.com`
|
|
101
101
|
}
|
|
102
102
|
}
|
|
103
|
-
const eq = Equivalence.string.
|
|
103
|
+
const eq = Equivalence.string.mapInput((to: { name?: string; email: string } | string) =>
|
|
104
104
|
typeof to === "string" ? to.toLowerCase() : to.email.toLowerCase()
|
|
105
105
|
)
|
|
106
106
|
|
|
@@ -5,7 +5,7 @@ const makeFake = Effect
|
|
|
5
5
|
.logDebug("FAKE Emailer Service enabled")
|
|
6
6
|
.map((): Emailer => ({
|
|
7
7
|
sendMail(msg) {
|
|
8
|
-
return Effect.logDebug(`Fake send mail`).
|
|
8
|
+
return Effect.logDebug(`Fake send mail`).annotateLogs("msg", pretty(msg))
|
|
9
9
|
}
|
|
10
10
|
}))
|
|
11
11
|
|