@effect-app/infra 0.48.0 → 0.49.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/_cjs/_ext/Array.cjs.map +1 -1
  3. package/_cjs/api/defaultErrorHandler.cjs.map +1 -1
  4. package/_cjs/api/express/makeJsonSchema.cjs +2 -2
  5. package/_cjs/api/express/makeJsonSchema.cjs.map +1 -1
  6. package/_cjs/api/express/schema/jwt.cjs.map +1 -1
  7. package/_cjs/api/express/schema/requestHandler.cjs.map +1 -1
  8. package/_cjs/api/express/schema/routing.cjs.map +1 -1
  9. package/_cjs/api/reportError.cjs.map +1 -1
  10. package/_cjs/api/routing.cjs.map +1 -1
  11. package/_cjs/api/setupRequest.cjs.map +1 -1
  12. package/_cjs/api/writeDocs.cjs.map +1 -1
  13. package/_cjs/rateLimit.cjs.map +1 -1
  14. package/_cjs/services/Emailer/Sendgrid.cjs.map +1 -1
  15. package/_cjs/services/Emailer/fake.cjs.map +1 -1
  16. package/_cjs/services/Operations/live.cjs.map +1 -1
  17. package/_cjs/services/Operations/service.cjs.map +1 -1
  18. package/_cjs/services/QueueMaker/errors.cjs.map +1 -1
  19. package/_cjs/services/QueueMaker/memQueue.cjs.map +1 -1
  20. package/_cjs/services/QueueMaker/sbqueue.cjs.map +1 -1
  21. package/_cjs/services/Repository.cjs +8 -8
  22. package/_cjs/services/Repository.cjs.map +1 -1
  23. package/_cjs/services/RepositoryBase.cjs +13 -13
  24. package/_cjs/services/RepositoryBase.cjs.map +1 -1
  25. package/_cjs/services/RequestContextContainer.cjs.map +1 -1
  26. package/_cjs/services/Store/Cosmos.cjs +9 -9
  27. package/_cjs/services/Store/Cosmos.cjs.map +1 -1
  28. package/_cjs/services/Store/Cosmos.test.cjs.map +1 -1
  29. package/_cjs/services/Store/Disk.cjs.map +1 -1
  30. package/_cjs/services/Store/Memory.cjs +42 -42
  31. package/_cjs/services/Store/Memory.cjs.map +1 -1
  32. package/_cjs/services/Store/Redis.cjs +13 -13
  33. package/_cjs/services/Store/Redis.cjs.map +1 -1
  34. package/_cjs/services/Store/codeFilter.test.cjs.map +1 -1
  35. package/_cjs/services/Store/index.cjs.map +1 -1
  36. package/_cjs/services/Store/service.cjs.map +1 -1
  37. package/_cjs/services/Store/utils.cjs +2 -3
  38. package/_cjs/services/Store/utils.cjs.map +1 -1
  39. package/_cjs/services/simpledb/cosmosdb.cjs +12 -4
  40. package/_cjs/services/simpledb/cosmosdb.cjs.map +1 -1
  41. package/_cjs/services/simpledb/diskdb.cjs.map +1 -1
  42. package/_cjs/services/simpledb/memdb.cjs.map +1 -1
  43. package/_cjs/services/simpledb/mongodb.cjs +15 -5
  44. package/_cjs/services/simpledb/mongodb.cjs.map +1 -1
  45. package/_cjs/services/simpledb/redisdb.cjs +13 -7
  46. package/_cjs/services/simpledb/redisdb.cjs.map +1 -1
  47. package/_cjs/services/simpledb/simpledb.cjs.map +1 -1
  48. package/_src/_ext/Array.ts +3 -2
  49. package/_src/api/defaultErrorHandler.ts +14 -12
  50. package/_src/api/express/makeJsonSchema.ts +6 -5
  51. package/_src/api/express/schema/jwt.ts +1 -1
  52. package/_src/api/express/schema/requestHandler.ts +112 -100
  53. package/_src/api/express/schema/routing.ts +61 -55
  54. package/_src/api/reportError.ts +16 -12
  55. package/_src/api/routing.ts +157 -135
  56. package/_src/api/setupRequest.ts +3 -1
  57. package/_src/api/writeDocs.ts +4 -3
  58. package/_src/rateLimit.ts +21 -14
  59. package/_src/services/Emailer/Sendgrid.ts +11 -10
  60. package/_src/services/Emailer/fake.ts +2 -1
  61. package/_src/services/Operations/live.ts +18 -12
  62. package/_src/services/Operations/service.ts +26 -17
  63. package/_src/services/QueueMaker/errors.ts +7 -6
  64. package/_src/services/QueueMaker/memQueue.ts +13 -11
  65. package/_src/services/QueueMaker/sbqueue.ts +16 -14
  66. package/_src/services/Repository.ts +53 -51
  67. package/_src/services/RepositoryBase.ts +33 -28
  68. package/_src/services/RequestContextContainer.ts +4 -3
  69. package/_src/services/Store/Cosmos.test.ts +31 -29
  70. package/_src/services/Store/Cosmos.ts +203 -180
  71. package/_src/services/Store/Disk.ts +19 -18
  72. package/_src/services/Store/Memory.ts +37 -32
  73. package/_src/services/Store/Redis.ts +31 -27
  74. package/_src/services/Store/codeFilter.test.ts +26 -16
  75. package/_src/services/Store/index.ts +26 -24
  76. package/_src/services/Store/service.ts +5 -5
  77. package/_src/services/Store/utils.ts +27 -24
  78. package/_src/services/simpledb/cosmosdb.ts +61 -51
  79. package/_src/services/simpledb/diskdb.ts +38 -31
  80. package/_src/services/simpledb/memdb.ts +25 -21
  81. package/_src/services/simpledb/mongodb.ts +40 -35
  82. package/_src/services/simpledb/redisdb.ts +66 -55
  83. package/_src/services/simpledb/simpledb.ts +32 -30
  84. package/dist/_ext/Array.d.ts.map +1 -1
  85. package/dist/_ext/Array.js +2 -2
  86. package/dist/api/defaultErrorHandler.d.ts.map +1 -1
  87. package/dist/api/defaultErrorHandler.js +5 -5
  88. package/dist/api/express/makeJsonSchema.d.ts +0 -1
  89. package/dist/api/express/makeJsonSchema.d.ts.map +1 -1
  90. package/dist/api/express/makeJsonSchema.js +4 -4
  91. package/dist/api/express/schema/jwt.js +2 -2
  92. package/dist/api/express/schema/requestHandler.d.ts.map +1 -1
  93. package/dist/api/express/schema/requestHandler.js +17 -17
  94. package/dist/api/express/schema/routing.d.ts.map +1 -1
  95. package/dist/api/express/schema/routing.js +13 -11
  96. package/dist/api/reportError.d.ts.map +1 -1
  97. package/dist/api/reportError.js +6 -6
  98. package/dist/api/routing.d.ts.map +1 -1
  99. package/dist/api/routing.js +29 -25
  100. package/dist/api/setupRequest.d.ts.map +1 -1
  101. package/dist/api/setupRequest.js +2 -2
  102. package/dist/api/writeDocs.d.ts.map +1 -1
  103. package/dist/api/writeDocs.js +5 -4
  104. package/dist/rateLimit.d.ts +4 -4
  105. package/dist/rateLimit.d.ts.map +1 -1
  106. package/dist/rateLimit.js +5 -4
  107. package/dist/services/Emailer/Sendgrid.d.ts.map +1 -1
  108. package/dist/services/Emailer/Sendgrid.js +9 -9
  109. package/dist/services/Emailer/fake.d.ts.map +1 -1
  110. package/dist/services/Emailer/fake.js +1 -1
  111. package/dist/services/Operations/live.d.ts.map +1 -1
  112. package/dist/services/Operations/live.js +11 -8
  113. package/dist/services/Operations/service.d.ts.map +1 -1
  114. package/dist/services/Operations/service.js +10 -4
  115. package/dist/services/QueueMaker/errors.d.ts.map +1 -1
  116. package/dist/services/QueueMaker/errors.js +5 -5
  117. package/dist/services/QueueMaker/memQueue.d.ts +1 -1
  118. package/dist/services/QueueMaker/memQueue.d.ts.map +1 -1
  119. package/dist/services/QueueMaker/memQueue.js +5 -4
  120. package/dist/services/QueueMaker/sbqueue.d.ts.map +1 -1
  121. package/dist/services/QueueMaker/sbqueue.js +5 -5
  122. package/dist/services/Repository.d.ts +34 -35
  123. package/dist/services/Repository.d.ts.map +1 -1
  124. package/dist/services/Repository.js +16 -16
  125. package/dist/services/RepositoryBase.d.ts +4 -4
  126. package/dist/services/RepositoryBase.d.ts.map +1 -1
  127. package/dist/services/RepositoryBase.js +25 -22
  128. package/dist/services/RequestContextContainer.d.ts.map +1 -1
  129. package/dist/services/RequestContextContainer.js +3 -3
  130. package/dist/services/Store/Cosmos.d.ts +3 -3
  131. package/dist/services/Store/Cosmos.d.ts.map +1 -1
  132. package/dist/services/Store/Cosmos.js +53 -39
  133. package/dist/services/Store/Disk.d.ts.map +1 -1
  134. package/dist/services/Store/Disk.js +18 -18
  135. package/dist/services/Store/Memory.d.ts +2 -3
  136. package/dist/services/Store/Memory.d.ts.map +1 -1
  137. package/dist/services/Store/Memory.js +44 -44
  138. package/dist/services/Store/Redis.d.ts +4 -4
  139. package/dist/services/Store/Redis.d.ts.map +1 -1
  140. package/dist/services/Store/Redis.js +19 -17
  141. package/dist/services/Store/index.d.ts.map +1 -1
  142. package/dist/services/Store/index.js +4 -4
  143. package/dist/services/Store/service.d.ts +4 -5
  144. package/dist/services/Store/service.d.ts.map +1 -1
  145. package/dist/services/Store/service.js +3 -3
  146. package/dist/services/Store/utils.d.ts +2 -2
  147. package/dist/services/Store/utils.d.ts.map +1 -1
  148. package/dist/services/Store/utils.js +16 -14
  149. package/dist/services/simpledb/cosmosdb.d.ts.map +1 -1
  150. package/dist/services/simpledb/cosmosdb.js +16 -12
  151. package/dist/services/simpledb/diskdb.d.ts.map +1 -1
  152. package/dist/services/simpledb/diskdb.js +15 -15
  153. package/dist/services/simpledb/memdb.d.ts.map +1 -1
  154. package/dist/services/simpledb/memdb.js +6 -6
  155. package/dist/services/simpledb/mongodb.d.ts +5 -5
  156. package/dist/services/simpledb/mongodb.d.ts.map +1 -1
  157. package/dist/services/simpledb/mongodb.js +9 -9
  158. package/dist/services/simpledb/redisdb.d.ts +4 -4
  159. package/dist/services/simpledb/redisdb.d.ts.map +1 -1
  160. package/dist/services/simpledb/redisdb.js +18 -18
  161. package/dist/services/simpledb/simpledb.d.ts.map +1 -1
  162. package/dist/services/simpledb/simpledb.js +9 -9
  163. package/package.json +7 -7
@@ -47,44 +47,49 @@ export function makeRequestParsers<
47
47
  >["Request"]
48
48
  ): RequestParsers<PathA, CookieA, QueryA, BodyA, HeaderA> {
49
49
  const ph = Effect(
50
- Option.fromNullable(Request.Headers)
51
- .map(s => s)
50
+ Option
51
+ .fromNullable(Request.Headers)
52
+ .map((s) => s)
52
53
  .map(Parser.for)
53
54
  .map(MO.condemnFail)
54
55
  )
55
- const parseHeaders = (u: unknown) => ph.flatMapOpt(d => d(u))
56
+ const parseHeaders = (u: unknown) => ph.flatMapOpt((d) => d(u))
56
57
 
57
58
  const pq = Effect(
58
- Option.fromNullable(Request.Query)
59
- .map(s => s)
59
+ Option
60
+ .fromNullable(Request.Query)
61
+ .map((s) => s)
60
62
  .map(Parser.for)
61
63
  .map(MO.condemnFail)
62
64
  )
63
- const parseQuery = (u: unknown) => pq.flatMapOpt(d => d(u))
65
+ const parseQuery = (u: unknown) => pq.flatMapOpt((d) => d(u))
64
66
 
65
67
  const pb = Effect(
66
- Option.fromNullable(Request.Body)
67
- .map(s => s)
68
+ Option
69
+ .fromNullable(Request.Body)
70
+ .map((s) => s)
68
71
  .map(Parser.for)
69
72
  .map(MO.condemnFail)
70
73
  )
71
- const parseBody = (u: unknown) => pb.flatMapOpt(d => d(u))
74
+ const parseBody = (u: unknown) => pb.flatMapOpt((d) => d(u))
72
75
 
73
76
  const pp = Effect(
74
- Option.fromNullable(Request.Path)
75
- .map(s => s)
77
+ Option
78
+ .fromNullable(Request.Path)
79
+ .map((s) => s)
76
80
  .map(Parser.for)
77
81
  .map(MO.condemnFail)
78
82
  )
79
- const parsePath = (u: unknown) => pp.flatMapOpt(d => d(u))
83
+ const parsePath = (u: unknown) => pp.flatMapOpt((d) => d(u))
80
84
 
81
85
  const pc = Effect(
82
- Option.fromNullable(Request.Cookie)
83
- .map(s => s)
86
+ Option
87
+ .fromNullable(Request.Cookie)
88
+ .map((s) => s)
84
89
  .map(Parser.for)
85
90
  .map(MO.condemnFail)
86
91
  )
87
- const parseCookie = (u: unknown) => pc.flatMapOpt(d => d(u))
92
+ const parseCookie = (u: unknown) => pc.flatMapOpt((d) => d(u))
88
93
 
89
94
  return {
90
95
  parseBody,
@@ -169,22 +174,24 @@ export function match<
169
174
  requestHandler = handler
170
175
  makeMiddlewareContext = makeContext
171
176
  }
172
- return Ex.match(requestHandler.Request.method.toLowerCase() as any)(
173
- requestHandler.Request.path.split("?")[0],
174
- makeRequestHandler<R, E, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, R2, PR, RErr>(
175
- requestHandler,
176
- errorHandler,
177
- makeMiddlewareContext
177
+ return Ex
178
+ .match(requestHandler.Request.method.toLowerCase() as any)(
179
+ requestHandler.Request.path.split("?")[0],
180
+ makeRequestHandler<R, E, PathA, CookieA, QueryA, BodyA, HeaderA, ReqA, ResA, R2, PR, RErr>(
181
+ requestHandler,
182
+ errorHandler,
183
+ makeMiddlewareContext
184
+ )
178
185
  )
179
- ).zipRight(
180
- Effect(
181
- makeRouteDescriptor(
182
- requestHandler.Request.path,
183
- requestHandler.Request.method,
184
- requestHandler
186
+ .zipRight(
187
+ Effect(
188
+ makeRouteDescriptor(
189
+ requestHandler.Request.path,
190
+ requestHandler.Request.method,
191
+ requestHandler
192
+ )
185
193
  )
186
194
  )
187
- )
188
195
  }
189
196
 
190
197
  export function respondSuccess<ReqA, A, E>(
@@ -192,11 +199,12 @@ export function respondSuccess<ReqA, A, E>(
192
199
  ) {
193
200
  return (req: ReqA, res: express.Response, a: A) =>
194
201
  Effect(encodeResponse(req)(a))
195
- .flatMap(r =>
202
+ .flatMap((r) =>
196
203
  Effect.sync(() => {
197
204
  r === undefined
198
205
  ? res.status(204).send()
199
- : res.status(200)
206
+ : res
207
+ .status(200)
200
208
  .send(JSON.stringify(r))
201
209
  })
202
210
  )
@@ -300,122 +308,136 @@ export function makeRequestHandler<
300
308
  }
301
309
 
302
310
  return (req: express.Request, res: express.Response) => {
303
- return Debug.untraced(restore =>
304
- Effect.all({
305
- requestContext: Effect.sync(() => {
306
- const requestContext = makeContext(req)
307
- if (req.method === "GET") {
308
- res.setHeader("Cache-Control", "no-store")
309
- }
310
- res.setHeader("Content-Language", requestContext.locale)
311
- return requestContext
312
- }),
313
- pars: getParams(req)
314
- })
311
+ return Debug.untraced((restore) =>
312
+ 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
+ })
315
324
  .flatMap(({ pars, requestContext }) =>
316
- RequestSettings.get.flatMap(s =>
317
- // TODO: we don;t have access to user id here cause context is not yet created
318
- Effect.logInfo("Incoming request").apply(
319
- Effect.logAnnotates({
320
- method: req.method,
321
- path: req.originalUrl,
322
- ...s.verbose
323
- ? {
324
- reqPath: pars.path.$$.pretty,
325
- reqQuery: pars.query.$$.pretty,
326
- reqBody: pretty(pars.body),
327
- reqCookies: pretty(pars.cookies),
328
- reqHeaders: pars.headers.$$.pretty
329
- } :
330
- undefined
331
- })
332
- )
333
- ).zipRight(
334
- Effect.suspend(() => {
335
- const handleRequest = parseRequest(req)
336
- .map(({ body, path, query }) => {
337
- const hn = {
338
- ...body.value,
339
- ...query.value,
340
- ...path.value
341
- } as unknown as ReqA
342
- return hn
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.logAnnotates({
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
343
342
  })
344
- .flatMap(parsedReq =>
345
- restore(() => handle(parsedReq as any))()
346
- .flatMap(r => respond(parsedReq, res, r))
347
- )
348
-
349
- // Commands should not be interruptable.
350
- const r = req.method !== "GET" ? handleRequest.uninterruptible : handleRequest // .instrument("Performance.RequestResponse")
351
- // the first log entry should be of the request start.
352
- const r2 = makeMiddlewareContext
353
- ? restoreFromRequestContext
354
- .zipRight(r.setupRequestFrom
355
- // the db namespace must be restored, before calling provide here
356
- .provideSomeContextEffect(makeMiddlewareContext(req, res)))
357
- : restoreFromRequestContext
358
- // PR is not relevant here
359
- .zipRight(r) as Effect<R, E | ValidationError, void>
360
- return errorHandler(
361
- req,
362
- res,
363
- r2
364
343
  )
365
- })
366
- )
367
- .tapErrorCause(cause =>
368
- Effect.allPar(
369
- Effect(res.status(500).send()),
370
- RequestContextContainer.get.flatMap(requestContext =>
371
- reportRequestError(cause, {
372
- requestContext,
373
- path: req.originalUrl,
374
- method: req.method
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
+ restore(() => 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
+ .setupRequestFrom
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
+ )
378
+ })
379
+ )
380
+ .tapErrorCause((cause) =>
381
+ Effect
382
+ .allPar(
383
+ Effect(res.status(500).send()),
384
+ RequestContextContainer.get.flatMap((requestContext) =>
385
+ reportRequestError(cause, {
386
+ requestContext,
387
+ path: req.originalUrl,
388
+ method: req.method
389
+ })
390
+ ),
391
+ Effect.suspend(() => {
392
+ const headers = res.getHeaders()
393
+ return Effect
394
+ .logErrorCauseMessage(
395
+ "Finished request",
396
+ cause
397
+ )
398
+ .apply(Effect.logAnnotates({
399
+ method: req.method,
400
+ path: req.originalUrl,
401
+ statusCode: res.statusCode.toString(),
402
+
403
+ reqPath: pars.path.$$.pretty,
404
+ reqQuery: pars.query.$$.pretty,
405
+ reqBody: pretty(pars.body),
406
+ reqCookies: pretty(pars.cookies),
407
+ reqHeaders: pars.headers.$$.pretty,
408
+
409
+ resHeaders: Object
410
+ .entries(headers)
411
+ .reduce((prev, [key, value]) => {
412
+ prev[key] = value && typeof value === "string" ? snipString(value) : value
413
+ return prev
414
+ }, {} as Record<string, any>)
415
+ .$$
416
+ .pretty
417
+ }))
375
418
  })
376
- ),
377
- Effect.suspend(() => {
419
+ )
420
+ .tapErrorCause((cause) => Effect(console.error("Error occurred while reporting error", cause)))
421
+ .setupRequestFrom
422
+ )
423
+ .tap(() =>
424
+ RequestSettings
425
+ .get
426
+ .flatMap((s) => {
378
427
  const headers = res.getHeaders()
379
- return Effect.logErrorCauseMessage(
380
- "Finished request",
381
- cause
382
- ).apply(Effect.logAnnotates({
428
+ return Effect.logInfo("Finished request").apply(Effect.logAnnotates({
383
429
  method: req.method,
384
430
  path: req.originalUrl,
385
431
  statusCode: res.statusCode.toString(),
386
-
387
- reqPath: pars.path.$$.pretty,
388
- reqQuery: pars.query.$$.pretty,
389
- reqBody: pretty(pars.body),
390
- reqCookies: pretty(pars.cookies),
391
- reqHeaders: pars.headers.$$.pretty,
392
-
393
- resHeaders: Object.entries(headers).reduce((prev, [key, value]) => {
394
- prev[key] = value && typeof value === "string" ? snipString(value) : value
395
- return prev
396
- }, {} as Record<string, any>)
397
- .$$.pretty
432
+ ...s.verbose
433
+ ? {
434
+ resHeaders: headers.$$.pretty
435
+ }
436
+ : undefined
398
437
  }))
399
438
  })
400
- )
401
- .tapErrorCause(cause => Effect(console.error("Error occurred while reporting error", cause)))
402
439
  .setupRequestFrom
403
440
  )
404
- .tap(() =>
405
- RequestSettings.get.flatMap(s => {
406
- const headers = res.getHeaders()
407
- return Effect.logInfo("Finished request").apply(Effect.logAnnotates({
408
- method: req.method,
409
- path: req.originalUrl,
410
- statusCode: res.statusCode.toString(),
411
- ...s.verbose
412
- ? {
413
- resHeaders: headers.$$.pretty
414
- } :
415
- undefined
416
- }))
417
- }).setupRequestFrom
418
- )
419
441
  .setupRequestFrom
420
442
  .provideService(RequestContextContainer, new RequestContextContainerImpl(requestContext)) // otherwise external error reporter breaks.
421
443
  )
@@ -484,7 +506,7 @@ export function matchAll<T extends RequestHandlers>(handlers: T) {
484
506
  export function matchAllAlt<T extends RequestHandlersTest>(handlers: T) {
485
507
  const mapped = handlers.$$.keys.reduce((prev, cur) => {
486
508
  const matches = matchAll(handlers[cur])
487
- matches.$$.keys.forEach(key => prev[`${cur as string}.${key as string}`] = matches[key])
509
+ matches.$$.keys.forEach((key) => prev[`${cur as string}.${key as string}`] = matches[key])
488
510
  return prev
489
511
  }, {} as any) as Flatten<RouteAllTest<typeof handlers>>
490
512
 
@@ -22,7 +22,9 @@ export function setupRequest<R, E, A>(self: Effect<R, E, A>, requestContext: Req
22
22
  * @tsplus getter effect/io/Effect setupRequestFrom
23
23
  */
24
24
  export function setupRequestFrom<R, E, A>(self: Effect<R, E, A>) {
25
- return Debug.untraced(() => RequestContextContainer.get.flatMap(requestContext => self.setupRequest(requestContext)))
25
+ return Debug.untraced(() =>
26
+ RequestContextContainer.get.flatMap((requestContext) => self.setupRequest(requestContext))
27
+ )
26
28
  }
27
29
 
28
30
  /**
@@ -6,7 +6,8 @@ import type { RouteDescriptorAny } from "./express/schema/routing.js"
6
6
 
7
7
  export function writeOpenapiDocs(rdescs: Record<string, Record<string, RouteDescriptorAny>>) {
8
8
  return makeOpenApiSpecs(
9
- typedValuesOf(rdescs).reduce((prev, cur) => prev.concat(typedValuesOf(cur)), [] as readonly RouteDescriptorAny[])
9
+ typedValuesOf(rdescs)
10
+ .reduce((prev, cur) => prev.concat(typedValuesOf(cur)), [] as readonly RouteDescriptorAny[])
10
11
  .sortWith(Order.string.contramap((a: RouteDescriptorAny) => a.path)),
11
12
  Plutus.info({
12
13
  title: "api",
@@ -14,12 +15,12 @@ export function writeOpenapiDocs(rdescs: Record<string, Record<string, RouteDesc
14
15
  pageTitle: "api"
15
16
  })
16
17
  )
17
- .map(_ => ({
18
+ .map((_) => ({
18
19
  ..._,
19
20
  tags: [
20
21
  // add the tags here
21
22
  ]
22
23
  }))
23
- .flatMap(_ => writeTextFile("./openapi.json", JSON.stringify(_, undefined, 2)).orDie)
24
+ .flatMap((_) => writeTextFile("./openapi.json", JSON.stringify(_, undefined, 2)).orDie)
24
25
  .flatMap(() => Effect.logInfo("OpenAPI spec written to './openapi.json'"))
25
26
  }
package/_src/rateLimit.ts CHANGED
@@ -34,13 +34,14 @@
34
34
  */
35
35
  export function SEM_withPermitsDuration(permits: number, duration: Duration) {
36
36
  return (self: Semaphore): <R, E, A>(effect: Effect<R, E, A>) => Effect<R, E, A> => {
37
- return effect =>
37
+ return (effect) =>
38
38
  Effect.uninterruptibleMask(
39
- restore =>
39
+ (restore) =>
40
40
  restore(self.take(permits))
41
41
  > restore(effect)
42
42
  .ensuring(
43
- self.release(permits)
43
+ self
44
+ .release(permits)
44
45
  .delay(duration)
45
46
  )
46
47
  )
@@ -54,13 +55,15 @@ export function SEM_withPermitsDuration(permits: number, duration: Duration) {
54
55
  export function batchPar<R, E, A, R2, E2, A2, T>(
55
56
  n: number,
56
57
  forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect<R, E, A>,
57
- forEachBatch: (a: NonEmptyChunk<A>, i: number) => Effect<R2, E2, A2>
58
+ forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect<R2, E2, A2>
58
59
  ) {
59
60
  return (items: Iterable<T>) =>
60
- items.chunk(n)
61
+ items
62
+ .chunk(n)
61
63
  .forEachEffectParWithIndex((_, i) =>
62
- _.forEachParWithIndex((_, j) => forEachItem(_, j, i))
63
- .flatMap(_ => forEachBatch(_ as NonEmptyChunk<A>, i))
64
+ _
65
+ .forEachParWithIndex((_, j) => forEachItem(_, j, i))
66
+ .flatMap((_) => forEachBatch(_ as NonEmptyArray<A>, i))
64
67
  )
65
68
  }
66
69
 
@@ -71,13 +74,15 @@ export function batchPar<R, E, A, R2, E2, A2, T>(
71
74
  export function batch<R, E, A, R2, E2, A2, T>(
72
75
  n: number,
73
76
  forEachItem: (item: T, iWithinBatch: number, batchI: number) => Effect<R, E, A>,
74
- forEachBatch: (a: NonEmptyChunk<A>, i: number) => Effect<R2, E2, A2>
77
+ forEachBatch: (a: NonEmptyArray<A>, i: number) => Effect<R2, E2, A2>
75
78
  ) {
76
79
  return (items: Iterable<T>) =>
77
- items.chunk(n)
80
+ items
81
+ .chunk(n)
78
82
  .forEachEffectWithIndex((_, i) =>
79
- _.forEachParWithIndex((_, j) => forEachItem(_, j, i))
80
- .flatMap(_ => forEachBatch(_ as NonEmptyChunk<A>, i))
83
+ _
84
+ .forEachParWithIndex((_, j) => forEachItem(_, j, i))
85
+ .flatMap((_) => forEachBatch(_ as NonEmptyArray<A>, i))
81
86
  )
82
87
  }
83
88
 
@@ -112,13 +117,15 @@ export function naiveRateLimit(
112
117
  ) {
113
118
  return <T>(items: Iterable<T>) => (<R, E, A, R2, E2, A2>(
114
119
  forEachItem: (i: T) => Effect<R, E, A>,
115
- forEachBatch: (a: Chunk<A>) => Effect<R2, E2, A2>
120
+ forEachBatch: (a: A[]) => Effect<R2, E2, A2>
116
121
  ) =>
117
- items.chunk(n)
122
+ items
123
+ .chunk(n)
118
124
  .forEachEffectWithIndex((batch, i) =>
119
125
  ((i === 0) ? Effect.unit : Effect.sleep(d))
120
126
  .zipRight(
121
- batch.forEachEffectPar(forEachItem)
127
+ batch
128
+ .forEachEffectPar(forEachItem)
122
129
  .withParallelism(n)
123
130
  .flatMap(forEachBatch)
124
131
  )
@@ -28,11 +28,11 @@ const makeLiveSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subje
28
28
  Error | sgMail.ResponseError,
29
29
  [sgMail.ClientResponse, Record<string, unknown>]
30
30
  >(
31
- cb =>
31
+ (cb) =>
32
32
  void sgMail.send(renderedMsg, false, (err, result) =>
33
- err ?
34
- cb(Effect.fail(err)) :
35
- cb(Effect(result)))
33
+ err
34
+ ? cb(Effect.fail(err))
35
+ : cb(Effect(result)))
36
36
  )
37
37
  )
38
38
 
@@ -55,7 +55,8 @@ const makeLiveSendgrid = ({ apiKey, defaultFrom, defaultReplyTo, realMail, subje
55
55
  * @tsplus static Emailer.Ops LiveSendgrid
56
56
  */
57
57
  export function LiveSendgrid(config: Config<SendgridConfig>) {
58
- return config.config
58
+ return config
59
+ .config
59
60
  .flatMap(makeLiveSendgrid)
60
61
  .toLayer(Emailer)
61
62
  }
@@ -86,10 +87,10 @@ export function renderMessage(forceFake: boolean) {
86
87
  */
87
88
  export function isTestAddress(to: EmailData) {
88
89
  return (
89
- (typeof to === "string" && to.toLowerCase().endsWith(".test")) ||
90
- (typeof to === "object" &&
91
- "email" in to &&
92
- to.email.toLowerCase().endsWith(".test"))
90
+ (typeof to === "string" && to.toLowerCase().endsWith(".test"))
91
+ || (typeof to === "object"
92
+ && "email" in to
93
+ && to.email.toLowerCase().endsWith(".test"))
93
94
  )
94
95
  }
95
96
 
@@ -108,7 +109,7 @@ const eq = Equivalence.string.contramap((to: { name?: string; email: string } |
108
109
  function renderFakeIfTest(addr: EmailData | EmailData[], makeId: () => number) {
109
110
  return Array.isArray(addr)
110
111
  ? addr
111
- .map(x => (isTestAddress(x) ? renderFake(x, makeId) : x))
112
+ .map((x) => (isTestAddress(x) ? renderFake(x, makeId) : x))
112
113
  .uniq(eq)
113
114
  .toArray
114
115
  : isTestAddress(addr)
@@ -1,7 +1,8 @@
1
1
  import { pretty } from "@effect-app/prelude/utils"
2
2
  import { Emailer } from "./service.js"
3
3
 
4
- const makeFake = Effect.logDebug("FAKE Emailer Service enabled")
4
+ const makeFake = Effect
5
+ .logDebug("FAKE Emailer Service enabled")
5
6
  .map((): Emailer => ({
6
7
  sendMail(msg) {
7
8
  return Effect.logDebug(`Fake send mail`).logAnnotate("msg", pretty(msg))
@@ -4,7 +4,7 @@ import type { OperationProgress } from "@effect-app/prelude/Operations"
4
4
  import { Failure, Operation, OperationId, Success } from "@effect-app/prelude/Operations"
5
5
  import { Operations } from "./service.js"
6
6
 
7
- const reportAppError = reportError(cause => new RequestException(cause))
7
+ const reportAppError = reportError((cause) => new RequestException(cause))
8
8
 
9
9
  const make = Effect.sync(() => {
10
10
  const ops = new Map<OperationId, Operation>()
@@ -12,7 +12,8 @@ const make = Effect.sync(() => {
12
12
 
13
13
  const cleanup = Effect.sync(() => {
14
14
  const before = new Date().subHours(1)
15
- ops.entries()
15
+ ops
16
+ .entries()
16
17
  .toChunk
17
18
  .forEach(([id, op]) => {
18
19
  const lastChanged = Option.fromNullable(op.updatedAt).getOrElse(() => op.createdAt)
@@ -31,7 +32,7 @@ const make = Effect.sync(() => {
31
32
  return Effect(Option.fromNullable(ops.get(id)))
32
33
  }
33
34
  function finishOp(id: OperationId, exit: Exit<unknown, unknown>) {
34
- return findOp(id).flatMap(_ =>
35
+ return findOp(id).flatMap((_) =>
35
36
  Effect.sync(() => {
36
37
  if (_.isNone()) {
37
38
  throw new Error("Not found")
@@ -46,18 +47,22 @@ const make = Effect.sync(() => {
46
47
  ? LongString("Interrupted")
47
48
  : exit.cause.isDie()
48
49
  ? LongString("Unknown error")
49
- : exit.cause.failureOption.flatMap(_ =>
50
- typeof _ === "object" && _ !== null && "message" in _ && LongString.Guard(_.message)
51
- ? Option(_.message)
52
- : Option.none
53
- ).value ?? null
50
+ : exit
51
+ .cause
52
+ .failureOption
53
+ .flatMap((_) =>
54
+ typeof _ === "object" && _ !== null && "message" in _ && LongString.Guard(_.message)
55
+ ? Option(_.message)
56
+ : Option.none
57
+ )
58
+ .value ?? null
54
59
  })
55
60
  })
56
61
  })
57
62
  )
58
63
  }
59
64
  function update(id: OperationId, progress: OperationProgress) {
60
- return findOp(id).flatMap(_ =>
65
+ return findOp(id).flatMap((_) =>
61
66
  Effect.sync(() => {
62
67
  if (_.isNone()) {
63
68
  throw new Error("Not found")
@@ -69,7 +74,7 @@ const make = Effect.sync(() => {
69
74
  return Operations.make({
70
75
  cleanup,
71
76
  register: makeOp
72
- .tap(id =>
77
+ .tap((id) =>
73
78
  Effect.logAnnotateScoped("operationId", id)
74
79
  > addOp(id).acquireRelease(
75
80
  (_, exit) => finishOp(id, exit)
@@ -81,9 +86,10 @@ const make = Effect.sync(() => {
81
86
  })
82
87
  })
83
88
 
84
- const cleanupLoop = Operations.flatMap(_ => _.cleanup)
89
+ const cleanupLoop = Operations
90
+ .flatMap((_) => _.cleanup)
85
91
  .exit
86
- .flatMap(_ => {
92
+ .flatMap((_) => {
87
93
  if (_.isSuccess()) {
88
94
  return Effect.unit
89
95
  } else {