@azure-tools/typespec-ts 0.43.0 → 0.44.0
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 +20 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +6 -2
- package/dist/src/index.js.map +1 -1
- package/dist/src/modular/buildClientContext.js +1 -1
- package/dist/src/modular/buildClientContext.js.map +1 -1
- package/dist/src/modular/buildRestorePoller.d.ts.map +1 -1
- package/dist/src/modular/buildRestorePoller.js +1 -0
- package/dist/src/modular/buildRestorePoller.js.map +1 -1
- package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
- package/dist/src/modular/buildRootIndex.js +2 -2
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/buildSubpathIndex.d.ts.map +1 -1
- package/dist/src/modular/buildSubpathIndex.js +2 -2
- package/dist/src/modular/buildSubpathIndex.js.map +1 -1
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +3 -3
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/serialization/buildDeserializerFunction.js +2 -3
- package/dist/src/modular/serialization/buildDeserializerFunction.js.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.js +2 -3
- package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +22 -22
- package/src/index.ts +8 -2
- package/src/modular/buildClientContext.ts +1 -1
- package/src/modular/buildRestorePoller.ts +1 -0
- package/src/modular/buildRootIndex.ts +2 -3
- package/src/modular/buildSubpathIndex.ts +3 -2
- package/src/modular/emitModels.ts +6 -3
- package/src/modular/serialization/buildDeserializerFunction.ts +2 -2
- package/src/modular/serialization/buildSerializerFunction.ts +2 -2
- package/static/static-helpers/cloudSettingHelpers.ts +10 -1
- package/static/static-helpers/urlTemplate.ts +26 -14
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@azure-tools/typespec-ts",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.44.0",
|
|
4
4
|
"description": "An experimental TypeSpec emitter for TypeScript RLC",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -18,15 +18,15 @@
|
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"devDependencies": {
|
|
20
20
|
"@azure-rest/core-client": "^2.3.1",
|
|
21
|
-
"@typespec/http-specs": "0.1.0-alpha.
|
|
22
|
-
"@typespec/spector": "0.1.0-alpha.
|
|
23
|
-
"@typespec/spec-api": "0.1.0-alpha.
|
|
21
|
+
"@typespec/http-specs": "0.1.0-alpha.27-dev.0",
|
|
22
|
+
"@typespec/spector": "0.1.0-alpha.19-dev.0",
|
|
23
|
+
"@typespec/spec-api": "0.1.0-alpha.10-dev.0",
|
|
24
24
|
"@typespec/tspd": "0.72.1",
|
|
25
|
-
"@azure-tools/azure-http-specs": "0.1.0-alpha.
|
|
26
|
-
"@azure-tools/typespec-autorest": "^0.
|
|
27
|
-
"@azure-tools/typespec-azure-core": "^0.
|
|
28
|
-
"@azure-tools/typespec-azure-resource-manager": "^0.
|
|
29
|
-
"@azure-tools/typespec-client-generator-core": "^0.
|
|
25
|
+
"@azure-tools/azure-http-specs": "0.1.0-alpha.29-dev.0",
|
|
26
|
+
"@azure-tools/typespec-autorest": "^0.60.0",
|
|
27
|
+
"@azure-tools/typespec-azure-core": "^0.60.0",
|
|
28
|
+
"@azure-tools/typespec-azure-resource-manager": "^0.60.0",
|
|
29
|
+
"@azure-tools/typespec-client-generator-core": "^0.60.0",
|
|
30
30
|
"@azure/abort-controller": "^2.1.2",
|
|
31
31
|
"@azure/core-auth": "^1.6.0",
|
|
32
32
|
"@azure/core-lro": "^3.1.0",
|
|
@@ -41,12 +41,12 @@
|
|
|
41
41
|
"@types/node": "^18.0.0",
|
|
42
42
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
|
43
43
|
"@typescript-eslint/parser": "^8.28.0",
|
|
44
|
-
"@typespec/compiler": "^1.
|
|
45
|
-
"@typespec/http": "^1.
|
|
46
|
-
"@typespec/openapi": "^1.
|
|
47
|
-
"@typespec/rest": "^0.
|
|
44
|
+
"@typespec/compiler": "^1.4.0",
|
|
45
|
+
"@typespec/http": "^1.4.0",
|
|
46
|
+
"@typespec/openapi": "^1.4.0",
|
|
47
|
+
"@typespec/rest": "^0.74.0",
|
|
48
48
|
"@typespec/ts-http-runtime": "^0.1.0",
|
|
49
|
-
"@typespec/versioning": "^0.
|
|
49
|
+
"@typespec/versioning": "^0.74.0",
|
|
50
50
|
"chai": "^4.3.6",
|
|
51
51
|
"chalk": "^4.0.0",
|
|
52
52
|
"cross-env": "^7.0.3",
|
|
@@ -68,16 +68,16 @@
|
|
|
68
68
|
"js-yaml": "^4.1.0"
|
|
69
69
|
},
|
|
70
70
|
"peerDependencies": {
|
|
71
|
-
"@azure-tools/typespec-azure-core": "^0.
|
|
72
|
-
"@azure-tools/typespec-client-generator-core": "^0.
|
|
73
|
-
"@typespec/compiler": "^1.
|
|
74
|
-
"@typespec/http": "^1.
|
|
75
|
-
"@typespec/rest": "^0.
|
|
76
|
-
"@typespec/versioning": "^0.
|
|
77
|
-
"@typespec/xml": "^0.
|
|
71
|
+
"@azure-tools/typespec-azure-core": "^0.60.0",
|
|
72
|
+
"@azure-tools/typespec-client-generator-core": "^0.60.0",
|
|
73
|
+
"@typespec/compiler": "^1.4.0",
|
|
74
|
+
"@typespec/http": "^1.4.0",
|
|
75
|
+
"@typespec/rest": "^0.74.0",
|
|
76
|
+
"@typespec/versioning": "^0.74.0",
|
|
77
|
+
"@typespec/xml": "^0.74.0"
|
|
78
78
|
},
|
|
79
79
|
"dependencies": {
|
|
80
|
-
"@azure-tools/rlc-common": "^0.
|
|
80
|
+
"@azure-tools/rlc-common": "^0.44.0",
|
|
81
81
|
"fs-extra": "^11.1.0",
|
|
82
82
|
"lodash": "^4.17.21",
|
|
83
83
|
"prettier": "^3.3.3",
|
package/src/index.ts
CHANGED
|
@@ -210,9 +210,15 @@ export async function $onEmit(context: EmitContext) {
|
|
|
210
210
|
async function calculateGenerationDir(): Promise<GenerationDirDetail> {
|
|
211
211
|
const projectRoot = context.emitterOutputDir ?? "";
|
|
212
212
|
const customizationFolder = join(projectRoot, "generated");
|
|
213
|
+
const srcGeneratedFolder = join(projectRoot, "src", "generated");
|
|
213
214
|
// if customization folder exists, use it as sources root
|
|
214
|
-
const
|
|
215
|
-
|
|
215
|
+
const finalCustomizationFolder = (await fsextra.pathExists(
|
|
216
|
+
srcGeneratedFolder
|
|
217
|
+
))
|
|
218
|
+
? srcGeneratedFolder
|
|
219
|
+
: customizationFolder;
|
|
220
|
+
const sourcesRoot = (await fsextra.pathExists(finalCustomizationFolder))
|
|
221
|
+
? finalCustomizationFolder
|
|
216
222
|
: join(projectRoot, "src");
|
|
217
223
|
return {
|
|
218
224
|
rootDir: projectRoot,
|
|
@@ -108,7 +108,7 @@ export function buildClientContext(
|
|
|
108
108
|
const propertiesInOptions = getClientParameters(client, dpgContext, {
|
|
109
109
|
optionalOnly: true
|
|
110
110
|
})
|
|
111
|
-
.filter((p) => p
|
|
111
|
+
.filter((p) => getClientParameterName(p) !== "endpoint")
|
|
112
112
|
.map((p) => {
|
|
113
113
|
return {
|
|
114
114
|
name: getClientParameterName(p),
|
|
@@ -294,7 +294,7 @@ function exportModules(
|
|
|
294
294
|
}
|
|
295
295
|
|
|
296
296
|
const exported = [...indexFile.getExportedDeclarations().keys()];
|
|
297
|
-
|
|
297
|
+
const serializerOrDeserializerRegex = /.*(Serializer|Deserializer)(_\d+)?$/;
|
|
298
298
|
const namedExports = [...modelsFile.getExportedDeclarations().entries()]
|
|
299
299
|
.filter((exDeclaration) => {
|
|
300
300
|
if (exDeclaration[0].startsWith("_")) {
|
|
@@ -310,8 +310,7 @@ function exportModules(
|
|
|
310
310
|
if (
|
|
311
311
|
moduleName === "models" &&
|
|
312
312
|
ex.getKindName() === "FunctionDeclaration" &&
|
|
313
|
-
(exDeclaration[0]
|
|
314
|
-
exDeclaration[0].endsWith("Deserializer"))
|
|
313
|
+
serializerOrDeserializerRegex.test(exDeclaration[0])
|
|
315
314
|
) {
|
|
316
315
|
return false;
|
|
317
316
|
}
|
|
@@ -72,6 +72,8 @@ export function buildSubpathIndexFile(
|
|
|
72
72
|
const indexFile = project.createSourceFile(`${folder}/index.ts`);
|
|
73
73
|
for (const file of apiFiles) {
|
|
74
74
|
const filePath = file.getFilePath();
|
|
75
|
+
const serializerOrDeserializerRegex =
|
|
76
|
+
/.*(Serializer|Deserializer)(_\d+)?$/;
|
|
75
77
|
if (!options.exportIndex && filePath.endsWith("index.ts")) {
|
|
76
78
|
continue;
|
|
77
79
|
}
|
|
@@ -100,8 +102,7 @@ export function buildSubpathIndexFile(
|
|
|
100
102
|
if (
|
|
101
103
|
subpath === "models" &&
|
|
102
104
|
ex.getKindName() === "FunctionDeclaration" &&
|
|
103
|
-
(exDeclaration[0]
|
|
104
|
-
exDeclaration[0].endsWith("Deserializer"))
|
|
105
|
+
serializerOrDeserializerRegex.test(exDeclaration[0])
|
|
105
106
|
) {
|
|
106
107
|
return false;
|
|
107
108
|
}
|
|
@@ -396,7 +396,7 @@ export function buildEnumTypes(
|
|
|
396
396
|
const docs = type.doc ? type.doc : "Type of " + enumAsUnion.name;
|
|
397
397
|
enumAsUnion.docs =
|
|
398
398
|
isExtensibleEnum(context, type) && type.doc
|
|
399
|
-
? [getExtensibleEnumDescription(type) ?? docs]
|
|
399
|
+
? [getExtensibleEnumDescription(context, type) ?? docs]
|
|
400
400
|
: [docs];
|
|
401
401
|
enumDeclaration.docs = type.doc
|
|
402
402
|
? [type.doc]
|
|
@@ -405,7 +405,10 @@ export function buildEnumTypes(
|
|
|
405
405
|
return [enumAsUnion, enumDeclaration];
|
|
406
406
|
}
|
|
407
407
|
|
|
408
|
-
function getExtensibleEnumDescription(
|
|
408
|
+
function getExtensibleEnumDescription(
|
|
409
|
+
context: SdkContext,
|
|
410
|
+
model: SdkEnumType
|
|
411
|
+
): string | undefined {
|
|
409
412
|
if (model.isFixed && model.name && model.values) {
|
|
410
413
|
return;
|
|
411
414
|
}
|
|
@@ -415,7 +418,7 @@ function getExtensibleEnumDescription(model: SdkEnumType): string | undefined {
|
|
|
415
418
|
// Escape the character / to make sure we don't incorrectly announce a comment blocks /** */
|
|
416
419
|
.replace(/^\//g, "\\/")
|
|
417
420
|
.replace(/([^\\])(\/)/g, "$1\\/");
|
|
418
|
-
const enumLink = `{@link Known${model
|
|
421
|
+
const enumLink = `{@link Known${normalizeModelName(context, model)}} can be used interchangeably with ${normalizeModelName(context, model)},\n this enum contains the known values that the service supports.`;
|
|
419
422
|
|
|
420
423
|
return [
|
|
421
424
|
`${model.doc} \\`,
|
|
@@ -165,7 +165,7 @@ function buildPolymorphicDeserializer(
|
|
|
165
165
|
});
|
|
166
166
|
|
|
167
167
|
statements.push(`
|
|
168
|
-
switch (item.${type.discriminatorProperty.name}) {
|
|
168
|
+
switch (item.${normalizeName(type.discriminatorProperty.name, NameType.Property)}) {
|
|
169
169
|
${cases.join("\n")}
|
|
170
170
|
default:
|
|
171
171
|
return item;
|
|
@@ -232,7 +232,7 @@ function buildDiscriminatedUnionDeserializer(
|
|
|
232
232
|
`);
|
|
233
233
|
}
|
|
234
234
|
output.push(`
|
|
235
|
-
switch (item.${type.discriminatorProperty
|
|
235
|
+
switch (item.${type.discriminatorProperty ? normalizeName(type.discriminatorProperty.name, NameType.Property) : "unknown"}) {
|
|
236
236
|
${cases.join("\n")}
|
|
237
237
|
default:
|
|
238
238
|
return ${baseDeserializerName}(item);
|
|
@@ -172,7 +172,7 @@ function buildPolymorphicSerializer(
|
|
|
172
172
|
});
|
|
173
173
|
|
|
174
174
|
statements.push(`
|
|
175
|
-
switch (item.${type.discriminatorProperty.name}) {
|
|
175
|
+
switch (item.${normalizeName(type.discriminatorProperty.name, NameType.Property)}) {
|
|
176
176
|
${cases.join("\n")}
|
|
177
177
|
default:
|
|
178
178
|
return item;
|
|
@@ -239,7 +239,7 @@ function buildDiscriminatedUnionSerializer(
|
|
|
239
239
|
`);
|
|
240
240
|
}
|
|
241
241
|
output.push(`
|
|
242
|
-
switch (item.${type.discriminatorProperty
|
|
242
|
+
switch (item.${type.discriminatorProperty ? normalizeName(type.discriminatorProperty.name, NameType.Property) : "unknown"}) {
|
|
243
243
|
${cases.join("\n")}
|
|
244
244
|
default:
|
|
245
245
|
return ${baseSerializerName}(item);
|
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
/**
|
|
1
|
+
/**
|
|
2
|
+
* An enum to describe Azure Cloud environments.
|
|
3
|
+
* @enum {string}
|
|
4
|
+
*/
|
|
2
5
|
export enum AzureClouds {
|
|
3
6
|
/** Azure public cloud, which is the default cloud for Azure SDKs. */
|
|
4
7
|
AZURE_PUBLIC_CLOUD = "AZURE_PUBLIC_CLOUD",
|
|
@@ -11,6 +14,12 @@ export enum AzureClouds {
|
|
|
11
14
|
/** The supported values for cloud setting as a string literal type */
|
|
12
15
|
export type AzureSupportedClouds = `${AzureClouds}`;
|
|
13
16
|
|
|
17
|
+
/**
|
|
18
|
+
* Gets the Azure Resource Manager endpoint URL for the specified cloud setting.
|
|
19
|
+
* @param cloudSetting - The Azure cloud environment setting. Use one of the AzureClouds enum values.
|
|
20
|
+
* @returns The ARM endpoint URL for the specified cloud, or undefined if cloudSetting is undefined.
|
|
21
|
+
* @throws {Error} Throws an error if an unknown cloud setting is provided.
|
|
22
|
+
*/
|
|
14
23
|
export function getArmEndpoint(
|
|
15
24
|
cloudSetting?: AzureSupportedClouds
|
|
16
25
|
): string | undefined {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
|
|
1
|
+
// ---------------------
|
|
2
2
|
// interfaces
|
|
3
|
-
|
|
3
|
+
// ---------------------
|
|
4
4
|
interface ValueOptions {
|
|
5
5
|
isFirst: boolean; // is first value in the expression
|
|
6
6
|
op?: string; // operator
|
|
@@ -18,27 +18,27 @@ export interface UrlTemplateOptions {
|
|
|
18
18
|
// ---------------------
|
|
19
19
|
// helpers
|
|
20
20
|
// ---------------------
|
|
21
|
-
function encodeComponent(val: string, reserved?: boolean, op?: string) {
|
|
21
|
+
function encodeComponent(val: string, reserved?: boolean, op?: string): string {
|
|
22
22
|
return (reserved ?? op === "+") || op === "#"
|
|
23
23
|
? encodeReservedComponent(val)
|
|
24
24
|
: encodeRFC3986URIComponent(val);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
function encodeReservedComponent(str: string) {
|
|
27
|
+
function encodeReservedComponent(str: string): string {
|
|
28
28
|
return str
|
|
29
29
|
.split(/(%[0-9A-Fa-f]{2})/g)
|
|
30
30
|
.map((part) => (!/%[0-9A-Fa-f]/.test(part) ? encodeURI(part) : part))
|
|
31
31
|
.join("");
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
function encodeRFC3986URIComponent(str: string) {
|
|
34
|
+
function encodeRFC3986URIComponent(str: string): string {
|
|
35
35
|
return encodeURIComponent(str).replace(
|
|
36
36
|
/[!'()*]/g,
|
|
37
37
|
(c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`
|
|
38
38
|
);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
function isDefined(val: any) {
|
|
41
|
+
function isDefined(val: any): boolean {
|
|
42
42
|
return val !== undefined && val !== null;
|
|
43
43
|
}
|
|
44
44
|
|
|
@@ -49,7 +49,7 @@ function getNamedAndIfEmpty(op?: string): [boolean, string] {
|
|
|
49
49
|
];
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function getFirstOrSep(op?: string, isFirst = false) {
|
|
52
|
+
function getFirstOrSep(op?: string, isFirst = false): string {
|
|
53
53
|
if (isFirst) {
|
|
54
54
|
return !op || op === "+" ? "" : op;
|
|
55
55
|
} else if (!op || op === "+" || op === "#") {
|
|
@@ -61,7 +61,7 @@ function getFirstOrSep(op?: string, isFirst = false) {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
function getExpandedValue(option: ValueOptions) {
|
|
64
|
+
function getExpandedValue(option: ValueOptions): string {
|
|
65
65
|
let isFirst = option.isFirst;
|
|
66
66
|
const { op, varName, varValue: value, reserved } = option;
|
|
67
67
|
const vals: string[] = [];
|
|
@@ -73,7 +73,11 @@ function getExpandedValue(option: ValueOptions) {
|
|
|
73
73
|
vals.push(`${getFirstOrSep(op, isFirst)}`);
|
|
74
74
|
if (named && varName) {
|
|
75
75
|
vals.push(`${encodeURIComponent(varName)}`);
|
|
76
|
-
val === ""
|
|
76
|
+
if (val === "") {
|
|
77
|
+
vals.push(ifEmpty);
|
|
78
|
+
} else {
|
|
79
|
+
vals.push("=");
|
|
80
|
+
}
|
|
77
81
|
}
|
|
78
82
|
vals.push(encodeComponent(val, reserved, op));
|
|
79
83
|
isFirst = false;
|
|
@@ -88,7 +92,11 @@ function getExpandedValue(option: ValueOptions) {
|
|
|
88
92
|
vals.push(`${getFirstOrSep(op, isFirst)}`);
|
|
89
93
|
if (key) {
|
|
90
94
|
vals.push(`${encodeURIComponent(key)}`);
|
|
91
|
-
named && val === ""
|
|
95
|
+
if (named && val === "") {
|
|
96
|
+
vals.push(ifEmpty);
|
|
97
|
+
} else {
|
|
98
|
+
vals.push("=");
|
|
99
|
+
}
|
|
92
100
|
}
|
|
93
101
|
vals.push(encodeComponent(val, reserved, op));
|
|
94
102
|
isFirst = false;
|
|
@@ -97,7 +105,7 @@ function getExpandedValue(option: ValueOptions) {
|
|
|
97
105
|
return vals.join("");
|
|
98
106
|
}
|
|
99
107
|
|
|
100
|
-
function getNonExpandedValue(option: ValueOptions) {
|
|
108
|
+
function getNonExpandedValue(option: ValueOptions): string | undefined {
|
|
101
109
|
const { op, varName, varValue: value, isFirst, reserved } = option;
|
|
102
110
|
const vals: string[] = [];
|
|
103
111
|
const first = getFirstOrSep(op, isFirst);
|
|
@@ -143,7 +151,11 @@ function getVarValue(option: ValueOptions): string | undefined {
|
|
|
143
151
|
if (named && varName) {
|
|
144
152
|
// No need to encode varName considering it is already encoded
|
|
145
153
|
vals.push(varName);
|
|
146
|
-
val === ""
|
|
154
|
+
if (val === "") {
|
|
155
|
+
vals.push(ifEmpty);
|
|
156
|
+
} else {
|
|
157
|
+
vals.push("=");
|
|
158
|
+
}
|
|
147
159
|
}
|
|
148
160
|
if (modifier && modifier !== "*") {
|
|
149
161
|
val = val.substring(0, parseInt(modifier, 10));
|
|
@@ -165,7 +177,7 @@ export function expandUrlTemplate(
|
|
|
165
177
|
context: Record<string, any>,
|
|
166
178
|
option?: UrlTemplateOptions
|
|
167
179
|
): string {
|
|
168
|
-
return template.replace(/\{([
|
|
180
|
+
return template.replace(/\{([^{}]+)\}|([^{}]+)/g, (_, expr, text) => {
|
|
169
181
|
if (!expr) {
|
|
170
182
|
return encodeReservedComponent(text);
|
|
171
183
|
}
|
|
@@ -177,7 +189,7 @@ export function expandUrlTemplate(
|
|
|
177
189
|
const varList = expr.split(/,/g);
|
|
178
190
|
const result = [];
|
|
179
191
|
for (const varSpec of varList) {
|
|
180
|
-
const varMatch = /([
|
|
192
|
+
const varMatch = /([^:*]*)(?::(\d+)|(\*))?/.exec(varSpec);
|
|
181
193
|
if (!varMatch || !varMatch[1]) {
|
|
182
194
|
continue;
|
|
183
195
|
}
|