@azure-tools/typespec-ts 0.49.0 → 0.49.1
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/CHANGELOG.md +24 -0
- package/dist/src/framework/hooks/binder.d.ts.map +1 -1
- package/dist/src/framework/hooks/binder.js +8 -17
- package/dist/src/framework/hooks/binder.js.map +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +13 -11
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +8 -0
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +10 -0
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +10 -5
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildProjectFiles.d.ts.map +1 -1
- package/dist/src/modular/buildProjectFiles.js +13 -10
- package/dist/src/modular/buildProjectFiles.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +43 -40
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/emitSamples.d.ts.map +1 -1
- package/dist/src/modular/emitSamples.js +9 -0
- package/dist/src/modular/emitSamples.js.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +4 -1
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.d.ts +7 -0
- package/dist/src/modular/helpers/namingHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/namingHelpers.js +15 -0
- package/dist/src/modular/helpers/namingHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +19 -2
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +410 -39
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +9 -3
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts +12 -0
- package/dist/src/modular/serialization/buildXmlSerializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js +259 -18
- package/dist/src/modular/serialization/buildXmlSerializerFunction.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +10 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -1
- package/dist/src/modular/static-helpers-metadata.js +10 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts +3 -1
- package/dist/src/modular/type-expressions/get-model-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-model-expression.js +50 -9
- package/dist/src/modular/type-expressions/get-model-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-nullable-expression.js +8 -0
- package/dist/src/modular/type-expressions/get-nullable-expression.js.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.d.ts +3 -2
- package/dist/src/modular/type-expressions/get-type-expression.d.ts.map +1 -1
- package/dist/src/modular/type-expressions/get-type-expression.js.map +1 -1
- package/dist/src/transform/transform.d.ts.map +1 -1
- package/dist/src/transform/transform.js +10 -10
- package/dist/src/transform/transform.js.map +1 -1
- package/dist/src/transform/transformSchemas.d.ts.map +1 -1
- package/dist/src/transform/transformSchemas.js +4 -4
- package/dist/src/transform/transformSchemas.js.map +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts +1 -1
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +37 -24
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/clientUtils.d.ts +1 -1
- package/dist/src/utils/clientUtils.d.ts.map +1 -1
- package/dist/src/utils/clientUtils.js +40 -17
- package/dist/src/utils/clientUtils.js.map +1 -1
- package/dist/src/utils/crossLanguageDef.d.ts.map +1 -1
- package/dist/src/utils/crossLanguageDef.js +9 -3
- package/dist/src/utils/crossLanguageDef.js.map +1 -1
- package/dist/src/utils/interfaces.d.ts +2 -1
- package/dist/src/utils/interfaces.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +2 -2
- package/dist/src/utils/modelUtils.d.ts.map +1 -1
- package/dist/src/utils/modelUtils.js +15 -16
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/framework/hooks/binder.ts +12 -22
- package/src/index.ts +17 -10
- package/src/lib.ts +20 -0
- package/src/modular/buildOperations.ts +12 -4
- package/src/modular/buildProjectFiles.ts +19 -16
- package/src/modular/emitModels.ts +72 -44
- package/src/modular/emitSamples.ts +11 -1
- package/src/modular/helpers/clientHelpers.ts +5 -1
- package/src/modular/helpers/namingHelpers.ts +19 -0
- package/src/modular/helpers/operationHelpers.ts +533 -40
- package/src/modular/serialization/buildDeserializerFunction.ts +11 -2
- package/src/modular/serialization/buildXmlSerializerFunction.ts +375 -24
- package/src/modular/static-helpers-metadata.ts +10 -0
- package/src/modular/type-expressions/get-model-expression.ts +78 -13
- package/src/modular/type-expressions/get-nullable-expression.ts +9 -0
- package/src/modular/type-expressions/get-type-expression.ts +3 -1
- package/src/transform/transform.ts +5 -2
- package/src/transform/transformSchemas.ts +4 -1
- package/src/transform/transfromRLCOptions.ts +65 -24
- package/src/utils/clientUtils.ts +49 -16
- package/src/utils/crossLanguageDef.ts +8 -0
- package/src/utils/interfaces.ts +2 -1
- package/src/utils/modelUtils.ts +22 -18
- package/static/static-helpers/serialization/serialize-record.ts +3 -3
- package/static/static-helpers/serialization/xml-helpers.ts +91 -36
- package/static/static-helpers/urlTemplate.ts +5 -5
|
@@ -58,7 +58,7 @@ export async function transformRLCModel(
|
|
|
58
58
|
? client.name
|
|
59
59
|
: (options?.title ??
|
|
60
60
|
client.name ??
|
|
61
|
-
getDefaultService(program)?.title ??
|
|
61
|
+
getDefaultService(program, options.isModularLibrary)?.title ??
|
|
62
62
|
""),
|
|
63
63
|
NameType.Class
|
|
64
64
|
);
|
|
@@ -123,7 +123,10 @@ export function transformUrlInfo(
|
|
|
123
123
|
const importedModels = new Set<string>();
|
|
124
124
|
const usage = [SchemaContext.Exception, SchemaContext.Input];
|
|
125
125
|
const program = dpgContext.program;
|
|
126
|
-
const serviceNs = getDefaultService(
|
|
126
|
+
const serviceNs = getDefaultService(
|
|
127
|
+
program,
|
|
128
|
+
dpgContext.rlcOptions?.isModularLibrary
|
|
129
|
+
)?.type;
|
|
127
130
|
let endpoint = undefined;
|
|
128
131
|
const urlParameters: PathParameter[] = [];
|
|
129
132
|
if (serviceNs) {
|
|
@@ -89,7 +89,10 @@ export function transformSchemas(client: SdkClient, dpgContext: SdkContext) {
|
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
function transformHostParameters() {
|
|
92
|
-
const serviceNs = getDefaultService(
|
|
92
|
+
const serviceNs = getDefaultService(
|
|
93
|
+
program,
|
|
94
|
+
dpgContext.rlcOptions?.isModularLibrary
|
|
95
|
+
)?.type;
|
|
93
96
|
if (serviceNs) {
|
|
94
97
|
const host = getServers(program, serviceNs);
|
|
95
98
|
if (host && host?.[0] && host?.[0]?.parameters) {
|
|
@@ -33,10 +33,7 @@ export function transformRLCOptions(
|
|
|
33
33
|
emitterOptions,
|
|
34
34
|
dpgContext.generationPathDetail?.rootDir ?? ""
|
|
35
35
|
);
|
|
36
|
-
|
|
37
|
-
options.isModularLibrary = true;
|
|
38
|
-
}
|
|
39
|
-
const batch = getRLCClients(dpgContext);
|
|
36
|
+
const batch = getRLCClients(dpgContext, options.isModularLibrary);
|
|
40
37
|
options.batch = batch;
|
|
41
38
|
return options;
|
|
42
39
|
}
|
|
@@ -46,20 +43,33 @@ function extractRLCOptions(
|
|
|
46
43
|
generationRootDir: string
|
|
47
44
|
): RLCOptions {
|
|
48
45
|
const program = dpgContext.program;
|
|
46
|
+
// Compute isModularLibrary early - defaults to true unless explicitly set to false
|
|
47
|
+
const isModularLibrary = emitterOptions["is-modular-library"] !== false;
|
|
49
48
|
const includeShortcuts = getIncludeShortcuts(emitterOptions);
|
|
50
|
-
const packageDetails = getPackageDetails(
|
|
49
|
+
const packageDetails = getPackageDetails(
|
|
50
|
+
program,
|
|
51
|
+
emitterOptions,
|
|
52
|
+
isModularLibrary
|
|
53
|
+
);
|
|
51
54
|
const flavor = getFlavor(emitterOptions, packageDetails);
|
|
52
55
|
const moduleKind = getModuleKind(emitterOptions);
|
|
53
|
-
const serviceInfo = getServiceInfo(program);
|
|
56
|
+
const serviceInfo = getServiceInfo(program, isModularLibrary);
|
|
57
|
+
const includeHeadersInResponse =
|
|
58
|
+
emitterOptions["include-headers-in-response"] === true;
|
|
54
59
|
const azureSdkForJs = getAzureSdkForJs(emitterOptions, flavor);
|
|
55
60
|
const generateMetadata = getGenerateMetadata(emitterOptions);
|
|
56
61
|
const generateTest = getGenerateTest(emitterOptions, flavor);
|
|
57
62
|
const generateSample = getGenerateSample(dpgContext, emitterOptions);
|
|
58
|
-
const credentialInfo = getCredentialInfo(
|
|
63
|
+
const credentialInfo = getCredentialInfo(
|
|
64
|
+
program,
|
|
65
|
+
emitterOptions,
|
|
66
|
+
isModularLibrary
|
|
67
|
+
);
|
|
59
68
|
const azureOutputDirectory = getAzureOutputDirectory(generationRootDir);
|
|
60
69
|
const enableOperationGroup = getEnableOperationGroup(
|
|
61
70
|
dpgContext,
|
|
62
|
-
emitterOptions
|
|
71
|
+
emitterOptions,
|
|
72
|
+
isModularLibrary
|
|
63
73
|
);
|
|
64
74
|
const enableModelNamespace = getEnableModelNamespace(
|
|
65
75
|
dpgContext,
|
|
@@ -72,7 +82,6 @@ function extractRLCOptions(
|
|
|
72
82
|
const title = emitterOptions.title;
|
|
73
83
|
const dependencyInfo = emitterOptions["dependency-info"];
|
|
74
84
|
const productDocLink = emitterOptions["product-doc-link"];
|
|
75
|
-
const isModularLibrary = emitterOptions["is-modular-library"];
|
|
76
85
|
const compatibilityMode = emitterOptions["compatibility-mode"];
|
|
77
86
|
const compatibilityLro = emitterOptions["compatibility-lro"];
|
|
78
87
|
const experimentalExtensibleEnums =
|
|
@@ -85,9 +94,15 @@ function extractRLCOptions(
|
|
|
85
94
|
emitterOptions["compatibility-query-multi-format"];
|
|
86
95
|
const typespecTitleMap = emitterOptions["typespec-title-map"];
|
|
87
96
|
const hasSubscriptionId = getSubscriptionId(dpgContext);
|
|
97
|
+
const ignoreNullableOnOptional = getIgnoreNullableOnOptional(
|
|
98
|
+
emitterOptions,
|
|
99
|
+
flavor
|
|
100
|
+
);
|
|
101
|
+
const isMultiService = (dpgContext.allServiceNamespaces?.length ?? 0) > 1;
|
|
88
102
|
|
|
89
103
|
return {
|
|
90
104
|
...credentialInfo,
|
|
105
|
+
includeHeadersInResponse,
|
|
91
106
|
flavor,
|
|
92
107
|
moduleKind,
|
|
93
108
|
includeShortcuts,
|
|
@@ -117,12 +132,14 @@ function extractRLCOptions(
|
|
|
117
132
|
compatibilityQueryMultiFormat,
|
|
118
133
|
typespecTitleMap,
|
|
119
134
|
ignoreEnumMemberNameNormalize,
|
|
120
|
-
hasSubscriptionId
|
|
135
|
+
hasSubscriptionId,
|
|
136
|
+
ignoreNullableOnOptional,
|
|
137
|
+
isMultiService
|
|
121
138
|
};
|
|
122
139
|
}
|
|
123
140
|
|
|
124
|
-
function processAuth(program: Program) {
|
|
125
|
-
const serviceNs = getDefaultService(program)?.type;
|
|
141
|
+
function processAuth(program: Program, isModularLibrary: boolean) {
|
|
142
|
+
const serviceNs = getDefaultService(program, isModularLibrary)?.type;
|
|
126
143
|
if (!serviceNs) {
|
|
127
144
|
return undefined;
|
|
128
145
|
}
|
|
@@ -190,7 +207,8 @@ function processAuth(program: Program) {
|
|
|
190
207
|
|
|
191
208
|
function getEnableOperationGroup(
|
|
192
209
|
dpgContext: SdkContext,
|
|
193
|
-
emitterOptions: EmitterOptions
|
|
210
|
+
emitterOptions: EmitterOptions,
|
|
211
|
+
isModularLibrary: boolean
|
|
194
212
|
) {
|
|
195
213
|
if (
|
|
196
214
|
emitterOptions["enable-operation-group"] === true ||
|
|
@@ -199,7 +217,7 @@ function getEnableOperationGroup(
|
|
|
199
217
|
return emitterOptions["enable-operation-group"];
|
|
200
218
|
}
|
|
201
219
|
// Only detect if existing name conflicts if customers don't set hierarchyClient to true
|
|
202
|
-
return detectIfNameConflicts(dpgContext);
|
|
220
|
+
return detectIfNameConflicts(dpgContext, isModularLibrary);
|
|
203
221
|
}
|
|
204
222
|
|
|
205
223
|
function getEnableModelNamespace(
|
|
@@ -231,8 +249,11 @@ function getClearOutputFolder(emitterOptions: EmitterOptions) {
|
|
|
231
249
|
return emitterOptions["clear-output-folder"] ? true : false;
|
|
232
250
|
}
|
|
233
251
|
|
|
234
|
-
function detectIfNameConflicts(
|
|
235
|
-
|
|
252
|
+
function detectIfNameConflicts(
|
|
253
|
+
dpgContext: SdkContext,
|
|
254
|
+
isModularLibrary: boolean
|
|
255
|
+
) {
|
|
256
|
+
const clients = getRLCClients(dpgContext, isModularLibrary);
|
|
236
257
|
for (const client of clients) {
|
|
237
258
|
// only consider it's conflict when there are conflicts in the same client
|
|
238
259
|
const nameSet = new Set<string>();
|
|
@@ -251,6 +272,18 @@ function detectIfNameConflicts(dpgContext: SdkContext) {
|
|
|
251
272
|
return false;
|
|
252
273
|
}
|
|
253
274
|
|
|
275
|
+
function getIgnoreNullableOnOptional(
|
|
276
|
+
emitterOptions: EmitterOptions,
|
|
277
|
+
flavor: PackageFlavor
|
|
278
|
+
): boolean {
|
|
279
|
+
// If explicitly set in options, use that value
|
|
280
|
+
if (emitterOptions["ignore-nullable-on-optional"] !== undefined) {
|
|
281
|
+
return Boolean(emitterOptions["ignore-nullable-on-optional"]);
|
|
282
|
+
}
|
|
283
|
+
// Default to true for Azure services (same as HLC behavior)
|
|
284
|
+
return flavor === "azure";
|
|
285
|
+
}
|
|
286
|
+
|
|
254
287
|
function getIncludeShortcuts(emitterOptions: EmitterOptions) {
|
|
255
288
|
return Boolean(emitterOptions["include-shortcuts"]);
|
|
256
289
|
}
|
|
@@ -290,7 +323,8 @@ function getFlavor(
|
|
|
290
323
|
}
|
|
291
324
|
function buildPackageDetails(
|
|
292
325
|
program: Program,
|
|
293
|
-
emitterOptions: EmitterOptions
|
|
326
|
+
emitterOptions: EmitterOptions,
|
|
327
|
+
isModularLibrary: boolean
|
|
294
328
|
): PackageDetails {
|
|
295
329
|
const defaultDetail = {
|
|
296
330
|
name: "@msinternal/unamedpackage",
|
|
@@ -305,7 +339,9 @@ function buildPackageDetails(
|
|
|
305
339
|
name:
|
|
306
340
|
emitterOptions["package-details"]?.name ??
|
|
307
341
|
normalizeName(
|
|
308
|
-
emitterOptions?.title ??
|
|
342
|
+
emitterOptions?.title ??
|
|
343
|
+
getDefaultService(program, isModularLibrary)?.title ??
|
|
344
|
+
"",
|
|
309
345
|
NameType.Class
|
|
310
346
|
),
|
|
311
347
|
version: emitterOptions["package-details"]?.version ?? "1.0.0-beta.1",
|
|
@@ -323,13 +359,17 @@ function buildPackageDetails(
|
|
|
323
359
|
|
|
324
360
|
function getPackageDetails(
|
|
325
361
|
program: Program,
|
|
326
|
-
emitterOptions: EmitterOptions
|
|
362
|
+
emitterOptions: EmitterOptions,
|
|
363
|
+
isModularLibrary: boolean
|
|
327
364
|
): PackageDetails {
|
|
328
|
-
return buildPackageDetails(program, emitterOptions);
|
|
365
|
+
return buildPackageDetails(program, emitterOptions, isModularLibrary);
|
|
329
366
|
}
|
|
330
367
|
|
|
331
|
-
function getServiceInfo(
|
|
332
|
-
|
|
368
|
+
function getServiceInfo(
|
|
369
|
+
program: Program,
|
|
370
|
+
isModularLibrary: boolean
|
|
371
|
+
): ServiceInfo {
|
|
372
|
+
const defaultService = getDefaultService(program, isModularLibrary);
|
|
333
373
|
return {
|
|
334
374
|
title: defaultService?.title,
|
|
335
375
|
description: defaultService && getDoc(program, defaultService.type)
|
|
@@ -397,9 +437,10 @@ function getGenerateSample(
|
|
|
397
437
|
|
|
398
438
|
export function getCredentialInfo(
|
|
399
439
|
program: Program,
|
|
400
|
-
emitterOptions: EmitterOptions
|
|
440
|
+
emitterOptions: EmitterOptions,
|
|
441
|
+
isModularLibrary: boolean = true
|
|
401
442
|
) {
|
|
402
|
-
const securityInfo = processAuth(program);
|
|
443
|
+
const securityInfo = processAuth(program, isModularLibrary);
|
|
403
444
|
const addCredentials =
|
|
404
445
|
emitterOptions["add-credentials"] === false
|
|
405
446
|
? false
|
package/src/utils/clientUtils.ts
CHANGED
|
@@ -18,23 +18,58 @@ import { SdkContext } from "./interfaces.js";
|
|
|
18
18
|
import { ModularClientOptions } from "../modular/interfaces.js";
|
|
19
19
|
import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
20
20
|
|
|
21
|
-
export function getRLCClients(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
21
|
+
export function getRLCClients(
|
|
22
|
+
dpgContext: SdkContext,
|
|
23
|
+
isModularLibrary?: boolean
|
|
24
|
+
): SdkClient[] {
|
|
25
|
+
const modular =
|
|
26
|
+
isModularLibrary ?? dpgContext.rlcOptions?.isModularLibrary ?? false;
|
|
27
|
+
const clients = listClients(dpgContext);
|
|
28
|
+
const rawServiceNamespaces =
|
|
29
|
+
dpgContext.allServiceNamespaces ?? listAllServiceNamespaces(dpgContext);
|
|
30
|
+
|
|
31
|
+
// For one client in Modular: Return the client from listClients with multi-service support
|
|
32
|
+
if (modular && clients.length === 1) {
|
|
33
|
+
return clients.map((client) => {
|
|
34
|
+
const services = client.services;
|
|
35
|
+
return {
|
|
36
|
+
...client,
|
|
37
|
+
services: services,
|
|
38
|
+
crossLanguageDefinitionId: `${getNamespaceFullName(
|
|
39
|
+
services[0]!
|
|
40
|
+
)}.${client.name}`
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
} else {
|
|
44
|
+
// For RLC and multiple clients in Modular:
|
|
45
|
+
// Flatten all services and return one client per service
|
|
46
|
+
const services = new Set<Namespace>();
|
|
47
|
+
clients.forEach((c) => {
|
|
48
|
+
const clientService = c.services;
|
|
26
49
|
clientService.forEach((ns) => services.add(ns));
|
|
27
|
-
}
|
|
28
|
-
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
if (services.size > 0) {
|
|
53
|
+
return [...services.values()].map((service) => {
|
|
54
|
+
const clientName = service.name + "Client";
|
|
55
|
+
return {
|
|
56
|
+
kind: "SdkClient",
|
|
57
|
+
name: clientName,
|
|
58
|
+
service: service,
|
|
59
|
+
type: service,
|
|
60
|
+
services: [service],
|
|
61
|
+
arm: Boolean(dpgContext.arm),
|
|
62
|
+
crossLanguageDefinitionId: `${getNamespaceFullName(
|
|
63
|
+
service
|
|
64
|
+
)}.${clientName}`,
|
|
65
|
+
subOperationGroups: []
|
|
66
|
+
};
|
|
67
|
+
});
|
|
29
68
|
}
|
|
30
|
-
});
|
|
31
|
-
const rawServiceNamespaces = listAllServiceNamespaces(dpgContext);
|
|
32
|
-
if (services.size === 0 && rawServiceNamespaces.length > 0) {
|
|
33
|
-
// If no clients are found, fall back to raw service namespaces
|
|
34
|
-
[...rawServiceNamespaces.values()].forEach((ns) => services.add(ns));
|
|
35
69
|
}
|
|
36
70
|
|
|
37
|
-
|
|
71
|
+
// Fallback to raw service namespaces if no clients found
|
|
72
|
+
return rawServiceNamespaces.map((service) => {
|
|
38
73
|
const clientName = service.name + "Client";
|
|
39
74
|
return {
|
|
40
75
|
kind: "SdkClient",
|
|
@@ -53,9 +88,7 @@ export function getRLCClients(dpgContext: SdkContext): SdkClient[] {
|
|
|
53
88
|
|
|
54
89
|
export function listOperationsUnderRLCClient(client: SdkClient): Operation[] {
|
|
55
90
|
const operations = [];
|
|
56
|
-
const serviceArray =
|
|
57
|
-
? client.service
|
|
58
|
-
: [client.service];
|
|
91
|
+
const serviceArray = client.services;
|
|
59
92
|
const queue: (Namespace | Interface)[] = [...serviceArray];
|
|
60
93
|
while (queue.length > 0) {
|
|
61
94
|
const current = queue.shift()!;
|
|
@@ -5,6 +5,7 @@ import { SdkContext } from "./interfaces.js";
|
|
|
5
5
|
import { transformModularEmitterOptions } from "../modular/buildModularOptions.js";
|
|
6
6
|
import { getMethodHierarchiesMap } from "./operationUtil.js";
|
|
7
7
|
import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
8
|
+
import { UsageFlags } from "@azure-tools/typespec-client-generator-core";
|
|
8
9
|
|
|
9
10
|
export function generateCrossLanguageDefinitionFile(dpgContext: SdkContext): {
|
|
10
11
|
CrossLanguagePackageId: string;
|
|
@@ -28,6 +29,13 @@ export function generateCrossLanguageDefinitionFile(dpgContext: SdkContext): {
|
|
|
28
29
|
model.crossLanguageDefinitionId;
|
|
29
30
|
}
|
|
30
31
|
for (const enm of dpgContext.sdkPackage.enums) {
|
|
32
|
+
// Skip api version enum for multi-service scenarios since each service may have different versions
|
|
33
|
+
if (
|
|
34
|
+
dpgContext.rlcOptions?.isMultiService &&
|
|
35
|
+
enm.usage === UsageFlags.ApiVersionEnum
|
|
36
|
+
) {
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
31
39
|
CrossLanguageDefinitionId[`${packageName}!Known${enm.name}:enum`] =
|
|
32
40
|
enm.crossLanguageDefinitionId;
|
|
33
41
|
}
|
package/src/utils/interfaces.ts
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { RLCOptions, SchemaContext } from "@azure-tools/rlc-common";
|
|
2
2
|
import { SdkContext as TCGCSdkContext } from "@azure-tools/typespec-client-generator-core";
|
|
3
|
-
import { ModelProperty } from "@typespec/compiler";
|
|
3
|
+
import { ModelProperty, Namespace } from "@typespec/compiler";
|
|
4
4
|
import { KnownMediaType } from "./mediaTypes.js";
|
|
5
5
|
|
|
6
6
|
export interface SdkContext extends TCGCSdkContext {
|
|
7
7
|
rlcOptions?: RLCOptions;
|
|
8
8
|
generationPathDetail?: GenerationDirDetail;
|
|
9
9
|
hasApiVersionInClient?: boolean;
|
|
10
|
+
allServiceNamespaces?: Namespace[];
|
|
10
11
|
}
|
|
11
12
|
|
|
12
13
|
export interface GenerationDirDetail {
|
package/src/utils/modelUtils.ts
CHANGED
|
@@ -232,10 +232,7 @@ export function getSchemaForType(
|
|
|
232
232
|
});
|
|
233
233
|
schema.type = "object";
|
|
234
234
|
}
|
|
235
|
-
} else if (
|
|
236
|
-
!isArrayModelType(program, type) &&
|
|
237
|
-
!isRecordModelType(program, type)
|
|
238
|
-
) {
|
|
235
|
+
} else if (!isArrayModelType(type) && !isRecordModelType(type)) {
|
|
239
236
|
if (usage && usage.includes(SchemaContext.Output)) {
|
|
240
237
|
schema.outputTypeName = `${schema.name}Output`;
|
|
241
238
|
}
|
|
@@ -659,7 +656,7 @@ function getSchemaForModel(
|
|
|
659
656
|
isRequestBody,
|
|
660
657
|
mediaTypes: contentTypes
|
|
661
658
|
} = options ?? {};
|
|
662
|
-
if (isArrayModelType(
|
|
659
|
+
if (isArrayModelType(model)) {
|
|
663
660
|
return getSchemaForArrayModel(dpgContext, model, options);
|
|
664
661
|
}
|
|
665
662
|
|
|
@@ -680,7 +677,7 @@ function getSchemaForModel(
|
|
|
680
677
|
true /** shouldGuard */
|
|
681
678
|
);
|
|
682
679
|
|
|
683
|
-
if (model.name === "Record" && isRecordModelType(
|
|
680
|
+
if (model.name === "Record" && isRecordModelType(model)) {
|
|
684
681
|
return getSchemaForRecordModel(dpgContext, model, { usage });
|
|
685
682
|
}
|
|
686
683
|
modelSchema.typeName = modelSchema.name;
|
|
@@ -748,7 +745,7 @@ function getSchemaForModel(
|
|
|
748
745
|
if (needRef) {
|
|
749
746
|
return modelSchema;
|
|
750
747
|
}
|
|
751
|
-
if (isRecordModelType(
|
|
748
|
+
if (isRecordModelType(model)) {
|
|
752
749
|
modelSchema.parents = {
|
|
753
750
|
all: [getSchemaForRecordModel(dpgContext, model, { usage })],
|
|
754
751
|
immediate: [getSchemaForRecordModel(dpgContext, model, { usage })]
|
|
@@ -1113,7 +1110,7 @@ function getSchemaForArrayModel(
|
|
|
1113
1110
|
if (!indexer) {
|
|
1114
1111
|
return schema;
|
|
1115
1112
|
}
|
|
1116
|
-
if (isArrayModelType(
|
|
1113
|
+
if (isArrayModelType(type)) {
|
|
1117
1114
|
schema = {
|
|
1118
1115
|
type: "array",
|
|
1119
1116
|
items: getSchemaForType(dpgContext, indexer.value!, {
|
|
@@ -1210,7 +1207,7 @@ function getSchemaForRecordModel(
|
|
|
1210
1207
|
if (!indexer) {
|
|
1211
1208
|
return schema;
|
|
1212
1209
|
}
|
|
1213
|
-
if (isRecordModelType(
|
|
1210
|
+
if (isRecordModelType(type)) {
|
|
1214
1211
|
const valueType = getSchemaForType(dpgContext, indexer?.value, {
|
|
1215
1212
|
usage,
|
|
1216
1213
|
needRef: !isAnonymousModelType(indexer.value)
|
|
@@ -1661,7 +1658,10 @@ export function predictDefaultValue(
|
|
|
1661
1658
|
}
|
|
1662
1659
|
return specificDefault;
|
|
1663
1660
|
}
|
|
1664
|
-
const serviceNamespace = getDefaultService(
|
|
1661
|
+
const serviceNamespace = getDefaultService(
|
|
1662
|
+
program,
|
|
1663
|
+
dpgContext.rlcOptions?.isModularLibrary
|
|
1664
|
+
)?.type;
|
|
1665
1665
|
if (!serviceNamespace) {
|
|
1666
1666
|
return;
|
|
1667
1667
|
}
|
|
@@ -1672,7 +1672,10 @@ export function predictDefaultValue(
|
|
|
1672
1672
|
return;
|
|
1673
1673
|
}
|
|
1674
1674
|
|
|
1675
|
-
export function getDefaultService(
|
|
1675
|
+
export function getDefaultService(
|
|
1676
|
+
program: Program,
|
|
1677
|
+
isModularLibrary: boolean = true
|
|
1678
|
+
): Service | undefined {
|
|
1676
1679
|
const services = listServices(program);
|
|
1677
1680
|
if (!services || services.length === 0) {
|
|
1678
1681
|
reportDiagnostic(program, {
|
|
@@ -1680,7 +1683,7 @@ export function getDefaultService(program: Program): Service | undefined {
|
|
|
1680
1683
|
target: NoTarget
|
|
1681
1684
|
});
|
|
1682
1685
|
}
|
|
1683
|
-
if (services.length > 1) {
|
|
1686
|
+
if (services.length > 1 && !isModularLibrary) {
|
|
1684
1687
|
reportDiagnostic(program, {
|
|
1685
1688
|
code: "more-than-one-service",
|
|
1686
1689
|
target: NoTarget
|
|
@@ -1695,8 +1698,12 @@ export function getDefaultApiVersionString(
|
|
|
1695
1698
|
dpgContext: SdkContext
|
|
1696
1699
|
): string | undefined {
|
|
1697
1700
|
const program = dpgContext.program;
|
|
1698
|
-
|
|
1699
|
-
|
|
1701
|
+
const isModularLibrary = dpgContext.rlcOptions?.isModularLibrary;
|
|
1702
|
+
return getDefaultService(program, isModularLibrary)
|
|
1703
|
+
? getDefaultApiVersion(
|
|
1704
|
+
dpgContext,
|
|
1705
|
+
getDefaultService(program, isModularLibrary)!.type
|
|
1706
|
+
)?.value
|
|
1700
1707
|
: undefined;
|
|
1701
1708
|
}
|
|
1702
1709
|
|
|
@@ -1922,10 +1929,7 @@ export function getCollectionFormat(
|
|
|
1922
1929
|
): string | undefined {
|
|
1923
1930
|
const type = param.param;
|
|
1924
1931
|
const encode = getEncode(context.program, param.param);
|
|
1925
|
-
if (
|
|
1926
|
-
type.type.kind === "Model" &&
|
|
1927
|
-
isArrayModelType(context.program, type.type)
|
|
1928
|
-
) {
|
|
1932
|
+
if (type.type.kind === "Model" && isArrayModelType(type.type)) {
|
|
1929
1933
|
if (param.explode) {
|
|
1930
1934
|
return "multi";
|
|
1931
1935
|
}
|
|
@@ -2,11 +2,11 @@ export function serializeRecord(
|
|
|
2
2
|
item: any,
|
|
3
3
|
excludes?: string[],
|
|
4
4
|
serializer?: (item: any) => any
|
|
5
|
-
) {
|
|
6
|
-
|
|
5
|
+
): Record<string, any> {
|
|
6
|
+
const propertiesToExclude = excludes ?? [];
|
|
7
7
|
const res: any = {};
|
|
8
8
|
for (const key of Object.keys(item)) {
|
|
9
|
-
if (
|
|
9
|
+
if (propertiesToExclude.includes(key) || item[key] === undefined) {
|
|
10
10
|
continue;
|
|
11
11
|
}
|
|
12
12
|
if (serializer) {
|