-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathadd-x-ms-enum-value-names.js
142 lines (121 loc) · 3.58 KB
/
add-x-ms-enum-value-names.js
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
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* @copyright Copyright 2019 Kevin Locke <kevin@kevinlocke.name>
* @license MIT
* @module "openapi-transformers/add-x-ms-enum-value-names.js"
*/
import assert from 'node:assert';
import dotnetCase from '@kevinoid/dotnet-identifier-case';
import OpenApiTransformerBase from 'openapi-transformer-base';
assert(/\p{L}/u.test('X'), 'Unicode property escapes are supported.');
function firstToLower(word) {
if (!word) {
return word;
}
// Lower-case 2-letter acronym together (as Autorest does)
if (word.length === 2 && word === word.toUpperCase()) {
return word.toLowerCase();
}
return word.charAt(0).toLowerCase() + word.slice(1);
}
function firstToUpper(word) {
if (!word) {
return word;
}
return word.charAt(0).toUpperCase() + word.slice(1);
}
/** Returns the enum member name which would be used by Autorest.
* https://github.com/Azure/autorest.common/blob/54c21af/src/CodeNamer.cs#L178
*
* @private
*/
function autorestEnumMemberName(value) {
const clean = value.replaceAll(/[^\p{L}\p{N}_-]/gu, '');
const words = clean.split(/[_-]/);
if (clean.charAt(0) === '_') {
// eslint-disable-next-line prefer-template
return '_' + words
.map((word, i) => (i > 0 ? firstToUpper(word) : firstToLower(word)))
.join('');
}
return words
.map(firstToUpper)
.join('');
}
function addXMsEnumValueNamesToSchema(schema) {
if (!schema.enum || !schema['x-ms-enum']) {
// Schema won't generate an enum
return schema;
}
const xMsEnum = schema['x-ms-enum'];
const xMsEnumValues = xMsEnum.values;
if (xMsEnumValues
&& xMsEnumValues.every((v) => v.name !== null && v.name !== undefined)) {
// Names already specified for all values
return schema;
}
const values =
Array.isArray(xMsEnumValues) ? xMsEnumValues.map((v) => v.value)
: schema.enum;
const stringValues = values.map(String);
const autorestNames = stringValues.map(autorestEnumMemberName);
const microsoftNames = stringValues.map(dotnetCase);
let anyNameChanged = false;
let newXMsEnumValues;
if (Array.isArray(xMsEnumValues)) {
newXMsEnumValues = xMsEnumValues.map((xMsEnumValue, i) => {
if (xMsEnumValue.name !== null && xMsEnumValue.name !== undefined) {
return xMsEnumValue;
}
const autorestName = autorestNames[i];
const microsoftName = microsoftNames[i];
if (autorestName === microsoftName) {
return xMsEnumValue;
}
anyNameChanged = true;
return {
...xMsEnumValue,
name: microsoftName,
};
});
} else {
newXMsEnumValues = schema.enum.map((value, i) => {
const autorestName = autorestNames[i];
const microsoftName = microsoftNames[i];
const newXMsEnumValue = { value };
if (autorestName !== microsoftName) {
anyNameChanged = true;
newXMsEnumValue.name = microsoftName;
}
return newXMsEnumValue;
});
}
if (!anyNameChanged) {
return schema;
}
return {
...schema,
'x-ms-enum': {
...xMsEnum,
values: newXMsEnumValues,
},
};
}
/**
* Transformer to add x-ms-enum.values.name to enums where the name generated by
* Autorest differs from the Microsoft C# Capitalization Rules for Identifiers.
*
* https://github.com/Azure/autorest/issues/3328
*/
export default class AddXMsEnumValueNamesTransformer
extends OpenApiTransformerBase {
transformSchema(schema) {
return addXMsEnumValueNamesToSchema(
super.transformSchema(schema),
);
}
transformParameter(parameter) {
return addXMsEnumValueNamesToSchema(
super.transformParameter(parameter),
);
}
}