@typespec/openapi3 0.56.0-dev.2 → 0.56.0-dev.3

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.
@@ -1,15 +1,3 @@
1
- var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2
- if (kind === "m") throw new TypeError("Private method is not writable");
3
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
4
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
5
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
6
- };
7
- var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
8
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
9
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
10
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
11
- };
12
- var _OpenAPI3SchemaEmitter_instances, _OpenAPI3SchemaEmitter_metadataInfo, _OpenAPI3SchemaEmitter_visibilityUsage, _OpenAPI3SchemaEmitter_options, _OpenAPI3SchemaEmitter_applyExternalDocs, _OpenAPI3SchemaEmitter_typeNameOptions, _OpenAPI3SchemaEmitter_getVisibilityContext, _OpenAPI3SchemaEmitter_getContentType, _OpenAPI3SchemaEmitter_requiredModelProperties, _OpenAPI3SchemaEmitter_isBytesKeptRaw, _OpenAPI3SchemaEmitter_enumSchema, _OpenAPI3SchemaEmitter_unionSchema, _OpenAPI3SchemaEmitter_getDiscriminatorMapping, _OpenAPI3SchemaEmitter_attachExtensions, _OpenAPI3SchemaEmitter_getSchemaForScalar, _OpenAPI3SchemaEmitter_getSchemaForStdScalars, _OpenAPI3SchemaEmitter_applyConstraints, _OpenAPI3SchemaEmitter_inlineType, _OpenAPI3SchemaEmitter_createDeclaration, _OpenAPI3SchemaEmitter_isStdType, _OpenAPI3SchemaEmitter_applyEncoding, _OpenAPI3SchemaEmitter_mergeFormatAndEncoding;
13
1
  import { compilerAssert, getDeprecated, getDiscriminatedUnion, getDiscriminator, getDoc, getEncode, getFormat, getKnownValues, getMaxItems, getMaxLength, getMaxValue, getMaxValueExclusive, getMinItems, getMinLength, getMinValue, getMinValueExclusive, getNamespaceFullName, getPattern, getSummary, getTypeName, ignoreDiagnostics, isArrayModelType, isNeverType, isNullType, isSecret, isTemplateDeclaration, resolveEncodedName, stringTemplateToString, } from "@typespec/compiler";
14
2
  import { ArrayBuilder, ObjectBuilder, Placeholder, TypeEmitter, } from "@typespec/compiler/emitter-framework";
15
3
  import { Visibility, getVisibilitySuffix } from "@typespec/http";
@@ -20,15 +8,14 @@ import { reportDiagnostic } from "./lib.js";
20
8
  * OpenAPI3 schema emitter. Deals with emitting content of `components/schemas` section.
21
9
  */
22
10
  export class OpenAPI3SchemaEmitter extends TypeEmitter {
11
+ #metadataInfo;
12
+ #visibilityUsage;
13
+ #options;
23
14
  constructor(emitter, metadataInfo, visibilityUsage, options) {
24
15
  super(emitter);
25
- _OpenAPI3SchemaEmitter_instances.add(this);
26
- _OpenAPI3SchemaEmitter_metadataInfo.set(this, void 0);
27
- _OpenAPI3SchemaEmitter_visibilityUsage.set(this, void 0);
28
- _OpenAPI3SchemaEmitter_options.set(this, void 0);
29
- __classPrivateFieldSet(this, _OpenAPI3SchemaEmitter_metadataInfo, metadataInfo, "f");
30
- __classPrivateFieldSet(this, _OpenAPI3SchemaEmitter_visibilityUsage, visibilityUsage, "f");
31
- __classPrivateFieldSet(this, _OpenAPI3SchemaEmitter_options, options, "f");
16
+ this.#metadataInfo = metadataInfo;
17
+ this.#visibilityUsage = visibilityUsage;
18
+ this.#options = options;
32
19
  }
33
20
  modelDeclarationReferenceContext(model, name) {
34
21
  return this.reduceContext(model);
@@ -46,12 +33,12 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
46
33
  return this.reduceContext(union);
47
34
  }
48
35
  reduceContext(type) {
49
- const visibility = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this);
36
+ const visibility = this.#getVisibilityContext();
50
37
  const patch = {};
51
- if (visibility !== Visibility.Read && !__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_metadataInfo, "f").isTransformed(type, visibility)) {
38
+ if (visibility !== Visibility.Read && !this.#metadataInfo.isTransformed(type, visibility)) {
52
39
  patch.visibility = Visibility.Read;
53
40
  }
54
- const contentType = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this);
41
+ const contentType = this.#getContentType();
55
42
  if (contentType === "application/json") {
56
43
  patch.contentType = undefined;
57
44
  }
@@ -59,10 +46,10 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
59
46
  }
60
47
  modelDeclaration(model, _) {
61
48
  const program = this.emitter.getProgram();
62
- const visibility = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this);
49
+ const visibility = this.#getVisibilityContext();
63
50
  const schema = new ObjectBuilder({
64
51
  type: "object",
65
- required: __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_requiredModelProperties).call(this, model, visibility),
52
+ required: this.#requiredModelProperties(model, visibility),
66
53
  properties: this.emitter.emitModelProperties(model),
67
54
  });
68
55
  if (model.indexer) {
@@ -78,24 +65,46 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
78
65
  const [union] = getDiscriminatedUnion(model, discriminator);
79
66
  const openApiDiscriminator = { ...discriminator };
80
67
  if (union.variants.size > 0) {
81
- openApiDiscriminator.mapping = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getDiscriminatorMapping).call(this, union);
68
+ openApiDiscriminator.mapping = this.#getDiscriminatorMapping(union);
82
69
  }
83
70
  schema.discriminator = openApiDiscriminator;
84
71
  }
85
- __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyExternalDocs).call(this, model, schema);
72
+ this.#applyExternalDocs(model, schema);
86
73
  if (model.baseModel) {
87
74
  schema.set("allOf", B.array([this.emitter.emitTypeReference(model.baseModel)]));
88
75
  }
89
- const baseName = getOpenAPITypeName(program, model, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_typeNameOptions).call(this));
90
- const isMultipart = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this).startsWith("multipart/");
76
+ const baseName = getOpenAPITypeName(program, model, this.#typeNameOptions());
77
+ const isMultipart = this.#getContentType().startsWith("multipart/");
91
78
  const name = isMultipart ? baseName + "MultiPart" : baseName;
92
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_createDeclaration).call(this, model, name, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, model, schema));
79
+ return this.#createDeclaration(model, name, this.#applyConstraints(model, schema));
80
+ }
81
+ #applyExternalDocs(typespecType, target) {
82
+ const externalDocs = getExternalDocs(this.emitter.getProgram(), typespecType);
83
+ if (externalDocs) {
84
+ target.externalDocs = externalDocs;
85
+ }
86
+ }
87
+ #typeNameOptions() {
88
+ const serviceNamespaceName = this.emitter.getContext().serviceNamespaceName;
89
+ return {
90
+ // shorten type names by removing TypeSpec and service namespace
91
+ namespaceFilter(ns) {
92
+ const name = getNamespaceFullName(ns);
93
+ return name !== serviceNamespaceName;
94
+ },
95
+ };
96
+ }
97
+ #getVisibilityContext() {
98
+ return this.emitter.getContext().visibility ?? Visibility.Read;
99
+ }
100
+ #getContentType() {
101
+ return this.emitter.getContext().contentType ?? "application/json";
93
102
  }
94
103
  modelLiteral(model) {
95
104
  const schema = new ObjectBuilder({
96
105
  type: "object",
97
106
  properties: this.emitter.emitModelProperties(model),
98
- required: __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_requiredModelProperties).call(this, model, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this)),
107
+ required: this.#requiredModelProperties(model, this.#getVisibilityContext()),
99
108
  });
100
109
  if (model.indexer) {
101
110
  schema.set("additionalProperties", this.emitter.emitTypeReference(model.indexer.value));
@@ -103,7 +112,7 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
103
112
  return schema;
104
113
  }
105
114
  modelInstantiation(model, name) {
106
- name = name !== null && name !== void 0 ? name : getOpenAPITypeName(this.emitter.getProgram(), model, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_typeNameOptions).call(this));
115
+ name = name ?? getOpenAPITypeName(this.emitter.getProgram(), model, this.#typeNameOptions());
107
116
  if (!name) {
108
117
  return this.modelLiteral(model);
109
118
  }
@@ -114,35 +123,52 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
114
123
  type: "array",
115
124
  items: this.emitter.emitTypeReference(elementType),
116
125
  });
117
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_createDeclaration).call(this, array, name, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, array, schema));
126
+ return this.#createDeclaration(array, name, this.#applyConstraints(array, schema));
118
127
  }
119
128
  arrayDeclarationReferenceContext(array, name, elementType) {
120
129
  return {
121
- visibility: __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this) | Visibility.Item,
130
+ visibility: this.#getVisibilityContext() | Visibility.Item,
122
131
  };
123
132
  }
124
133
  arrayLiteral(array, elementType) {
125
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_inlineType).call(this, array, new ObjectBuilder({
134
+ return this.#inlineType(array, new ObjectBuilder({
126
135
  type: "array",
127
136
  items: this.emitter.emitTypeReference(elementType),
128
137
  }));
129
138
  }
130
139
  arrayLiteralReferenceContext(array, elementType) {
131
140
  return {
132
- visibility: __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this) | Visibility.Item,
141
+ visibility: this.#getVisibilityContext() | Visibility.Item,
133
142
  };
134
143
  }
144
+ #requiredModelProperties(model, visibility) {
145
+ const requiredProps = [];
146
+ for (const prop of model.properties.values()) {
147
+ if (isNeverType(prop.type)) {
148
+ // If the property has a type of 'never', don't include it in the schema
149
+ continue;
150
+ }
151
+ if (!this.#metadataInfo.isPayloadProperty(prop, visibility)) {
152
+ continue;
153
+ }
154
+ if (!this.#metadataInfo.isOptional(prop, visibility)) {
155
+ const encodedName = resolveEncodedName(this.emitter.getProgram(), prop, this.#getContentType());
156
+ requiredProps.push(encodedName);
157
+ }
158
+ }
159
+ return requiredProps.length > 0 ? requiredProps : undefined;
160
+ }
135
161
  modelProperties(model) {
136
162
  const program = this.emitter.getProgram();
137
163
  const props = new ObjectBuilder();
138
164
  const visibility = this.emitter.getContext().visibility;
139
- const contentType = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this);
165
+ const contentType = this.#getContentType();
140
166
  for (const prop of model.properties.values()) {
141
167
  if (isNeverType(prop.type)) {
142
168
  // If the property has a type of 'never', don't include it in the schema
143
169
  continue;
144
170
  }
145
- if (!__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_metadataInfo, "f").isPayloadProperty(prop, visibility)) {
171
+ if (!this.#metadataInfo.isPayloadProperty(prop, visibility)) {
146
172
  continue;
147
173
  }
148
174
  const result = this.emitter.emitModelProperty(prop);
@@ -161,23 +187,27 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
161
187
  }
162
188
  return props;
163
189
  }
190
+ #isBytesKeptRaw(type) {
191
+ const program = this.emitter.getProgram();
192
+ return (type.kind === "Scalar" && type.name === "bytes" && getEncode(program, type) === undefined);
193
+ }
164
194
  modelPropertyLiteral(prop) {
165
195
  const program = this.emitter.getProgram();
166
- const isMultipart = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this).startsWith("multipart/");
196
+ const isMultipart = this.#getContentType().startsWith("multipart/");
167
197
  if (isMultipart) {
168
- if (__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isBytesKeptRaw).call(this, prop.type) && getEncode(program, prop) === undefined) {
198
+ if (this.#isBytesKeptRaw(prop.type) && getEncode(program, prop) === undefined) {
169
199
  return { type: "string", format: "binary" };
170
200
  }
171
201
  if (prop.type.kind === "Model" &&
172
202
  isArrayModelType(program, prop.type) &&
173
- __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isBytesKeptRaw).call(this, prop.type.indexer.value)) {
203
+ this.#isBytesKeptRaw(prop.type.indexer.value)) {
174
204
  return { type: "array", items: { type: "string", format: "binary" } };
175
205
  }
176
206
  }
177
207
  const refSchema = this.emitter.emitTypeReference(prop.type, {
178
208
  referenceContext: isMultipart &&
179
209
  (prop.type.kind !== "Union" ||
180
- ![...prop.type.variants.values()].some((x) => __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isBytesKeptRaw).call(this, x.type)))
210
+ ![...prop.type.variants.values()].some((x) => this.#isBytesKeptRaw(x.type)))
181
211
  ? { contentType: "application/json" }
182
212
  : {},
183
213
  });
@@ -185,9 +215,9 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
185
215
  throw new Error("Unexpected non-code result from emit reference");
186
216
  }
187
217
  const isRef = refSchema.value instanceof Placeholder || "$ref" in refSchema.value;
188
- const schema = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyEncoding).call(this, prop, refSchema.value);
218
+ const schema = this.#applyEncoding(prop, refSchema.value);
189
219
  // Apply decorators on the property to the type's schema
190
- const additionalProps = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, prop, {});
220
+ const additionalProps = this.#applyConstraints(prop, {});
191
221
  if (prop.default) {
192
222
  additionalProps.default = getDefaultValue(program, prop.type, prop.default);
193
223
  }
@@ -195,7 +225,7 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
195
225
  additionalProps.readOnly = true;
196
226
  }
197
227
  // Attach any additional OpenAPI extensions
198
- __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_attachExtensions).call(this, program, prop, additionalProps);
228
+ this.#attachExtensions(program, prop, additionalProps);
199
229
  if (schema && isRef && !(prop.type.kind === "Model" && isArrayModelType(program, prop.type))) {
200
230
  if (Object.keys(additionalProps).length === 0) {
201
231
  return schema;
@@ -239,8 +269,26 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
239
269
  return { type: "number", enum: [number.value] };
240
270
  }
241
271
  enumDeclaration(en, name) {
242
- const baseName = getOpenAPITypeName(this.emitter.getProgram(), en, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_typeNameOptions).call(this));
243
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_createDeclaration).call(this, en, baseName, new ObjectBuilder(__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_enumSchema).call(this, en)));
272
+ const baseName = getOpenAPITypeName(this.emitter.getProgram(), en, this.#typeNameOptions());
273
+ return this.#createDeclaration(en, baseName, new ObjectBuilder(this.#enumSchema(en)));
274
+ }
275
+ #enumSchema(en) {
276
+ const program = this.emitter.getProgram();
277
+ if (en.members.size === 0) {
278
+ reportDiagnostic(program, { code: "empty-enum", target: en });
279
+ return {};
280
+ }
281
+ const enumTypes = new Set();
282
+ const enumValues = new Set();
283
+ for (const member of en.members.values()) {
284
+ enumTypes.add(typeof member.value === "number" ? "number" : "string");
285
+ enumValues.add(member.value ?? member.name);
286
+ }
287
+ if (enumTypes.size > 1) {
288
+ reportDiagnostic(program, { code: "enum-unique-type", target: en });
289
+ }
290
+ const schema = { type: enumTypes.values().next().value, enum: [...enumValues] };
291
+ return this.#applyConstraints(en, schema);
244
292
  }
245
293
  enumMember(member) {
246
294
  return this.enumMemberReference(member);
@@ -257,11 +305,127 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
257
305
  }
258
306
  }
259
307
  unionDeclaration(union, name) {
260
- const schema = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_unionSchema).call(this, union);
261
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_createDeclaration).call(this, union, name, schema);
308
+ const schema = this.#unionSchema(union);
309
+ return this.#createDeclaration(union, name, schema);
310
+ }
311
+ #unionSchema(union) {
312
+ const program = this.emitter.getProgram();
313
+ if (union.variants.size === 0) {
314
+ reportDiagnostic(program, { code: "empty-union", target: union });
315
+ return new ObjectBuilder({});
316
+ }
317
+ const variants = Array.from(union.variants.values());
318
+ const literalVariantEnumByType = {};
319
+ const ofType = getOneOf(program, union) ? "oneOf" : "anyOf";
320
+ const schemaMembers = [];
321
+ let nullable = false;
322
+ const discriminator = getDiscriminator(program, union);
323
+ const isMultipart = this.#getContentType().startsWith("multipart/");
324
+ for (const variant of variants) {
325
+ if (isNullType(variant.type)) {
326
+ nullable = true;
327
+ continue;
328
+ }
329
+ if (isMultipart && this.#isBytesKeptRaw(variant.type)) {
330
+ schemaMembers.push({ schema: { type: "string", format: "binary" }, type: variant.type });
331
+ continue;
332
+ }
333
+ if (isLiteralType(variant.type)) {
334
+ if (!literalVariantEnumByType[variant.type.kind]) {
335
+ const enumValue = [variant.type.value];
336
+ literalVariantEnumByType[variant.type.kind] = enumValue;
337
+ schemaMembers.push({
338
+ schema: { type: literalType(variant.type), enum: enumValue },
339
+ type: null,
340
+ });
341
+ }
342
+ else {
343
+ literalVariantEnumByType[variant.type.kind].push(variant.type.value);
344
+ }
345
+ }
346
+ else {
347
+ const enumSchema = this.emitter.emitTypeReference(variant.type, {
348
+ referenceContext: isMultipart ? { contentType: "application/json" } : {},
349
+ });
350
+ compilerAssert(enumSchema.kind === "code", "Unexpected enum schema. Should be kind: code");
351
+ schemaMembers.push({ schema: enumSchema.value, type: variant.type });
352
+ }
353
+ }
354
+ if (schemaMembers.length === 0) {
355
+ if (nullable) {
356
+ // This union is equivalent to just `null` but OA3 has no way to specify
357
+ // null as a value, so we throw an error.
358
+ reportDiagnostic(program, { code: "union-null", target: union });
359
+ return new ObjectBuilder({});
360
+ }
361
+ else {
362
+ // completely empty union can maybe only happen with bugs?
363
+ compilerAssert(false, "Attempting to emit an empty union");
364
+ }
365
+ }
366
+ if (schemaMembers.length === 1) {
367
+ // we can just return the single schema member after applying nullable
368
+ const schema = schemaMembers[0].schema;
369
+ const type = schemaMembers[0].type;
370
+ const additionalProps = this.#applyConstraints(union, {});
371
+ if (nullable) {
372
+ additionalProps.nullable = true;
373
+ }
374
+ if (Object.keys(additionalProps).length === 0) {
375
+ return new ObjectBuilder(schema);
376
+ }
377
+ else {
378
+ if ((schema instanceof Placeholder || "$ref" in schema) &&
379
+ !(type && shouldInline(program, type))) {
380
+ if (type && type.kind === "Model") {
381
+ return new ObjectBuilder({
382
+ type: "object",
383
+ allOf: B.array([schema]),
384
+ ...additionalProps,
385
+ });
386
+ }
387
+ else {
388
+ return new ObjectBuilder({ oneOf: B.array([schema]), ...additionalProps });
389
+ }
390
+ }
391
+ else {
392
+ const merged = new ObjectBuilder(schema);
393
+ for (const [key, value] of Object.entries(additionalProps)) {
394
+ merged.set(key, value);
395
+ }
396
+ return merged;
397
+ }
398
+ }
399
+ }
400
+ const schema = {
401
+ [ofType]: schemaMembers.map((m) => m.schema),
402
+ };
403
+ if (nullable) {
404
+ schema.nullable = true;
405
+ }
406
+ if (discriminator) {
407
+ // the decorator validates that all the variants will be a model type
408
+ // with the discriminator field present.
409
+ schema.discriminator = { ...discriminator };
410
+ // Diagnostic already reported in compiler for unions
411
+ const discriminatedUnion = ignoreDiagnostics(getDiscriminatedUnion(union, discriminator));
412
+ if (discriminatedUnion.variants.size > 0) {
413
+ schema.discriminator.mapping = this.#getDiscriminatorMapping(discriminatedUnion);
414
+ }
415
+ }
416
+ return this.#applyConstraints(union, schema);
417
+ }
418
+ #getDiscriminatorMapping(union) {
419
+ const mapping = {};
420
+ for (const [key, model] of union.variants.entries()) {
421
+ const ref = this.emitter.emitTypeReference(model);
422
+ compilerAssert(ref.kind === "code", "Unexpected ref schema. Should be kind: code");
423
+ mapping[key] = ref.value.$ref;
424
+ }
425
+ return mapping;
262
426
  }
263
427
  unionLiteral(union) {
264
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_unionSchema).call(this, union);
428
+ return this.#unionSchema(union);
265
429
  }
266
430
  unionVariants(union) {
267
431
  const variants = new ArrayBuilder();
@@ -276,6 +440,15 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
276
440
  modelPropertyReference(prop) {
277
441
  return this.modelPropertyLiteral(prop);
278
442
  }
443
+ #attachExtensions(program, type, emitObject) {
444
+ // Attach any OpenAPI extensions
445
+ const extensions = getExtensions(program, type);
446
+ if (extensions) {
447
+ for (const key of extensions.keys()) {
448
+ emitObject[key] = extensions.get(key);
449
+ }
450
+ }
451
+ }
279
452
  reference(targetDeclaration, pathUp, pathDown, commonScope) {
280
453
  if (targetDeclaration.value instanceof Placeholder) {
281
454
  // I don't think this is possible, confirm.
@@ -303,18 +476,212 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
303
476
  return super.circularReference(target, scope, cycle);
304
477
  }
305
478
  scalarDeclaration(scalar, name) {
306
- const isStd = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isStdType).call(this, scalar);
307
- const schema = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getSchemaForScalar).call(this, scalar);
308
- const baseName = getOpenAPITypeName(this.emitter.getProgram(), scalar, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_typeNameOptions).call(this));
479
+ const isStd = this.#isStdType(scalar);
480
+ const schema = this.#getSchemaForScalar(scalar);
481
+ const baseName = getOpenAPITypeName(this.emitter.getProgram(), scalar, this.#typeNameOptions());
309
482
  // Don't create a declaration for std types
310
- return isStd ? schema : __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_createDeclaration).call(this, scalar, baseName, new ObjectBuilder(schema));
483
+ return isStd ? schema : this.#createDeclaration(scalar, baseName, new ObjectBuilder(schema));
311
484
  }
312
485
  scalarInstantiation(scalar, name) {
313
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getSchemaForScalar).call(this, scalar);
486
+ return this.#getSchemaForScalar(scalar);
314
487
  }
315
488
  tupleLiteral(tuple) {
316
489
  return { type: "array", items: {} };
317
490
  }
491
+ #getSchemaForScalar(scalar) {
492
+ let result = {};
493
+ const isStd = this.#isStdType(scalar);
494
+ if (isStd) {
495
+ result = this.#getSchemaForStdScalars(scalar);
496
+ }
497
+ else if (scalar.baseScalar) {
498
+ result = this.#getSchemaForScalar(scalar.baseScalar);
499
+ }
500
+ const withDecorators = this.#applyEncoding(scalar, this.#applyConstraints(scalar, result));
501
+ if (isStd) {
502
+ // Standard types are going to be inlined in the spec and we don't want the description of the scalar to show up
503
+ delete withDecorators.description;
504
+ }
505
+ return withDecorators;
506
+ }
507
+ #getSchemaForStdScalars(scalar) {
508
+ switch (scalar.name) {
509
+ case "bytes":
510
+ return { type: "string", format: "byte" };
511
+ case "numeric":
512
+ return { type: "number" };
513
+ case "integer":
514
+ return { type: "integer" };
515
+ case "int8":
516
+ return { type: "integer", format: "int8" };
517
+ case "int16":
518
+ return { type: "integer", format: "int16" };
519
+ case "int32":
520
+ return { type: "integer", format: "int32" };
521
+ case "int64":
522
+ return { type: "integer", format: "int64" };
523
+ case "safeint":
524
+ switch (this.#options.safeintStrategy) {
525
+ case "double-int":
526
+ return { type: "integer", format: "double-int" };
527
+ case "int64":
528
+ default:
529
+ return { type: "integer", format: "int64" };
530
+ }
531
+ case "uint8":
532
+ return { type: "integer", format: "uint8" };
533
+ case "uint16":
534
+ return { type: "integer", format: "uint16" };
535
+ case "uint32":
536
+ return { type: "integer", format: "uint32" };
537
+ case "uint64":
538
+ return { type: "integer", format: "uint64" };
539
+ case "float":
540
+ return { type: "number" };
541
+ case "float64":
542
+ return { type: "number", format: "double" };
543
+ case "float32":
544
+ return { type: "number", format: "float" };
545
+ case "decimal":
546
+ return { type: "number", format: "decimal" };
547
+ case "decimal128":
548
+ return { type: "number", format: "decimal128" };
549
+ case "string":
550
+ return { type: "string" };
551
+ case "boolean":
552
+ return { type: "boolean" };
553
+ case "plainDate":
554
+ return { type: "string", format: "date" };
555
+ case "utcDateTime":
556
+ case "offsetDateTime":
557
+ return { type: "string", format: "date-time" };
558
+ case "plainTime":
559
+ return { type: "string", format: "time" };
560
+ case "duration":
561
+ return { type: "string", format: "duration" };
562
+ case "url":
563
+ return { type: "string", format: "uri" };
564
+ default:
565
+ const _assertNever = scalar.name;
566
+ return {};
567
+ }
568
+ }
569
+ #applyConstraints(type, original) {
570
+ const schema = new ObjectBuilder(original);
571
+ const program = this.emitter.getProgram();
572
+ const applyConstraint = (fn, key) => {
573
+ const value = fn(program, type);
574
+ if (value !== undefined) {
575
+ schema[key] = value;
576
+ }
577
+ };
578
+ applyConstraint(getMinLength, "minLength");
579
+ applyConstraint(getMaxLength, "maxLength");
580
+ applyConstraint(getMinValue, "minimum");
581
+ applyConstraint(getMaxValue, "maximum");
582
+ applyConstraint(getPattern, "pattern");
583
+ applyConstraint(getMinItems, "minItems");
584
+ applyConstraint(getMaxItems, "maxItems");
585
+ const minValueExclusive = getMinValueExclusive(program, type);
586
+ if (minValueExclusive !== undefined) {
587
+ schema.minimum = minValueExclusive;
588
+ schema.exclusiveMinimum = true;
589
+ }
590
+ const maxValueExclusive = getMaxValueExclusive(program, type);
591
+ if (maxValueExclusive !== undefined) {
592
+ schema.maximum = maxValueExclusive;
593
+ schema.exclusiveMaximum = true;
594
+ }
595
+ if (isSecret(program, type)) {
596
+ schema.format = "password";
597
+ }
598
+ // the stdlib applies a format of "url" but json schema wants "uri",
599
+ // so ignore this format if it's the built-in type.
600
+ if (!this.#isStdType(type) || type.name !== "url") {
601
+ applyConstraint(getFormat, "format");
602
+ }
603
+ applyConstraint(getDoc, "description");
604
+ applyConstraint(getSummary, "title");
605
+ applyConstraint((p, t) => (getDeprecated(p, t) !== undefined ? true : undefined), "deprecated");
606
+ this.#attachExtensions(program, type, schema);
607
+ const values = getKnownValues(program, type);
608
+ if (values) {
609
+ return new ObjectBuilder({
610
+ oneOf: [schema, this.#enumSchema(values)],
611
+ });
612
+ }
613
+ return new ObjectBuilder(schema);
614
+ }
615
+ #inlineType(type, schema) {
616
+ if (this.#options.includeXTypeSpecName !== "never") {
617
+ schema.set("x-typespec-name", getTypeName(type, this.#typeNameOptions()));
618
+ }
619
+ return schema;
620
+ }
621
+ #createDeclaration(type, name, schema) {
622
+ const refUrl = getRef(this.emitter.getProgram(), type);
623
+ if (refUrl) {
624
+ return {
625
+ $ref: refUrl,
626
+ };
627
+ }
628
+ if (shouldInline(this.emitter.getProgram(), type)) {
629
+ return this.#inlineType(type, schema);
630
+ }
631
+ const title = getSummary(this.emitter.getProgram(), type);
632
+ if (title) {
633
+ schema.set("title", title);
634
+ }
635
+ const usage = this.#visibilityUsage.getUsage(type);
636
+ const shouldAddSuffix = usage !== undefined && usage.size > 1;
637
+ const visibility = this.#getVisibilityContext();
638
+ const fullName = name + (shouldAddSuffix ? getVisibilitySuffix(visibility, Visibility.Read) : "");
639
+ const decl = this.emitter.result.declaration(fullName, schema);
640
+ checkDuplicateTypeName(this.emitter.getProgram(), type, fullName, Object.fromEntries(decl.scope.declarations.map((x) => [x.name, true])));
641
+ return decl;
642
+ }
643
+ #isStdType(type) {
644
+ return this.emitter.getProgram().checker.isStdType(type);
645
+ }
646
+ #applyEncoding(typespecType, target) {
647
+ const encodeData = getEncode(this.emitter.getProgram(), typespecType);
648
+ if (encodeData) {
649
+ const newTarget = new ObjectBuilder(target);
650
+ const newType = this.#getSchemaForStdScalars(encodeData.type);
651
+ newTarget.type = newType.type;
652
+ // If the target already has a format it takes priority. (e.g. int32)
653
+ newTarget.format = this.#mergeFormatAndEncoding(newTarget.format, encodeData.encoding, newType.format);
654
+ return newTarget;
655
+ }
656
+ const result = new ObjectBuilder(target);
657
+ return result;
658
+ }
659
+ #mergeFormatAndEncoding(format, encoding, encodeAsFormat) {
660
+ switch (format) {
661
+ case undefined:
662
+ return encodeAsFormat ?? encoding;
663
+ case "date-time":
664
+ switch (encoding) {
665
+ case "rfc3339":
666
+ return "date-time";
667
+ case "unixTimestamp":
668
+ return "unixtime";
669
+ case "rfc7231":
670
+ return "http-date";
671
+ default:
672
+ return encoding;
673
+ }
674
+ case "duration":
675
+ switch (encoding) {
676
+ case "ISO8601":
677
+ return "duration";
678
+ default:
679
+ return encodeAsFormat ?? encoding;
680
+ }
681
+ default:
682
+ return encodeAsFormat ?? encoding;
683
+ }
684
+ }
318
685
  intrinsic(intrinsic, name) {
319
686
  switch (name) {
320
687
  case "unknown":
@@ -334,372 +701,6 @@ export class OpenAPI3SchemaEmitter extends TypeEmitter {
334
701
  return { scope: sourceFile.globalScope };
335
702
  }
336
703
  }
337
- _OpenAPI3SchemaEmitter_metadataInfo = new WeakMap(), _OpenAPI3SchemaEmitter_visibilityUsage = new WeakMap(), _OpenAPI3SchemaEmitter_options = new WeakMap(), _OpenAPI3SchemaEmitter_instances = new WeakSet(), _OpenAPI3SchemaEmitter_applyExternalDocs = function _OpenAPI3SchemaEmitter_applyExternalDocs(typespecType, target) {
338
- const externalDocs = getExternalDocs(this.emitter.getProgram(), typespecType);
339
- if (externalDocs) {
340
- target.externalDocs = externalDocs;
341
- }
342
- }, _OpenAPI3SchemaEmitter_typeNameOptions = function _OpenAPI3SchemaEmitter_typeNameOptions() {
343
- const serviceNamespaceName = this.emitter.getContext().serviceNamespaceName;
344
- return {
345
- // shorten type names by removing TypeSpec and service namespace
346
- namespaceFilter(ns) {
347
- const name = getNamespaceFullName(ns);
348
- return name !== serviceNamespaceName;
349
- },
350
- };
351
- }, _OpenAPI3SchemaEmitter_getVisibilityContext = function _OpenAPI3SchemaEmitter_getVisibilityContext() {
352
- var _a;
353
- return (_a = this.emitter.getContext().visibility) !== null && _a !== void 0 ? _a : Visibility.Read;
354
- }, _OpenAPI3SchemaEmitter_getContentType = function _OpenAPI3SchemaEmitter_getContentType() {
355
- var _a;
356
- return (_a = this.emitter.getContext().contentType) !== null && _a !== void 0 ? _a : "application/json";
357
- }, _OpenAPI3SchemaEmitter_requiredModelProperties = function _OpenAPI3SchemaEmitter_requiredModelProperties(model, visibility) {
358
- const requiredProps = [];
359
- for (const prop of model.properties.values()) {
360
- if (isNeverType(prop.type)) {
361
- // If the property has a type of 'never', don't include it in the schema
362
- continue;
363
- }
364
- if (!__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_metadataInfo, "f").isPayloadProperty(prop, visibility)) {
365
- continue;
366
- }
367
- if (!__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_metadataInfo, "f").isOptional(prop, visibility)) {
368
- const encodedName = resolveEncodedName(this.emitter.getProgram(), prop, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this));
369
- requiredProps.push(encodedName);
370
- }
371
- }
372
- return requiredProps.length > 0 ? requiredProps : undefined;
373
- }, _OpenAPI3SchemaEmitter_isBytesKeptRaw = function _OpenAPI3SchemaEmitter_isBytesKeptRaw(type) {
374
- const program = this.emitter.getProgram();
375
- return (type.kind === "Scalar" && type.name === "bytes" && getEncode(program, type) === undefined);
376
- }, _OpenAPI3SchemaEmitter_enumSchema = function _OpenAPI3SchemaEmitter_enumSchema(en) {
377
- var _a;
378
- const program = this.emitter.getProgram();
379
- if (en.members.size === 0) {
380
- reportDiagnostic(program, { code: "empty-enum", target: en });
381
- return {};
382
- }
383
- const enumTypes = new Set();
384
- const enumValues = new Set();
385
- for (const member of en.members.values()) {
386
- enumTypes.add(typeof member.value === "number" ? "number" : "string");
387
- enumValues.add((_a = member.value) !== null && _a !== void 0 ? _a : member.name);
388
- }
389
- if (enumTypes.size > 1) {
390
- reportDiagnostic(program, { code: "enum-unique-type", target: en });
391
- }
392
- const schema = { type: enumTypes.values().next().value, enum: [...enumValues] };
393
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, en, schema);
394
- }, _OpenAPI3SchemaEmitter_unionSchema = function _OpenAPI3SchemaEmitter_unionSchema(union) {
395
- const program = this.emitter.getProgram();
396
- if (union.variants.size === 0) {
397
- reportDiagnostic(program, { code: "empty-union", target: union });
398
- return new ObjectBuilder({});
399
- }
400
- const variants = Array.from(union.variants.values());
401
- const literalVariantEnumByType = {};
402
- const ofType = getOneOf(program, union) ? "oneOf" : "anyOf";
403
- const schemaMembers = [];
404
- let nullable = false;
405
- const discriminator = getDiscriminator(program, union);
406
- const isMultipart = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getContentType).call(this).startsWith("multipart/");
407
- for (const variant of variants) {
408
- if (isNullType(variant.type)) {
409
- nullable = true;
410
- continue;
411
- }
412
- if (isMultipart && __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isBytesKeptRaw).call(this, variant.type)) {
413
- schemaMembers.push({ schema: { type: "string", format: "binary" }, type: variant.type });
414
- continue;
415
- }
416
- if (isLiteralType(variant.type)) {
417
- if (!literalVariantEnumByType[variant.type.kind]) {
418
- const enumValue = [variant.type.value];
419
- literalVariantEnumByType[variant.type.kind] = enumValue;
420
- schemaMembers.push({
421
- schema: { type: literalType(variant.type), enum: enumValue },
422
- type: null,
423
- });
424
- }
425
- else {
426
- literalVariantEnumByType[variant.type.kind].push(variant.type.value);
427
- }
428
- }
429
- else {
430
- const enumSchema = this.emitter.emitTypeReference(variant.type, {
431
- referenceContext: isMultipart ? { contentType: "application/json" } : {},
432
- });
433
- compilerAssert(enumSchema.kind === "code", "Unexpected enum schema. Should be kind: code");
434
- schemaMembers.push({ schema: enumSchema.value, type: variant.type });
435
- }
436
- }
437
- if (schemaMembers.length === 0) {
438
- if (nullable) {
439
- // This union is equivalent to just `null` but OA3 has no way to specify
440
- // null as a value, so we throw an error.
441
- reportDiagnostic(program, { code: "union-null", target: union });
442
- return new ObjectBuilder({});
443
- }
444
- else {
445
- // completely empty union can maybe only happen with bugs?
446
- compilerAssert(false, "Attempting to emit an empty union");
447
- }
448
- }
449
- if (schemaMembers.length === 1) {
450
- // we can just return the single schema member after applying nullable
451
- const schema = schemaMembers[0].schema;
452
- const type = schemaMembers[0].type;
453
- const additionalProps = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, union, {});
454
- if (nullable) {
455
- additionalProps.nullable = true;
456
- }
457
- if (Object.keys(additionalProps).length === 0) {
458
- return new ObjectBuilder(schema);
459
- }
460
- else {
461
- if ((schema instanceof Placeholder || "$ref" in schema) &&
462
- !(type && shouldInline(program, type))) {
463
- if (type && type.kind === "Model") {
464
- return new ObjectBuilder({
465
- type: "object",
466
- allOf: B.array([schema]),
467
- ...additionalProps,
468
- });
469
- }
470
- else {
471
- return new ObjectBuilder({ oneOf: B.array([schema]), ...additionalProps });
472
- }
473
- }
474
- else {
475
- const merged = new ObjectBuilder(schema);
476
- for (const [key, value] of Object.entries(additionalProps)) {
477
- merged.set(key, value);
478
- }
479
- return merged;
480
- }
481
- }
482
- }
483
- const schema = {
484
- [ofType]: schemaMembers.map((m) => m.schema),
485
- };
486
- if (nullable) {
487
- schema.nullable = true;
488
- }
489
- if (discriminator) {
490
- // the decorator validates that all the variants will be a model type
491
- // with the discriminator field present.
492
- schema.discriminator = { ...discriminator };
493
- // Diagnostic already reported in compiler for unions
494
- const discriminatedUnion = ignoreDiagnostics(getDiscriminatedUnion(union, discriminator));
495
- if (discriminatedUnion.variants.size > 0) {
496
- schema.discriminator.mapping = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getDiscriminatorMapping).call(this, discriminatedUnion);
497
- }
498
- }
499
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, union, schema);
500
- }, _OpenAPI3SchemaEmitter_getDiscriminatorMapping = function _OpenAPI3SchemaEmitter_getDiscriminatorMapping(union) {
501
- const mapping = {};
502
- for (const [key, model] of union.variants.entries()) {
503
- const ref = this.emitter.emitTypeReference(model);
504
- compilerAssert(ref.kind === "code", "Unexpected ref schema. Should be kind: code");
505
- mapping[key] = ref.value.$ref;
506
- }
507
- return mapping;
508
- }, _OpenAPI3SchemaEmitter_attachExtensions = function _OpenAPI3SchemaEmitter_attachExtensions(program, type, emitObject) {
509
- // Attach any OpenAPI extensions
510
- const extensions = getExtensions(program, type);
511
- if (extensions) {
512
- for (const key of extensions.keys()) {
513
- emitObject[key] = extensions.get(key);
514
- }
515
- }
516
- }, _OpenAPI3SchemaEmitter_getSchemaForScalar = function _OpenAPI3SchemaEmitter_getSchemaForScalar(scalar) {
517
- let result = {};
518
- const isStd = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isStdType).call(this, scalar);
519
- if (isStd) {
520
- result = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getSchemaForStdScalars).call(this, scalar);
521
- }
522
- else if (scalar.baseScalar) {
523
- result = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getSchemaForScalar).call(this, scalar.baseScalar);
524
- }
525
- const withDecorators = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyEncoding).call(this, scalar, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_applyConstraints).call(this, scalar, result));
526
- if (isStd) {
527
- // Standard types are going to be inlined in the spec and we don't want the description of the scalar to show up
528
- delete withDecorators.description;
529
- }
530
- return withDecorators;
531
- }, _OpenAPI3SchemaEmitter_getSchemaForStdScalars = function _OpenAPI3SchemaEmitter_getSchemaForStdScalars(scalar) {
532
- switch (scalar.name) {
533
- case "bytes":
534
- return { type: "string", format: "byte" };
535
- case "numeric":
536
- return { type: "number" };
537
- case "integer":
538
- return { type: "integer" };
539
- case "int8":
540
- return { type: "integer", format: "int8" };
541
- case "int16":
542
- return { type: "integer", format: "int16" };
543
- case "int32":
544
- return { type: "integer", format: "int32" };
545
- case "int64":
546
- return { type: "integer", format: "int64" };
547
- case "safeint":
548
- switch (__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_options, "f").safeintStrategy) {
549
- case "double-int":
550
- return { type: "integer", format: "double-int" };
551
- case "int64":
552
- default:
553
- return { type: "integer", format: "int64" };
554
- }
555
- case "uint8":
556
- return { type: "integer", format: "uint8" };
557
- case "uint16":
558
- return { type: "integer", format: "uint16" };
559
- case "uint32":
560
- return { type: "integer", format: "uint32" };
561
- case "uint64":
562
- return { type: "integer", format: "uint64" };
563
- case "float":
564
- return { type: "number" };
565
- case "float64":
566
- return { type: "number", format: "double" };
567
- case "float32":
568
- return { type: "number", format: "float" };
569
- case "decimal":
570
- return { type: "number", format: "decimal" };
571
- case "decimal128":
572
- return { type: "number", format: "decimal128" };
573
- case "string":
574
- return { type: "string" };
575
- case "boolean":
576
- return { type: "boolean" };
577
- case "plainDate":
578
- return { type: "string", format: "date" };
579
- case "utcDateTime":
580
- case "offsetDateTime":
581
- return { type: "string", format: "date-time" };
582
- case "plainTime":
583
- return { type: "string", format: "time" };
584
- case "duration":
585
- return { type: "string", format: "duration" };
586
- case "url":
587
- return { type: "string", format: "uri" };
588
- default:
589
- const _assertNever = scalar.name;
590
- return {};
591
- }
592
- }, _OpenAPI3SchemaEmitter_applyConstraints = function _OpenAPI3SchemaEmitter_applyConstraints(type, original) {
593
- const schema = new ObjectBuilder(original);
594
- const program = this.emitter.getProgram();
595
- const applyConstraint = (fn, key) => {
596
- const value = fn(program, type);
597
- if (value !== undefined) {
598
- schema[key] = value;
599
- }
600
- };
601
- applyConstraint(getMinLength, "minLength");
602
- applyConstraint(getMaxLength, "maxLength");
603
- applyConstraint(getMinValue, "minimum");
604
- applyConstraint(getMaxValue, "maximum");
605
- applyConstraint(getPattern, "pattern");
606
- applyConstraint(getMinItems, "minItems");
607
- applyConstraint(getMaxItems, "maxItems");
608
- const minValueExclusive = getMinValueExclusive(program, type);
609
- if (minValueExclusive !== undefined) {
610
- schema.minimum = minValueExclusive;
611
- schema.exclusiveMinimum = true;
612
- }
613
- const maxValueExclusive = getMaxValueExclusive(program, type);
614
- if (maxValueExclusive !== undefined) {
615
- schema.maximum = maxValueExclusive;
616
- schema.exclusiveMaximum = true;
617
- }
618
- if (isSecret(program, type)) {
619
- schema.format = "password";
620
- }
621
- // the stdlib applies a format of "url" but json schema wants "uri",
622
- // so ignore this format if it's the built-in type.
623
- if (!__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_isStdType).call(this, type) || type.name !== "url") {
624
- applyConstraint(getFormat, "format");
625
- }
626
- applyConstraint(getDoc, "description");
627
- applyConstraint(getSummary, "title");
628
- applyConstraint((p, t) => (getDeprecated(p, t) !== undefined ? true : undefined), "deprecated");
629
- __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_attachExtensions).call(this, program, type, schema);
630
- const values = getKnownValues(program, type);
631
- if (values) {
632
- return new ObjectBuilder({
633
- oneOf: [schema, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_enumSchema).call(this, values)],
634
- });
635
- }
636
- return new ObjectBuilder(schema);
637
- }, _OpenAPI3SchemaEmitter_inlineType = function _OpenAPI3SchemaEmitter_inlineType(type, schema) {
638
- if (__classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_options, "f").includeXTypeSpecName !== "never") {
639
- schema.set("x-typespec-name", getTypeName(type, __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_typeNameOptions).call(this)));
640
- }
641
- return schema;
642
- }, _OpenAPI3SchemaEmitter_createDeclaration = function _OpenAPI3SchemaEmitter_createDeclaration(type, name, schema) {
643
- const refUrl = getRef(this.emitter.getProgram(), type);
644
- if (refUrl) {
645
- return {
646
- $ref: refUrl,
647
- };
648
- }
649
- if (shouldInline(this.emitter.getProgram(), type)) {
650
- return __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_inlineType).call(this, type, schema);
651
- }
652
- const title = getSummary(this.emitter.getProgram(), type);
653
- if (title) {
654
- schema.set("title", title);
655
- }
656
- const usage = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_visibilityUsage, "f").getUsage(type);
657
- const shouldAddSuffix = usage !== undefined && usage.size > 1;
658
- const visibility = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getVisibilityContext).call(this);
659
- const fullName = name + (shouldAddSuffix ? getVisibilitySuffix(visibility, Visibility.Read) : "");
660
- const decl = this.emitter.result.declaration(fullName, schema);
661
- checkDuplicateTypeName(this.emitter.getProgram(), type, fullName, Object.fromEntries(decl.scope.declarations.map((x) => [x.name, true])));
662
- return decl;
663
- }, _OpenAPI3SchemaEmitter_isStdType = function _OpenAPI3SchemaEmitter_isStdType(type) {
664
- return this.emitter.getProgram().checker.isStdType(type);
665
- }, _OpenAPI3SchemaEmitter_applyEncoding = function _OpenAPI3SchemaEmitter_applyEncoding(typespecType, target) {
666
- const encodeData = getEncode(this.emitter.getProgram(), typespecType);
667
- if (encodeData) {
668
- const newTarget = new ObjectBuilder(target);
669
- const newType = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_getSchemaForStdScalars).call(this, encodeData.type);
670
- newTarget.type = newType.type;
671
- // If the target already has a format it takes priority. (e.g. int32)
672
- newTarget.format = __classPrivateFieldGet(this, _OpenAPI3SchemaEmitter_instances, "m", _OpenAPI3SchemaEmitter_mergeFormatAndEncoding).call(this, newTarget.format, encodeData.encoding, newType.format);
673
- return newTarget;
674
- }
675
- const result = new ObjectBuilder(target);
676
- return result;
677
- }, _OpenAPI3SchemaEmitter_mergeFormatAndEncoding = function _OpenAPI3SchemaEmitter_mergeFormatAndEncoding(format, encoding, encodeAsFormat) {
678
- switch (format) {
679
- case undefined:
680
- return encodeAsFormat !== null && encodeAsFormat !== void 0 ? encodeAsFormat : encoding;
681
- case "date-time":
682
- switch (encoding) {
683
- case "rfc3339":
684
- return "date-time";
685
- case "unixTimestamp":
686
- return "unixtime";
687
- case "rfc7231":
688
- return "http-date";
689
- default:
690
- return encoding;
691
- }
692
- case "duration":
693
- switch (encoding) {
694
- case "ISO8601":
695
- return "duration";
696
- default:
697
- return encodeAsFormat !== null && encodeAsFormat !== void 0 ? encodeAsFormat : encoding;
698
- }
699
- default:
700
- return encodeAsFormat !== null && encodeAsFormat !== void 0 ? encodeAsFormat : encoding;
701
- }
702
- };
703
704
  function isLiteralType(type) {
704
705
  return type.kind === "Boolean" || type.kind === "String" || type.kind === "Number";
705
706
  }
@@ -714,10 +715,9 @@ function literalType(type) {
714
715
  }
715
716
  }
716
717
  function includeDerivedModel(model) {
717
- var _a, _b;
718
718
  return (!isTemplateDeclaration(model) &&
719
- (((_a = model.templateMapper) === null || _a === void 0 ? void 0 : _a.args) === undefined ||
720
- ((_b = model.templateMapper.args) === null || _b === void 0 ? void 0 : _b.length) === 0 ||
719
+ (model.templateMapper?.args === undefined ||
720
+ model.templateMapper.args?.length === 0 ||
721
721
  model.derivedModels.length > 0));
722
722
  }
723
723
  const B = {
@@ -737,7 +737,6 @@ const B = {
737
737
  },
738
738
  };
739
739
  export function getDefaultValue(program, type, defaultType) {
740
- var _a;
741
740
  switch (defaultType.kind) {
742
741
  case "String":
743
742
  return defaultType.value;
@@ -762,7 +761,7 @@ export function getDefaultValue(program, type, defaultType) {
762
761
  target: defaultType,
763
762
  });
764
763
  case "EnumMember":
765
- return (_a = defaultType.value) !== null && _a !== void 0 ? _a : defaultType.name;
764
+ return defaultType.value ?? defaultType.name;
766
765
  case "UnionVariant":
767
766
  return getDefaultValue(program, type, defaultType.type);
768
767
  default: