effect 4.0.0-beta.97 → 4.0.0-beta.99

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 (221) hide show
  1. package/README.md +1 -3
  2. package/dist/Array.js +1 -1
  3. package/dist/Array.js.map +1 -1
  4. package/dist/Graph.d.ts +1187 -196
  5. package/dist/Graph.d.ts.map +1 -1
  6. package/dist/Graph.js +1031 -283
  7. package/dist/Graph.js.map +1 -1
  8. package/dist/Iterable.d.ts.map +1 -1
  9. package/dist/Iterable.js +41 -1
  10. package/dist/Iterable.js.map +1 -1
  11. package/dist/LayerRef.d.ts +4 -6
  12. package/dist/LayerRef.d.ts.map +1 -1
  13. package/dist/LayerRef.js +4 -6
  14. package/dist/LayerRef.js.map +1 -1
  15. package/dist/Number.d.ts.map +1 -1
  16. package/dist/Number.js +28 -10
  17. package/dist/Number.js.map +1 -1
  18. package/dist/Schema.d.ts +22 -22
  19. package/dist/Schema.d.ts.map +1 -1
  20. package/dist/Schema.js +37 -34
  21. package/dist/Schema.js.map +1 -1
  22. package/dist/SchemaAST.d.ts.map +1 -1
  23. package/dist/SchemaAST.js +25 -10
  24. package/dist/SchemaAST.js.map +1 -1
  25. package/dist/SchemaError.d.ts +53 -0
  26. package/dist/SchemaError.d.ts.map +1 -0
  27. package/dist/SchemaError.js +61 -0
  28. package/dist/SchemaError.js.map +1 -0
  29. package/dist/SchemaGetter.d.ts.map +1 -1
  30. package/dist/SchemaGetter.js +17 -12
  31. package/dist/SchemaGetter.js.map +1 -1
  32. package/dist/SchemaRepresentation.d.ts.map +1 -1
  33. package/dist/SchemaRepresentation.js +186 -224
  34. package/dist/SchemaRepresentation.js.map +1 -1
  35. package/dist/index.d.ts +8 -0
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +8 -0
  38. package/dist/index.js.map +1 -1
  39. package/dist/internal/effect.js +35 -11
  40. package/dist/internal/effect.js.map +1 -1
  41. package/dist/internal/schema/equivalence.js +1 -2
  42. package/dist/internal/schema/equivalence.js.map +1 -1
  43. package/dist/internal/schema/representation.js +1 -3
  44. package/dist/internal/schema/representation.js.map +1 -1
  45. package/dist/internal/schema/schema.d.ts +0 -13
  46. package/dist/internal/schema/schema.d.ts.map +1 -1
  47. package/dist/internal/schema/schema.js +4 -29
  48. package/dist/internal/schema/schema.js.map +1 -1
  49. package/dist/unstable/ai/Tool.d.ts.map +1 -1
  50. package/dist/unstable/ai/Tool.js +11 -13
  51. package/dist/unstable/ai/Tool.js.map +1 -1
  52. package/dist/unstable/cli/CliConfig.d.ts +76 -0
  53. package/dist/unstable/cli/CliConfig.d.ts.map +1 -0
  54. package/dist/unstable/cli/CliConfig.js +63 -0
  55. package/dist/unstable/cli/CliConfig.js.map +1 -0
  56. package/dist/unstable/cli/CliError.d.ts +8 -16
  57. package/dist/unstable/cli/CliError.d.ts.map +1 -1
  58. package/dist/unstable/cli/CliError.js +11 -16
  59. package/dist/unstable/cli/CliError.js.map +1 -1
  60. package/dist/unstable/cli/Command.d.ts +40 -4
  61. package/dist/unstable/cli/Command.d.ts.map +1 -1
  62. package/dist/unstable/cli/Command.js +63 -6
  63. package/dist/unstable/cli/Command.js.map +1 -1
  64. package/dist/unstable/cli/GlobalFlag.d.ts +24 -5
  65. package/dist/unstable/cli/GlobalFlag.d.ts.map +1 -1
  66. package/dist/unstable/cli/GlobalFlag.js +26 -10
  67. package/dist/unstable/cli/GlobalFlag.js.map +1 -1
  68. package/dist/unstable/cli/Param.js +6 -2
  69. package/dist/unstable/cli/Param.js.map +1 -1
  70. package/dist/unstable/cli/index.d.ts +4 -0
  71. package/dist/unstable/cli/index.d.ts.map +1 -1
  72. package/dist/unstable/cli/index.js +4 -0
  73. package/dist/unstable/cli/index.js.map +1 -1
  74. package/dist/unstable/cli/internal/ansi.d.ts.map +1 -1
  75. package/dist/unstable/cli/internal/ansi.js +2 -0
  76. package/dist/unstable/cli/internal/ansi.js.map +1 -1
  77. package/dist/unstable/cli/internal/parser.js +11 -2
  78. package/dist/unstable/cli/internal/parser.js.map +1 -1
  79. package/dist/unstable/cli/internal/wizard.d.ts +13 -0
  80. package/dist/unstable/cli/internal/wizard.d.ts.map +1 -0
  81. package/dist/unstable/cli/internal/wizard.js +212 -0
  82. package/dist/unstable/cli/internal/wizard.js.map +1 -0
  83. package/dist/unstable/cluster/EntityProxyServer.d.ts +1 -1
  84. package/dist/unstable/cluster/EntityProxyServer.d.ts.map +1 -1
  85. package/dist/unstable/cluster/EntityProxyServer.js +2 -4
  86. package/dist/unstable/cluster/EntityProxyServer.js.map +1 -1
  87. package/dist/unstable/cluster/RunnerStorage.js +1 -1
  88. package/dist/unstable/cluster/RunnerStorage.js.map +1 -1
  89. package/dist/unstable/cluster/internal/entityManager.js +15 -12
  90. package/dist/unstable/cluster/internal/entityManager.js.map +1 -1
  91. package/dist/unstable/http/Multipart.d.ts.map +1 -1
  92. package/dist/unstable/http/Multipart.js +3 -1
  93. package/dist/unstable/http/Multipart.js.map +1 -1
  94. package/dist/unstable/httpapi/HttpApi.d.ts +36 -15
  95. package/dist/unstable/httpapi/HttpApi.d.ts.map +1 -1
  96. package/dist/unstable/httpapi/HttpApi.js +19 -20
  97. package/dist/unstable/httpapi/HttpApi.js.map +1 -1
  98. package/dist/unstable/httpapi/HttpApiBuilder.d.ts +51 -62
  99. package/dist/unstable/httpapi/HttpApiBuilder.d.ts.map +1 -1
  100. package/dist/unstable/httpapi/HttpApiBuilder.js +68 -58
  101. package/dist/unstable/httpapi/HttpApiBuilder.js.map +1 -1
  102. package/dist/unstable/httpapi/HttpApiClient.d.ts +53 -53
  103. package/dist/unstable/httpapi/HttpApiClient.d.ts.map +1 -1
  104. package/dist/unstable/httpapi/HttpApiClient.js +40 -30
  105. package/dist/unstable/httpapi/HttpApiClient.js.map +1 -1
  106. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts +165 -164
  107. package/dist/unstable/httpapi/HttpApiEndpoint.d.ts.map +1 -1
  108. package/dist/unstable/httpapi/HttpApiEndpoint.js +31 -19
  109. package/dist/unstable/httpapi/HttpApiEndpoint.js.map +1 -1
  110. package/dist/unstable/httpapi/HttpApiError.d.ts +22 -0
  111. package/dist/unstable/httpapi/HttpApiError.d.ts.map +1 -1
  112. package/dist/unstable/httpapi/HttpApiError.js +31 -0
  113. package/dist/unstable/httpapi/HttpApiError.js.map +1 -1
  114. package/dist/unstable/httpapi/HttpApiGroup.d.ts +55 -30
  115. package/dist/unstable/httpapi/HttpApiGroup.d.ts.map +1 -1
  116. package/dist/unstable/httpapi/HttpApiGroup.js +22 -29
  117. package/dist/unstable/httpapi/HttpApiGroup.js.map +1 -1
  118. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts +8 -8
  119. package/dist/unstable/httpapi/HttpApiMiddleware.d.ts.map +1 -1
  120. package/dist/unstable/httpapi/HttpApiMiddleware.js.map +1 -1
  121. package/dist/unstable/httpapi/HttpApiScalar.d.ts +2 -2
  122. package/dist/unstable/httpapi/HttpApiScalar.d.ts.map +1 -1
  123. package/dist/unstable/httpapi/HttpApiScalar.js +4 -3
  124. package/dist/unstable/httpapi/HttpApiScalar.js.map +1 -1
  125. package/dist/unstable/httpapi/HttpApiSchema.d.ts +8 -0
  126. package/dist/unstable/httpapi/HttpApiSchema.d.ts.map +1 -1
  127. package/dist/unstable/httpapi/HttpApiSchema.js.map +1 -1
  128. package/dist/unstable/httpapi/HttpApiSwagger.d.ts +1 -1
  129. package/dist/unstable/httpapi/HttpApiSwagger.d.ts.map +1 -1
  130. package/dist/unstable/httpapi/HttpApiSwagger.js.map +1 -1
  131. package/dist/unstable/httpapi/HttpApiTest.d.ts +4 -4
  132. package/dist/unstable/httpapi/HttpApiTest.d.ts.map +1 -1
  133. package/dist/unstable/httpapi/HttpApiTest.js +9 -8
  134. package/dist/unstable/httpapi/HttpApiTest.js.map +1 -1
  135. package/dist/unstable/httpapi/OpenApi.d.ts +1 -1
  136. package/dist/unstable/httpapi/OpenApi.d.ts.map +1 -1
  137. package/dist/unstable/httpapi/OpenApi.js +77 -37
  138. package/dist/unstable/httpapi/OpenApi.js.map +1 -1
  139. package/dist/unstable/httpapi/internal/html.js +6 -2
  140. package/dist/unstable/httpapi/internal/html.js.map +1 -1
  141. package/dist/unstable/httpapi/internal/mediaType.d.ts +2 -0
  142. package/dist/unstable/httpapi/internal/mediaType.d.ts.map +1 -0
  143. package/dist/unstable/httpapi/internal/mediaType.js +7 -0
  144. package/dist/unstable/httpapi/internal/mediaType.js.map +1 -0
  145. package/dist/unstable/persistence/PersistedQueue.d.ts.map +1 -1
  146. package/dist/unstable/persistence/PersistedQueue.js +16 -12
  147. package/dist/unstable/persistence/PersistedQueue.js.map +1 -1
  148. package/dist/unstable/persistence/Redis.d.ts.map +1 -1
  149. package/dist/unstable/persistence/Redis.js +5 -3
  150. package/dist/unstable/persistence/Redis.js.map +1 -1
  151. package/dist/unstable/reactivity/Atom.js +1 -1
  152. package/dist/unstable/reactivity/Atom.js.map +1 -1
  153. package/dist/unstable/reactivity/AtomHttpApi.d.ts +7 -7
  154. package/dist/unstable/reactivity/AtomHttpApi.d.ts.map +1 -1
  155. package/dist/unstable/reactivity/AtomHttpApi.js +3 -2
  156. package/dist/unstable/reactivity/AtomHttpApi.js.map +1 -1
  157. package/dist/unstable/rpc/RpcServer.d.ts +3 -1
  158. package/dist/unstable/rpc/RpcServer.d.ts.map +1 -1
  159. package/dist/unstable/rpc/RpcServer.js +6 -3
  160. package/dist/unstable/rpc/RpcServer.js.map +1 -1
  161. package/dist/unstable/sql/SqlClient.d.ts +1 -2
  162. package/dist/unstable/sql/SqlClient.d.ts.map +1 -1
  163. package/dist/unstable/sql/SqlClient.js.map +1 -1
  164. package/dist/unstable/workflow/DurableDeferred.js +1 -1
  165. package/dist/unstable/workflow/DurableDeferred.js.map +1 -1
  166. package/dist/unstable/workflow/WorkflowProxyServer.d.ts +1 -1
  167. package/dist/unstable/workflow/WorkflowProxyServer.d.ts.map +1 -1
  168. package/dist/unstable/workflow/WorkflowProxyServer.js +1 -2
  169. package/dist/unstable/workflow/WorkflowProxyServer.js.map +1 -1
  170. package/package.json +3 -3
  171. package/src/Array.ts +1 -1
  172. package/src/Graph.ts +2967 -457
  173. package/src/Iterable.ts +32 -2
  174. package/src/LayerRef.ts +4 -6
  175. package/src/Number.ts +29 -10
  176. package/src/Schema.ts +43 -35
  177. package/src/SchemaAST.ts +25 -13
  178. package/src/SchemaError.ts +64 -0
  179. package/src/SchemaGetter.ts +22 -16
  180. package/src/SchemaRepresentation.ts +165 -202
  181. package/src/index.ts +10 -0
  182. package/src/internal/effect.ts +48 -25
  183. package/src/internal/schema/equivalence.ts +1 -2
  184. package/src/internal/schema/representation.ts +4 -4
  185. package/src/internal/schema/schema.ts +4 -37
  186. package/src/unstable/ai/Tool.ts +13 -16
  187. package/src/unstable/cli/CliConfig.ts +85 -0
  188. package/src/unstable/cli/CliError.ts +27 -16
  189. package/src/unstable/cli/Command.ts +90 -14
  190. package/src/unstable/cli/GlobalFlag.ts +46 -29
  191. package/src/unstable/cli/Param.ts +15 -3
  192. package/src/unstable/cli/index.ts +5 -0
  193. package/src/unstable/cli/internal/ansi.ts +3 -0
  194. package/src/unstable/cli/internal/parser.ts +14 -2
  195. package/src/unstable/cli/internal/wizard.ts +283 -0
  196. package/src/unstable/cluster/EntityProxyServer.ts +15 -17
  197. package/src/unstable/cluster/RunnerStorage.ts +1 -1
  198. package/src/unstable/cluster/internal/entityManager.ts +48 -34
  199. package/src/unstable/http/Multipart.ts +3 -1
  200. package/src/unstable/httpapi/HttpApi.ts +72 -47
  201. package/src/unstable/httpapi/HttpApiBuilder.ts +320 -217
  202. package/src/unstable/httpapi/HttpApiClient.ts +196 -151
  203. package/src/unstable/httpapi/HttpApiEndpoint.ts +251 -447
  204. package/src/unstable/httpapi/HttpApiError.ts +33 -0
  205. package/src/unstable/httpapi/HttpApiGroup.ts +95 -74
  206. package/src/unstable/httpapi/HttpApiMiddleware.ts +10 -7
  207. package/src/unstable/httpapi/HttpApiScalar.ts +15 -12
  208. package/src/unstable/httpapi/HttpApiSchema.ts +8 -0
  209. package/src/unstable/httpapi/HttpApiSwagger.ts +2 -2
  210. package/src/unstable/httpapi/HttpApiTest.ts +15 -14
  211. package/src/unstable/httpapi/OpenApi.ts +74 -36
  212. package/src/unstable/httpapi/internal/html.ts +9 -2
  213. package/src/unstable/httpapi/internal/mediaType.ts +6 -0
  214. package/src/unstable/persistence/PersistedQueue.ts +16 -14
  215. package/src/unstable/persistence/Redis.ts +9 -4
  216. package/src/unstable/reactivity/Atom.ts +1 -1
  217. package/src/unstable/reactivity/AtomHttpApi.ts +164 -162
  218. package/src/unstable/rpc/RpcServer.ts +10 -4
  219. package/src/unstable/sql/SqlClient.ts +1 -2
  220. package/src/unstable/workflow/DurableDeferred.ts +1 -1
  221. package/src/unstable/workflow/WorkflowProxyServer.ts +11 -12
@@ -11,7 +11,9 @@
11
11
  import * as Arr from "../../Array.ts"
12
12
  import type { NonEmptyArray } from "../../Array.ts"
13
13
  import * as Context from "../../Context.ts"
14
+ import * as Equal from "../../Equal.ts"
14
15
  import { constFalse } from "../../Function.ts"
16
+ import * as internalRecord from "../../internal/record.ts"
15
17
  import * as JsonPatch from "../../JsonPatch.ts"
16
18
  import { escapeToken } from "../../JsonPointer.ts"
17
19
  import * as JsonSchema from "../../JsonSchema.ts"
@@ -208,7 +210,7 @@ export const annotations: (
208
210
  transform: Transform
209
211
  })
210
212
 
211
- const apiCache = new WeakMap<HttpApi.Any, OpenAPISpec>()
213
+ const apiCache = new WeakMap<HttpApi.Constraint, OpenAPISpec>()
212
214
 
213
215
  /**
214
216
  * This function checks if a given tag exists within the provided context. If
@@ -246,7 +248,7 @@ function processAnnotation<Services, S, I>(
246
248
  * @category constructors
247
249
  * @since 4.0.0
248
250
  */
249
- export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
251
+ export function fromApi<Id extends string, Groups extends HttpApiGroup.Constraint>(
250
252
  api: HttpApi.HttpApi<Id, Groups>
251
253
  ): OpenAPISpec {
252
254
  const cached = apiCache.get(api)
@@ -279,6 +281,8 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
279
281
  readonly path: ReadonlyArray<string>
280
282
  }
281
283
  > = []
284
+ const pathOperations = new Set<string>()
285
+ const operationIds = new Set<string>()
282
286
 
283
287
  processAnnotation(api.annotations, Title, (title) => {
284
288
  spec.info.title = title
@@ -331,7 +335,7 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
331
335
  operationId: Context.getOrElse(
332
336
  endpoint.annotations,
333
337
  Identifier,
334
- () => group.topLevel ? endpoint.name : `${group.identifier}.${endpoint.name}`
338
+ () => group.topLevel ? endpoint.identifier : `${group.identifier}.${endpoint.identifier}`
335
339
  ),
336
340
  parameters: [],
337
341
  security: [],
@@ -341,31 +345,6 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
341
345
  const path = endpoint.path.replace(/:(\w+)\??/g, "{$1}")
342
346
  const method = endpoint.method.toLowerCase() as OpenAPISpecMethodName
343
347
 
344
- function processRequestBodies(payloadMap: HttpApiEndpoint.PayloadMap) {
345
- if (payloadMap.size > 0) {
346
- const c: OpenApiSpecContent = {}
347
- let hasContent = false
348
- payloadMap.forEach(({ encoding, schemas }, contentType) => {
349
- const filtered = schemas.filter((s) => !HttpApiSchema.isNoContent(s.ast))
350
- if (filtered.length === 0) return
351
- hasContent = true
352
- const asts = filtered.map(SchemaAST.getAST)
353
- const ast = asts.length === 1 ? asts[0] : new SchemaAST.Union(asts, "anyOf")
354
- pathOps.push({
355
- _tag: "schema",
356
- ast: toEncodingAST(ast, encoding._tag),
357
- path: ["paths", path, method, "requestBody", "content", contentType, "schema"]
358
- })
359
- c[contentType] = {
360
- schema: {}
361
- }
362
- })
363
- if (hasContent) {
364
- op.requestBody = { content: c, required: true }
365
- }
366
- }
367
- }
368
-
369
348
  function processResponseBodies(bodies: ResponseBodies, defaultDescription: () => string) {
370
349
  for (const [status, { content, descriptions, streamContent }] of bodies) {
371
350
  const description = descriptions.size > 0 ? Array.from(descriptions).join(" | ") : defaultDescription()
@@ -502,15 +481,53 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
502
481
  name: string,
503
482
  security: HttpApiSecurity
504
483
  ) {
505
- if (spec.components.securitySchemes[name] !== undefined) {
484
+ const scheme = makeSecurityScheme(security)
485
+ if (!Object.hasOwn(spec.components.securitySchemes, name)) {
486
+ internalRecord.set(spec.components.securitySchemes, name, scheme)
506
487
  return
507
488
  }
508
- spec.components.securitySchemes[name] = makeSecurityScheme(security)
489
+ if (
490
+ !Equal.equals(
491
+ securitySchemeForComparison(spec.components.securitySchemes[name]),
492
+ securitySchemeForComparison(scheme)
493
+ )
494
+ ) {
495
+ throw new globalThis.Error(`Conflicting OpenAPI security scheme: ${name}`)
496
+ }
509
497
  }
510
498
 
511
499
  const hasBody = HttpMethod.hasBody(endpoint.method)
512
500
  if (hasBody) {
513
- processRequestBodies(endpoint.payload)
501
+ const schemasByContentType = new Map<string, {
502
+ readonly encoding: HttpApiSchema.PayloadEncoding
503
+ readonly schemas: Array<Schema.Top>
504
+ }>()
505
+ for (const schema of HttpApiEndpoint.getPayloadSchemas(endpoint)) {
506
+ if (HttpApiSchema.isNoContent(schema.ast)) continue
507
+ const encoding = HttpApiSchema.getPayloadEncoding(schema.ast, endpoint.method)
508
+ const existing = schemasByContentType.get(encoding.contentType)
509
+ if (existing === undefined) {
510
+ schemasByContentType.set(encoding.contentType, { encoding, schemas: [schema] })
511
+ } else {
512
+ existing.schemas.push(schema)
513
+ }
514
+ }
515
+ if (schemasByContentType.size > 0) {
516
+ const content: OpenApiSpecContent = {}
517
+ for (const [contentType, { encoding, schemas }] of schemasByContentType) {
518
+ const asts = schemas.map(SchemaAST.getAST)
519
+ const ast = asts.length === 1 ? asts[0] : new SchemaAST.Union(asts, "anyOf")
520
+ pathOps.push({
521
+ _tag: "schema",
522
+ ast: toEncodingAST(ast, encoding._tag),
523
+ path: ["paths", path, method, "requestBody", "content", contentType, "schema"]
524
+ })
525
+ content[contentType] = {
526
+ schema: {}
527
+ }
528
+ }
529
+ op.requestBody = { content, required: true }
530
+ }
514
531
  }
515
532
 
516
533
  processParameters(endpoint.params, "path")
@@ -534,10 +551,6 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
534
551
  () => "Error"
535
552
  )
536
553
 
537
- if (!spec.paths[path]) {
538
- spec.paths[path] = {}
539
- }
540
-
541
554
  processAnnotation(endpoint.annotations, Override, (override) => {
542
555
  Object.assign(op, override)
543
556
  })
@@ -545,6 +558,21 @@ export function fromApi<Id extends string, Groups extends HttpApiGroup.Any>(
545
558
  op = transformFn(op) as OpenAPISpecOperation
546
559
  })
547
560
 
561
+ const pathOperation = `${method} ${path.replace(/\{[^}]+\}/g, "{}")}`
562
+ if (pathOperations.has(pathOperation)) {
563
+ throw new globalThis.Error(`Duplicate OpenAPI operation for ${endpoint.method} ${path}`)
564
+ }
565
+ const operationId = op.operationId
566
+ if (operationId !== undefined) {
567
+ if (operationIds.has(operationId)) {
568
+ throw new globalThis.Error(`Duplicate OpenAPI operationId: ${operationId}`)
569
+ }
570
+ operationIds.add(operationId)
571
+ }
572
+ pathOperations.add(pathOperation)
573
+ if (!spec.paths[path]) {
574
+ spec.paths[path] = {}
575
+ }
548
576
  spec.paths[path][method] = op
549
577
  }
550
578
  })
@@ -627,7 +655,7 @@ type ResponseBodies = Map<
627
655
 
628
656
  const reservedStreamFailureEvent = "effect/httpapi/stream/failure"
629
657
 
630
- function extractSuccessResponseBodies(endpoint: HttpApiEndpoint.AnyWithProps): ResponseBodies {
658
+ function extractSuccessResponseBodies(endpoint: HttpApiEndpoint.Top): ResponseBodies {
631
659
  return extractResponseBodies(
632
660
  HttpApiEndpoint.getSuccessSchemas(endpoint),
633
661
  HttpApiSchema.getStatusSuccess,
@@ -814,6 +842,16 @@ const makeSecurityScheme = (security: HttpApiSecurity): OpenAPISecurityScheme =>
814
842
  }
815
843
  }
816
844
 
845
+ const securitySchemeForComparison = (scheme: OpenAPISecurityScheme): OpenAPISecurityScheme => {
846
+ if (scheme.type === "http") {
847
+ return { ...scheme, scheme: scheme.scheme.toLowerCase() }
848
+ }
849
+ if (scheme.in === "header") {
850
+ return { ...scheme, name: scheme.name.toLowerCase() }
851
+ }
852
+ return scheme
853
+ }
854
+
817
855
  /**
818
856
  * This model describes the OpenAPI specification (version 3.1.0) returned by
819
857
  * {@link fromApi}. It is not intended to describe the entire OpenAPI
@@ -1,11 +1,11 @@
1
- const ESCAPE_SCRIPT_END = /<\/script>/gi
1
+ const ESCAPE_SCRIPT_DATA = /</g
2
2
 
3
3
  const ESCAPE_LINE_TERMS = /[\u2028\u2029]/g
4
4
 
5
5
  /** @internal */
6
6
  export function escapeJson(spec: unknown): string {
7
7
  return JSON.stringify(spec)
8
- .replace(ESCAPE_SCRIPT_END, "<\\/script>")
8
+ .replace(ESCAPE_SCRIPT_DATA, "\\u003c")
9
9
  .replace(ESCAPE_LINE_TERMS, (c) => c === "\u2028" ? "\\u2028" : "\\u2029")
10
10
  }
11
11
 
@@ -16,3 +16,10 @@ export function escape(str: string): string {
16
16
  .replace(/</g, "&lt;")
17
17
  .replace(/>/g, "&gt;")
18
18
  }
19
+
20
+ /** @internal */
21
+ export function escapeAttribute(str: string): string {
22
+ return escape(str)
23
+ .replace(/"/g, "&quot;")
24
+ .replace(/'/g, "&#39;")
25
+ }
@@ -0,0 +1,6 @@
1
+ /** @internal */
2
+ export function normalize(contentType: string): string {
3
+ const normalized = contentType.toLowerCase().trim()
4
+ const index = normalized.indexOf(";")
5
+ return index === -1 ? normalized : normalized.slice(0, index).trim()
6
+ }
@@ -170,19 +170,13 @@ export const makeFactory = Effect.gen(function*() {
170
170
  }
171
171
  ),
172
172
  take: (f, opts) =>
173
- Effect.uninterruptibleMask(Effect.fnUntraced(function*(restore) {
174
- const scope = yield* Scope.make()
173
+ Effect.scopedWith(Effect.fnUntraced(function*(scope) {
175
174
  const item = yield* store.take({
176
175
  name: options.name,
177
176
  maxAttempts: opts?.maxAttempts ?? 10
178
- }).pipe(
179
- Scope.provide(scope),
180
- restore
181
- )
177
+ }).pipe(Scope.provide(scope))
182
178
  const decoded = yield* decodeUnknown(item.element)
183
- const exit = yield* Effect.exit(restore(f(decoded, { id: item.id, attempts: item.attempts })))
184
- yield* Scope.close(scope, exit)
185
- return yield* exit
179
+ return yield* f(decoded, { id: item.id, attempts: item.attempts })
186
180
  }))
187
181
  })
188
182
  }
@@ -613,7 +607,9 @@ local key_pending = KEYS[2]
613
607
  local prefix = ARGV[1]
614
608
 
615
609
  local entries = redis.call("HGETALL", key_pending)
616
- for id, payload in pairs(entries) do
610
+ for i = 1, #entries, 2 do
611
+ local id = entries[i]
612
+ local payload = entries[i + 1]
617
613
  local lock_key = prefix .. id .. ":lock"
618
614
  local exists = redis.call("EXISTS", lock_key)
619
615
  if exists == 0 then
@@ -673,7 +669,7 @@ redis.call("DEL", key_lock)
673
669
  redis.call("HDEL", key_pending, id)
674
670
  redis.call("RPUSH", key_failed, payload)
675
671
  `,
676
- numberOfKeys: 2
672
+ numberOfKeys: 3
677
673
  }
678
674
  )
679
675
 
@@ -936,10 +932,12 @@ export const makeStoreSql: (
936
932
  const elementIds = new Set<number>()
937
933
  const refreshLocks: Effect.Effect<void, SqlError> = Effect.suspend((): Effect.Effect<void, SqlError> => {
938
934
  if (elementIds.size === 0) return Effect.void
935
+ const ids = Array.from(elementIds)
939
936
  return sql`
940
937
  UPDATE ${tableNameSql}
941
938
  SET acquired_at = ${sqlNow}
942
- WHERE acquired_by = ${workerIdSql}
939
+ WHERE sequence IN (${sql.literal(ids.join(","))})
940
+ AND acquired_by = ${workerIdSql}
943
941
  `
944
942
  })
945
943
  const complete = (sequence: number, attempts: number) => {
@@ -1110,7 +1108,7 @@ export const makeStoreSql: (
1110
1108
  takenLatch.closeUnsafe()
1111
1109
  for (let i = 0; i < results.length; i++) {
1112
1110
  const element = results[i]
1113
- element.element = JSON.parse(element.element)
1111
+ elementIds.add(element.sequence)
1114
1112
  }
1115
1113
  yield* Queue.offerAll(queue, results)
1116
1114
  yield* takenLatch.await
@@ -1165,7 +1163,11 @@ export const makeStoreSql: (
1165
1163
  : retry(element.sequence, element.attempts + 1, cause),
1166
1164
  onSuccess: () => complete(element.sequence, element.attempts + 1)
1167
1165
  }))
1168
- )
1166
+ ),
1167
+ Effect.map((element) => ({
1168
+ ...element,
1169
+ element: JSON.parse(element.element)
1170
+ }))
1169
1171
  )
1170
1172
  )
1171
1173
  })
@@ -11,8 +11,10 @@
11
11
  */
12
12
  import * as Cache from "../../Cache.ts"
13
13
  import * as Context from "../../Context.ts"
14
+ import * as Duration from "../../Duration.ts"
14
15
  import * as Effect from "../../Effect.ts"
15
16
  import * as Equal from "../../Equal.ts"
17
+ import * as Exit from "../../Exit.ts"
16
18
  import { constant, identity } from "../../Function.ts"
17
19
  import * as Hash from "../../Hash.ts"
18
20
  import * as Schema from "../../Schema.ts"
@@ -50,10 +52,13 @@ export const make = Effect.fnUntraced(function*(
50
52
  readonly send: <A = unknown>(command: string, ...args: ReadonlyArray<string>) => Effect.Effect<A, RedisError>
51
53
  }
52
54
  ) {
53
- const scriptCache = yield* Cache.make({
54
- lookup: (script: Script<any>) => options.send<string>("SCRIPT", "LOAD", script.lua),
55
- capacity: Number.POSITIVE_INFINITY
56
- })
55
+ const scriptCache = yield* Cache.makeWith(
56
+ (script: Script<any>) => options.send<string>("SCRIPT", "LOAD", script.lua),
57
+ {
58
+ capacity: Number.POSITIVE_INFINITY,
59
+ timeToLive: (exit) => Exit.isSuccess(exit) ? Duration.infinity : Duration.zero
60
+ }
61
+ )
57
62
 
58
63
  const eval_ = <
59
64
  Config extends {
@@ -2650,7 +2650,7 @@ export const kvs = <S extends Schema.ConstraintCodec<any, any>, const Mode exten
2650
2650
  },
2651
2651
  (ctx, value: S["Type"]) => {
2652
2652
  ctx.set(setAtom, value as any)
2653
- ctx.setSelf(value)
2653
+ ctx.setSelf(options.mode === "async" ? AsyncResult.success(value) : value)
2654
2654
  }
2655
2655
  ) as any
2656
2656
  }