forked from microsoft/typespec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathencoding.ts
89 lines (82 loc) · 2.84 KB
/
encoding.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
import { ObjectBuilder } from "@typespec/asset-emitter";
import { type ModelProperty, Program, type Scalar, getEncode } from "@typespec/compiler";
import { isHeader, isQueryParam } from "@typespec/http";
import type { ResolvedOpenAPI3EmitterOptions } from "./openapi.js";
import { getSchemaForStdScalars } from "./std-scalar-schemas.js";
import type { OpenAPI3Schema, OpenAPISchema3_1 } from "./types.js";
function isParameterStyleEncoding(encoding: string | undefined): boolean {
if (!encoding) return false;
return ["ArrayEncoding.pipeDelimited", "ArrayEncoding.spaceDelimited"].includes(encoding);
}
export function applyEncoding(
program: Program,
typespecType: Scalar | ModelProperty,
target: OpenAPI3Schema | OpenAPISchema3_1,
getEncodedFieldName: (typespecType: Scalar | ModelProperty) => string,
options: ResolvedOpenAPI3EmitterOptions,
): OpenAPI3Schema & OpenAPISchema3_1 {
const encodedFieldName = getEncodedFieldName(typespecType);
const targetObject = new ObjectBuilder(target);
const encodeData = getEncode(program, typespecType);
if (encodeData) {
// Query parameters have a couple of special cases where encoding ends up as style.
if (isQueryParam(program, typespecType) && isParameterStyleEncoding(encodeData.encoding)) {
return targetObject;
}
const newType = getSchemaForStdScalars(encodeData.type as any, options);
targetObject.type = newType.type;
// If the target already has a format it takes priority. (e.g. int32)
targetObject[encodedFieldName] = mergeFormatAndEncoding(
targetObject[encodedFieldName],
encodeData.encoding,
newType.format,
);
return targetObject;
}
if (isDateTimeHeader(program, typespecType, targetObject, encodedFieldName)) {
targetObject[encodedFieldName] = "http-date";
return targetObject;
}
return targetObject;
}
function mergeFormatAndEncoding(
format: string | undefined,
encoding: string | undefined,
encodeAsFormat: string | undefined,
): string | undefined {
switch (format) {
case undefined:
return encodeAsFormat ?? encoding ?? format;
case "date-time":
switch (encoding) {
case "rfc3339":
return "date-time";
case "unixTimestamp":
return "unixtime";
case "rfc7231":
return "http-date";
default:
return encoding;
}
case "duration":
switch (encoding) {
case "ISO8601":
return "duration";
default:
return encodeAsFormat ?? encoding;
}
default:
return encodeAsFormat ?? encoding ?? format;
}
}
function isDateTimeHeader(
program: Program,
typespecType: Scalar | ModelProperty,
target: ObjectBuilder<any>,
encodedFieldName: string,
): boolean {
if (isHeader(program, typespecType) && target[encodedFieldName] === "date-time") {
return true;
}
return false;
}