@azure-tools/typespec-ts 0.31.0 → 0.32.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 +25 -7
- package/README.md +8 -0
- package/dist/src/contextManager.d.ts +2 -0
- package/dist/src/contextManager.d.ts.map +1 -1
- package/dist/src/contextManager.js.map +1 -1
- package/dist/src/framework/dependency.d.ts +69 -0
- package/dist/src/framework/dependency.d.ts.map +1 -0
- package/dist/src/framework/dependency.js +2 -0
- package/dist/src/framework/dependency.js.map +1 -0
- package/dist/src/framework/hooks/binder.d.ts +8 -2
- package/dist/src/framework/hooks/binder.d.ts.map +1 -1
- package/dist/src/framework/hooks/binder.js +107 -20
- package/dist/src/framework/hooks/binder.js.map +1 -1
- package/dist/src/framework/hooks/useDependencies.d.ts +4 -0
- package/dist/src/framework/hooks/useDependencies.d.ts.map +1 -0
- package/dist/src/framework/hooks/useDependencies.js +13 -0
- package/dist/src/framework/hooks/useDependencies.js.map +1 -0
- package/dist/src/framework/load-static-helpers.d.ts +16 -0
- package/dist/src/framework/load-static-helpers.d.ts.map +1 -0
- package/dist/src/framework/load-static-helpers.js +93 -0
- package/dist/src/framework/load-static-helpers.js.map +1 -0
- package/dist/src/framework/reference.d.ts +1 -1
- package/dist/src/framework/reference.d.ts.map +1 -1
- package/dist/src/framework/reference.js +16 -2
- package/dist/src/framework/reference.js.map +1 -1
- package/dist/src/framework/sample.js +1 -1
- package/dist/src/framework/sample.js.map +1 -1
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +113 -79
- package/dist/src/index.js.map +1 -1
- package/dist/src/lib.d.ts +10 -1
- package/dist/src/lib.d.ts.map +1 -1
- package/dist/src/lib.js +8 -1
- package/dist/src/lib.js.map +1 -1
- package/dist/src/modular/buildClassicalClient.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalClient.js +12 -9
- package/dist/src/modular/buildClassicalClient.js.map +1 -1
- package/dist/src/modular/buildClassicalOperationGroups.d.ts.map +1 -1
- package/dist/src/modular/buildClassicalOperationGroups.js +1 -11
- package/dist/src/modular/buildClassicalOperationGroups.js.map +1 -1
- package/dist/src/modular/buildClientContext.d.ts.map +1 -1
- package/dist/src/modular/buildClientContext.js +73 -52
- package/dist/src/modular/buildClientContext.js.map +1 -1
- package/dist/src/modular/buildCodeModel.d.ts +1 -1
- package/dist/src/modular/buildCodeModel.d.ts.map +1 -1
- package/dist/src/modular/buildCodeModel.js +36 -62
- package/dist/src/modular/buildCodeModel.js.map +1 -1
- package/dist/src/modular/buildHelperSerializers.d.ts.map +1 -1
- package/dist/src/modular/buildHelperSerializers.js.map +1 -1
- package/dist/src/modular/buildOperations.d.ts +1 -3
- package/dist/src/modular/buildOperations.d.ts.map +1 -1
- package/dist/src/modular/buildOperations.js +9 -69
- package/dist/src/modular/buildOperations.js.map +1 -1
- package/dist/src/modular/buildRestorePoller.d.ts +3 -0
- package/dist/src/modular/buildRestorePoller.d.ts.map +1 -0
- package/dist/src/modular/buildRestorePoller.js +203 -0
- package/dist/src/modular/buildRestorePoller.js.map +1 -0
- package/dist/src/modular/buildRootIndex.d.ts.map +1 -1
- package/dist/src/modular/buildRootIndex.js +37 -0
- package/dist/src/modular/buildRootIndex.js.map +1 -1
- package/dist/src/modular/emitLoggerFile.d.ts +4 -0
- package/dist/src/modular/emitLoggerFile.d.ts.map +1 -0
- package/dist/src/modular/emitLoggerFile.js +16 -0
- package/dist/src/modular/emitLoggerFile.js.map +1 -0
- package/dist/src/modular/emitModels.d.ts.map +1 -1
- package/dist/src/modular/emitModels.js +0 -5
- package/dist/src/modular/emitModels.js.map +1 -1
- package/dist/src/modular/external-dependencies.d.ts +26 -0
- package/dist/src/modular/external-dependencies.d.ts.map +1 -0
- package/dist/src/modular/external-dependencies.js +137 -0
- package/dist/src/modular/external-dependencies.js.map +1 -0
- package/dist/src/modular/helpers/clientHelpers.d.ts +13 -6
- package/dist/src/modular/helpers/clientHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/clientHelpers.js +92 -7
- package/dist/src/modular/helpers/clientHelpers.js.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts +6 -1
- package/dist/src/modular/helpers/operationHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/operationHelpers.js +43 -69
- package/dist/src/modular/helpers/operationHelpers.js.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.d.ts +1 -0
- package/dist/src/modular/helpers/typeHelpers.d.ts.map +1 -1
- package/dist/src/modular/helpers/typeHelpers.js +6 -0
- package/dist/src/modular/helpers/typeHelpers.js.map +1 -1
- package/dist/src/modular/interfaces.d.ts +1 -0
- package/dist/src/modular/interfaces.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.d.ts.map +1 -1
- package/dist/src/modular/serialization/buildSerializerFunction.js +2 -20
- package/dist/src/modular/serialization/buildSerializerFunction.js.map +1 -1
- package/dist/src/modular/static-helpers-metadata.d.ts +72 -0
- package/dist/src/modular/static-helpers-metadata.d.ts.map +1 -0
- package/dist/src/modular/static-helpers-metadata.js +72 -0
- package/dist/src/modular/static-helpers-metadata.js.map +1 -0
- package/dist/src/transform/transfromRLCOptions.d.ts.map +1 -1
- package/dist/src/transform/transfromRLCOptions.js +56 -49
- package/dist/src/transform/transfromRLCOptions.js.map +1 -1
- package/dist/src/utils/credentialUtils.d.ts +10 -0
- package/dist/src/utils/credentialUtils.d.ts.map +1 -0
- package/dist/src/utils/credentialUtils.js +37 -0
- package/dist/src/utils/credentialUtils.js.map +1 -0
- package/dist/src/utils/dirname.d.ts +9 -0
- package/dist/src/utils/dirname.d.ts.map +1 -0
- package/dist/src/utils/dirname.js +12 -0
- package/dist/src/utils/dirname.js.map +1 -0
- package/dist/src/utils/emitUtil.d.ts.map +1 -1
- package/dist/src/utils/emitUtil.js +3 -5
- package/dist/src/utils/emitUtil.js.map +1 -1
- package/dist/src/utils/modelUtils.d.ts +1 -1
- package/dist/src/utils/modelUtils.js +3 -2
- package/dist/src/utils/modelUtils.js.map +1 -1
- package/dist/src/utils/operationUtil.d.ts.map +1 -1
- package/dist/src/utils/operationUtil.js +20 -2
- package/dist/src/utils/operationUtil.js.map +1 -1
- package/dist/src/utils/resolve-project-root.d.ts +7 -0
- package/dist/src/utils/resolve-project-root.d.ts.map +1 -0
- package/dist/src/utils/resolve-project-root.js +22 -0
- package/dist/src/utils/resolve-project-root.js.map +1 -0
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +29 -25
- package/src/contextManager.ts +2 -0
- package/src/framework/dependency.ts +56 -0
- package/src/framework/hooks/binder.ts +144 -27
- package/src/framework/hooks/useDependencies.ts +18 -0
- package/src/framework/load-static-helpers.ts +174 -0
- package/src/framework/reference.ts +27 -3
- package/src/framework/sample.ts +1 -1
- package/src/index.ts +154 -113
- package/src/lib.ts +8 -1
- package/src/modular/buildClassicalClient.ts +14 -12
- package/src/modular/buildClassicalOperationGroups.ts +1 -24
- package/src/modular/buildClientContext.ts +93 -63
- package/src/modular/buildCodeModel.ts +93 -128
- package/src/modular/buildHelperSerializers.ts +1 -0
- package/src/modular/buildOperations.ts +9 -110
- package/src/modular/buildRestorePoller.ts +239 -0
- package/src/modular/buildRootIndex.ts +68 -0
- package/src/modular/emitLoggerFile.ts +28 -0
- package/src/modular/emitModels.ts +0 -8
- package/src/modular/external-dependencies.ts +140 -0
- package/src/modular/helpers/clientHelpers.ts +148 -14
- package/src/modular/helpers/operationHelpers.ts +72 -109
- package/src/modular/helpers/typeHelpers.ts +8 -0
- package/src/modular/interfaces.ts +1 -0
- package/src/modular/serialization/buildSerializerFunction.ts +3 -33
- package/src/modular/static-helpers-metadata.ts +73 -0
- package/src/transform/transfromRLCOptions.ts +61 -53
- package/src/utils/credentialUtils.ts +41 -0
- package/src/utils/dirname.ts +12 -0
- package/src/utils/emitUtil.ts +3 -2
- package/src/utils/modelUtils.ts +4 -4
- package/src/utils/operationUtil.ts +25 -2
- package/src/utils/resolve-project-root.ts +28 -0
- package/static/static-helpers/pagingHelpers.ts +274 -0
- package/static/static-helpers/pollingHelpers.ts +137 -0
- package/static/static-helpers/serialization/build-csv-collection.ts +6 -0
- package/static/static-helpers/serialization/build-multi-collection.ts +13 -0
- package/static/static-helpers/serialization/build-pipe-collection.ts +3 -0
- package/static/static-helpers/serialization/build-ssv-collection.ts +3 -0
- package/static/static-helpers/serialization/build-tsv-collection.ts +3 -0
- package/dist/src/modular/buildLroFiles.d.ts +0 -24
- package/dist/src/modular/buildLroFiles.d.ts.map +0 -1
- package/dist/src/modular/buildLroFiles.js +0 -393
- package/dist/src/modular/buildLroFiles.js.map +0 -1
- package/dist/src/modular/buildPagingFiles.d.ts +0 -4
- package/dist/src/modular/buildPagingFiles.d.ts.map +0 -1
- package/dist/src/modular/buildPagingFiles.js +0 -333
- package/dist/src/modular/buildPagingFiles.js.map +0 -1
- package/src/modular/buildLroFiles.ts +0 -429
- package/src/modular/buildPagingFiles.ts +0 -356
|
@@ -8,11 +8,11 @@ import {
|
|
|
8
8
|
import { Project, SourceFile } from "ts-morph";
|
|
9
9
|
import { isRLCMultiEndpoint } from "../utils/clientUtils.js";
|
|
10
10
|
import { SdkContext } from "../utils/interfaces.js";
|
|
11
|
-
import { importLroCoreDependencies } from "./buildLroFiles.js";
|
|
12
11
|
import { getDocsFromDescription } from "./helpers/docsHelpers.js";
|
|
13
12
|
import { getOperationName } from "./helpers/namingHelpers.js";
|
|
14
13
|
import {
|
|
15
14
|
getDeserializePrivateFunction,
|
|
15
|
+
getExpectedStatuses,
|
|
16
16
|
getOperationFunction,
|
|
17
17
|
getOperationOptionsName,
|
|
18
18
|
getSendPrivateFunction,
|
|
@@ -30,8 +30,7 @@ import { addImportBySymbol } from "../utils/importHelper.js";
|
|
|
30
30
|
export function buildOperationFiles(
|
|
31
31
|
client: Client,
|
|
32
32
|
dpgContext: SdkContext,
|
|
33
|
-
codeModel: ModularCodeModel
|
|
34
|
-
needUnexpectedHelper: boolean = true
|
|
33
|
+
codeModel: ModularCodeModel
|
|
35
34
|
) {
|
|
36
35
|
const operationFiles = [];
|
|
37
36
|
const isMultiEndpoint = isRLCMultiEndpoint(dpgContext);
|
|
@@ -58,11 +57,6 @@ export function buildOperationFiles(
|
|
|
58
57
|
subfolder && subfolder !== "" ? subfolder + "/" : ""
|
|
59
58
|
}api/${operationFileName}.ts`
|
|
60
59
|
);
|
|
61
|
-
// We need to import the lro helpers and types explicitly because ts-morph may not be able to find correct ones.
|
|
62
|
-
importLroDependencies(
|
|
63
|
-
operationGroupFile,
|
|
64
|
-
operationGroup.namespaceHierarchies.length
|
|
65
|
-
);
|
|
66
60
|
|
|
67
61
|
// Import models used from ./models.ts
|
|
68
62
|
// We SHOULD keep this because otherwise ts-morph will "helpfully" try to import models from the rest layer when we call fixMissingImports().
|
|
@@ -94,46 +88,13 @@ export function buildOperationFiles(
|
|
|
94
88
|
operationGroup.namespaceHierarchies.length
|
|
95
89
|
);
|
|
96
90
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
operationGroup.namespaceHierarchies.length
|
|
104
|
-
);
|
|
91
|
+
const indexPathPrefix =
|
|
92
|
+
"../".repeat(operationGroup.namespaceHierarchies.length) || "./";
|
|
93
|
+
operationGroupFile.addImportDeclaration({
|
|
94
|
+
namedImports: [`${client.rlcClientName} as Client`],
|
|
95
|
+
moduleSpecifier: `${indexPathPrefix}index.js`
|
|
96
|
+
});
|
|
105
97
|
|
|
106
|
-
const namedImports: string[] = [];
|
|
107
|
-
if (isMultiEndpoint) {
|
|
108
|
-
namedImports.push(`Client`);
|
|
109
|
-
if (needUnexpectedHelper) {
|
|
110
|
-
namedImports.push("UnexpectedHelper");
|
|
111
|
-
}
|
|
112
|
-
operationGroupFile.addImportDeclarations([
|
|
113
|
-
{
|
|
114
|
-
moduleSpecifier: `../${"../".repeat(
|
|
115
|
-
operationGroup.namespaceHierarchies.length
|
|
116
|
-
)}rest/${subfolder}/index.js`,
|
|
117
|
-
namedImports
|
|
118
|
-
}
|
|
119
|
-
]);
|
|
120
|
-
} else {
|
|
121
|
-
if (needUnexpectedHelper) {
|
|
122
|
-
namedImports.push("isUnexpected");
|
|
123
|
-
}
|
|
124
|
-
const rlcClientName = client.rlcClientName;
|
|
125
|
-
namedImports.push(`${rlcClientName} as Client`);
|
|
126
|
-
operationGroupFile.addImportDeclarations([
|
|
127
|
-
{
|
|
128
|
-
moduleSpecifier: `${
|
|
129
|
-
subfolder && subfolder !== "" ? "../" : ""
|
|
130
|
-
}${"../".repeat(
|
|
131
|
-
operationGroup.namespaceHierarchies.length + 1
|
|
132
|
-
)}rest/index.js`,
|
|
133
|
-
namedImports
|
|
134
|
-
}
|
|
135
|
-
]);
|
|
136
|
-
}
|
|
137
98
|
operationGroup.operations.forEach((o) => {
|
|
138
99
|
const operationDeclaration = getOperationFunction(o, clientType);
|
|
139
100
|
const sendOperationDeclaration = getSendPrivateFunction(
|
|
@@ -144,8 +105,6 @@ export function buildOperationFiles(
|
|
|
144
105
|
);
|
|
145
106
|
const deserializeOperationDeclaration = getDeserializePrivateFunction(
|
|
146
107
|
o,
|
|
147
|
-
isMultiEndpoint,
|
|
148
|
-
needUnexpectedHelper,
|
|
149
108
|
codeModel.runtimeImports
|
|
150
109
|
);
|
|
151
110
|
operationGroupFile.addFunctions([
|
|
@@ -171,9 +130,6 @@ export function buildOperationFiles(
|
|
|
171
130
|
addImportsToFiles(codeModel.runtimeImports, operationGroupFile);
|
|
172
131
|
addImportBySymbol("serializeRecord", operationGroupFile);
|
|
173
132
|
|
|
174
|
-
operationGroupFile.fixMissingImports();
|
|
175
|
-
// have to fixUnusedIdentifiers after everything get generated.
|
|
176
|
-
operationGroupFile.fixUnusedIdentifiers();
|
|
177
133
|
operationFiles.push(operationGroupFile);
|
|
178
134
|
}
|
|
179
135
|
return operationFiles;
|
|
@@ -246,64 +202,6 @@ export function importDeserializeUtils(
|
|
|
246
202
|
});
|
|
247
203
|
}
|
|
248
204
|
}
|
|
249
|
-
// Import all deserializeUtil and then let ts-morph clean up the unused ones
|
|
250
|
-
// we can't fixUnusedIdentifiers here because the operaiton files are still being generated.
|
|
251
|
-
// sourceFile.fixUnusedIdentifiers();
|
|
252
|
-
export function importPagingDependencies(
|
|
253
|
-
srcPath: string,
|
|
254
|
-
sourceFile: SourceFile,
|
|
255
|
-
project: Project,
|
|
256
|
-
subfolder: string = "",
|
|
257
|
-
importLayer: number = 0
|
|
258
|
-
) {
|
|
259
|
-
const pagingTypes = project.getSourceFile(
|
|
260
|
-
`${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}models/pagingTypes.ts`
|
|
261
|
-
);
|
|
262
|
-
|
|
263
|
-
if (!pagingTypes) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const exportedPaingTypes = [...pagingTypes.getExportedDeclarations().keys()];
|
|
268
|
-
|
|
269
|
-
sourceFile.addImportDeclaration({
|
|
270
|
-
moduleSpecifier: `${"../".repeat(importLayer + 1)}models/pagingTypes.js`,
|
|
271
|
-
namedImports: exportedPaingTypes
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
const pagingHelper = project.getSourceFile(
|
|
275
|
-
`${srcPath}/${subfolder !== "" ? subfolder + "/" : ""}api/pagingHelpers.ts`
|
|
276
|
-
);
|
|
277
|
-
|
|
278
|
-
if (!pagingHelper) {
|
|
279
|
-
return;
|
|
280
|
-
}
|
|
281
|
-
|
|
282
|
-
const exportedPaingHelpers = [
|
|
283
|
-
...pagingHelper.getExportedDeclarations().keys()
|
|
284
|
-
];
|
|
285
|
-
|
|
286
|
-
sourceFile.addImportDeclaration({
|
|
287
|
-
moduleSpecifier: `${
|
|
288
|
-
importLayer === 0 ? "./" : "../".repeat(importLayer)
|
|
289
|
-
}pagingHelpers.js`,
|
|
290
|
-
namedImports: exportedPaingHelpers
|
|
291
|
-
});
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
export function importLroDependencies(
|
|
295
|
-
sourceFile: SourceFile,
|
|
296
|
-
importLayer: number = 0
|
|
297
|
-
) {
|
|
298
|
-
sourceFile.addImportDeclaration({
|
|
299
|
-
moduleSpecifier: `${
|
|
300
|
-
importLayer === 0 ? "./" : "../".repeat(importLayer)
|
|
301
|
-
}pollingHelpers.js`,
|
|
302
|
-
namedImports: ["getLongRunningPoller"]
|
|
303
|
-
});
|
|
304
|
-
|
|
305
|
-
importLroCoreDependencies(sourceFile);
|
|
306
|
-
}
|
|
307
205
|
|
|
308
206
|
/**
|
|
309
207
|
* This function generates the interfaces for each operation options
|
|
@@ -383,6 +281,7 @@ export function buildLroDeserDetailMap(client: Client) {
|
|
|
383
281
|
existingNames.add(deserName);
|
|
384
282
|
return {
|
|
385
283
|
path: `${o.method.toUpperCase()} ${o.url}`,
|
|
284
|
+
expectedStatusesExpression: getExpectedStatuses(o),
|
|
386
285
|
deserName,
|
|
387
286
|
renamedDeserName
|
|
388
287
|
};
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
import { SourceFile } from "ts-morph";
|
|
2
|
+
import { isLroOnlyOperation } from "./helpers/operationHelpers.js";
|
|
3
|
+
import { ModularCodeModel, Client } from "./modularCodeModel.js";
|
|
4
|
+
import path from "path";
|
|
5
|
+
import { buildLroDeserDetailMap } from "./buildOperations.js";
|
|
6
|
+
import { getClientName } from "./helpers/namingHelpers.js";
|
|
7
|
+
import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
8
|
+
import { resolveReference } from "../framework/reference.js";
|
|
9
|
+
import {
|
|
10
|
+
AzureCoreDependencies,
|
|
11
|
+
AzurePollingDependencies
|
|
12
|
+
} from "./external-dependencies.js";
|
|
13
|
+
import { PollingHelpers } from "./static-helpers-metadata.js";
|
|
14
|
+
|
|
15
|
+
export function buildRestorePoller(
|
|
16
|
+
codeModel: ModularCodeModel,
|
|
17
|
+
client: Client
|
|
18
|
+
) {
|
|
19
|
+
const lros = client.operationGroups
|
|
20
|
+
.flatMap((op) => op.operations)
|
|
21
|
+
.filter(isLroOnlyOperation);
|
|
22
|
+
if (lros.length === 0) {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
const srcPath = codeModel.modularOptions.sourceRoot;
|
|
26
|
+
const subfolder = client.subfolder ?? "";
|
|
27
|
+
const filePath = path.join(
|
|
28
|
+
`${srcPath}/${
|
|
29
|
+
subfolder !== "" ? subfolder + "/" : ""
|
|
30
|
+
}restorePollerHelpers.ts`
|
|
31
|
+
);
|
|
32
|
+
const restorePollerFile = codeModel.project.createSourceFile(
|
|
33
|
+
filePath,
|
|
34
|
+
undefined,
|
|
35
|
+
{
|
|
36
|
+
overwrite: true
|
|
37
|
+
}
|
|
38
|
+
);
|
|
39
|
+
|
|
40
|
+
const clientNames = importClassicalClient(client, restorePollerFile);
|
|
41
|
+
const deserializeMap = importDeserializeHelpers(client, restorePollerFile);
|
|
42
|
+
const pathUncheckedReference = resolveReference(
|
|
43
|
+
AzureCoreDependencies.PathUncheckedResponse
|
|
44
|
+
);
|
|
45
|
+
const pollerLikeReference = resolveReference(
|
|
46
|
+
AzurePollingDependencies.PollerLike
|
|
47
|
+
);
|
|
48
|
+
const operationStateReference = resolveReference(
|
|
49
|
+
AzurePollingDependencies.OperationState
|
|
50
|
+
);
|
|
51
|
+
const operationOptionsReference = resolveReference(
|
|
52
|
+
AzureCoreDependencies.OperationOptions
|
|
53
|
+
);
|
|
54
|
+
const deserializeStateReference = resolveReference(
|
|
55
|
+
AzurePollingDependencies.DeserializeState
|
|
56
|
+
);
|
|
57
|
+
const restorePollerHelperContent = `
|
|
58
|
+
export interface RestorePollerOptions<
|
|
59
|
+
TResult,
|
|
60
|
+
TResponse extends ${pathUncheckedReference} = ${pathUncheckedReference}
|
|
61
|
+
> extends ${operationOptionsReference} {
|
|
62
|
+
/** Delay to wait until next poll, in milliseconds. */
|
|
63
|
+
updateIntervalInMs?: number;
|
|
64
|
+
/**
|
|
65
|
+
* The signal which can be used to abort requests.
|
|
66
|
+
*/
|
|
67
|
+
abortSignal?: ${resolveReference(AzureCoreDependencies.AbortSignalLike)};
|
|
68
|
+
/** Deserialization function for raw response body */
|
|
69
|
+
processResponseBody?: (result: TResponse) => Promise<TResult>;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Creates a poller from the serialized state of another poller. This can be
|
|
74
|
+
* useful when you want to create pollers on a different host or a poller
|
|
75
|
+
* needs to be constructed after the original one is not in scope.
|
|
76
|
+
*/
|
|
77
|
+
export function restorePoller<TResponse extends ${pathUncheckedReference}, TResult>(
|
|
78
|
+
client: ${clientNames.join(" | ")},
|
|
79
|
+
serializedState: string,
|
|
80
|
+
sourceOperation: (
|
|
81
|
+
...args: any[]
|
|
82
|
+
) => ${pollerLikeReference}<${operationStateReference}<TResult>, TResult>,
|
|
83
|
+
options?: RestorePollerOptions<TResult>
|
|
84
|
+
): ${pollerLikeReference}<${operationStateReference}<TResult>, TResult> {
|
|
85
|
+
const pollerConfig = ${deserializeStateReference}(serializedState).config;
|
|
86
|
+
const { initialRequestUrl, requestMethod, metadata } = pollerConfig;
|
|
87
|
+
if (!initialRequestUrl || !requestMethod) {
|
|
88
|
+
throw new Error(
|
|
89
|
+
\`Invalid serialized state: \${serializedState} for sourceOperation \${sourceOperation?.name}\`
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
const resourceLocationConfig = metadata?.["resourceLocationConfig"] as
|
|
93
|
+
| ${resolveReference(AzurePollingDependencies.ResourceLocationConfig)}
|
|
94
|
+
| undefined;
|
|
95
|
+
const { deserializer, expectedStatuses = [] } =
|
|
96
|
+
getDeserializationHelper(initialRequestUrl, requestMethod) ?? {};
|
|
97
|
+
const deserializeHelper = options?.processResponseBody ?? deserializer;
|
|
98
|
+
if (!deserializeHelper) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
\`Please ensure the operation is in this client! We can't find its deserializeHelper for \${sourceOperation?.name}.\`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
return ${resolveReference(PollingHelpers.GetLongRunningPoller)}(
|
|
104
|
+
(client as any)["_client"] ?? client,
|
|
105
|
+
deserializeHelper as (result: TResponse) => Promise<TResult>,
|
|
106
|
+
expectedStatuses,
|
|
107
|
+
{
|
|
108
|
+
updateIntervalInMs: options?.updateIntervalInMs,
|
|
109
|
+
abortSignal: options?.abortSignal,
|
|
110
|
+
resourceLocationConfig,
|
|
111
|
+
restoreFrom: serializedState,
|
|
112
|
+
initialRequestUrl
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
interface DeserializationHelper {
|
|
118
|
+
deserializer: Function;
|
|
119
|
+
expectedStatuses: string[];
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const deserializeMap: Record<string, DeserializationHelper> = {
|
|
123
|
+
${deserializeMap.join(",\n")}
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
function getDeserializationHelper(
|
|
127
|
+
urlStr: string,
|
|
128
|
+
method: string
|
|
129
|
+
): DeserializationHelper | undefined {
|
|
130
|
+
const path = new URL(urlStr).pathname;
|
|
131
|
+
const pathParts = path.split("/");
|
|
132
|
+
|
|
133
|
+
// Traverse list to match the longest candidate
|
|
134
|
+
// matchedLen: the length of candidate path
|
|
135
|
+
// matchedValue: the matched status code array
|
|
136
|
+
let matchedLen = -1,
|
|
137
|
+
matchedValue: DeserializationHelper | undefined;
|
|
138
|
+
|
|
139
|
+
// Iterate the responseMap to find a match
|
|
140
|
+
for (const [key, value] of Object.entries(deserializeMap)) {
|
|
141
|
+
// Extracting the path from the map key which is in format
|
|
142
|
+
// GET /path/foo
|
|
143
|
+
if (!key.startsWith(method)) {
|
|
144
|
+
continue;
|
|
145
|
+
}
|
|
146
|
+
const candidatePath = getPathFromMapKey(key);
|
|
147
|
+
// Get each part of the url path
|
|
148
|
+
const candidateParts = candidatePath.split("/");
|
|
149
|
+
|
|
150
|
+
// track if we have found a match to return the values found.
|
|
151
|
+
let found = true;
|
|
152
|
+
for (
|
|
153
|
+
let i = candidateParts.length - 1, j = pathParts.length - 1;
|
|
154
|
+
i >= 1 && j >= 1;
|
|
155
|
+
i--, j--
|
|
156
|
+
) {
|
|
157
|
+
if (
|
|
158
|
+
candidateParts[i]?.startsWith("{") &&
|
|
159
|
+
candidateParts[i]?.indexOf("}") !== -1
|
|
160
|
+
) {
|
|
161
|
+
const start = candidateParts[i]!.indexOf("}") + 1,
|
|
162
|
+
end = candidateParts[i]?.length;
|
|
163
|
+
// If the current part of the candidate is a "template" part
|
|
164
|
+
// Try to use the suffix of pattern to match the path
|
|
165
|
+
// {guid} ==> $
|
|
166
|
+
// {guid}:export ==> :export$
|
|
167
|
+
const isMatched = new RegExp(
|
|
168
|
+
\`\${candidateParts[i]?.slice(start, end)}\`
|
|
169
|
+
).test(pathParts[j] || "");
|
|
170
|
+
|
|
171
|
+
if (!isMatched) {
|
|
172
|
+
found = false;
|
|
173
|
+
break;
|
|
174
|
+
}
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// If the candidate part is not a template and
|
|
179
|
+
// the parts don't match mark the candidate as not found
|
|
180
|
+
// to move on with the next candidate path.
|
|
181
|
+
if (candidateParts[i] !== pathParts[j]) {
|
|
182
|
+
found = false;
|
|
183
|
+
break;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// We finished evaluating the current candidate parts
|
|
188
|
+
// Update the matched value if and only if we found the longer pattern
|
|
189
|
+
if (found && candidatePath.length > matchedLen) {
|
|
190
|
+
matchedLen = candidatePath.length;
|
|
191
|
+
matchedValue = value;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
return matchedValue;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
function getPathFromMapKey(mapKey: string): string {
|
|
199
|
+
const pathStart = mapKey.indexOf("/");
|
|
200
|
+
return mapKey.slice(pathStart);
|
|
201
|
+
}
|
|
202
|
+
`;
|
|
203
|
+
restorePollerFile.addStatements(restorePollerHelperContent);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function importDeserializeHelpers(client: Client, sourceFile: SourceFile) {
|
|
207
|
+
const deserializeDetails = buildLroDeserDetailMap(client);
|
|
208
|
+
const deserializeMap: string[] = [];
|
|
209
|
+
for (const [key, value] of deserializeDetails.entries()) {
|
|
210
|
+
sourceFile.addImportDeclaration({
|
|
211
|
+
namedImports: value.map((detail) =>
|
|
212
|
+
detail.renamedDeserName
|
|
213
|
+
? `${detail.deserName} as ${detail.renamedDeserName}`
|
|
214
|
+
: detail.deserName
|
|
215
|
+
),
|
|
216
|
+
moduleSpecifier: key
|
|
217
|
+
});
|
|
218
|
+
value.forEach((detail) => {
|
|
219
|
+
deserializeMap.push(
|
|
220
|
+
`"${detail.path}": { deserializer: ${
|
|
221
|
+
detail.renamedDeserName ?? detail.deserName
|
|
222
|
+
}, expectedStatuses: ${detail.expectedStatusesExpression} }`
|
|
223
|
+
);
|
|
224
|
+
});
|
|
225
|
+
}
|
|
226
|
+
return deserializeMap;
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
function importClassicalClient(
|
|
230
|
+
client: Client,
|
|
231
|
+
sourceFile: SourceFile
|
|
232
|
+
): string[] {
|
|
233
|
+
const classicalClientName = `${getClientName(client)}Client`;
|
|
234
|
+
sourceFile.addImportDeclaration({
|
|
235
|
+
namedImports: [`${classicalClientName}`],
|
|
236
|
+
moduleSpecifier: `./${normalizeName(classicalClientName, NameType.File)}.js`
|
|
237
|
+
});
|
|
238
|
+
return [classicalClientName];
|
|
239
|
+
}
|
|
@@ -2,6 +2,8 @@ import { NameType, normalizeName } from "@azure-tools/rlc-common";
|
|
|
2
2
|
import { Project, SourceFile } from "ts-morph";
|
|
3
3
|
import { getClientName } from "./helpers/namingHelpers.js";
|
|
4
4
|
import { Client, ModularCodeModel } from "./modularCodeModel.js";
|
|
5
|
+
import { resolveReference } from "../framework/reference.js";
|
|
6
|
+
import { PagingHelpers } from "./static-helpers-metadata.js";
|
|
5
7
|
|
|
6
8
|
export function buildRootIndex(
|
|
7
9
|
client: Client,
|
|
@@ -55,6 +57,72 @@ export function buildRootIndex(
|
|
|
55
57
|
subfolder,
|
|
56
58
|
true
|
|
57
59
|
);
|
|
60
|
+
|
|
61
|
+
exportPagingTypes(codeModel, rootIndexFile);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* This is a temporary solution for adding paging exports. Eventually we will have the binder generate the exports automatically.
|
|
66
|
+
*/
|
|
67
|
+
function exportPagingTypes(
|
|
68
|
+
codeModel: ModularCodeModel,
|
|
69
|
+
rootIndexFile: SourceFile
|
|
70
|
+
) {
|
|
71
|
+
if (!hasPaging(codeModel)) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const existingExports = getExistingExports(rootIndexFile);
|
|
76
|
+
const namedExports = [
|
|
77
|
+
resolveReference(PagingHelpers.PageSettings),
|
|
78
|
+
resolveReference(PagingHelpers.ContinuablePage),
|
|
79
|
+
resolveReference(PagingHelpers.PagedAsyncIterableIterator)
|
|
80
|
+
];
|
|
81
|
+
|
|
82
|
+
const newNamedExports = getNewNamedExports(namedExports, existingExports);
|
|
83
|
+
|
|
84
|
+
if (newNamedExports.length > 0) {
|
|
85
|
+
addExportsToRootIndexFile(rootIndexFile, newNamedExports);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
function hasPaging(codeModel: ModularCodeModel): boolean {
|
|
90
|
+
return codeModel.clients.some((c) =>
|
|
91
|
+
c.operationGroups.some((og) =>
|
|
92
|
+
og.operations.some(
|
|
93
|
+
(op) =>
|
|
94
|
+
op.discriminator === "paging" || op.discriminator === "lropaging"
|
|
95
|
+
)
|
|
96
|
+
)
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
function getExistingExports(rootIndexFile: SourceFile): Set<string> {
|
|
101
|
+
return new Set(
|
|
102
|
+
rootIndexFile
|
|
103
|
+
.getExportDeclarations()
|
|
104
|
+
.flatMap((exportDecl) =>
|
|
105
|
+
exportDecl.getNamedExports().map((namedExport) => namedExport.getName())
|
|
106
|
+
)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function getNewNamedExports(
|
|
111
|
+
namedExports: string[],
|
|
112
|
+
existingExports: Set<string>
|
|
113
|
+
): string[] {
|
|
114
|
+
return namedExports.filter(
|
|
115
|
+
(namedExport) => !existingExports.has(namedExport)
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function addExportsToRootIndexFile(
|
|
120
|
+
rootIndexFile: SourceFile,
|
|
121
|
+
newNamedExports: string[]
|
|
122
|
+
) {
|
|
123
|
+
rootIndexFile.addExportDeclaration({
|
|
124
|
+
namedExports: newNamedExports
|
|
125
|
+
});
|
|
58
126
|
}
|
|
59
127
|
|
|
60
128
|
function exportRestoreHelpers(
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Project } from "ts-morph";
|
|
2
|
+
import { ModularCodeModel } from "./modularCodeModel.js";
|
|
3
|
+
|
|
4
|
+
export function emitLoggerFile(
|
|
5
|
+
codeModel: ModularCodeModel,
|
|
6
|
+
project: Project,
|
|
7
|
+
srcPath: string = "src"
|
|
8
|
+
) {
|
|
9
|
+
if (codeModel.options.flavor !== "azure") {
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const sourceFile = project.createSourceFile(`${srcPath}/logger.ts`, "", {
|
|
14
|
+
overwrite: true
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
sourceFile.addImportDeclaration({
|
|
18
|
+
namedImports: ["createClientLogger"],
|
|
19
|
+
moduleSpecifier: "@azure/logger"
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
const name =
|
|
23
|
+
codeModel.options.packageDetails?.nameWithoutScope ??
|
|
24
|
+
codeModel.options.packageDetails?.name;
|
|
25
|
+
sourceFile.addStatements(
|
|
26
|
+
`export const logger = createClientLogger("${name}");`
|
|
27
|
+
);
|
|
28
|
+
}
|
|
@@ -253,7 +253,6 @@ export function buildModels(
|
|
|
253
253
|
|
|
254
254
|
const projectRootFromModels = codeModel.clients.length > 1 ? "../.." : "../";
|
|
255
255
|
addImportsToFiles(codeModel.runtimeImports, modelsFile, {
|
|
256
|
-
rlcIndex: path.posix.join(projectRootFromModels, "rest", "index.js"),
|
|
257
256
|
serializerHelpers: path.posix.join(
|
|
258
257
|
projectRootFromModels,
|
|
259
258
|
"helpers",
|
|
@@ -394,13 +393,6 @@ export function buildModelsOptions(
|
|
|
394
393
|
}
|
|
395
394
|
]);
|
|
396
395
|
|
|
397
|
-
modelOptionsFile.fixMissingImports(
|
|
398
|
-
{},
|
|
399
|
-
{
|
|
400
|
-
importModuleSpecifierPreference: "shortest",
|
|
401
|
-
importModuleSpecifierEnding: "js"
|
|
402
|
-
}
|
|
403
|
-
);
|
|
404
396
|
modelOptionsFile
|
|
405
397
|
.getImportDeclarations()
|
|
406
398
|
.filter((id) => {
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { CoreDependencies } from "../framework/dependency.js";
|
|
2
|
+
|
|
3
|
+
export const DefaultCoreDependencies: CoreDependencies = {
|
|
4
|
+
Client: {
|
|
5
|
+
kind: "externalDependency",
|
|
6
|
+
name: "Client",
|
|
7
|
+
module: "@typespec/ts-http-runtime"
|
|
8
|
+
},
|
|
9
|
+
ClientOptions: {
|
|
10
|
+
kind: "externalDependency",
|
|
11
|
+
name: "ClientOptions",
|
|
12
|
+
module: "@typespec/ts-http-runtime"
|
|
13
|
+
},
|
|
14
|
+
Pipeline: {
|
|
15
|
+
kind: "externalDependency",
|
|
16
|
+
name: "Pipeline",
|
|
17
|
+
module: "@typespec/ts-http-runtime"
|
|
18
|
+
},
|
|
19
|
+
getClient: {
|
|
20
|
+
kind: "externalDependency",
|
|
21
|
+
name: "getClient",
|
|
22
|
+
module: "@typespec/ts-http-runtime"
|
|
23
|
+
},
|
|
24
|
+
RestError: {
|
|
25
|
+
kind: "externalDependency",
|
|
26
|
+
name: "RestError",
|
|
27
|
+
module: "@typespec/ts-http-runtime"
|
|
28
|
+
},
|
|
29
|
+
OperationOptions: {
|
|
30
|
+
kind: "externalDependency",
|
|
31
|
+
name: "OperationOptions",
|
|
32
|
+
module: "@typespec/ts-http-runtime"
|
|
33
|
+
},
|
|
34
|
+
PathUncheckedResponse: {
|
|
35
|
+
kind: "externalDependency",
|
|
36
|
+
name: "PathUncheckedResponse",
|
|
37
|
+
module: "@typespec/ts-http-runtime"
|
|
38
|
+
},
|
|
39
|
+
AbortSignalLike: {
|
|
40
|
+
kind: "externalDependency",
|
|
41
|
+
name: "AbortSignalLike",
|
|
42
|
+
module: "@typespec/ts-http-runtime"
|
|
43
|
+
},
|
|
44
|
+
createRestError: {
|
|
45
|
+
kind: "externalDependency",
|
|
46
|
+
name: "createRestError",
|
|
47
|
+
module: "@typespec/ts-http-runtime"
|
|
48
|
+
},
|
|
49
|
+
operationOptionsToRequestParameters: {
|
|
50
|
+
kind: "externalDependency",
|
|
51
|
+
name: "operationOptionsToRequestParameters",
|
|
52
|
+
module: "@typespec/ts-http-runtime"
|
|
53
|
+
},
|
|
54
|
+
uint8ArrayToString: {
|
|
55
|
+
kind: "externalDependency",
|
|
56
|
+
name: "uint8ArrayToString",
|
|
57
|
+
module: "@typespec/ts-http-runtime"
|
|
58
|
+
}
|
|
59
|
+
} as const;
|
|
60
|
+
|
|
61
|
+
export const AzurePollingDependencies = {
|
|
62
|
+
PollerLike: {
|
|
63
|
+
kind: "externalDependency",
|
|
64
|
+
module: "@azure/core-lro",
|
|
65
|
+
name: "PollerLike"
|
|
66
|
+
},
|
|
67
|
+
OperationState: {
|
|
68
|
+
kind: "externalDependency",
|
|
69
|
+
module: "@azure/core-lro",
|
|
70
|
+
name: "OperationState"
|
|
71
|
+
},
|
|
72
|
+
DeserializeState: {
|
|
73
|
+
kind: "externalDependency",
|
|
74
|
+
module: "@azure/core-lro",
|
|
75
|
+
name: "deserializeState"
|
|
76
|
+
},
|
|
77
|
+
ResourceLocationConfig: {
|
|
78
|
+
kind: "externalDependency",
|
|
79
|
+
module: "@azure/core-lro",
|
|
80
|
+
name: "ResourceLocationConfig"
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const AzureCoreDependencies: CoreDependencies = {
|
|
85
|
+
Client: {
|
|
86
|
+
kind: "externalDependency",
|
|
87
|
+
module: "@azure-rest/core-client",
|
|
88
|
+
name: "Client"
|
|
89
|
+
},
|
|
90
|
+
ClientOptions: {
|
|
91
|
+
kind: "externalDependency",
|
|
92
|
+
module: "@azure-rest/core-client",
|
|
93
|
+
name: "ClientOptions"
|
|
94
|
+
},
|
|
95
|
+
Pipeline: {
|
|
96
|
+
kind: "externalDependency",
|
|
97
|
+
module: "@azure-rest/core-client",
|
|
98
|
+
name: "Pipeline"
|
|
99
|
+
},
|
|
100
|
+
getClient: {
|
|
101
|
+
kind: "externalDependency",
|
|
102
|
+
module: "@azure-rest/core-client",
|
|
103
|
+
name: "getClient"
|
|
104
|
+
},
|
|
105
|
+
RestError: {
|
|
106
|
+
kind: "externalDependency",
|
|
107
|
+
module: "@azure-rest/core-client",
|
|
108
|
+
name: "RestError"
|
|
109
|
+
},
|
|
110
|
+
OperationOptions: {
|
|
111
|
+
kind: "externalDependency",
|
|
112
|
+
module: "@azure-rest/core-client",
|
|
113
|
+
name: "OperationOptions"
|
|
114
|
+
},
|
|
115
|
+
PathUncheckedResponse: {
|
|
116
|
+
kind: "externalDependency",
|
|
117
|
+
module: "@azure-rest/core-client",
|
|
118
|
+
name: "PathUncheckedResponse"
|
|
119
|
+
},
|
|
120
|
+
AbortSignalLike: {
|
|
121
|
+
kind: "externalDependency",
|
|
122
|
+
module: "@azure/abort-controller",
|
|
123
|
+
name: "AbortSignalLike"
|
|
124
|
+
},
|
|
125
|
+
createRestError: {
|
|
126
|
+
kind: "externalDependency",
|
|
127
|
+
module: "@azure-rest/core-client",
|
|
128
|
+
name: "createRestError"
|
|
129
|
+
},
|
|
130
|
+
operationOptionsToRequestParameters: {
|
|
131
|
+
kind: "externalDependency",
|
|
132
|
+
module: "@azure-rest/core-client",
|
|
133
|
+
name: "operationOptionsToRequestParameters"
|
|
134
|
+
},
|
|
135
|
+
uint8ArrayToString: {
|
|
136
|
+
kind: "externalDependency",
|
|
137
|
+
module: "@azure/core-util",
|
|
138
|
+
name: "uint8ArrayToString"
|
|
139
|
+
}
|
|
140
|
+
};
|