@azure-tools/typespec-ts 0.56.1-dev.1 → 0.57.0-dev.10
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.
- package/README.md +6 -0
- package/dist/src/framework/hooks/sdk-types.d.ts.map +1 -1
- package/dist/src/framework/hooks/sdk-types.js +2 -0
- package/dist/src/framework/hooks/sdk-types.js.map +1 -1
- package/dist/src/interfaces.d.ts +4 -0
- package/dist/src/interfaces.d.ts.map +1 -1
- package/dist/src/interfaces.js.map +1 -1
- package/dist/src/lib.d.ts +11 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +11 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/metadata/build-package-file.d.ts +1 -0
- package/dist/src/metadata/build-package-file.d.ts.map +1 -1
- package/dist/src/metadata/build-package-file.js +3 -0
- package/dist/src/metadata/build-package-file.js.map +1 -1
- package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts +2 -0
- package/dist/src/metadata/package-json/build-azure-monorepo-package.d.ts.map +1 -1
- package/dist/src/metadata/package-json/build-azure-monorepo-package.js +1 -0
- package/dist/src/metadata/package-json/build-azure-monorepo-package.js.map +1 -1
- package/dist/src/modular/build-classical-client.d.ts.map +1 -1
- package/dist/src/modular/build-classical-client.js +19 -33
- package/dist/src/modular/build-classical-client.js.map +1 -1
- package/dist/src/modular/build-operations.d.ts.map +1 -1
- package/dist/src/modular/build-operations.js +4 -5
- package/dist/src/modular/build-operations.js.map +1 -1
- package/dist/src/modular/build-root-index.js +1 -1
- package/dist/src/modular/build-root-index.js.map +1 -1
- package/dist/src/modular/emit-models.d.ts.map +1 -1
- package/dist/src/modular/emit-models.js +46 -23
- package/dist/src/modular/emit-models.js.map +1 -1
- package/dist/src/modular/emit-samples.d.ts.map +1 -1
- package/dist/src/modular/emit-samples.js +29 -21
- package/dist/src/modular/emit-samples.js.map +1 -1
- package/dist/src/modular/emit-tests.js +2 -2
- package/dist/src/modular/emit-tests.js.map +1 -1
- package/dist/src/modular/helpers/classical-operation-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/classical-operation-helpers.js +17 -15
- package/dist/src/modular/helpers/classical-operation-helpers.js.map +1 -1
- package/dist/src/modular/helpers/client-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/client-helpers.js +7 -6
- package/dist/src/modular/helpers/client-helpers.js.map +1 -1
- package/dist/src/modular/helpers/example-value-helpers.d.ts +2 -1
- package/dist/src/modular/helpers/example-value-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/example-value-helpers.js +34 -24
- package/dist/src/modular/helpers/example-value-helpers.js.map +1 -1
- package/dist/src/modular/helpers/naming-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/naming-helpers.js +3 -3
- package/dist/src/modular/helpers/naming-helpers.js.map +1 -1
- package/dist/src/modular/helpers/operation-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operation-helpers.js +23 -18
- package/dist/src/modular/helpers/operation-helpers.js.map +1 -1
- package/dist/src/modular/helpers/type-helpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/type-helpers.js +2 -2
- package/dist/src/modular/helpers/type-helpers.js.map +1 -1
- package/dist/src/modular/helpers/visibility-helpers.d.ts +7 -0
- package/dist/src/modular/helpers/visibility-helpers.d.ts.map +1 -0
- package/dist/src/modular/helpers/visibility-helpers.js +353 -0
- package/dist/src/modular/helpers/visibility-helpers.js.map +1 -0
- package/dist/src/modular/serialization/build-deserializer-function.js +6 -4
- package/dist/src/modular/serialization/build-deserializer-function.js.map +1 -1
- package/dist/src/modular/serialization/build-serializer-function.d.ts.map +1 -1
- package/dist/src/modular/serialization/build-serializer-function.js +9 -7
- package/dist/src/modular/serialization/build-serializer-function.js.map +1 -1
- package/dist/src/modular/serialization/build-xml-serializer-function.d.ts.map +1 -1
- package/dist/src/modular/serialization/build-xml-serializer-function.js +11 -13
- package/dist/src/modular/serialization/build-xml-serializer-function.js.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.d.ts +1 -0
- package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js +6 -4
- package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
- package/dist/src/transform/transform-client-options.d.ts.map +1 -1
- package/dist/src/transform/transform-client-options.js +2 -0
- package/dist/src/transform/transform-client-options.js.map +1 -1
- package/dist/src/utils/client-utils.d.ts.map +1 -1
- package/dist/src/utils/client-utils.js +16 -5
- package/dist/src/utils/client-utils.js.map +1 -1
- package/dist/src/utils/cross-language-def.d.ts.map +1 -1
- package/dist/src/utils/cross-language-def.js +1 -2
- package/dist/src/utils/cross-language-def.js.map +1 -1
- package/dist/src/utils/interfaces.d.ts +1 -0
- package/dist/src/utils/interfaces.d.ts.map +1 -1
- package/dist/src/utils/name-utils.d.ts +15 -0
- package/dist/src/utils/name-utils.d.ts.map +1 -1
- package/dist/src/utils/name-utils.js +60 -0
- package/dist/src/utils/name-utils.js.map +1 -1
- package/dist/src/utils/operation-util.d.ts.map +1 -1
- package/dist/src/utils/operation-util.js +15 -5
- package/dist/src/utils/operation-util.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +35 -35
- package/src/framework/hooks/sdk-types.ts +2 -0
- package/src/interfaces.ts +4 -0
- package/src/lib.ts +13 -0
- package/src/metadata/build-package-file.ts +4 -0
- package/src/metadata/package-json/build-azure-monorepo-package.ts +1 -0
- package/src/modular/build-classical-client.ts +21 -32
- package/src/modular/build-operations.ts +4 -5
- package/src/modular/build-root-index.ts +1 -1
- package/src/modular/emit-models.ts +59 -24
- package/src/modular/emit-samples.ts +42 -34
- package/src/modular/emit-tests.ts +2 -2
- package/src/modular/helpers/classical-operation-helpers.ts +21 -20
- package/src/modular/helpers/client-helpers.ts +6 -5
- package/src/modular/helpers/example-value-helpers.ts +52 -41
- package/src/modular/helpers/naming-helpers.ts +8 -3
- package/src/modular/helpers/operation-helpers.ts +31 -18
- package/src/modular/helpers/type-helpers.ts +2 -5
- package/src/modular/helpers/visibility-helpers.ts +471 -0
- package/src/modular/serialization/build-deserializer-function.ts +6 -9
- package/src/modular/serialization/build-serializer-function.ts +14 -11
- package/src/modular/serialization/build-xml-serializer-function.ts +11 -17
- package/src/modular/type-expressions/get-type-expression.ts +10 -4
- package/src/transform/transform-client-options.ts +3 -0
- package/src/utils/client-utils.ts +28 -4
- package/src/utils/cross-language-def.ts +1 -2
- package/src/utils/interfaces.ts +1 -0
- package/src/utils/name-utils.ts +94 -0
- package/src/utils/operation-util.ts +27 -14
- package/static/static-helpers/storageCompatResponse.ts +3 -2
- package/static/static-helpers/urlTemplate.ts +4 -2
|
@@ -16,7 +16,12 @@ import { refkey } from "../../framework/refkey.js";
|
|
|
16
16
|
import { reportDiagnostic } from "../../lib.js";
|
|
17
17
|
import type { SdkContext } from "../../utils/interfaces.js";
|
|
18
18
|
import { isAzureCoreErrorType } from "../../utils/model-utils.js";
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
formatPropertyAccess,
|
|
21
|
+
NameType,
|
|
22
|
+
normalizeName,
|
|
23
|
+
normalizeSdkPropertyName,
|
|
24
|
+
} from "../../utils/name-utils.js";
|
|
20
25
|
import { getAdditionalPropertiesName, normalizeModelName } from "../emit-models.js";
|
|
21
26
|
import {
|
|
22
27
|
getAllAncestors,
|
|
@@ -185,7 +190,6 @@ function buildPolymorphicSerializer(
|
|
|
185
190
|
) {
|
|
186
191
|
return;
|
|
187
192
|
}
|
|
188
|
-
const union = subType?.discriminatedSubtypes ? "_Union" : "";
|
|
189
193
|
if (!subType || !subType?.name) {
|
|
190
194
|
reportDiagnostic(context.program, {
|
|
191
195
|
code: "anonymous-type-serialization",
|
|
@@ -193,13 +197,12 @@ function buildPolymorphicSerializer(
|
|
|
193
197
|
});
|
|
194
198
|
return; // Skip this subtype
|
|
195
199
|
}
|
|
196
|
-
const
|
|
197
|
-
const subTypeName =
|
|
198
|
-
const subtypeSerializerName =
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
);
|
|
200
|
+
const union = subType.discriminatedSubtypes ? "Union" : "";
|
|
201
|
+
const subTypeName = normalizeModelName(context, subType, NameType.Interface, !union);
|
|
202
|
+
const subtypeSerializerName = buildModelSerializer(context, subType, {
|
|
203
|
+
nameOnly: true,
|
|
204
|
+
skipDiscriminatedUnionSuffix: false,
|
|
205
|
+
}) as string;
|
|
203
206
|
|
|
204
207
|
cases.push(`
|
|
205
208
|
case "${discriminatedValue}":
|
|
@@ -208,7 +211,7 @@ function buildPolymorphicSerializer(
|
|
|
208
211
|
});
|
|
209
212
|
|
|
210
213
|
statements.push(`
|
|
211
|
-
switch (
|
|
214
|
+
switch (${formatPropertyAccess("item", normalizeSdkPropertyName(type.discriminatorProperty))}) {
|
|
212
215
|
${cases.join("\n")}
|
|
213
216
|
default:
|
|
214
217
|
return item;
|
|
@@ -281,7 +284,7 @@ function buildDiscriminatedUnionSerializer(
|
|
|
281
284
|
`);
|
|
282
285
|
}
|
|
283
286
|
output.push(`
|
|
284
|
-
switch (item
|
|
287
|
+
switch (${formatPropertyAccess("item", type.discriminatorProperty ? normalizeSdkPropertyName(type.discriminatorProperty) : "unknown")}) {
|
|
285
288
|
${cases.join("\n")}
|
|
286
289
|
default:
|
|
287
290
|
return ${baseSerializerName}(item);
|
|
@@ -23,7 +23,7 @@ import { getAdditionalPropertiesName, normalizeModelName } from "../emit-models.
|
|
|
23
23
|
import { getAllAncestors, getAllProperties } from "../helpers/operation-helpers.js";
|
|
24
24
|
import { getAdditionalPropertiesType } from "../helpers/type-helpers.js";
|
|
25
25
|
import { XmlHelpers } from "../static-helpers-metadata.js";
|
|
26
|
-
import {
|
|
26
|
+
import { getModelPropertyName } from "../type-expressions/get-type-expression.js";
|
|
27
27
|
import { isSupportedSerializeType, type ModelSerializeOptions } from "./serialize-utils.js";
|
|
28
28
|
|
|
29
29
|
/**
|
|
@@ -290,8 +290,8 @@ function buildXmlObjectPropertyAssignments(
|
|
|
290
290
|
}
|
|
291
291
|
|
|
292
292
|
const xmlOptions = property.serializationOptions?.xml;
|
|
293
|
-
const propertyName =
|
|
294
|
-
const
|
|
293
|
+
const propertyName = getModelPropertyName(context, property);
|
|
294
|
+
const propertyAccessor = `item[${JSON.stringify(propertyName)}]`;
|
|
295
295
|
|
|
296
296
|
// Use XML name if available, fall back to serializedName, then JSON name, then property name
|
|
297
297
|
const xmlName = xmlOptions?.name ?? property.name;
|
|
@@ -302,14 +302,14 @@ function buildXmlObjectPropertyAssignments(
|
|
|
302
302
|
let valueExpr: string;
|
|
303
303
|
if (nestedSerializer && property.type.kind === "model") {
|
|
304
304
|
// Nested object - use XML object serializer
|
|
305
|
-
valueExpr =
|
|
305
|
+
valueExpr = `${propertyAccessor} !== undefined ? ${nestedSerializer}(${propertyAccessor}) : undefined`;
|
|
306
306
|
} else if (
|
|
307
307
|
nestedSerializer &&
|
|
308
308
|
property.type.kind === "array" &&
|
|
309
309
|
property.type.valueType.kind === "model"
|
|
310
310
|
) {
|
|
311
311
|
// Array of objects - map each item through XML object serializer
|
|
312
|
-
const mappedExpr =
|
|
312
|
+
const mappedExpr = `${propertyAccessor}?.map((i: any) => ${nestedSerializer}(i))`;
|
|
313
313
|
if (xmlOptions?.unwrapped) {
|
|
314
314
|
// Unwrapped: items are direct siblings under the item element name
|
|
315
315
|
const itemKey = xmlOptions?.itemsName ?? xmlName;
|
|
@@ -326,7 +326,7 @@ function buildXmlObjectPropertyAssignments(
|
|
|
326
326
|
const primitiveExpr = buildXmlValueSerializationExpr(
|
|
327
327
|
context,
|
|
328
328
|
property.type,
|
|
329
|
-
|
|
329
|
+
propertyAccessor,
|
|
330
330
|
);
|
|
331
331
|
if (xmlOptions?.unwrapped) {
|
|
332
332
|
const itemKey = xmlOptions?.itemsName ?? xmlName;
|
|
@@ -339,11 +339,7 @@ function buildXmlObjectPropertyAssignments(
|
|
|
339
339
|
}
|
|
340
340
|
} else {
|
|
341
341
|
// Handle type-specific serialization
|
|
342
|
-
valueExpr = buildXmlValueSerializationExpr(
|
|
343
|
-
context,
|
|
344
|
-
property.type,
|
|
345
|
-
`item["${cleanPropertyName}"]`,
|
|
346
|
-
);
|
|
342
|
+
valueExpr = buildXmlValueSerializationExpr(context, property.type, propertyAccessor);
|
|
347
343
|
}
|
|
348
344
|
|
|
349
345
|
assignments.push(`"${xmlName}": ${valueExpr}`);
|
|
@@ -419,14 +415,13 @@ function buildPropertyMetadataArray(
|
|
|
419
415
|
|
|
420
416
|
const xmlOptions = property.serializationOptions?.xml;
|
|
421
417
|
const jsonOptions = property.serializationOptions?.json;
|
|
422
|
-
const propertyName =
|
|
423
|
-
const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
|
|
418
|
+
const propertyName = getModelPropertyName(context, property);
|
|
424
419
|
|
|
425
420
|
// Use XML name if available, fall back to JSON name, then property name
|
|
426
421
|
const serializedName = xmlOptions?.name ?? jsonOptions?.name ?? property.name;
|
|
427
422
|
|
|
428
423
|
const metadataObj: string[] = [
|
|
429
|
-
`propertyName:
|
|
424
|
+
`propertyName: ${JSON.stringify(propertyName)}`,
|
|
430
425
|
`xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`,
|
|
431
426
|
];
|
|
432
427
|
|
|
@@ -737,14 +732,13 @@ function buildDeserializePropertyMetadataArray(
|
|
|
737
732
|
|
|
738
733
|
const xmlOptions = property.serializationOptions?.xml;
|
|
739
734
|
const jsonOptions = property.serializationOptions?.json;
|
|
740
|
-
const propertyName =
|
|
741
|
-
const cleanPropertyName = propertyName.replace(/^"|"$/g, "");
|
|
735
|
+
const propertyName = getModelPropertyName(context, property);
|
|
742
736
|
|
|
743
737
|
// Use XML name if available, fall back to JSON name, then property name
|
|
744
738
|
const serializedName = xmlOptions?.name ?? jsonOptions?.name ?? property.name;
|
|
745
739
|
|
|
746
740
|
const metadataObj: string[] = [
|
|
747
|
-
`propertyName:
|
|
741
|
+
`propertyName: ${JSON.stringify(propertyName)}`,
|
|
748
742
|
`xmlOptions: { name: "${serializedName}"${buildXmlOptionsString(xmlOptions)} }`,
|
|
749
743
|
];
|
|
750
744
|
|
|
@@ -5,7 +5,7 @@ import type {
|
|
|
5
5
|
SdkType,
|
|
6
6
|
} from "@azure-tools/typespec-client-generator-core";
|
|
7
7
|
import type { SdkContext } from "../../utils/interfaces.js";
|
|
8
|
-
import {
|
|
8
|
+
import { normalizeSdkPropertyName } from "../../utils/name-utils.js";
|
|
9
9
|
import { getCredentialExpression } from "./get-credential-expression.js";
|
|
10
10
|
import { getEnumExpression } from "./get-enum-expression.js";
|
|
11
11
|
import { getModelExpression } from "./get-model-expression.js";
|
|
@@ -21,10 +21,16 @@ export function normalizeModelPropertyName(
|
|
|
21
21
|
context: SdkContext,
|
|
22
22
|
property: SdkModelPropertyType | SdkHttpParameter | SdkServiceResponseHeader,
|
|
23
23
|
): string {
|
|
24
|
-
|
|
24
|
+
return JSON.stringify(getModelPropertyName(context, property));
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function getModelPropertyName(
|
|
28
|
+
context: SdkContext,
|
|
29
|
+
property: SdkModelPropertyType | SdkHttpParameter | SdkServiceResponseHeader,
|
|
30
|
+
): string {
|
|
25
31
|
return context.emitterOptions?.ignorePropertyNameNormalize
|
|
26
|
-
?
|
|
27
|
-
:
|
|
32
|
+
? property.name
|
|
33
|
+
: normalizeSdkPropertyName(property);
|
|
28
34
|
}
|
|
29
35
|
|
|
30
36
|
export function getTypeExpression(
|
|
@@ -57,6 +57,8 @@ function extractClientOptions(
|
|
|
57
57
|
const ignoreNullableOnOptional = getIgnoreNullableOnOptional(emitterOptions);
|
|
58
58
|
const wrapNonModelReturn = getWrapNonModelReturn(emitterOptions);
|
|
59
59
|
const isMultiService = (dpgContext.allServiceNamespaces?.length ?? 0) > 1;
|
|
60
|
+
const experimentalSplitModelsByVisibility =
|
|
61
|
+
emitterOptions["experimental-split-models-by-visibility"] === true;
|
|
60
62
|
|
|
61
63
|
return {
|
|
62
64
|
...credentialInfo,
|
|
@@ -85,6 +87,7 @@ function extractClientOptions(
|
|
|
85
87
|
enableStorageCompat,
|
|
86
88
|
treatUnknownAsRecord,
|
|
87
89
|
generateReactNativeTarget,
|
|
90
|
+
experimentalSplitModelsByVisibility,
|
|
88
91
|
};
|
|
89
92
|
}
|
|
90
93
|
|
|
@@ -12,11 +12,12 @@ import {
|
|
|
12
12
|
isTemplateDeclaration,
|
|
13
13
|
isTemplateDeclarationOrInstance,
|
|
14
14
|
type Namespace,
|
|
15
|
+
NoTarget,
|
|
15
16
|
type Operation,
|
|
16
17
|
} from "@typespec/compiler";
|
|
17
18
|
import type { ClientModuleInfo } from "../modular/interfaces.js";
|
|
18
19
|
import type { SdkContext } from "./interfaces.js";
|
|
19
|
-
import { NameType,
|
|
20
|
+
import { NameType, normalizeSdkName, reportInvalidExactName } from "./name-utils.js";
|
|
20
21
|
|
|
21
22
|
export function getClients(dpgContext: SdkContext): SdkClient[] {
|
|
22
23
|
const clients = listClients(dpgContext);
|
|
@@ -116,8 +117,9 @@ export function isMultiEndpointClient(dpgContext: SdkContext): boolean {
|
|
|
116
117
|
|
|
117
118
|
export function getClientModuleInfo(clientMap: [string[], SdkClientType<SdkServiceOperation>]) {
|
|
118
119
|
const [hierarchy, client] = clientMap;
|
|
120
|
+
const clientName = client.name.replace(/Client$/, "");
|
|
119
121
|
const clientModuleInfo: ClientModuleInfo = {
|
|
120
|
-
clientName: `${
|
|
122
|
+
clientName: `${clientName}Context`,
|
|
121
123
|
};
|
|
122
124
|
clientModuleInfo.subfolder = hierarchy.join("/");
|
|
123
125
|
return clientModuleInfo;
|
|
@@ -133,13 +135,33 @@ export function getClientHierarchyMap(
|
|
|
133
135
|
const clients = individualClients.map((client) => {
|
|
134
136
|
return [
|
|
135
137
|
context.sdkPackage.clients.length > 1
|
|
136
|
-
? [
|
|
138
|
+
? [
|
|
139
|
+
normalizeSdkName(client, NameType.File, {
|
|
140
|
+
nameOverride: client.name.replace(/Client$/, ""),
|
|
141
|
+
}),
|
|
142
|
+
]
|
|
137
143
|
: [],
|
|
138
144
|
client,
|
|
139
145
|
];
|
|
140
146
|
}) as [string[], SdkClientType<SdkServiceOperation>][];
|
|
141
147
|
for (let i = 0; i < clients.length; i++) {
|
|
142
148
|
const [hierarchy, client] = clients[i]!;
|
|
149
|
+
reportInvalidExactName(
|
|
150
|
+
context.program,
|
|
151
|
+
client,
|
|
152
|
+
NameType.Class,
|
|
153
|
+
"client",
|
|
154
|
+
client.__raw.type ?? NoTarget,
|
|
155
|
+
);
|
|
156
|
+
for (const parameter of client.clientInitialization.parameters) {
|
|
157
|
+
reportInvalidExactName(
|
|
158
|
+
context.program,
|
|
159
|
+
parameter,
|
|
160
|
+
NameType.Parameter,
|
|
161
|
+
"parameter",
|
|
162
|
+
parameter.__raw ?? NoTarget,
|
|
163
|
+
);
|
|
164
|
+
}
|
|
143
165
|
clientMap.push([hierarchy, client]);
|
|
144
166
|
const childClientsToGenerate = client.children?.filter((child) => {
|
|
145
167
|
return (
|
|
@@ -151,7 +173,9 @@ export function getClientHierarchyMap(
|
|
|
151
173
|
childClientsToGenerate.forEach((child) => {
|
|
152
174
|
const childHierarchy = [
|
|
153
175
|
...hierarchy,
|
|
154
|
-
|
|
176
|
+
normalizeSdkName(child, NameType.File, {
|
|
177
|
+
nameOverride: child.name.replace(/Client$/, ""),
|
|
178
|
+
}),
|
|
155
179
|
];
|
|
156
180
|
clients.push([childHierarchy, child]);
|
|
157
181
|
});
|
|
@@ -48,8 +48,7 @@ export function generateCrossLanguageDefinitionFile(dpgContext: SdkContext): {
|
|
|
48
48
|
}
|
|
49
49
|
} else {
|
|
50
50
|
// e,g., @azure/ai-client!ConnectionsOperations#getConnectionWithSecrets:member": "Azure.AI.Projects.Connections.getConnectionWithSecrets"
|
|
51
|
-
const
|
|
52
|
-
const propertyType = `${normalizeName(rawGroupName, NameType.OperationGroup)}Operations`;
|
|
51
|
+
const propertyType = `${normalizeName(prefixes[0] ?? "", NameType.OperationGroup)}Operations`;
|
|
53
52
|
for (const operation of operations) {
|
|
54
53
|
const { name } = operation;
|
|
55
54
|
const operationName = `${packageName}!${propertyType}#${name}:member`;
|
package/src/utils/interfaces.ts
CHANGED
package/src/utils/name-utils.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
// Copyright (c) Microsoft Corporation.
|
|
2
2
|
// Licensed under the MIT License.
|
|
3
3
|
|
|
4
|
+
import { NoTarget, type DiagnosticTarget, type Program } from "@typespec/compiler";
|
|
5
|
+
import { reportDiagnostic } from "../lib.js";
|
|
6
|
+
|
|
4
7
|
export interface NormalizeNameOption {
|
|
5
8
|
shouldGuard?: boolean;
|
|
6
9
|
customReservedNames?: ReservedName[];
|
|
@@ -8,6 +11,15 @@ export interface NormalizeNameOption {
|
|
|
8
11
|
numberPrefixOverride?: string;
|
|
9
12
|
}
|
|
10
13
|
|
|
14
|
+
export interface NormalizeSdkNameOption extends NormalizeNameOption {
|
|
15
|
+
nameOverride?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export interface SdkName {
|
|
19
|
+
name: string;
|
|
20
|
+
isExactName?: boolean;
|
|
21
|
+
}
|
|
22
|
+
|
|
11
23
|
export interface ReservedName {
|
|
12
24
|
name: string;
|
|
13
25
|
reservedFor: NameType[];
|
|
@@ -208,6 +220,88 @@ export function normalizeName(
|
|
|
208
220
|
return fixLeadingNumber(result, nameType, numberPrefixOverride);
|
|
209
221
|
}
|
|
210
222
|
|
|
223
|
+
export function normalizeSdkName(
|
|
224
|
+
sdkName: SdkName,
|
|
225
|
+
nameType: NameType,
|
|
226
|
+
options: NormalizeSdkNameOption = {},
|
|
227
|
+
): string {
|
|
228
|
+
const { nameOverride, ...normalizeOptions } = options;
|
|
229
|
+
const name = nameOverride ?? sdkName.name;
|
|
230
|
+
if (!sdkName.isExactName) {
|
|
231
|
+
return normalizeName(name, nameType, normalizeOptions);
|
|
232
|
+
}
|
|
233
|
+
return normalizeOptions.shouldGuard && nameType === NameType.Method
|
|
234
|
+
? guardReservedNames(name, nameType, normalizeOptions.customReservedNames)
|
|
235
|
+
: name;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
export function normalizeSdkPropertyName(sdkName: SdkName): string {
|
|
239
|
+
return normalizeSdkName(sdkName, NameType.Property);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function isValidTypeScriptIdentifierName(name: string): boolean {
|
|
243
|
+
return /^[$_\p{ID_Start}][$\u200c\u200d\p{ID_Continue}]*$/u.test(name);
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
const reportedInvalidExactNames = new WeakMap<Program, WeakSet<object>>();
|
|
247
|
+
|
|
248
|
+
export function reportInvalidExactName(
|
|
249
|
+
program: Program,
|
|
250
|
+
item: SdkName & object,
|
|
251
|
+
nameType: NameType,
|
|
252
|
+
nameKind: string,
|
|
253
|
+
target: DiagnosticTarget | typeof NoTarget = NoTarget,
|
|
254
|
+
): void {
|
|
255
|
+
if (
|
|
256
|
+
!item.isExactName ||
|
|
257
|
+
nameType === NameType.Property ||
|
|
258
|
+
nameType === NameType.EnumMemberName ||
|
|
259
|
+
nameType === NameType.File
|
|
260
|
+
) {
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
const requiresMethodGuard = guardReservedNames(item.name, NameType.Method) !== item.name;
|
|
265
|
+
const isValid =
|
|
266
|
+
isValidTypeScriptIdentifierName(item.name) &&
|
|
267
|
+
(nameType === NameType.Method || !requiresMethodGuard);
|
|
268
|
+
if (isValid) {
|
|
269
|
+
return;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
let reported = reportedInvalidExactNames.get(program);
|
|
273
|
+
if (!reported) {
|
|
274
|
+
reported = new WeakSet<object>();
|
|
275
|
+
reportedInvalidExactNames.set(program, reported);
|
|
276
|
+
}
|
|
277
|
+
if (reported.has(item)) {
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
reported.add(item);
|
|
281
|
+
|
|
282
|
+
reportDiagnostic(program, {
|
|
283
|
+
code: "invalid-exact-name",
|
|
284
|
+
format: { nameKind, name: item.name },
|
|
285
|
+
target,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
export function formatPropertyName(name: string): string {
|
|
290
|
+
return isValidTypeScriptIdentifierName(name) ? name : JSON.stringify(name);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export function formatPropertyAccess(base: string, name: string): string {
|
|
294
|
+
return isValidTypeScriptIdentifierName(name)
|
|
295
|
+
? `${base}.${name}`
|
|
296
|
+
: `${base}[${JSON.stringify(name)}]`;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
export function formatOptionalPropertyAccess(base: string, name: string): string {
|
|
300
|
+
return isValidTypeScriptIdentifierName(name)
|
|
301
|
+
? `${base}?.${name}`
|
|
302
|
+
: `${base}?.[${JSON.stringify(name)}]`;
|
|
303
|
+
}
|
|
304
|
+
|
|
211
305
|
export function fixLeadingNumber(name: string, nameType: NameType, prefix: string = "_"): string {
|
|
212
306
|
const casingConvention = getCasingConvention(nameType);
|
|
213
307
|
if (!name || !name.match(/^[-.]?\d/)) {
|
|
@@ -53,7 +53,7 @@ import {
|
|
|
53
53
|
} from "./media-types.js";
|
|
54
54
|
import { isByteOrByteUnion } from "./model-utils.js";
|
|
55
55
|
import { getLroLogicalResponseName, getResponseTypeName } from "./name-constructors.js";
|
|
56
|
-
import { NameType, normalizeName } from "./name-utils.js";
|
|
56
|
+
import { NameType, normalizeName, normalizeSdkName, reportInvalidExactName } from "./name-utils.js";
|
|
57
57
|
import { getOperationNamespaceInterfaceName } from "./namespace-utils.js";
|
|
58
58
|
|
|
59
59
|
// Sorts the responses by status code
|
|
@@ -645,9 +645,10 @@ export function getMethodHierarchiesMap(
|
|
|
645
645
|
const operationOrGroup = method[1];
|
|
646
646
|
|
|
647
647
|
if (operationOrGroup.kind === "client") {
|
|
648
|
-
operationOrGroup.
|
|
649
|
-
|
|
650
|
-
|
|
648
|
+
const hierarchyName = operationOrGroup.isExactName
|
|
649
|
+
? `$DO_NOT_NORMALIZE$${operationOrGroup.name}`
|
|
650
|
+
: operationOrGroup.name;
|
|
651
|
+
operationOrGroup.methods.forEach((m) => methodQueue.push([[...prefixes, hierarchyName], m]));
|
|
651
652
|
const nonIndependentChildren = operationOrGroup.children?.filter((child) => {
|
|
652
653
|
return (
|
|
653
654
|
!(child.clientInitialization.initializedBy & InitializedByFlags.Individually) &&
|
|
@@ -656,10 +657,26 @@ export function getMethodHierarchiesMap(
|
|
|
656
657
|
});
|
|
657
658
|
if (nonIndependentChildren && nonIndependentChildren.length > 0) {
|
|
658
659
|
nonIndependentChildren.forEach((child) =>
|
|
659
|
-
methodQueue.push([[...prefixes,
|
|
660
|
+
methodQueue.push([[...prefixes, hierarchyName], child]),
|
|
660
661
|
);
|
|
661
662
|
}
|
|
662
663
|
} else {
|
|
664
|
+
reportInvalidExactName(
|
|
665
|
+
context.program,
|
|
666
|
+
operationOrGroup,
|
|
667
|
+
NameType.Method,
|
|
668
|
+
"operation",
|
|
669
|
+
operationOrGroup.__raw ?? NoTarget,
|
|
670
|
+
);
|
|
671
|
+
for (const parameter of operationOrGroup.parameters) {
|
|
672
|
+
reportInvalidExactName(
|
|
673
|
+
context.program,
|
|
674
|
+
parameter,
|
|
675
|
+
NameType.Parameter,
|
|
676
|
+
"parameter",
|
|
677
|
+
parameter.__raw ?? NoTarget,
|
|
678
|
+
);
|
|
679
|
+
}
|
|
663
680
|
const prefixKey =
|
|
664
681
|
context.emitterOptions?.hierarchyClient || context.emitterOptions?.enableOperationGroup
|
|
665
682
|
? prefixes.join("/")
|
|
@@ -736,18 +753,14 @@ function resolveParameterNameConflict(
|
|
|
736
753
|
// subsequent calls (e.g. emitNonModelResponseTypes then buildApiOptions both call
|
|
737
754
|
// getMethodHierarchiesMap on the same TCGC object) always normalize from the
|
|
738
755
|
// original, not from the already-mutated value.
|
|
739
|
-
const paramName =
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
undefined,
|
|
744
|
-
undefined,
|
|
745
|
-
p.oriName,
|
|
746
|
-
);
|
|
756
|
+
const paramName = normalizeSdkName(p, NameType.Parameter, {
|
|
757
|
+
shouldGuard: true,
|
|
758
|
+
nameOverride: p.oriName ?? p.name,
|
|
759
|
+
});
|
|
747
760
|
if (!p.oriName) {
|
|
748
761
|
p.oriName = p.name;
|
|
749
762
|
}
|
|
750
|
-
if (paramName === operationOrGroup.name) {
|
|
763
|
+
if (!p.isExactName && paramName === operationOrGroup.name) {
|
|
751
764
|
p.name = `${paramName}Parameter`;
|
|
752
765
|
} else {
|
|
753
766
|
p.name = paramName;
|
|
@@ -55,14 +55,15 @@ type StorageCompatResult<TBody, THeaders> = TBody extends undefined | void | nul
|
|
|
55
55
|
* @param rawResponse - The raw FullOperationResponse from the HTTP pipeline.
|
|
56
56
|
* @param parsedBody - The deserialized response body.
|
|
57
57
|
* @param parsedHeaders - The deserialized response headers.
|
|
58
|
-
* @returns
|
|
58
|
+
* @returns A flattened copy of the body and headers augmented with a `_response` property.
|
|
59
59
|
*/
|
|
60
60
|
export function addStorageCompatResponse<TBody, THeaders = Record<string, unknown>>(
|
|
61
61
|
rawResponse: FullOperationResponse,
|
|
62
62
|
parsedBody: TBody,
|
|
63
63
|
parsedHeaders: THeaders,
|
|
64
64
|
): StorageCompatResult<TBody, THeaders> {
|
|
65
|
-
const base =
|
|
65
|
+
const base =
|
|
66
|
+
parsedBody !== undefined && parsedBody !== null ? Object.assign({}, parsedBody) : ({} as TBody);
|
|
66
67
|
return Object.assign(base as any, parsedHeaders, {
|
|
67
68
|
_response: {
|
|
68
69
|
rawResponse,
|
|
@@ -69,7 +69,8 @@ function getExpandedValue(option: ValueOptions): string {
|
|
|
69
69
|
// prepare the following parts: separator, varName, value
|
|
70
70
|
vals.push(`${getFirstOrSep(op, isFirst)}`);
|
|
71
71
|
if (named && varName) {
|
|
72
|
-
|
|
72
|
+
// No need to encode varName considering it is already encoded
|
|
73
|
+
vals.push(`${varName}`);
|
|
73
74
|
if (val === "") {
|
|
74
75
|
vals.push(ifEmpty);
|
|
75
76
|
} else {
|
|
@@ -108,7 +109,8 @@ function getNonExpandedValue(option: ValueOptions): string | undefined {
|
|
|
108
109
|
const first = getFirstOrSep(op, isFirst);
|
|
109
110
|
const [named, ifEmpty] = getNamedAndIfEmpty(op);
|
|
110
111
|
if (named && varName) {
|
|
111
|
-
|
|
112
|
+
// No need to encode varName considering it is already encoded
|
|
113
|
+
vals.push(varName);
|
|
112
114
|
if (value === "") {
|
|
113
115
|
if (!ifEmpty) {
|
|
114
116
|
vals.push(ifEmpty);
|