@effect/platform 0.77.4 → 0.77.7

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/src/OpenApi.ts CHANGED
@@ -175,6 +175,12 @@ function processAnnotation<Services, S, I>(
175
175
  }
176
176
  }
177
177
 
178
+ /**
179
+ * @since 1.0.0
180
+ * @category models
181
+ */
182
+ export type AdditionalPropertiesStrategy = "allow" | "strict"
183
+
178
184
  /**
179
185
  * Converts an `HttpApi` instance into an OpenAPI Specification object.
180
186
  *
@@ -192,6 +198,12 @@ function processAnnotation<Services, S, I>(
192
198
  * and overrides. Cached results are used for better performance when the same
193
199
  * `HttpApi` instance is processed multiple times.
194
200
  *
201
+ * **Options**
202
+ *
203
+ * - `additionalPropertiesStrategy`: Controls the handling of additional properties. Possible values are:
204
+ * - `"strict"`: Disallow additional properties (default behavior).
205
+ * - `"allow"`: Allow additional properties.
206
+ *
195
207
  * @example
196
208
  * ```ts
197
209
  * import { HttpApi, HttpApiEndpoint, HttpApiGroup, OpenApi } from "@effect/platform"
@@ -214,7 +226,10 @@ function processAnnotation<Services, S, I>(
214
226
  * @since 1.0.0
215
227
  */
216
228
  export const fromApi = <Id extends string, Groups extends HttpApiGroup.Any, E, R>(
217
- api: HttpApi.HttpApi<Id, Groups, E, R>
229
+ api: HttpApi.HttpApi<Id, Groups, E, R>,
230
+ options?: {
231
+ readonly additionalPropertiesStrategy?: AdditionalPropertiesStrategy | undefined
232
+ } | undefined
218
233
  ): OpenAPISpec => {
219
234
  const cached = apiCache.get(api)
220
235
  if (cached !== undefined) {
@@ -238,7 +253,8 @@ export const fromApi = <Id extends string, Groups extends HttpApiGroup.Any, E, R
238
253
 
239
254
  function processAST(ast: AST.AST): JsonSchema.JsonSchema {
240
255
  return JsonSchema.fromAST(ast, {
241
- defs: jsonSchemaDefs
256
+ defs: jsonSchemaDefs,
257
+ additionalPropertiesStrategy: options?.additionalPropertiesStrategy
242
258
  })
243
259
  }
244
260
 
@@ -255,35 +255,47 @@ export const make = <A, I, R>(schema: Schema.Schema<A, I, R>): Root => {
255
255
  return out
256
256
  }
257
257
 
258
+ type TopLevelReferenceStrategy = "skip" | "keep"
259
+
260
+ type AdditionalPropertiesStrategy = "allow" | "strict"
261
+
258
262
  /**
259
263
  * Creates a schema with additional options and definitions.
260
264
  *
265
+ * **Options**
266
+ *
261
267
  * - `defs`: A record of definitions that are included in the schema.
262
268
  * - `defsPath`: The path to the definitions within the schema (defaults to "#/$defs/").
263
269
  * - `topLevelReferenceStrategy`: Controls the handling of the top-level reference. Possible values are:
264
270
  * - `"keep"`: Keep the top-level reference (default behavior).
265
271
  * - `"skip"`: Skip the top-level reference.
272
+ * - `additionalPropertiesStrategy`: Controls the handling of additional properties. Possible values are:
273
+ * - `"strict"`: Disallow additional properties (default behavior).
274
+ * - `"allow"`: Allow additional properties.
266
275
  *
267
276
  * @category encoding
268
277
  * @since 1.0.0
269
278
  */
270
279
  export const makeWithDefs = <A, I, R>(schema: Schema.Schema<A, I, R>, options: {
271
280
  readonly defs: Record<string, any>
272
- readonly defsPath?: string
273
- readonly topLevelReferenceStrategy?: "skip" | "keep"
281
+ readonly defsPath?: string | undefined
282
+ readonly topLevelReferenceStrategy?: TopLevelReferenceStrategy | undefined
283
+ readonly additionalPropertiesStrategy?: AdditionalPropertiesStrategy | undefined
274
284
  }): JsonSchema => fromAST(schema.ast, options)
275
285
 
276
286
  /** @internal */
277
287
  export const fromAST = (ast: AST.AST, options: {
278
288
  readonly defs: Record<string, any>
279
- readonly defsPath?: string
280
- readonly topLevelReferenceStrategy?: "skip" | "keep"
289
+ readonly defsPath?: string | undefined
290
+ readonly topLevelReferenceStrategy?: TopLevelReferenceStrategy | undefined
291
+ readonly additionalPropertiesStrategy?: AdditionalPropertiesStrategy | undefined
281
292
  }): JsonSchema => {
282
293
  const jsonSchema = JSONSchema.fromAST(ast, {
283
294
  definitions: options.defs,
284
295
  definitionPath: options.defsPath ?? "#/components/schemas/",
285
296
  target: "openApi3.1",
286
- topLevelReferenceStrategy: options.topLevelReferenceStrategy ?? "keep"
297
+ topLevelReferenceStrategy: options.topLevelReferenceStrategy,
298
+ additionalPropertiesStrategy: options.additionalPropertiesStrategy
287
299
  })
288
300
  return jsonSchema as JsonSchema
289
301
  }
@@ -1,6 +1,7 @@
1
1
  import * as Effect from "effect/Effect"
2
2
  import * as FiberRef from "effect/FiberRef"
3
3
  import * as Stream from "effect/Stream"
4
+ import * as Headers from "../Headers.js"
4
5
  import type * as Client from "../HttpClient.js"
5
6
  import * as Error from "../HttpClientError.js"
6
7
  import * as client from "./httpClient.js"
@@ -15,7 +16,7 @@ const fetch: Client.HttpClient = client.make((request, url, signal, fiber) => {
15
16
  const context = fiber.getFiberRef(FiberRef.currentContext)
16
17
  const fetch: typeof globalThis.fetch = context.unsafeMap.get(fetchTagKey) ?? globalThis.fetch
17
18
  const options: RequestInit = context.unsafeMap.get(requestInitTagKey) ?? {}
18
- const headers = new globalThis.Headers(request.headers)
19
+ const headers = options.headers ? Headers.merge(Headers.fromInput(options.headers), request.headers) : request.headers
19
20
  const send = (body: BodyInit | undefined) =>
20
21
  Effect.map(
21
22
  Effect.tryPromise({
@@ -12,7 +12,7 @@ import * as Predicate from "effect/Predicate"
12
12
  import * as Ref from "effect/Ref"
13
13
  import * as Schedule from "effect/Schedule"
14
14
  import * as Scope from "effect/Scope"
15
- import type { NoInfer } from "effect/Types"
15
+ import type { NoExcessProperties, NoInfer } from "effect/Types"
16
16
  import * as Cookies from "../Cookies.js"
17
17
  import * as Headers from "../Headers.js"
18
18
  import type * as Client from "../HttpClient.js"
@@ -541,13 +541,13 @@ export const mapRequestInputEffect = dual<
541
541
 
542
542
  /** @internal */
543
543
  export const retry: {
544
- <E, O extends Effect.Retry.Options<E>>(
544
+ <E, O extends NoExcessProperties<Effect.Retry.Options<E>, O>>(
545
545
  options: O
546
546
  ): <R>(self: Client.HttpClient.With<E, R>) => Client.Retry.Return<R, E, O>
547
547
  <B, E, R1>(
548
548
  policy: Schedule.Schedule<B, NoInfer<E>, R1>
549
549
  ): <R>(self: Client.HttpClient.With<E, R>) => Client.HttpClient.With<E, R1 | R>
550
- <E, R, O extends Effect.Retry.Options<E>>(
550
+ <E, R, O extends NoExcessProperties<Effect.Retry.Options<E>, O>>(
551
551
  self: Client.HttpClient.With<E, R>,
552
552
  options: O
553
553
  ): Client.Retry.Return<R, E, O>