microsoft/typespec

Public

mirrored from https://github.com/microsoft/typespecAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
e07d86c87a444d4145b98d85fa416eca819e251c

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

packages/openapi/src/helpers.ts

133lines · modecode

1import {
2 getFriendlyName,
3 getServiceNamespace,
4 isGlobalNamespace,
5 isTemplateInstance,
6 ModelProperty,
7 Operation,
8 Program,
9 Type,
10 TypeNameOptions,
11} from "@cadl-lang/compiler";
12import { getOperationId } from "./decorators.js";
13import { reportDiagnostic } from "./lib.js";
14
15/**
16 * Determines whether a type will be inlined in OpenAPI rather than defined
17 * as a schema and referenced.
18 *
19 * All anonymous types (anonymous models, arrays, tuples, etc.) are inlined.
20 *
21 * Template instantiations are inlined unless they have a friendly name.
22 *
23 * A friendly name can be provided by the user using `@friendlyName`
24 * decorator, or chosen by default in simple cases.
25 */
26export function shouldInline(program: Program, type: Type): boolean {
27 if (getFriendlyName(program, type)) {
28 return false;
29 }
30 switch (type.kind) {
31 case "Model":
32 return !type.name || isTemplateInstance(type);
33 case "Enum":
34 case "Union":
35 return !type.name;
36 default:
37 return true;
38 }
39}
40
41/**
42 * Gets the name of a type to be used in OpenAPI.
43 *
44 * For inlined types: this is the Cadl-native name written to `x-cadl-name`.
45 *
46 * For non-inlined types: this is either the friendly name or the Cadl-native name.
47 *
48 * Cadl-native names are shortened to exclude root `Cadl` namespace and service
49 * namespace using the provided `TypeNameOptions`.
50 */
51export function getTypeName(
52 program: Program,
53 type: Type,
54 options: TypeNameOptions,
55 existing?: Record<string, any>
56): string {
57 const name = getFriendlyName(program, type) ?? program.checker.getTypeName(type, options);
58
59 if (existing && existing[name]) {
60 reportDiagnostic(program, {
61 code: "duplicate-type-name",
62 format: {
63 value: name,
64 },
65 target: type,
66 });
67 }
68
69 return name;
70}
71
72/**
73 * Gets the key that is used to define a parameter in OpenAPI.
74 */
75export function getParameterKey(
76 program: Program,
77 propery: ModelProperty,
78 newParam: unknown,
79 existingParams: Record<string, unknown>,
80 options: TypeNameOptions
81): string {
82 const parent = propery.model!;
83 let key = getTypeName(program, parent, options);
84
85 if (parent.properties.size > 1) {
86 key += `.${propery.name}`;
87 }
88
89 // JSON check is workaround for https://github.com/microsoft/cadl/issues/462
90 if (existingParams[key] && JSON.stringify(newParam) !== JSON.stringify(existingParams[key])) {
91 reportDiagnostic(program, {
92 code: "duplicate-type-name",
93 messageId: "parameter",
94 format: {
95 value: key,
96 },
97 target: propery,
98 });
99 }
100
101 return key;
102}
103
104/**
105 * Resolve the OpenAPI operation ID for the given operation using the following logic:
106 * - If @operationId was specified use that value
107 * - If operation is defined at the root or under the service namespace return <operation.name>
108 * - Otherwise(operation is under another namespace or interface) return <namespace/interface.name>_<opration.name>
109 *
110 * @param program Cadl Program
111 * @param operation Operation
112 * @returns Operation ID in this format <name> or <group>_<name>
113 */
114export function resolveOperationId(program: Program, operation: Operation) {
115 const explicitOperationId = getOperationId(program, operation);
116 if (explicitOperationId) {
117 return explicitOperationId;
118 }
119
120 if (operation.interface) {
121 return `${operation.interface.name}_${operation.name}`;
122 }
123 const namespace = operation.namespace;
124 if (
125 namespace === undefined ||
126 isGlobalNamespace(program, namespace) ||
127 namespace === getServiceNamespace(program)
128 ) {
129 return operation.name;
130 }
131
132 return `${namespace.name}_${operation.name}`;
133}
134