@effect/openapi-generator 4.0.0-beta.9 → 4.0.0-beta.90

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 (41) hide show
  1. package/dist/HttpApiTransformer.d.ts +41 -0
  2. package/dist/HttpApiTransformer.d.ts.map +1 -0
  3. package/dist/HttpApiTransformer.js +393 -0
  4. package/dist/HttpApiTransformer.js.map +1 -0
  5. package/dist/JsonSchemaGenerator.d.ts +25 -3
  6. package/dist/JsonSchemaGenerator.d.ts.map +1 -1
  7. package/dist/JsonSchemaGenerator.js +178 -47
  8. package/dist/JsonSchemaGenerator.js.map +1 -1
  9. package/dist/OpenApiGenerator.d.ts +81 -7
  10. package/dist/OpenApiGenerator.d.ts.map +1 -1
  11. package/dist/OpenApiGenerator.js +763 -119
  12. package/dist/OpenApiGenerator.js.map +1 -1
  13. package/dist/OpenApiPatch.d.ts +47 -24
  14. package/dist/OpenApiPatch.d.ts.map +1 -1
  15. package/dist/OpenApiPatch.js +42 -19
  16. package/dist/OpenApiPatch.js.map +1 -1
  17. package/dist/OpenApiTransformer.d.ts +85 -12
  18. package/dist/OpenApiTransformer.d.ts.map +1 -1
  19. package/dist/OpenApiTransformer.js +88 -11
  20. package/dist/OpenApiTransformer.js.map +1 -1
  21. package/dist/ParsedOperation.d.ts +184 -1
  22. package/dist/ParsedOperation.d.ts.map +1 -1
  23. package/dist/ParsedOperation.js +32 -0
  24. package/dist/ParsedOperation.js.map +1 -1
  25. package/dist/Utils.d.ts +51 -0
  26. package/dist/Utils.d.ts.map +1 -1
  27. package/dist/Utils.js +61 -0
  28. package/dist/Utils.js.map +1 -1
  29. package/dist/main.d.ts +12 -0
  30. package/dist/main.d.ts.map +1 -1
  31. package/dist/main.js +41 -8
  32. package/dist/main.js.map +1 -1
  33. package/package.json +10 -8
  34. package/src/HttpApiTransformer.ts +552 -0
  35. package/src/JsonSchemaGenerator.ts +272 -47
  36. package/src/OpenApiGenerator.ts +1057 -165
  37. package/src/OpenApiPatch.ts +56 -31
  38. package/src/OpenApiTransformer.ts +92 -15
  39. package/src/ParsedOperation.ts +235 -1
  40. package/src/Utils.ts +61 -0
  41. package/src/main.ts +58 -10
@@ -7,7 +7,7 @@
7
7
  * - YAML files (.yaml, .yml)
8
8
  * - Inline JSON strings
9
9
  *
10
- * @module OpenApiPatch
10
+ * @since 4.0.0
11
11
  */
12
12
 
13
13
  import * as Effect from "effect/Effect"
@@ -26,12 +26,15 @@ import * as Yaml from "yaml"
26
26
  /**
27
27
  * Error thrown when parsing a JSON Patch input fails.
28
28
  *
29
+ * **Details**
30
+ *
29
31
  * This error occurs when:
30
32
  * - A patch file cannot be read
31
33
  * - JSON or YAML syntax is invalid
32
34
  * - The file format is unsupported
33
35
  *
34
- * @example
36
+ * **Example** (Creating a parse error)
37
+ *
35
38
  * ```ts
36
39
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
37
40
  *
@@ -44,10 +47,10 @@ import * as Yaml from "yaml"
44
47
  * // "Failed to parse patch from ./patches/fix.json: Unexpected token at position 42"
45
48
  * ```
46
49
  *
47
- * @since 1.0.0
48
50
  * @category errors
51
+ * @since 4.0.0
49
52
  */
50
- export class JsonPatchParseError extends Schema.ErrorClass("JsonPatchParseError")({
53
+ export class JsonPatchParseError extends Schema.ErrorClass<JsonPatchParseError>("JsonPatchParseError")({
51
54
  _tag: Schema.tag("JsonPatchParseError"),
52
55
  source: Schema.String,
53
56
  reason: Schema.String
@@ -60,13 +63,16 @@ export class JsonPatchParseError extends Schema.ErrorClass("JsonPatchParseError"
60
63
  /**
61
64
  * Error thrown when a parsed value does not conform to the JSON Patch schema.
62
65
  *
66
+ * **Details**
67
+ *
63
68
  * This error occurs when:
64
69
  * - The patch is not an array
65
70
  * - An operation is missing required fields (op, path)
66
71
  * - An operation has an unsupported op value
67
72
  * - An add/replace operation is missing the value field
68
73
  *
69
- * @example
74
+ * **Example** (Creating a validation error)
75
+ *
70
76
  * ```ts
71
77
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
72
78
  *
@@ -79,10 +85,10 @@ export class JsonPatchParseError extends Schema.ErrorClass("JsonPatchParseError"
79
85
  * // "Invalid JSON Patch from inline: Expected 'add' | 'remove' | 'replace' at [0].op, got 'copy'"
80
86
  * ```
81
87
  *
82
- * @since 1.0.0
83
88
  * @category errors
89
+ * @since 4.0.0
84
90
  */
85
- export class JsonPatchValidationError extends Schema.ErrorClass("JsonPatchValidationError")({
91
+ export class JsonPatchValidationError extends Schema.ErrorClass<JsonPatchValidationError>("JsonPatchValidationError")({
86
92
  _tag: Schema.tag("JsonPatchValidationError"),
87
93
  source: Schema.String,
88
94
  reason: Schema.String
@@ -95,12 +101,15 @@ export class JsonPatchValidationError extends Schema.ErrorClass("JsonPatchValida
95
101
  /**
96
102
  * Error thrown when applying a JSON Patch operation fails.
97
103
  *
104
+ * **Details**
105
+ *
98
106
  * This error occurs when:
99
107
  * - A path does not exist for remove/replace operations
100
108
  * - An array index is out of bounds
101
109
  * - The target location is not a valid container
102
110
  *
103
- * @example
111
+ * **Example** (Creating an application error)
112
+ *
104
113
  * ```ts
105
114
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
106
115
  *
@@ -116,17 +125,19 @@ export class JsonPatchValidationError extends Schema.ErrorClass("JsonPatchValida
116
125
  * // "Failed to apply patch from ./patches/fix.json: operation 2 (remove at /paths/~1users): Property \"users\" does not exist"
117
126
  * ```
118
127
  *
119
- * @since 1.0.0
120
128
  * @category errors
129
+ * @since 4.0.0
121
130
  */
122
- export class JsonPatchApplicationError extends Schema.ErrorClass("JsonPatchApplicationError")({
123
- _tag: Schema.tag("JsonPatchApplicationError"),
124
- source: Schema.String,
125
- operationIndex: Schema.Number,
126
- operation: Schema.String,
127
- path: Schema.String,
128
- reason: Schema.String
129
- }) {
131
+ export class JsonPatchApplicationError
132
+ extends Schema.ErrorClass<JsonPatchApplicationError>("JsonPatchApplicationError")({
133
+ _tag: Schema.tag("JsonPatchApplicationError"),
134
+ source: Schema.String,
135
+ operationIndex: Schema.Number,
136
+ operation: Schema.String,
137
+ path: Schema.String,
138
+ reason: Schema.String
139
+ })
140
+ {
130
141
  override get message() {
131
142
  return `Failed to apply patch from ${this.source}: operation ${this.operationIndex} ` +
132
143
  `(${this.operation} at ${this.path}): ${this.reason}`
@@ -136,10 +147,13 @@ export class JsonPatchApplicationError extends Schema.ErrorClass("JsonPatchAppli
136
147
  /**
137
148
  * Error thrown when multiple JSON Patch operations fail.
138
149
  *
150
+ * **Details**
151
+ *
139
152
  * This error aggregates all application errors so users can see every
140
153
  * failing operation at once instead of fixing them one at a time.
141
154
  *
142
- * @example
155
+ * **Example** (Creating an aggregate error)
156
+ *
143
157
  * ```ts
144
158
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
145
159
  *
@@ -166,10 +180,10 @@ export class JsonPatchApplicationError extends Schema.ErrorClass("JsonPatchAppli
166
180
  * // "2 patch operations failed:\n 1. ..."
167
181
  * ```
168
182
  *
169
- * @since 1.0.0
170
183
  * @category errors
184
+ * @since 4.0.0
171
185
  */
172
- export class JsonPatchAggregateError extends Schema.ErrorClass("JsonPatchAggregateError")({
186
+ export class JsonPatchAggregateError extends Schema.ErrorClass<JsonPatchAggregateError>("JsonPatchAggregateError")({
173
187
  _tag: Schema.tag("JsonPatchAggregateError"),
174
188
  errors: Schema.Array(Schema.Unknown)
175
189
  }) {
@@ -191,8 +205,8 @@ export class JsonPatchAggregateError extends Schema.ErrorClass("JsonPatchAggrega
191
205
  /**
192
206
  * Schema for a JSON Patch "add" operation.
193
207
  *
194
- * @since 1.0.0
195
208
  * @category schemas
209
+ * @since 4.0.0
196
210
  */
197
211
  export const JsonPatchAdd: Schema.Codec<
198
212
  Extract<
@@ -209,8 +223,8 @@ export const JsonPatchAdd: Schema.Codec<
209
223
  /**
210
224
  * Schema for a JSON Patch "remove" operation.
211
225
  *
212
- * @since 1.0.0
213
226
  * @category schemas
227
+ * @since 4.0.0
214
228
  */
215
229
  export const JsonPatchRemove: Schema.Codec<
216
230
  Extract<
@@ -226,8 +240,8 @@ export const JsonPatchRemove: Schema.Codec<
226
240
  /**
227
241
  * Schema for a JSON Patch "replace" operation.
228
242
  *
229
- * @since 1.0.0
230
243
  * @category schemas
244
+ * @since 4.0.0
231
245
  */
232
246
  export const JsonPatchReplace: Schema.Codec<
233
247
  Extract<
@@ -244,11 +258,13 @@ export const JsonPatchReplace: Schema.Codec<
244
258
  /**
245
259
  * Schema for a single JSON Patch operation.
246
260
  *
261
+ * **Details**
262
+ *
247
263
  * Supports the subset of RFC 6902 operations that Effect's JsonPatch module
248
264
  * implements: `add`, `remove`, and `replace`.
249
265
  *
250
- * @since 1.0.0
251
266
  * @category schemas
267
+ * @since 4.0.0
252
268
  */
253
269
  export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Schema.Union([
254
270
  JsonPatchAdd,
@@ -259,11 +275,14 @@ export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Sc
259
275
  /**
260
276
  * Schema for a JSON Patch document (array of operations).
261
277
  *
278
+ * **Details**
279
+ *
262
280
  * A JSON Patch document is an ordered list of operations to apply to a JSON
263
281
  * document. Operations are applied in sequence, with each operation seeing
264
282
  * the result of previous operations.
265
283
  *
266
- * @example
284
+ * **Example** (Decoding a patch document)
285
+ *
267
286
  * ```ts
268
287
  * import { Schema } from "effect"
269
288
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
@@ -275,16 +294,16 @@ export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Sc
275
294
  * ])
276
295
  * ```
277
296
  *
278
- * @since 1.0.0
279
297
  * @category schemas
298
+ * @since 4.0.0
280
299
  */
281
300
  export const JsonPatchDocument = Schema.Array(JsonPatchOperation)
282
301
 
283
302
  /**
284
303
  * Type for a JSON Patch document.
285
304
  *
286
- * @since 1.0.0
287
305
  * @category types
306
+ * @since 4.0.0
288
307
  */
289
308
  export type JsonPatchDocument = typeof JsonPatchDocument.Type
290
309
 
@@ -407,11 +426,14 @@ const parseInlinePatch = Effect.fn("parseInlinePatch")(function*(input: string)
407
426
  /**
408
427
  * Parse a JSON Patch from either a file path or inline JSON string.
409
428
  *
429
+ * **Details**
430
+ *
410
431
  * The input is first checked as a file path. If the file exists, it is read
411
432
  * and parsed based on its extension (.json, .yaml, .yml). Otherwise, the
412
433
  * input is parsed as inline JSON.
413
434
  *
414
- * @example
435
+ * **Example** (Parsing patch input)
436
+ *
415
437
  * ```ts
416
438
  * import { Effect } from "effect"
417
439
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
@@ -431,8 +453,8 @@ const parseInlinePatch = Effect.fn("parseInlinePatch")(function*(input: string)
431
453
  * })
432
454
  * ```
433
455
  *
434
- * @since 1.0.0
435
456
  * @category parsing
457
+ * @since 4.0.0
436
458
  */
437
459
  export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: string) {
438
460
  if (looksLikeFilePath(input)) {
@@ -451,11 +473,14 @@ export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: str
451
473
  /**
452
474
  * Apply a sequence of JSON patches to a document.
453
475
  *
476
+ * **Details**
477
+ *
454
478
  * Patches are applied in order, with each patch operating on the result of
455
479
  * the previous one. All operations are attempted, and if any fail, the errors
456
480
  * are accumulated and reported together so users can fix all issues at once.
457
481
  *
458
- * @example
482
+ * **Example** (Applying patches)
483
+ *
459
484
  * ```ts
460
485
  * import { Effect } from "effect"
461
486
  * import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
@@ -475,8 +500,8 @@ export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: str
475
500
  * })
476
501
  * ```
477
502
  *
478
- * @since 1.0.0
479
503
  * @category application
504
+ * @since 4.0.0
480
505
  */
481
506
  export const applyPatches = Effect.fn("applyPatches")(function*(
482
507
  patches: ReadonlyArray<{ readonly source: string; readonly patch: JsonPatchDocument }>,
@@ -1,15 +1,40 @@
1
+ /**
2
+ * OpenAPI-to-HttpClient code generation for the OpenAPI generator.
3
+ *
4
+ * This module defines the `OpenApiTransformer` service used to render parsed
5
+ * OpenAPI operations into Effect `HttpClient` modules. It provides both
6
+ * schema-backed and type-only transformer implementations, including generated
7
+ * imports, public client interfaces, operation implementations, typed API
8
+ * errors, optional response handling, and helpers for server-sent events and
9
+ * binary response streams.
10
+ *
11
+ * @since 4.0.0
12
+ */
13
+ import * as Context from "effect/Context"
1
14
  import * as Layer from "effect/Layer"
2
15
  import * as Predicate from "effect/Predicate"
3
- import * as ServiceMap from "effect/ServiceMap"
4
- import type { ParsedOperation } from "./ParsedOperation.ts"
16
+ import type { ParsedOpenApi, ParsedOperation } from "./ParsedOperation.ts"
5
17
  import * as Utils from "./Utils.ts"
6
18
 
7
- export class OpenApiTransformer extends ServiceMap.Service<
19
+ /**
20
+ * Service used by the OpenAPI generator to render parsed operations as an
21
+ * Effect HttpClient module.
22
+ *
23
+ * **Details**
24
+ *
25
+ * A transformer owns the code-generation dialect for imports, public client
26
+ * types, and the implementation body. The generator swaps implementations to
27
+ * choose between schema-backed clients and type-only clients.
28
+ *
29
+ * @category code generation
30
+ * @since 4.0.0
31
+ */
32
+ export class OpenApiTransformer extends Context.Service<
8
33
  OpenApiTransformer,
9
34
  {
10
- readonly imports: (importName: string, operations: ReadonlyArray<ParsedOperation>) => string
11
- readonly toTypes: (importName: string, name: string, operations: ReadonlyArray<ParsedOperation>) => string
12
- readonly toImplementation: (importName: string, name: string, operations: ReadonlyArray<ParsedOperation>) => string
35
+ readonly imports: (importName: string, parsed: ParsedOpenApi) => string
36
+ readonly toTypes: (importName: string, name: string, parsed: ParsedOpenApi) => string
37
+ readonly toImplementation: (importName: string, name: string, parsed: ParsedOpenApi) => string
13
38
  }
14
39
  >()("OpenApiTransformer") {}
15
40
 
@@ -35,6 +60,18 @@ const computeImportRequirements = (operations: ReadonlyArray<ParsedOperation>):
35
60
  const requiresStreaming = (requirements: ImportRequirements): boolean =>
36
61
  requirements.eventStream || requirements.octetStream
37
62
 
63
+ /**
64
+ * Create the transformer used for schema-backed HttpClient output.
65
+ *
66
+ * **Details**
67
+ *
68
+ * Generated clients import Effect Schema values and use them at runtime to
69
+ * decode successful responses and typed API errors. Request parameters and
70
+ * payloads are typed against each schema's encoded representation.
71
+ *
72
+ * @category code generation
73
+ * @since 4.0.0
74
+ */
38
75
  export const makeTransformerSchema = () => {
39
76
  const operationsToInterface = (
40
77
  _importName: string,
@@ -226,11 +263,11 @@ export const make = (
226
263
  ): ${name} => {
227
264
  ${helpers.join("\n ")}
228
265
  const decodeSuccess =
229
- <Schema extends ${importName}.Top>(schema: Schema) =>
266
+ <Schema extends ${importName}.Constraint>(schema: Schema) =>
230
267
  (response: HttpClientResponse.HttpClientResponse) =>
231
268
  HttpClientResponse.schemaBodyJson(schema)(response)
232
269
  const decodeError =
233
- <const Tag extends string, Schema extends ${importName}.Top>(tag: Tag, schema: Schema) =>
270
+ <const Tag extends string, Schema extends ${importName}.Constraint>(tag: Tag, schema: Schema) =>
234
271
  (response: HttpClientResponse.HttpClientResponse) =>
235
272
  Effect.flatMap(
236
273
  HttpClientResponse.schemaBodyJson(schema)(response),
@@ -269,6 +306,8 @@ export const make = (
269
306
  const payloadVarName = "options.payload"
270
307
  if (operation.payloadFormData) {
271
308
  pipeline.push(`HttpClientRequest.bodyFormData(${payloadVarName} as any)`)
309
+ } else if (operation.payloadFormUrlEncoded) {
310
+ pipeline.push(`HttpClientRequest.bodyUrlParams(${payloadVarName} as any)`)
272
311
  } else if (operation.payload) {
273
312
  pipeline.push(`HttpClientRequest.bodyJsonUnsafe(${payloadVarName})`)
274
313
  }
@@ -382,7 +421,8 @@ export const make = (
382
421
  }
383
422
 
384
423
  return OpenApiTransformer.of({
385
- imports: (importName, operations) => {
424
+ imports: (importName, parsed) => {
425
+ const operations = parsed.operations
386
426
  const requirements = computeImportRequirements(operations)
387
427
  const imports = [
388
428
  `import * as Data from "effect/Data"`,
@@ -409,16 +449,40 @@ export const make = (
409
449
  )
410
450
  return imports.join("\n")
411
451
  },
412
- toTypes: operationsToInterface,
413
- toImplementation: operationsToImpl
452
+ toTypes: (importName, name, parsed) => operationsToInterface(importName, name, parsed.operations),
453
+ toImplementation: (importName, name, parsed) => operationsToImpl(importName, name, parsed.operations)
414
454
  })
415
455
  }
416
456
 
457
+ /**
458
+ * Layer that provides the schema-backed OpenApiTransformer service.
459
+ *
460
+ * **When to use**
461
+ *
462
+ * Use when you use this layer when generated HttpClient code should perform runtime response
463
+ * decoding with generated Effect Schema values.
464
+ *
465
+ * @category code generation
466
+ * @since 4.0.0
467
+ */
417
468
  export const layerTransformerSchema = Layer.sync(
418
469
  OpenApiTransformer,
419
470
  makeTransformerSchema
420
471
  )
421
472
 
473
+ /**
474
+ * Create the transformer used for type-only HttpClient output.
475
+ *
476
+ * **Details**
477
+ *
478
+ * Generated clients reference emitted TypeScript types directly and do not
479
+ * import schema decoders for JSON response bodies. Responses are typed as the
480
+ * declared operation result while preserving generated error and stream method
481
+ * shapes.
482
+ *
483
+ * @category code generation
484
+ * @since 4.0.0
485
+ */
422
486
  export const makeTransformerTs = () => {
423
487
  const operationsToInterface = (
424
488
  _importName: string,
@@ -777,7 +841,8 @@ export const make = (
777
841
  }
778
842
 
779
843
  return OpenApiTransformer.of({
780
- imports: (_importName, operations) => {
844
+ imports: (_importName, parsed) => {
845
+ const operations = parsed.operations
781
846
  const requirements = computeImportRequirements(operations)
782
847
  const imports = [
783
848
  `import * as Data from "effect/Data"`,
@@ -794,11 +859,23 @@ export const make = (
794
859
  )
795
860
  return imports.join("\n")
796
861
  },
797
- toTypes: operationsToInterface,
798
- toImplementation: operationsToImpl
862
+ toTypes: (importName, name, parsed) => operationsToInterface(importName, name, parsed.operations),
863
+ toImplementation: (importName, name, parsed) => operationsToImpl(importName, name, parsed.operations)
799
864
  })
800
865
  }
801
866
 
867
+ /**
868
+ * Layer that provides the type-only OpenApiTransformer service.
869
+ *
870
+ * **When to use**
871
+ *
872
+ * Use when you use this layer for the `httpclient-type-only` generator format, where the
873
+ * generated client relies on TypeScript types instead of runtime Schema
874
+ * decoding.
875
+ *
876
+ * @category code generation
877
+ * @since 4.0.0
878
+ */
802
879
  export const layerTransformerTs = Layer.sync(
803
880
  OpenApiTransformer,
804
881
  makeTransformerTs
@@ -840,7 +917,7 @@ const sseRequestSource = (_importName: string) =>
840
917
  Type,
841
918
  DecodingServices
842
919
  >(
843
- schema: Schema.Decoder<Type, DecodingServices>
920
+ schema: Schema.ConstraintDecoder<Type, DecodingServices>
844
921
  ) =>
845
922
  (
846
923
  request: HttpClientRequest.HttpClientRequest