@effect/openapi-generator 4.0.0-beta.6 → 4.0.0-beta.60

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.
@@ -0,0 +1,6 @@
1
+ import type { ParsedOpenApi } from "./ParsedOperation.ts";
2
+ export declare const imports: (importName: string, options?: {
3
+ readonly multipart?: boolean | undefined;
4
+ }) => string;
5
+ export declare const toImplementation: (_importName: string, name: string, parsed: ParsedOpenApi) => string;
6
+ //# sourceMappingURL=HttpApiTransformer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpApiTransformer.d.ts","sourceRoot":"","sources":["../src/HttpApiTransformer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,aAAa,EAMd,MAAM,sBAAsB,CAAA;AAmB7B,eAAO,MAAM,OAAO,GAClB,YAAY,MAAM,EAClB,UAAU;IACR,QAAQ,CAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;CACzC,KACA,MAKW,CAAA;AAEd,eAAO,MAAM,gBAAgB,GAC3B,aAAa,MAAM,EACnB,MAAM,MAAM,EACZ,QAAQ,aAAa,KACpB,MAqBF,CAAA"}
@@ -0,0 +1,354 @@
1
+ import * as Utils from "./Utils.js";
2
+ const fallbackGroupIdentifier = "default";
3
+ export const imports = (importName, options) => [`import * as ${importName} from "effect/Schema"`, ...(options?.multipart === true ? [`import { Multipart } from "effect/unstable/http"`] : []), `import { HttpApi, HttpApiEndpoint, HttpApiGroup, HttpApiMiddleware, HttpApiSchema, HttpApiSecurity, OpenApi } from "effect/unstable/httpapi"`].join("\n");
4
+ export const toImplementation = (_importName, name, parsed) => {
5
+ const security = buildSecurityRenderModel(parsed);
6
+ const groups = groupOperations(parsed);
7
+ const groupSources = groups.map(group => renderGroup(group, security.endpointMiddlewares));
8
+ const metadataAnnotations = renderApiAnnotations(parsed);
9
+ let apiValue = `export class ${name} extends HttpApi.make(${JSON.stringify(name)})`;
10
+ for (const annotation of metadataAnnotations) {
11
+ apiValue += `\n .${annotation}`;
12
+ }
13
+ if (groups.length > 0) {
14
+ apiValue += `\n .add(${groups.map(group => group.constName).join(", ")})`;
15
+ }
16
+ apiValue += ` {}`;
17
+ return [...security.securityDeclarations, ...security.middlewareDeclarations, ...groupSources, apiValue].join("\n\n");
18
+ };
19
+ const groupOperations = parsed => {
20
+ const tagMetadata = new Map(parsed.tags.map(tag => [tag.name, tag]));
21
+ const byIdentifier = new Map();
22
+ for (const operation of parsed.operations) {
23
+ const identifier = operation.tags[0] ?? fallbackGroupIdentifier;
24
+ const topLevel = operation.tags.length === 0;
25
+ const existing = byIdentifier.get(identifier);
26
+ if (existing) {
27
+ if (topLevel) {
28
+ existing.topLevel = true;
29
+ }
30
+ existing.operations.push(operation);
31
+ continue;
32
+ }
33
+ byIdentifier.set(identifier, {
34
+ identifier,
35
+ topLevel,
36
+ metadata: tagMetadata.get(identifier),
37
+ operations: [operation]
38
+ });
39
+ }
40
+ const allocateName = makeNameAllocator();
41
+ const groups = [];
42
+ for (const group of byIdentifier.values()) {
43
+ const baseName = ensureIdentifier(group.identifier, "Group");
44
+ groups.push({
45
+ ...group,
46
+ constName: allocateName(`${baseName}Group`)
47
+ });
48
+ }
49
+ return groups;
50
+ };
51
+ const renderGroup = (group, endpointMiddlewares) => {
52
+ let source = `class ${group.constName} extends HttpApiGroup.make(${JSON.stringify(group.identifier)}${group.topLevel ? ", { topLevel: true }" : ""})`;
53
+ const allocateEndpointName = makeNameAllocator();
54
+ const endpointSources = group.operations.map(operation => renderEndpoint(operation, allocateEndpointName(operation.id), endpointMiddlewares.get(toOperationKey(operation)) ?? []));
55
+ if (endpointSources.length > 0) {
56
+ source += `\n .add(${endpointSources.join(", \n ")})`;
57
+ }
58
+ if (group.metadata?.description !== undefined) {
59
+ source += `\n .annotate(OpenApi.Description, ${JSON.stringify(group.metadata.description)})`;
60
+ }
61
+ if (group.metadata?.externalDocs !== undefined) {
62
+ source += `\n .annotate(OpenApi.ExternalDocs, ${JSON.stringify(group.metadata.externalDocs)})`;
63
+ }
64
+ source += ` {}`;
65
+ return source;
66
+ };
67
+ const renderEndpoint = (operation, endpointName, endpointMiddlewares) => {
68
+ const options = [];
69
+ if (operation.pathSchema !== undefined) {
70
+ options.push(`params: ${operation.pathSchema}`);
71
+ }
72
+ if (operation.querySchema !== undefined) {
73
+ options.push(`query: ${operation.querySchema}`);
74
+ }
75
+ if (operation.headersSchema !== undefined) {
76
+ options.push(`headers: ${operation.headersSchema}`);
77
+ }
78
+ const payload = renderPayload(operation);
79
+ if (payload !== undefined) {
80
+ options.push(`payload: ${payload}`);
81
+ }
82
+ const success = renderResponseSet(operation.responses, "success");
83
+ if (success !== undefined) {
84
+ options.push(`success: ${success}`);
85
+ }
86
+ const error = renderResponseSet(operation.responses, "error");
87
+ if (error !== undefined) {
88
+ options.push(`error: ${error}`);
89
+ }
90
+ const endpoint = options.length === 0 ? `HttpApiEndpoint.${operation.method}(${JSON.stringify(endpointName)}, ${JSON.stringify(toHttpApiPath(operation.path))})` : `HttpApiEndpoint.${operation.method}(${JSON.stringify(endpointName)}, ${JSON.stringify(toHttpApiPath(operation.path))}, { ${options.join(", ")} })`;
91
+ const annotations = [];
92
+ if (operation.operationId !== undefined) {
93
+ annotations.push(`annotate(OpenApi.Identifier, ${JSON.stringify(operation.operationId)})`);
94
+ }
95
+ if (operation.metadata.summary !== undefined) {
96
+ annotations.push(`annotate(OpenApi.Summary, ${JSON.stringify(operation.metadata.summary)})`);
97
+ }
98
+ if (operation.metadata.description !== undefined) {
99
+ annotations.push(`annotate(OpenApi.Description, ${JSON.stringify(operation.metadata.description)})`);
100
+ }
101
+ if (operation.metadata.deprecated) {
102
+ annotations.push(`annotate(OpenApi.Deprecated, true)`);
103
+ }
104
+ if (operation.metadata.externalDocs !== undefined) {
105
+ annotations.push(`annotate(OpenApi.ExternalDocs, ${JSON.stringify(operation.metadata.externalDocs)})`);
106
+ }
107
+ if (annotations.length === 0 && endpointMiddlewares.length === 0) {
108
+ return endpoint;
109
+ }
110
+ let out = endpoint;
111
+ for (const middleware of endpointMiddlewares) {
112
+ out += `\n .middleware(${middleware})`;
113
+ }
114
+ for (const annotation of annotations) {
115
+ out += `\n .${annotation}`;
116
+ }
117
+ return out;
118
+ };
119
+ const renderPayload = operation => {
120
+ if (!methodSupportsBody(operation.method)) {
121
+ return;
122
+ }
123
+ const payloads = operation.requestBodyRepresentable.map(schema => renderMediaSchema(schema));
124
+ if (payloads.length === 0) {
125
+ return;
126
+ }
127
+ if (operation.requestBody?.required === false) {
128
+ payloads.unshift("HttpApiSchema.NoContent");
129
+ }
130
+ return joinSchemas(payloads);
131
+ };
132
+ const renderResponseSet = (responses, target) => {
133
+ const rendered = [];
134
+ for (const response of responses) {
135
+ const status = toStatus(response.status);
136
+ if (status === undefined) {
137
+ continue;
138
+ }
139
+ const isSuccess = status < 400;
140
+ if (target === "success" !== isSuccess) {
141
+ continue;
142
+ }
143
+ if (response.isEmpty) {
144
+ rendered.push(`HttpApiSchema.Empty(${status})`);
145
+ continue;
146
+ }
147
+ for (const media of response.representable) {
148
+ rendered.push(applyStatus(renderMediaSchema(media), status, target));
149
+ }
150
+ }
151
+ if (rendered.length === 0) {
152
+ return;
153
+ }
154
+ return joinSchemas(rendered);
155
+ };
156
+ const joinSchemas = schemas => schemas.length === 1 ? schemas[0] : `[${schemas.join(", ")}]`;
157
+ const renderMediaSchema = media => {
158
+ switch (media.encoding) {
159
+ case "json":
160
+ {
161
+ if (media.contentType === "application/json") {
162
+ return media.schema;
163
+ }
164
+ return `${media.schema}.pipe(HttpApiSchema.asJson({ contentType: ${JSON.stringify(media.contentType)} }))`;
165
+ }
166
+ case "multipart":
167
+ {
168
+ return `${media.schema}.pipe(HttpApiSchema.asMultipart())`;
169
+ }
170
+ case "form-url-encoded":
171
+ {
172
+ if (media.contentType === "application/x-www-form-urlencoded") {
173
+ return `${media.schema}.pipe(HttpApiSchema.asFormUrlEncoded())`;
174
+ }
175
+ return `${media.schema}.pipe(HttpApiSchema.asFormUrlEncoded({ contentType: ${JSON.stringify(media.contentType)} }))`;
176
+ }
177
+ case "text":
178
+ {
179
+ if (media.contentType === "text/plain") {
180
+ return `${media.schema}.pipe(HttpApiSchema.asText())`;
181
+ }
182
+ return `${media.schema}.pipe(HttpApiSchema.asText({ contentType: ${JSON.stringify(media.contentType)} }))`;
183
+ }
184
+ case "binary":
185
+ {
186
+ if (media.contentType === "application/octet-stream") {
187
+ return `${media.schema}.pipe(HttpApiSchema.asUint8Array())`;
188
+ }
189
+ return `${media.schema}.pipe(HttpApiSchema.asUint8Array({ contentType: ${JSON.stringify(media.contentType)} }))`;
190
+ }
191
+ }
192
+ };
193
+ const renderApiAnnotations = parsed => {
194
+ const annotations = [`annotate(OpenApi.Title, ${JSON.stringify(parsed.metadata.title)})`, `annotate(OpenApi.Version, ${JSON.stringify(parsed.metadata.version)})`];
195
+ if (parsed.metadata.summary !== undefined) {
196
+ annotations.push(`annotate(OpenApi.Summary, ${JSON.stringify(parsed.metadata.summary)})`);
197
+ }
198
+ if (parsed.metadata.description !== undefined) {
199
+ annotations.push(`annotate(OpenApi.Description, ${JSON.stringify(parsed.metadata.description)})`);
200
+ }
201
+ if (parsed.metadata.license !== undefined) {
202
+ annotations.push(`annotate(OpenApi.License, ${JSON.stringify(parsed.metadata.license)})`);
203
+ }
204
+ if (parsed.metadata.servers !== undefined) {
205
+ annotations.push(`annotate(OpenApi.Servers, ${JSON.stringify(parsed.metadata.servers)})`);
206
+ }
207
+ return annotations;
208
+ };
209
+ const buildSecurityRenderModel = parsed => {
210
+ const allocateName = makeNameAllocator();
211
+ const securityDeclarations = [];
212
+ const middlewareDeclarations = [];
213
+ const endpointMiddlewares = new Map();
214
+ const schemeDeclarations = new Map();
215
+ const middlewareNames = new Map();
216
+ for (const securityScheme of parsed.securitySchemes) {
217
+ const baseName = ensureIdentifier(securityScheme.name, "Security");
218
+ const declarationName = allocateName(`${baseName}Security`);
219
+ schemeDeclarations.set(securityScheme.name, declarationName);
220
+ securityDeclarations.push(`export const ${declarationName} = ${renderSecurityScheme(securityScheme)}`);
221
+ }
222
+ for (const operation of parsed.operations) {
223
+ if (operation.effectiveSecurity.length === 0) {
224
+ continue;
225
+ }
226
+ if (operation.effectiveSecurity.some(requirement => Object.keys(requirement).length === 0)) {
227
+ continue;
228
+ }
229
+ const operationMiddlewareNames = [];
230
+ const seenOrSchemes = new Set();
231
+ const andRequirements = [];
232
+ for (const requirement of operation.effectiveSecurity) {
233
+ const schemes = Object.keys(requirement);
234
+ if (schemes.length === 1) {
235
+ const schemeName = schemes[0];
236
+ if (schemeDeclarations.has(schemeName) && !seenOrSchemes.has(schemeName)) {
237
+ seenOrSchemes.add(schemeName);
238
+ }
239
+ } else if (schemes.length > 1) {
240
+ andRequirements.push([...schemes].sort());
241
+ }
242
+ }
243
+ const orSchemeNames = Array.from(seenOrSchemes).sort();
244
+ if (orSchemeNames.length > 0) {
245
+ const className = getOrSecurityMiddlewareName(orSchemeNames);
246
+ operationMiddlewareNames.push(className);
247
+ }
248
+ const seenAndRequirements = new Set();
249
+ for (const requirement of andRequirements) {
250
+ const key = requirement.join("\u0000");
251
+ if (seenAndRequirements.has(key)) {
252
+ continue;
253
+ }
254
+ seenAndRequirements.add(key);
255
+ const className = getAndSecurityMiddlewareName(requirement);
256
+ operationMiddlewareNames.push(className);
257
+ }
258
+ if (operationMiddlewareNames.length > 0) {
259
+ endpointMiddlewares.set(toOperationKey(operation), operationMiddlewareNames);
260
+ }
261
+ }
262
+ return {
263
+ securityDeclarations,
264
+ middlewareDeclarations,
265
+ endpointMiddlewares
266
+ };
267
+ function getOrSecurityMiddlewareName(schemes) {
268
+ const key = `or:${schemes.join("\u0000")}`;
269
+ const existing = middlewareNames.get(key);
270
+ if (existing !== undefined) {
271
+ return existing;
272
+ }
273
+ const className = allocateName(`${getSecurityMiddlewareBaseName(schemes, "Or")}SecurityMiddleware`);
274
+ const securityEntries = schemes.map(name => `${JSON.stringify(name)}: ${schemeDeclarations.get(name)}`).join(", ");
275
+ middlewareDeclarations.push(`export class ${className} extends HttpApiMiddleware.Service<${className}>()(${JSON.stringify(`${schemes.join(" | ")} security`)}, { security: { ${securityEntries} } }) {}`);
276
+ middlewareNames.set(key, className);
277
+ return className;
278
+ }
279
+ function getAndSecurityMiddlewareName(schemes) {
280
+ const key = `and:${schemes.join("\u0000")}`;
281
+ const existing = middlewareNames.get(key);
282
+ if (existing !== undefined) {
283
+ return existing;
284
+ }
285
+ const className = allocateName(`${getSecurityMiddlewareBaseName(schemes, "And")}SecurityMiddleware`);
286
+ middlewareDeclarations.push(`class ${className} extends HttpApiMiddleware.Service<${className}>()(${JSON.stringify(`${schemes.join(" & ")} security`)}) {}`);
287
+ middlewareNames.set(key, className);
288
+ return className;
289
+ }
290
+ };
291
+ const getSecurityMiddlewareBaseName = (schemes, joiner) => {
292
+ const [head, ...tail] = schemes.map(scheme => ensureIdentifier(scheme, "Security"));
293
+ return tail.length === 0 ? head : [head, ...tail.map(scheme => `${joiner}${scheme}`)].join("");
294
+ };
295
+ const renderSecurityScheme = securityScheme => {
296
+ let source;
297
+ switch (securityScheme.type) {
298
+ case "basic":
299
+ {
300
+ source = "HttpApiSecurity.basic";
301
+ break;
302
+ }
303
+ case "bearer":
304
+ {
305
+ source = "HttpApiSecurity.bearer";
306
+ break;
307
+ }
308
+ case "apiKey":
309
+ {
310
+ source = `HttpApiSecurity.apiKey({ key: ${JSON.stringify(securityScheme.key)}, in: ${JSON.stringify(securityScheme.in)} })`;
311
+ break;
312
+ }
313
+ }
314
+ if (securityScheme.description !== undefined) {
315
+ source += `.pipe(HttpApiSecurity.annotate(OpenApi.Description, ${JSON.stringify(securityScheme.description)}))`;
316
+ }
317
+ if (securityScheme.type === "bearer" && securityScheme.bearerFormat !== undefined) {
318
+ source += `.pipe(HttpApiSecurity.annotate(OpenApi.Format, ${JSON.stringify(securityScheme.bearerFormat)}))`;
319
+ }
320
+ return source;
321
+ };
322
+ const toOperationKey = operation => `${operation.method}:${operation.path}`;
323
+ const toHttpApiPath = path => path.replace(/{([^}]+)}/g, ":$1");
324
+ const toStatus = status => {
325
+ if (!/^\d{3}$/.test(status)) {
326
+ return;
327
+ }
328
+ return Number(status);
329
+ };
330
+ const applyStatus = (schema, status, target) => {
331
+ if (target === "success" && status === 200 || target === "error" && status === 500) {
332
+ return schema;
333
+ }
334
+ return `${schema}.pipe(HttpApiSchema.status(${status}))`;
335
+ };
336
+ const methodSupportsBody = method => method !== "get" && method !== "head" && method !== "options" && method !== "trace";
337
+ const ensureIdentifier = (value, fallback) => {
338
+ const sanitized = Utils.identifier(value);
339
+ return sanitized.length > 0 ? sanitized : fallback;
340
+ };
341
+ const makeNameAllocator = () => {
342
+ const used = new Set();
343
+ return base => {
344
+ let candidate = base;
345
+ let index = 2;
346
+ while (used.has(candidate)) {
347
+ candidate = `${base}${index}`;
348
+ index += 1;
349
+ }
350
+ used.add(candidate);
351
+ return candidate;
352
+ };
353
+ };
354
+ //# sourceMappingURL=HttpApiTransformer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"HttpApiTransformer.js","names":["Utils","fallbackGroupIdentifier","imports","importName","options","multipart","join","toImplementation","_importName","name","parsed","security","buildSecurityRenderModel","groups","groupOperations","groupSources","map","group","renderGroup","endpointMiddlewares","metadataAnnotations","renderApiAnnotations","apiValue","JSON","stringify","annotation","length","constName","securityDeclarations","middlewareDeclarations","tagMetadata","Map","tags","tag","byIdentifier","operation","operations","identifier","topLevel","existing","get","push","set","metadata","allocateName","makeNameAllocator","values","baseName","ensureIdentifier","source","allocateEndpointName","endpointSources","renderEndpoint","id","toOperationKey","description","undefined","externalDocs","endpointName","pathSchema","querySchema","headersSchema","payload","renderPayload","success","renderResponseSet","responses","error","endpoint","method","toHttpApiPath","path","annotations","operationId","summary","deprecated","out","middleware","methodSupportsBody","payloads","requestBodyRepresentable","schema","renderMediaSchema","requestBody","required","unshift","joinSchemas","target","rendered","response","status","toStatus","isSuccess","isEmpty","media","representable","applyStatus","schemas","encoding","contentType","title","version","license","servers","schemeDeclarations","middlewareNames","securityScheme","securitySchemes","declarationName","renderSecurityScheme","effectiveSecurity","some","requirement","Object","keys","operationMiddlewareNames","seenOrSchemes","Set","andRequirements","schemes","schemeName","has","add","sort","orSchemeNames","Array","from","className","getOrSecurityMiddlewareName","seenAndRequirements","key","getAndSecurityMiddlewareName","getSecurityMiddlewareBaseName","securityEntries","joiner","head","tail","scheme","type","in","bearerFormat","replace","test","Number","value","fallback","sanitized","used","base","candidate","index"],"sources":["../src/HttpApiTransformer.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
@@ -1,8 +1,18 @@
1
1
  import * as JsonSchema from "effect/JsonSchema";
2
+ type Source = "openapi-3.0" | "openapi-3.1";
3
+ interface GenerateOptions {
4
+ readonly onEnter?: ((js: JsonSchema.JsonSchema) => JsonSchema.JsonSchema) | undefined;
5
+ }
6
+ interface GenerateHttpApiOptions extends GenerateOptions {
7
+ readonly multipartSchemaRefs?: {
8
+ readonly singleFile: string;
9
+ readonly files: string;
10
+ } | undefined;
11
+ }
2
12
  export declare function make(): {
3
13
  readonly addSchema: (name: string, schema: JsonSchema.JsonSchema) => string;
4
- readonly generate: (source: "openapi-3.0" | "openapi-3.1", components: JsonSchema.Definitions, typeOnly: boolean, options?: {
5
- readonly onEnter?: ((js: JsonSchema.JsonSchema) => JsonSchema.JsonSchema) | undefined;
6
- }) => string;
14
+ readonly generate: (source: Source, components: JsonSchema.Definitions, typeOnly: boolean, options?: GenerateOptions) => string;
15
+ readonly generateHttpApi: (source: Source, components: JsonSchema.Definitions, options?: GenerateHttpApiOptions) => string;
7
16
  };
17
+ export {};
8
18
  //# sourceMappingURL=JsonSchemaGenerator.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"JsonSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/JsonSchemaGenerator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAI/C,wBAAgB,IAAI;+BAGO,MAAM,UAAU,UAAU,CAAC,UAAU,KAAG,MAAM;gCAS7D,aAAa,GAAG,aAAa,cACzB,UAAU,CAAC,WAAW,YACxB,OAAO,YACP;QACR,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,UAAU,KAAK,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;KACtF;EAuEJ"}
1
+ {"version":3,"file":"JsonSchemaGenerator.d.ts","sourceRoot":"","sources":["../src/JsonSchemaGenerator.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,UAAU,MAAM,mBAAmB,CAAA;AAI/C,KAAK,MAAM,GAAG,aAAa,GAAG,aAAa,CAAA;AAE3C,UAAU,eAAe;IACvB,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,UAAU,CAAC,UAAU,KAAK,UAAU,CAAC,UAAU,CAAC,GAAG,SAAS,CAAA;CACtF;AAED,UAAU,sBAAuB,SAAQ,eAAe;IACtD,QAAQ,CAAC,mBAAmB,CAAC,EAAE;QAC7B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;QAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;KACvB,GAAG,SAAS,CAAA;CACd;AAED,wBAAgB,IAAI;+BAGO,MAAM,UAAU,UAAU,CAAC,UAAU,KAAG,MAAM;gCAS7D,MAAM,cACF,UAAU,CAAC,WAAW,YACxB,OAAO,YACP,eAAe;uCA0DjB,MAAM,cACF,UAAU,CAAC,WAAW,YACxB,sBAAsB;EA8FnC"}
@@ -12,64 +12,163 @@ export function make() {
12
12
  return name;
13
13
  }
14
14
  function generate(source, components, typeOnly, options) {
15
- const nameMap = [];
16
- const schemas = [];
17
- const definitions = Rec.map(components, js => fromSchemaOpenApi(js).schema);
18
- for (const [name, js] of Object.entries(store)) {
19
- nameMap.push(name);
20
- schemas.push(fromSchemaOpenApi(js).schema);
15
+ const generated = makeCodeDocument(source, components, options);
16
+ if (generated === undefined) {
17
+ return "";
21
18
  }
22
- if (Arr.isArrayNonEmpty(schemas)) {
23
- const multiDocument = SchemaRepresentation.fromJsonSchemaMultiDocument({
24
- dialect: "draft-2020-12",
25
- schemas,
26
- definitions
27
- }, {
28
- onEnter(js) {
29
- const out = {
30
- ...js
31
- };
32
- if (out.type === "object" && out.additionalProperties === undefined) {
33
- out.additionalProperties = false;
34
- }
35
- return options?.onEnter?.(out) ?? out;
36
- }
37
- });
38
- const codeDocument = SchemaRepresentation.toCodeDocument(multiDocument);
39
- const nonRecursives = codeDocument.references.nonRecursives.map(({
40
- $ref,
41
- code
42
- }) => renderSchema($ref, code));
43
- const recursives = Object.entries(codeDocument.references.recursives).map(([$ref, code]) => renderSchema($ref, code));
44
- const codes = codeDocument.codes.map((code, i) => renderSchema(nameMap[i], code));
45
- const s = render("non-recursive definitions", nonRecursives) + render("recursive definitions", recursives) + render("schemas", codes);
46
- return s;
19
+ const nonRecursiveReferences = generated.codeDocument.references.nonRecursives;
20
+ const recursiveReferences = Object.entries(generated.codeDocument.references.recursives);
21
+ const nonRecursives = nonRecursiveReferences.map(({
22
+ $ref,
23
+ code
24
+ }) => renderSchemaTypeAndRuntime($ref, code, typeOnly));
25
+ const recursiveDeclarations = [];
26
+ const recursives = [];
27
+ if (typeOnly) {
28
+ for (const [$ref, code] of recursiveReferences) {
29
+ recursives.push(renderSchemaTypeAndRuntime($ref, code, true));
30
+ }
47
31
  } else {
32
+ const recursivelyForwardReferenced = collectForwardReferencedRecursives(nonRecursiveReferences, recursiveReferences);
33
+ const recursiveInternalNames = makeRecursiveInternalNameMap(recursivelyForwardReferenced, [...nonRecursiveReferences.map(({
34
+ $ref
35
+ }) => $ref), ...recursiveReferences.map(([$ref]) => $ref), ...generated.nameMap]);
36
+ for (const [$ref, code] of recursiveReferences) {
37
+ if (recursivelyForwardReferenced.has($ref)) {
38
+ const internalName = recursiveInternalNames.get($ref);
39
+ recursiveDeclarations.push(renderRecursiveReferenceDeclaration($ref, code, internalName));
40
+ recursives.push(`const ${internalName} = ${code.runtime}`);
41
+ continue;
42
+ }
43
+ recursives.push(renderSchemaTypeAndRuntime($ref, code, false));
44
+ }
45
+ }
46
+ const codes = generated.codeDocument.codes.map((code, i) => renderSchemaTypeAndRuntime(generated.nameMap[i], code, typeOnly));
47
+ return render("recursive declarations", recursiveDeclarations) + render("non-recursive definitions", nonRecursives) + render("recursive definitions", recursives) + render("schemas", codes);
48
+ }
49
+ function generateHttpApi(source, components, options) {
50
+ const generated = makeCodeDocument(source, components, options);
51
+ if (generated === undefined) {
48
52
  return "";
49
53
  }
50
- function fromSchemaOpenApi(jsonSchema) {
51
- switch (source) {
52
- case "openapi-3.1":
53
- return JsonSchema.fromSchemaOpenApi3_1(jsonSchema);
54
- case "openapi-3.0":
55
- return JsonSchema.fromSchemaOpenApi3_0(jsonSchema);
54
+ const nonRecursiveReferences = generated.codeDocument.references.nonRecursives;
55
+ const recursiveReferences = Object.entries(generated.codeDocument.references.recursives);
56
+ const nonRecursives = nonRecursiveReferences.map(({
57
+ $ref,
58
+ code
59
+ }) => renderSchemaTypeAndRuntime($ref, code, false, options?.multipartSchemaRefs));
60
+ const recursivelyForwardReferenced = collectForwardReferencedRecursives(nonRecursiveReferences, recursiveReferences);
61
+ const recursiveInternalNames = makeRecursiveInternalNameMap(recursivelyForwardReferenced, [...nonRecursiveReferences.map(({
62
+ $ref
63
+ }) => $ref), ...recursiveReferences.map(([$ref]) => $ref), ...generated.nameMap]);
64
+ const recursiveDeclarations = [];
65
+ const recursives = [];
66
+ for (const [$ref, code] of recursiveReferences) {
67
+ if (recursivelyForwardReferenced.has($ref)) {
68
+ const internalName = recursiveInternalNames.get($ref);
69
+ recursiveDeclarations.push(renderRecursiveReferenceDeclaration($ref, code, internalName));
70
+ recursives.push(`const ${internalName} = ${code.runtime}`);
71
+ continue;
56
72
  }
73
+ recursives.push(renderSchemaTypeAndRuntime($ref, code, false, options?.multipartSchemaRefs));
57
74
  }
58
- function renderSchema($ref, code) {
59
- const strings = [`export type ${$ref} = ${code.Type}`];
60
- if (!typeOnly) {
61
- strings.push(`export const ${$ref} = ${code.runtime}`);
62
- }
63
- return strings.join("\n");
75
+ const codes = generated.codeDocument.codes.map((code, i) => renderSchemaTypeAndRuntime(generated.nameMap[i], code, false, options?.multipartSchemaRefs));
76
+ return render("recursive declarations", recursiveDeclarations) + render("non-recursive definitions", nonRecursives) + render("recursive definitions", recursives) + render("schemas", codes);
77
+ }
78
+ function makeCodeDocument(source, components, options) {
79
+ const nameMap = [];
80
+ const schemas = [];
81
+ const definitions = Rec.map(components, js => fromSchemaOpenApi(source, js).schema);
82
+ for (const [name, js] of Object.entries(store)) {
83
+ nameMap.push(name);
84
+ schemas.push(fromSchemaOpenApi(source, js).schema);
64
85
  }
65
- function render(title, as) {
66
- if (as.length === 0) return "";
67
- return "// " + title + "\n" + as.join("\n") + "\n";
86
+ if (!Arr.isArrayNonEmpty(schemas)) {
87
+ return;
68
88
  }
89
+ const multiDocument = SchemaRepresentation.fromJsonSchemaMultiDocument({
90
+ dialect: "draft-2020-12",
91
+ schemas,
92
+ definitions
93
+ }, {
94
+ onEnter(js) {
95
+ const out = {
96
+ ...js
97
+ };
98
+ if (out.type === "object" && out.additionalProperties === undefined) {
99
+ out.additionalProperties = false;
100
+ }
101
+ return options?.onEnter?.(out) ?? out;
102
+ }
103
+ });
104
+ return {
105
+ nameMap,
106
+ codeDocument: SchemaRepresentation.toCodeDocument(multiDocument)
107
+ };
69
108
  }
70
109
  return {
71
110
  addSchema,
72
- generate
111
+ generate,
112
+ generateHttpApi
73
113
  };
74
114
  }
115
+ function fromSchemaOpenApi(source, jsonSchema) {
116
+ switch (source) {
117
+ case "openapi-3.1":
118
+ return JsonSchema.fromSchemaOpenApi3_1(jsonSchema);
119
+ case "openapi-3.0":
120
+ return JsonSchema.fromSchemaOpenApi3_0(jsonSchema);
121
+ }
122
+ }
123
+ function renderSchemaTypeAndRuntime($ref, code, typeOnly, multipartSchemaRefs) {
124
+ if (!typeOnly && multipartSchemaRefs !== undefined) {
125
+ if ($ref === multipartSchemaRefs.singleFile) {
126
+ return [`export type ${$ref} = Multipart.PersistedFile`, `export const ${$ref} = Multipart.SingleFileSchema`].join("\n");
127
+ }
128
+ if ($ref === multipartSchemaRefs.files) {
129
+ return [`export type ${$ref} = ReadonlyArray<Multipart.PersistedFile>`, `export const ${$ref} = Multipart.FilesSchema`].join("\n");
130
+ }
131
+ }
132
+ const strings = [`export type ${$ref} = ${code.Type}`];
133
+ if (!typeOnly) {
134
+ strings.push(`export const ${$ref} = ${code.runtime}`);
135
+ }
136
+ return strings.join("\n");
137
+ }
138
+ function renderRecursiveReferenceDeclaration($ref, code, internalName) {
139
+ return [`export type ${$ref} = ${code.Type}`, `export const ${$ref} = Schema.suspend((): Schema.Codec<${$ref}> => ${internalName})`].join("\n");
140
+ }
141
+ function render(title, as) {
142
+ if (as.length === 0) return "";
143
+ return "// " + title + "\n" + as.join("\n") + "\n";
144
+ }
145
+ const tokenPattern = /[A-Za-z_$][A-Za-z0-9_$]*/g;
146
+ function collectForwardReferencedRecursives(nonRecursives, recursives) {
147
+ const recursiveNames = new Set(recursives.map(([name]) => name));
148
+ const referenced = new Set();
149
+ for (const {
150
+ code
151
+ } of nonRecursives) {
152
+ for (const token of code.runtime.matchAll(tokenPattern)) {
153
+ const identifier = token[0];
154
+ if (recursiveNames.has(identifier)) {
155
+ referenced.add(identifier);
156
+ }
157
+ }
158
+ }
159
+ return referenced;
160
+ }
161
+ function makeRecursiveInternalNameMap(recursiveNames, existingNames) {
162
+ const usedNames = new Set(existingNames);
163
+ const internalNames = new Map();
164
+ for (const name of recursiveNames) {
165
+ let candidate = `__recursive_${name}`;
166
+ while (usedNames.has(candidate)) {
167
+ candidate = `_${candidate}`;
168
+ }
169
+ usedNames.add(candidate);
170
+ internalNames.set(name, candidate);
171
+ }
172
+ return internalNames;
173
+ }
75
174
  //# sourceMappingURL=JsonSchemaGenerator.js.map