@effect/openapi-generator 4.0.0-beta.66 → 4.0.0-beta.67
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/dist/HttpApiTransformer.d.ts +31 -0
- package/dist/HttpApiTransformer.d.ts.map +1 -1
- package/dist/HttpApiTransformer.js +20 -0
- package/dist/HttpApiTransformer.js.map +1 -1
- package/dist/JsonSchemaGenerator.d.ts +10 -0
- package/dist/JsonSchemaGenerator.d.ts.map +1 -1
- package/dist/JsonSchemaGenerator.js +30 -0
- package/dist/JsonSchemaGenerator.js.map +1 -1
- package/dist/OpenApiGenerator.d.ts +38 -0
- package/dist/OpenApiGenerator.d.ts.map +1 -1
- package/dist/OpenApiGenerator.js +25 -0
- package/dist/OpenApiGenerator.js.map +1 -1
- package/dist/OpenApiPatch.d.ts +26 -21
- package/dist/OpenApiPatch.d.ts.map +1 -1
- package/dist/OpenApiPatch.js +25 -20
- package/dist/OpenApiPatch.js.map +1 -1
- package/dist/OpenApiTransformer.d.ts +63 -0
- package/dist/OpenApiTransformer.d.ts.map +1 -1
- package/dist/OpenApiTransformer.js +63 -0
- package/dist/OpenApiTransformer.js.map +1 -1
- package/dist/ParsedOperation.d.ts +51 -0
- package/dist/ParsedOperation.d.ts.map +1 -1
- package/dist/ParsedOperation.js +3 -0
- package/dist/ParsedOperation.js.map +1 -1
- package/dist/Utils.d.ts +28 -0
- package/dist/Utils.d.ts.map +1 -1
- package/dist/Utils.js +38 -0
- package/dist/Utils.js.map +1 -1
- package/dist/main.d.ts +7 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +17 -0
- package/dist/main.js.map +1 -1
- package/package.json +5 -5
- package/src/HttpApiTransformer.ts +31 -0
- package/src/JsonSchemaGenerator.ts +30 -0
- package/src/OpenApiGenerator.ts +38 -0
- package/src/OpenApiPatch.ts +26 -21
- package/src/OpenApiTransformer.ts +63 -0
- package/src/ParsedOperation.ts +51 -0
- package/src/Utils.ts +38 -0
- package/src/main.ts +17 -0
package/src/OpenApiGenerator.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The `OpenApiGenerator` module orchestrates converting OpenAPI and Swagger
|
|
3
|
+
* documents into generated Effect source.
|
|
4
|
+
*
|
|
5
|
+
* It normalizes Swagger 2.0 input, resolves local references, builds the
|
|
6
|
+
* parsed operation model, registers request and response schemas, applies
|
|
7
|
+
* HttpApi-specific adaptations such as multipart helpers and security metadata,
|
|
8
|
+
* emits warnings for unsupported or lossy OpenAPI features, and then delegates
|
|
9
|
+
* final rendering to the HttpClient or HttpApi code generators.
|
|
10
|
+
*
|
|
11
|
+
* @since 4.0.0
|
|
12
|
+
*/
|
|
1
13
|
import * as Context from "effect/Context"
|
|
2
14
|
import * as Effect from "effect/Effect"
|
|
3
15
|
import type * as JsonSchema from "effect/JsonSchema"
|
|
@@ -12,13 +24,23 @@ import * as OpenApiTransformer from "./OpenApiTransformer.ts"
|
|
|
12
24
|
import * as ParsedOperation from "./ParsedOperation.ts"
|
|
13
25
|
import * as Utils from "./Utils.ts"
|
|
14
26
|
|
|
27
|
+
/**
|
|
28
|
+
* Service for turning OpenAPI or Swagger specifications into generated Effect
|
|
29
|
+
* HTTP client or HttpApi source code.
|
|
30
|
+
*/
|
|
15
31
|
export class OpenApiGenerator extends Context.Service<
|
|
16
32
|
OpenApiGenerator,
|
|
17
33
|
{ readonly generate: (spec: OpenAPISpec, options: OpenApiGenerateOptions) => Effect.Effect<string> }
|
|
18
34
|
>()("OpenApiGenerator") {}
|
|
19
35
|
|
|
36
|
+
/**
|
|
37
|
+
* Output targets supported by the OpenAPI generator.
|
|
38
|
+
*/
|
|
20
39
|
export type OpenApiGeneratorFormat = "httpclient" | "httpclient-type-only" | "httpapi"
|
|
21
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Stable identifiers for non-fatal OpenAPI generation warnings.
|
|
43
|
+
*/
|
|
22
44
|
export type OpenApiGeneratorWarningCode =
|
|
23
45
|
| "cookie-parameter-dropped"
|
|
24
46
|
| "additional-tags-dropped"
|
|
@@ -30,6 +52,10 @@ export type OpenApiGeneratorWarningCode =
|
|
|
30
52
|
| "no-body-method-request-body-skipped"
|
|
31
53
|
| "naming-collision"
|
|
32
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Describes a non-fatal issue encountered while mapping an OpenAPI operation to
|
|
57
|
+
* generated Effect source.
|
|
58
|
+
*/
|
|
33
59
|
export interface OpenApiGeneratorWarning {
|
|
34
60
|
readonly code: OpenApiGeneratorWarningCode
|
|
35
61
|
readonly message: string
|
|
@@ -38,6 +64,9 @@ export interface OpenApiGeneratorWarning {
|
|
|
38
64
|
readonly operationId?: string | undefined
|
|
39
65
|
}
|
|
40
66
|
|
|
67
|
+
/**
|
|
68
|
+
* Options that control one OpenAPI generation run.
|
|
69
|
+
*/
|
|
41
70
|
export interface OpenApiGenerateOptions {
|
|
42
71
|
/**
|
|
43
72
|
* The name to give to the generated output.
|
|
@@ -73,6 +102,9 @@ const methodNames: ReadonlyArray<OpenAPISpecMethodName> = [
|
|
|
73
102
|
"trace"
|
|
74
103
|
]
|
|
75
104
|
|
|
105
|
+
/**
|
|
106
|
+
* Constructs the OpenAPI generator service implementation.
|
|
107
|
+
*/
|
|
76
108
|
export const make = Effect.gen(function*() {
|
|
77
109
|
const generate = Effect.fn(
|
|
78
110
|
function*(spec: OpenAPISpec, options: OpenApiGenerateOptions) {
|
|
@@ -1018,8 +1050,14 @@ function getDialect(spec: OpenAPISpec): "openapi-3.0" | "openapi-3.1" {
|
|
|
1018
1050
|
return spec.openapi.trim().startsWith("3.0") ? "openapi-3.0" : "openapi-3.1"
|
|
1019
1051
|
}
|
|
1020
1052
|
|
|
1053
|
+
/**
|
|
1054
|
+
* Layer providing an OpenAPI generator for Schema-backed HTTP client and HttpApi output.
|
|
1055
|
+
*/
|
|
1021
1056
|
export const layerTransformerSchema: Layer.Layer<OpenApiGenerator> = Layer.effect(OpenApiGenerator, make)
|
|
1022
1057
|
|
|
1058
|
+
/**
|
|
1059
|
+
* Layer providing an OpenAPI generator for type-only HTTP client output.
|
|
1060
|
+
*/
|
|
1023
1061
|
export const layerTransformerTs: Layer.Layer<OpenApiGenerator> = Layer.effect(OpenApiGenerator, make)
|
|
1024
1062
|
|
|
1025
1063
|
const isSwaggerSpec = (spec: OpenAPISpec) => "swagger" in spec
|
package/src/OpenApiPatch.ts
CHANGED
|
@@ -6,8 +6,6 @@
|
|
|
6
6
|
* - JSON files (.json)
|
|
7
7
|
* - YAML files (.yaml, .yml)
|
|
8
8
|
* - Inline JSON strings
|
|
9
|
-
*
|
|
10
|
-
* @module OpenApiPatch
|
|
11
9
|
*/
|
|
12
10
|
|
|
13
11
|
import * as Effect from "effect/Effect"
|
|
@@ -31,7 +29,8 @@ import * as Yaml from "yaml"
|
|
|
31
29
|
* - JSON or YAML syntax is invalid
|
|
32
30
|
* - The file format is unsupported
|
|
33
31
|
*
|
|
34
|
-
*
|
|
32
|
+
* **Example** (Creating a parse error)
|
|
33
|
+
*
|
|
35
34
|
* ```ts
|
|
36
35
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
37
36
|
*
|
|
@@ -44,8 +43,8 @@ import * as Yaml from "yaml"
|
|
|
44
43
|
* // "Failed to parse patch from ./patches/fix.json: Unexpected token at position 42"
|
|
45
44
|
* ```
|
|
46
45
|
*
|
|
47
|
-
* @since 1.0.0
|
|
48
46
|
* @category errors
|
|
47
|
+
* @since 4.0.0
|
|
49
48
|
*/
|
|
50
49
|
export class JsonPatchParseError extends Schema.ErrorClass<JsonPatchParseError>("JsonPatchParseError")({
|
|
51
50
|
_tag: Schema.tag("JsonPatchParseError"),
|
|
@@ -66,7 +65,8 @@ export class JsonPatchParseError extends Schema.ErrorClass<JsonPatchParseError>(
|
|
|
66
65
|
* - An operation has an unsupported op value
|
|
67
66
|
* - An add/replace operation is missing the value field
|
|
68
67
|
*
|
|
69
|
-
*
|
|
68
|
+
* **Example** (Creating a validation error)
|
|
69
|
+
*
|
|
70
70
|
* ```ts
|
|
71
71
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
72
72
|
*
|
|
@@ -79,8 +79,8 @@ export class JsonPatchParseError extends Schema.ErrorClass<JsonPatchParseError>(
|
|
|
79
79
|
* // "Invalid JSON Patch from inline: Expected 'add' | 'remove' | 'replace' at [0].op, got 'copy'"
|
|
80
80
|
* ```
|
|
81
81
|
*
|
|
82
|
-
* @since 1.0.0
|
|
83
82
|
* @category errors
|
|
83
|
+
* @since 4.0.0
|
|
84
84
|
*/
|
|
85
85
|
export class JsonPatchValidationError extends Schema.ErrorClass<JsonPatchValidationError>("JsonPatchValidationError")({
|
|
86
86
|
_tag: Schema.tag("JsonPatchValidationError"),
|
|
@@ -100,7 +100,8 @@ export class JsonPatchValidationError extends Schema.ErrorClass<JsonPatchValidat
|
|
|
100
100
|
* - An array index is out of bounds
|
|
101
101
|
* - The target location is not a valid container
|
|
102
102
|
*
|
|
103
|
-
*
|
|
103
|
+
* **Example** (Creating an application error)
|
|
104
|
+
*
|
|
104
105
|
* ```ts
|
|
105
106
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
106
107
|
*
|
|
@@ -116,8 +117,8 @@ export class JsonPatchValidationError extends Schema.ErrorClass<JsonPatchValidat
|
|
|
116
117
|
* // "Failed to apply patch from ./patches/fix.json: operation 2 (remove at /paths/~1users): Property \"users\" does not exist"
|
|
117
118
|
* ```
|
|
118
119
|
*
|
|
119
|
-
* @since 1.0.0
|
|
120
120
|
* @category errors
|
|
121
|
+
* @since 4.0.0
|
|
121
122
|
*/
|
|
122
123
|
export class JsonPatchApplicationError
|
|
123
124
|
extends Schema.ErrorClass<JsonPatchApplicationError>("JsonPatchApplicationError")({
|
|
@@ -141,7 +142,8 @@ export class JsonPatchApplicationError
|
|
|
141
142
|
* This error aggregates all application errors so users can see every
|
|
142
143
|
* failing operation at once instead of fixing them one at a time.
|
|
143
144
|
*
|
|
144
|
-
*
|
|
145
|
+
* **Example** (Creating an aggregate error)
|
|
146
|
+
*
|
|
145
147
|
* ```ts
|
|
146
148
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
147
149
|
*
|
|
@@ -168,8 +170,8 @@ export class JsonPatchApplicationError
|
|
|
168
170
|
* // "2 patch operations failed:\n 1. ..."
|
|
169
171
|
* ```
|
|
170
172
|
*
|
|
171
|
-
* @since 1.0.0
|
|
172
173
|
* @category errors
|
|
174
|
+
* @since 4.0.0
|
|
173
175
|
*/
|
|
174
176
|
export class JsonPatchAggregateError extends Schema.ErrorClass<JsonPatchAggregateError>("JsonPatchAggregateError")({
|
|
175
177
|
_tag: Schema.tag("JsonPatchAggregateError"),
|
|
@@ -193,8 +195,8 @@ export class JsonPatchAggregateError extends Schema.ErrorClass<JsonPatchAggregat
|
|
|
193
195
|
/**
|
|
194
196
|
* Schema for a JSON Patch "add" operation.
|
|
195
197
|
*
|
|
196
|
-
* @since 1.0.0
|
|
197
198
|
* @category schemas
|
|
199
|
+
* @since 4.0.0
|
|
198
200
|
*/
|
|
199
201
|
export const JsonPatchAdd: Schema.Codec<
|
|
200
202
|
Extract<
|
|
@@ -211,8 +213,8 @@ export const JsonPatchAdd: Schema.Codec<
|
|
|
211
213
|
/**
|
|
212
214
|
* Schema for a JSON Patch "remove" operation.
|
|
213
215
|
*
|
|
214
|
-
* @since 1.0.0
|
|
215
216
|
* @category schemas
|
|
217
|
+
* @since 4.0.0
|
|
216
218
|
*/
|
|
217
219
|
export const JsonPatchRemove: Schema.Codec<
|
|
218
220
|
Extract<
|
|
@@ -228,8 +230,8 @@ export const JsonPatchRemove: Schema.Codec<
|
|
|
228
230
|
/**
|
|
229
231
|
* Schema for a JSON Patch "replace" operation.
|
|
230
232
|
*
|
|
231
|
-
* @since 1.0.0
|
|
232
233
|
* @category schemas
|
|
234
|
+
* @since 4.0.0
|
|
233
235
|
*/
|
|
234
236
|
export const JsonPatchReplace: Schema.Codec<
|
|
235
237
|
Extract<
|
|
@@ -249,8 +251,8 @@ export const JsonPatchReplace: Schema.Codec<
|
|
|
249
251
|
* Supports the subset of RFC 6902 operations that Effect's JsonPatch module
|
|
250
252
|
* implements: `add`, `remove`, and `replace`.
|
|
251
253
|
*
|
|
252
|
-
* @since 1.0.0
|
|
253
254
|
* @category schemas
|
|
255
|
+
* @since 4.0.0
|
|
254
256
|
*/
|
|
255
257
|
export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Schema.Union([
|
|
256
258
|
JsonPatchAdd,
|
|
@@ -265,7 +267,8 @@ export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Sc
|
|
|
265
267
|
* document. Operations are applied in sequence, with each operation seeing
|
|
266
268
|
* the result of previous operations.
|
|
267
269
|
*
|
|
268
|
-
*
|
|
270
|
+
* **Example** (Decoding a patch document)
|
|
271
|
+
*
|
|
269
272
|
* ```ts
|
|
270
273
|
* import { Schema } from "effect"
|
|
271
274
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
@@ -277,16 +280,16 @@ export const JsonPatchOperation: Schema.Codec<JsonPatch.JsonPatchOperation> = Sc
|
|
|
277
280
|
* ])
|
|
278
281
|
* ```
|
|
279
282
|
*
|
|
280
|
-
* @since 1.0.0
|
|
281
283
|
* @category schemas
|
|
284
|
+
* @since 4.0.0
|
|
282
285
|
*/
|
|
283
286
|
export const JsonPatchDocument = Schema.Array(JsonPatchOperation)
|
|
284
287
|
|
|
285
288
|
/**
|
|
286
289
|
* Type for a JSON Patch document.
|
|
287
290
|
*
|
|
288
|
-
* @since 1.0.0
|
|
289
291
|
* @category types
|
|
292
|
+
* @since 4.0.0
|
|
290
293
|
*/
|
|
291
294
|
export type JsonPatchDocument = typeof JsonPatchDocument.Type
|
|
292
295
|
|
|
@@ -413,7 +416,8 @@ const parseInlinePatch = Effect.fn("parseInlinePatch")(function*(input: string)
|
|
|
413
416
|
* and parsed based on its extension (.json, .yaml, .yml). Otherwise, the
|
|
414
417
|
* input is parsed as inline JSON.
|
|
415
418
|
*
|
|
416
|
-
*
|
|
419
|
+
* **Example** (Parsing patch input)
|
|
420
|
+
*
|
|
417
421
|
* ```ts
|
|
418
422
|
* import { Effect } from "effect"
|
|
419
423
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
@@ -433,8 +437,8 @@ const parseInlinePatch = Effect.fn("parseInlinePatch")(function*(input: string)
|
|
|
433
437
|
* })
|
|
434
438
|
* ```
|
|
435
439
|
*
|
|
436
|
-
* @since 1.0.0
|
|
437
440
|
* @category parsing
|
|
441
|
+
* @since 4.0.0
|
|
438
442
|
*/
|
|
439
443
|
export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: string) {
|
|
440
444
|
if (looksLikeFilePath(input)) {
|
|
@@ -457,7 +461,8 @@ export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: str
|
|
|
457
461
|
* the previous one. All operations are attempted, and if any fail, the errors
|
|
458
462
|
* are accumulated and reported together so users can fix all issues at once.
|
|
459
463
|
*
|
|
460
|
-
*
|
|
464
|
+
* **Example** (Applying patches)
|
|
465
|
+
*
|
|
461
466
|
* ```ts
|
|
462
467
|
* import { Effect } from "effect"
|
|
463
468
|
* import * as OpenApiPatch from "@effect/openapi-generator/OpenApiPatch"
|
|
@@ -477,8 +482,8 @@ export const parsePatchInput = Effect.fn("parsePatchInput")(function*(input: str
|
|
|
477
482
|
* })
|
|
478
483
|
* ```
|
|
479
484
|
*
|
|
480
|
-
* @since 1.0.0
|
|
481
485
|
* @category application
|
|
486
|
+
* @since 4.0.0
|
|
482
487
|
*/
|
|
483
488
|
export const applyPatches = Effect.fn("applyPatches")(function*(
|
|
484
489
|
patches: ReadonlyArray<{ readonly source: string; readonly patch: JsonPatchDocument }>,
|
|
@@ -1,9 +1,32 @@
|
|
|
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
|
+
*/
|
|
1
13
|
import * as Context from "effect/Context"
|
|
2
14
|
import * as Layer from "effect/Layer"
|
|
3
15
|
import * as Predicate from "effect/Predicate"
|
|
4
16
|
import type { ParsedOpenApi, ParsedOperation } from "./ParsedOperation.ts"
|
|
5
17
|
import * as Utils from "./Utils.ts"
|
|
6
18
|
|
|
19
|
+
/**
|
|
20
|
+
* Service used by the OpenAPI generator to render parsed operations as an
|
|
21
|
+
* Effect HttpClient module.
|
|
22
|
+
*
|
|
23
|
+
* A transformer owns the code-generation dialect for imports, public client
|
|
24
|
+
* types, and the implementation body. The generator swaps implementations to
|
|
25
|
+
* choose between schema-backed clients and type-only clients.
|
|
26
|
+
*
|
|
27
|
+
* @category code generation
|
|
28
|
+
* @since 4.0.0
|
|
29
|
+
*/
|
|
7
30
|
export class OpenApiTransformer extends Context.Service<
|
|
8
31
|
OpenApiTransformer,
|
|
9
32
|
{
|
|
@@ -35,6 +58,16 @@ const computeImportRequirements = (operations: ReadonlyArray<ParsedOperation>):
|
|
|
35
58
|
const requiresStreaming = (requirements: ImportRequirements): boolean =>
|
|
36
59
|
requirements.eventStream || requirements.octetStream
|
|
37
60
|
|
|
61
|
+
/**
|
|
62
|
+
* Create the transformer used for schema-backed HttpClient output.
|
|
63
|
+
*
|
|
64
|
+
* Generated clients import Effect Schema values and use them at runtime to
|
|
65
|
+
* decode successful responses and typed API errors. Request parameters and
|
|
66
|
+
* payloads are typed against each schema's encoded representation.
|
|
67
|
+
*
|
|
68
|
+
* @category code generation
|
|
69
|
+
* @since 4.0.0
|
|
70
|
+
*/
|
|
38
71
|
export const makeTransformerSchema = () => {
|
|
39
72
|
const operationsToInterface = (
|
|
40
73
|
_importName: string,
|
|
@@ -417,11 +450,31 @@ export const make = (
|
|
|
417
450
|
})
|
|
418
451
|
}
|
|
419
452
|
|
|
453
|
+
/**
|
|
454
|
+
* Layer that provides the schema-backed OpenApiTransformer service.
|
|
455
|
+
*
|
|
456
|
+
* Use this layer when generated HttpClient code should perform runtime response
|
|
457
|
+
* decoding with generated Effect Schema values.
|
|
458
|
+
*
|
|
459
|
+
* @category code generation
|
|
460
|
+
* @since 4.0.0
|
|
461
|
+
*/
|
|
420
462
|
export const layerTransformerSchema = Layer.sync(
|
|
421
463
|
OpenApiTransformer,
|
|
422
464
|
makeTransformerSchema
|
|
423
465
|
)
|
|
424
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Create the transformer used for type-only HttpClient output.
|
|
469
|
+
*
|
|
470
|
+
* Generated clients reference emitted TypeScript types directly and do not
|
|
471
|
+
* import schema decoders for JSON response bodies. Responses are typed as the
|
|
472
|
+
* declared operation result while preserving generated error and stream method
|
|
473
|
+
* shapes.
|
|
474
|
+
*
|
|
475
|
+
* @category code generation
|
|
476
|
+
* @since 4.0.0
|
|
477
|
+
*/
|
|
425
478
|
export const makeTransformerTs = () => {
|
|
426
479
|
const operationsToInterface = (
|
|
427
480
|
_importName: string,
|
|
@@ -803,6 +856,16 @@ export const make = (
|
|
|
803
856
|
})
|
|
804
857
|
}
|
|
805
858
|
|
|
859
|
+
/**
|
|
860
|
+
* Layer that provides the type-only OpenApiTransformer service.
|
|
861
|
+
*
|
|
862
|
+
* Use this layer for the `httpclient-type-only` generator format, where the
|
|
863
|
+
* generated client relies on TypeScript types instead of runtime Schema
|
|
864
|
+
* decoding.
|
|
865
|
+
*
|
|
866
|
+
* @category code generation
|
|
867
|
+
* @since 4.0.0
|
|
868
|
+
*/
|
|
806
869
|
export const layerTransformerTs = Layer.sync(
|
|
807
870
|
OpenApiTransformer,
|
|
808
871
|
makeTransformerTs
|
package/src/ParsedOperation.ts
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalized OpenAPI operation model shared by the generator pipeline.
|
|
3
|
+
*
|
|
4
|
+
* This module records the shape produced after an OpenAPI document is resolved
|
|
5
|
+
* into stable generator inputs: document metadata, tags, security schemes,
|
|
6
|
+
* per-operation parameters, request bodies, response media types, derived
|
|
7
|
+
* schema references, path templates, and streaming capabilities. Renderers
|
|
8
|
+
* consume this representation to emit HttpClient or HttpApi modules without
|
|
9
|
+
* reinterpreting raw OpenAPI path-item structures.
|
|
10
|
+
*
|
|
11
|
+
* @since 4.0.0
|
|
12
|
+
*/
|
|
1
13
|
import type * as Types from "effect/Types"
|
|
2
14
|
import type {
|
|
3
15
|
OpenAPISecurityRequirement,
|
|
@@ -7,6 +19,9 @@ import type {
|
|
|
7
19
|
OpenAPISpecServer
|
|
8
20
|
} from "effect/unstable/httpapi/OpenApi"
|
|
9
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Root OpenAPI metadata preserved for generated client and HttpApi output.
|
|
24
|
+
*/
|
|
10
25
|
export interface ParsedOpenApiMetadata {
|
|
11
26
|
readonly title: string
|
|
12
27
|
readonly version: string
|
|
@@ -16,12 +31,18 @@ export interface ParsedOpenApiMetadata {
|
|
|
16
31
|
readonly servers: ReadonlyArray<OpenAPISpecServer> | undefined
|
|
17
32
|
}
|
|
18
33
|
|
|
34
|
+
/**
|
|
35
|
+
* Tag metadata used to group and annotate generated operations.
|
|
36
|
+
*/
|
|
19
37
|
export interface ParsedOpenApiTag {
|
|
20
38
|
readonly name: string
|
|
21
39
|
readonly description: string | undefined
|
|
22
40
|
readonly externalDocs: OpenAPISpecExternalDocs | undefined
|
|
23
41
|
}
|
|
24
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Supported security scheme extracted from an OpenAPI components section.
|
|
45
|
+
*/
|
|
25
46
|
export interface ParsedOpenApiSecurityScheme {
|
|
26
47
|
readonly name: string
|
|
27
48
|
readonly type: "basic" | "bearer" | "apiKey"
|
|
@@ -31,6 +52,9 @@ export interface ParsedOpenApiSecurityScheme {
|
|
|
31
52
|
readonly in: "header" | "query" | "cookie" | undefined
|
|
32
53
|
}
|
|
33
54
|
|
|
55
|
+
/**
|
|
56
|
+
* Normalized OpenAPI document consumed by the generator renderers.
|
|
57
|
+
*/
|
|
34
58
|
export interface ParsedOpenApi {
|
|
35
59
|
readonly metadata: ParsedOpenApiMetadata
|
|
36
60
|
readonly tags: ReadonlyArray<ParsedOpenApiTag>
|
|
@@ -38,6 +62,9 @@ export interface ParsedOpenApi {
|
|
|
38
62
|
readonly operations: ReadonlyArray<ParsedOperation>
|
|
39
63
|
}
|
|
40
64
|
|
|
65
|
+
/**
|
|
66
|
+
* Documentation and lifecycle metadata associated with an operation.
|
|
67
|
+
*/
|
|
41
68
|
export interface ParsedOperationMetadata {
|
|
42
69
|
readonly summary: string | undefined
|
|
43
70
|
readonly description: string | undefined
|
|
@@ -45,6 +72,9 @@ export interface ParsedOperationMetadata {
|
|
|
45
72
|
readonly externalDocs: OpenAPISpecExternalDocs | undefined
|
|
46
73
|
}
|
|
47
74
|
|
|
75
|
+
/**
|
|
76
|
+
* Resolved OpenAPI parameter grouped by where it appears in the request.
|
|
77
|
+
*/
|
|
48
78
|
export interface ParsedOperationParameter {
|
|
49
79
|
readonly name: string
|
|
50
80
|
readonly in: "path" | "query" | "header" | "cookie"
|
|
@@ -53,11 +83,17 @@ export interface ParsedOperationParameter {
|
|
|
53
83
|
readonly schema: {}
|
|
54
84
|
}
|
|
55
85
|
|
|
86
|
+
/**
|
|
87
|
+
* Summary of the request body declaration before per-media schemas are rendered.
|
|
88
|
+
*/
|
|
56
89
|
export interface ParsedOperationRequestBody {
|
|
57
90
|
readonly required: boolean
|
|
58
91
|
readonly contentTypes: Array<string>
|
|
59
92
|
}
|
|
60
93
|
|
|
94
|
+
/**
|
|
95
|
+
* Encoding strategy the generator can use for a request or response media type.
|
|
96
|
+
*/
|
|
61
97
|
export type ParsedOperationMediaTypeEncoding =
|
|
62
98
|
| "json"
|
|
63
99
|
| "multipart"
|
|
@@ -65,12 +101,18 @@ export type ParsedOperationMediaTypeEncoding =
|
|
|
65
101
|
| "text"
|
|
66
102
|
| "binary"
|
|
67
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Media type whose schema can be represented in generated Effect code.
|
|
106
|
+
*/
|
|
68
107
|
export interface ParsedOperationMediaTypeSchema {
|
|
69
108
|
readonly contentType: string
|
|
70
109
|
readonly encoding: ParsedOperationMediaTypeEncoding
|
|
71
110
|
readonly schema: string
|
|
72
111
|
}
|
|
73
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Parsed response metadata together with generated schema references.
|
|
115
|
+
*/
|
|
74
116
|
export interface ParsedOperationResponse {
|
|
75
117
|
readonly status: string
|
|
76
118
|
readonly description: string | undefined
|
|
@@ -80,8 +122,14 @@ export interface ParsedOperationResponse {
|
|
|
80
122
|
readonly representable: ReadonlyArray<ParsedOperationMediaTypeSchema>
|
|
81
123
|
}
|
|
82
124
|
|
|
125
|
+
/**
|
|
126
|
+
* Resolved security requirement applied to a parsed operation.
|
|
127
|
+
*/
|
|
83
128
|
export type ParsedOperationSecurityRequirement = Readonly<OpenAPISecurityRequirement>
|
|
84
129
|
|
|
130
|
+
/**
|
|
131
|
+
* Normalized operation model shared by all OpenAPI generator backends.
|
|
132
|
+
*/
|
|
85
133
|
export interface ParsedOperation {
|
|
86
134
|
readonly id: string
|
|
87
135
|
readonly operationId: string | undefined
|
|
@@ -125,6 +173,9 @@ export interface ParsedOperation {
|
|
|
125
173
|
readonly binaryResponse: boolean
|
|
126
174
|
}
|
|
127
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Creates a mutable operation accumulator populated with parser defaults.
|
|
178
|
+
*/
|
|
128
179
|
export const makeDeepMutable = (options: {
|
|
129
180
|
readonly id: string
|
|
130
181
|
readonly method: OpenAPISpecMethodName
|
package/src/Utils.ts
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared utility helpers for the OpenAPI generator.
|
|
3
|
+
*
|
|
4
|
+
* This module centralizes the small transformations used while rendering
|
|
5
|
+
* generated TypeScript, including operation-name normalization, optional
|
|
6
|
+
* description handling, safe JSDoc comment emission, and direct array merging
|
|
7
|
+
* for code-generation accumulators.
|
|
8
|
+
*
|
|
9
|
+
* @since 4.0.0
|
|
10
|
+
*/
|
|
1
11
|
import * as String from "effect/String"
|
|
2
12
|
import * as UndefinedOr from "effect/UndefinedOr"
|
|
3
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Converts an OpenAPI name into the generator's camel-case form.
|
|
16
|
+
*
|
|
17
|
+
* Separators are removed, leading digits are ignored, and letters following a
|
|
18
|
+
* separator or digit are upper-cased without otherwise changing letter casing.
|
|
19
|
+
*/
|
|
4
20
|
export const camelize = (self: string): string => {
|
|
5
21
|
let str = ""
|
|
6
22
|
let hadSymbol = false
|
|
@@ -24,8 +40,18 @@ export const camelize = (self: string): string => {
|
|
|
24
40
|
return str
|
|
25
41
|
}
|
|
26
42
|
|
|
43
|
+
/**
|
|
44
|
+
* Converts an OpenAPI operation id into the exported operation identifier used
|
|
45
|
+
* by generated TypeScript modules.
|
|
46
|
+
*/
|
|
27
47
|
export const identifier = (operationId: string) => String.capitalize(camelize(operationId))
|
|
28
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Extracts a trimmed, non-empty string from an unknown value.
|
|
51
|
+
*
|
|
52
|
+
* Returns `undefined` for non-string values and for strings containing only
|
|
53
|
+
* whitespace.
|
|
54
|
+
*/
|
|
29
55
|
export const nonEmptyString = (a: unknown): string | undefined => {
|
|
30
56
|
if (typeof a === "string") {
|
|
31
57
|
const trimmed = String.trim(a)
|
|
@@ -35,6 +61,12 @@ export const nonEmptyString = (a: unknown): string | undefined => {
|
|
|
35
61
|
}
|
|
36
62
|
}
|
|
37
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Renders an optional description as a JSDoc block for generated TypeScript.
|
|
66
|
+
*
|
|
67
|
+
* Returns an empty string when the description is absent and escapes any
|
|
68
|
+
* closing comment marker so generated source remains syntactically valid.
|
|
69
|
+
*/
|
|
38
70
|
export const toComment = UndefinedOr.match({
|
|
39
71
|
onUndefined: () => "",
|
|
40
72
|
onDefined: (description: string) =>
|
|
@@ -43,6 +75,12 @@ export const toComment = UndefinedOr.match({
|
|
|
43
75
|
*/\n`
|
|
44
76
|
})
|
|
45
77
|
|
|
78
|
+
/**
|
|
79
|
+
* Appends every element from `source` into `destination` in order.
|
|
80
|
+
*
|
|
81
|
+
* This mutates `destination` directly, which avoids allocating an intermediate
|
|
82
|
+
* array when generator code needs to merge collections.
|
|
83
|
+
*/
|
|
46
84
|
export const spreadElementsInto = <A>(source: Array<A>, destination: Array<A>): void => {
|
|
47
85
|
for (let i = 0; i < source.length; i++) {
|
|
48
86
|
destination.push(source[i])
|
package/src/main.ts
CHANGED
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Command-line entry point for generating Effect HTTP clients or HttpApi
|
|
3
|
+
* definitions from an OpenAPI specification.
|
|
4
|
+
*
|
|
5
|
+
* The CLI reads a spec file, optionally applies JSON patches in order, selects
|
|
6
|
+
* the generator layer for the requested output format, reports generation
|
|
7
|
+
* warnings to stderr, and writes the generated source to stdout.
|
|
8
|
+
*
|
|
9
|
+
* @since 4.0.0
|
|
10
|
+
*/
|
|
1
11
|
import * as Console from "effect/Console"
|
|
2
12
|
import * as Effect from "effect/Effect"
|
|
3
13
|
import type * as Schema from "effect/Schema"
|
|
@@ -78,6 +88,13 @@ const root = Command.make("openapigen", { spec, format, name, patch }).pipe(
|
|
|
78
88
|
)
|
|
79
89
|
)
|
|
80
90
|
|
|
91
|
+
/**
|
|
92
|
+
* Runs the OpenAPI generator command-line program.
|
|
93
|
+
*
|
|
94
|
+
* The command reads an OpenAPI specification, optionally applies JSON patches,
|
|
95
|
+
* generates source code in the selected format, writes any generation warnings
|
|
96
|
+
* to stderr, and prints the generated source to stdout.
|
|
97
|
+
*/
|
|
81
98
|
export const run: Effect.Effect<void, CliError.CliError, Command.Environment> = Command.run(root, {
|
|
82
99
|
version: "0.0.0"
|
|
83
100
|
})
|