@azure-rest/ai-translation-document 1.0.0-beta.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 ADDED
@@ -0,0 +1,23 @@
1
+ # Release History
2
+ ## 1.0.0-beta.1 (2024-06-27)
3
+ - Initial release. Please see the README and wiki for information on the new design.
4
+
5
+ Version 1.0.0-beta.1 is preview of our efforts in creating a client library that is developer-friendly, idiomatic
6
+ to the JS/TS ecosystem, and as consistent across different languages and platforms as possible.
7
+
8
+ This package's
9
+ [documentation](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/translation/ai-translation-document-rest/README.md)
10
+ and
11
+ [samples](https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/translation/ai-translation-document-rest/samples)
12
+ demonstrate the new API.
13
+
14
+ ### Features Added
15
+ - Added support for Synchronous document translation - [translate-document API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/translate-document)
16
+ - Added support for Batch Translation - [start Translation API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/start-batch-translation)
17
+ - Added support for Get Translations Status - [get translations status API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-translations-status)
18
+ - Added support for Get Translation Status - [get translation status API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-translation-status)
19
+ - Added support for Get Documents Status - [get documents status API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-documents-status)
20
+ - Added support for Get Document Status - [get document status API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-document-status)
21
+ - Added support for Cancel Translation - [cancel translation API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/cancel-translation)
22
+ - Added support for Get Supported Document Formats - [get supported document formats API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-supported-document-formats)
23
+ - Added support for Get Supported Glossary Formats - [get supported glossary formats API](https://learn.microsoft.com/azure/ai-services/translator/document-translation/reference/get-supported-glossary-formats)
package/README.md ADDED
@@ -0,0 +1,346 @@
1
+ # DocumentTranslation REST client library for JavaScript
2
+
3
+ Document Translation is a cloud-based machine translation feature of the Azure AI Translator service. You can translate multiple and complex documents across all supported languages and dialects while preserving original document structure and data format. The Document translation API supports two translation processes:
4
+
5
+ Asynchronous batch translation supports the processing of multiple documents and large files. The batch translation process requires an Azure Blob storage account with storage containers for your source and translated documents.
6
+
7
+ Synchronous single file supports the processing of single file translations. The file translation process doesn't require an Azure Blob storage account. The final response contains the translated document and is returned directly to the calling client.
8
+
9
+ The following operations are supported by the Document Translation feature:
10
+
11
+ - **Synchronous document translation**: Used to synchronously translate a single document. The method doesn't require an Azure Blob storage account.
12
+
13
+ - **Start batch translation**: Used to execute an asynchronous batch translation request. The method requires an Azure Blob storage account with storage containers for your source and translated documents.
14
+
15
+ - **Get status for all translation jobs**: Used to request a list and the status of all translation jobs submitted by the user (associated with the resource).
16
+
17
+ - **Get status for a specific translation job**: Used to request the status of a specific translation job. The response includes the overall job status and the status for documents that are being translated as part of that job.
18
+
19
+ - **Get status for all documents**: Used to request the status for all documents in a translation job.
20
+
21
+ - **Get status for a specific document**: This returns the status for a specific document in a job as indicated in the request by the id and documentId query parameters.
22
+
23
+ - **Cancel translation**: This cancels a translation job that is currently processing or queued (pending) as indicated in the request by the id query parameter. An operation isn't canceled if already completed, failed, or still canceling. In those instances, a bad request is returned. Completed translations can't be canceled and are charged.
24
+
25
+ - **Get supported formats**: This returns a list of document or glossary formats supported by the Document Translation feature. The list includes common file extensions and content-type if using the upload API.
26
+
27
+ Key links:
28
+
29
+ - [Source code](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-document-rest)
30
+ - [Package (NPM)](https://www.npmjs.com/package/@azure-rest/ai-translation-document)
31
+ - [Samples](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/translation/ai-translation-document-rest/samples)
32
+
33
+ ## Getting started
34
+
35
+ ### Currently supported environments
36
+
37
+ - LTS versions of Node.js
38
+ - Latest versions of Edge, Chrome, Safar and Firefox
39
+
40
+ ### Prerequisites
41
+
42
+ - An existing Translator service or Cognitive Services resource. More info on [Pre-requisites][pre_requisities].
43
+
44
+ ### Install the `@azure-rest/ai-translation-document` package
45
+
46
+ Install the Document Translation REST client library for JavaScript with `npm`:
47
+
48
+ ```bash
49
+ npm install @azure-rest/ai-translation-document
50
+ ```
51
+
52
+ #### Create a Translator service resource
53
+
54
+ You can create Translator resource following [Create a Translator resource][translator_resource_create].
55
+
56
+ ### Create a `DocumentTranslationClient` using an endpoint URL and API key `KeyCredential`
57
+
58
+ Once you have the value for API key, create a credential
59
+ ```typescript
60
+ const credentials = { key: apiKey ?? "" };
61
+ ```
62
+
63
+ With the value of the `KeyCredential` you can create the `DocumentTranslationClient` using the `createClient` method of [documentTranslationClient_class]:
64
+
65
+ ```typescript
66
+ const client = createClient(endpoint, credentials);
67
+ ```
68
+
69
+ ## Examples
70
+
71
+ The following section provides several code snippets using the `client`, and covers the main features present in this client library.
72
+
73
+ ### Synchronous Document Translation
74
+
75
+ Used to synchronously translate a single document. The method doesn't require an Azure Blob storage account.
76
+
77
+ ```typescript
78
+ console.log("== Synchronous Document Translation ==");
79
+ const client = createClient(endpoint, credentials);
80
+ const options: DocumentTranslateParameters = {
81
+ queryParameters: {
82
+ targetLanguage: "hi",
83
+ },
84
+ contentType: "multipart/form-data",
85
+ body: [
86
+ {
87
+ name: "document",
88
+ body: "This is a test.",
89
+ filename: "test-input.txt",
90
+ contentType: "text/html",
91
+ },
92
+ ],
93
+ };
94
+
95
+ const response = await client.path("/document:translate").post(options);
96
+ if (isUnexpected(response)) {
97
+ throw response.body;
98
+ }
99
+ console.log('Response code: ' + response.status + ', Response body: ' + response.body);
100
+ ```
101
+
102
+ ### Batch Document Translation
103
+ Used to execute an asynchronous batch translation request. The method requires an Azure Blob storage account with storage containers for your source and translated documents.
104
+
105
+ ```typescript
106
+ console.log("== Batch Document Translation ==");
107
+ const client = createClient(endpoint, credentials);
108
+
109
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
110
+ const sourceInput = createSourceInput(sourceUrl);
111
+ const targetUrl = await createTargetContainer();
112
+ const targetInput = createTargetInput(targetUrl, "fr");
113
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
114
+
115
+ //Start translation
116
+ const batchRequests = {inputs: [batchRequest]};
117
+ const poller = await client.path("/document/batches").post({
118
+ body: batchRequests
119
+ });
120
+ const id = getTranslationOperationID(poller.headers["operation-location"]);
121
+ console.log('Translation started and the operationID is: ' + id);
122
+ ```
123
+
124
+ ### Cancel Document Translation
125
+ This cancels a translation job that is currently processing or queued (pending) as indicated in the request by the id query parameter. An operation isn't canceled if already completed, failed, or still canceling. In those instances, a bad request is returned. Completed translations can't be canceled and are charged.
126
+
127
+ ```typescript
128
+ console.log("== Cancel Translation ==");
129
+ const client = createClient(endpoint, credentials);
130
+
131
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
132
+ const sourceInput = createSourceInput(sourceUrl);
133
+ const targetUrl = await createTargetContainer();
134
+ const targetInput = createTargetInput(targetUrl, "fr");
135
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
136
+
137
+ //Start translation
138
+ const batchRequests = {inputs: [batchRequest]};
139
+ const poller = await client.path("/document/batches").post({
140
+ body: batchRequests
141
+ });
142
+ const id = getTranslationOperationID(poller.headers["operation-location"]);
143
+
144
+ //Cancel translation
145
+ await client.path("/document/batches/{id}", id).delete();
146
+
147
+ //get translation status and verify the job is cancelled, cancelling or notStarted
148
+ const response = await client.path("/document/batches/{id}", id).get();
149
+ if (isUnexpected(response)) {
150
+ throw response.body;
151
+ }
152
+ console.log("The status after cancelling the batch operation is:" + response.body.status);
153
+ ```
154
+
155
+ ### Get Documents Status
156
+ Used to request the status for all documents in a translation job.
157
+
158
+ ```typescript
159
+ console.log("== Gets Documents Status ==");
160
+ const client = createClient(endpoint, credentials);
161
+
162
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
163
+ const sourceInput = createSourceInput(sourceUrl);
164
+ const targetUrl = await createTargetContainer();
165
+ const targetInput = createTargetInput(targetUrl, "fr");
166
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
167
+
168
+ //Start translation
169
+ const batchRequests = {inputs: [batchRequest]};
170
+ const response = await StartTranslationAndWait(client, batchRequests);
171
+
172
+ const operationLocationUrl = response.headers["operation-location"]
173
+ const operationId = getTranslationOperationID(operationLocationUrl);
174
+
175
+ //get Documents Status
176
+ const documentResponse = await client.path("/document/batches/{id}/documents", operationId).get();
177
+ if (isUnexpected(documentResponse)) {
178
+ throw documentResponse.body;
179
+ }
180
+
181
+ const responseBody = documentResponse.body;
182
+ for (const documentStatus of responseBody.value) {
183
+ console.log("Document Status is: " + documentStatus.status);
184
+ console.log("Characters charged is: " + documentStatus.characterCharged);
185
+ break;
186
+ }
187
+ ```
188
+
189
+ ### Get Document Status
190
+ This returns the status for a specific document in a job as indicated in the request by the id and documentId query parameters.
191
+
192
+ ```typescript
193
+ console.log("== Get Document Status ==");
194
+ const client = createClient(endpoint, credentials);
195
+
196
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
197
+ const sourceInput = createSourceInput(sourceUrl);
198
+ const targetUrl = await createTargetContainer();
199
+ const targetInput = createTargetInput(targetUrl, "fr");
200
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
201
+
202
+ //Start translation
203
+ const batchRequests = {inputs: [batchRequest]};
204
+ const response = await StartTranslationAndWait(client, batchRequests);
205
+ const operationLocationUrl = response.headers["operation-location"]
206
+ const operationId = getTranslationOperationID(operationLocationUrl);
207
+
208
+ //get Documents Status
209
+ const documentResponse = await client.path("/document/batches/{id}/documents", operationId).get();
210
+ if (isUnexpected(documentResponse)) {
211
+ throw documentResponse.body;
212
+ }
213
+
214
+ const responseBody = documentResponse.body;
215
+ for (const document of responseBody.value) {
216
+ //get document status
217
+ const documentStatus = await client.path("/document/batches/{id}/documents/{documentId}", operationId, document.id).get();
218
+ console.log("Document Status = " + documentStatus.status);
219
+ const documentStatusOutput = documentStatus.body as DocumentStatusOutput;
220
+ console.log("Document ID = " +documentStatusOutput.id);
221
+ console.log("Document source path = " + documentStatusOutput.sourcePath);
222
+ console.log("Document path = " + documentStatusOutput.path);
223
+ console.log("Target language = " + documentStatusOutput.to);
224
+ console.log("Document created dateTime = " + documentStatusOutput.createdDateTimeUtc);
225
+ console.log("Document last action date time = " + documentStatusOutput.lastActionDateTimeUtc);
226
+ }
227
+ ```
228
+
229
+ ### Get Translations Status
230
+ Used to request a list and the status of all translation jobs submitted by the user (associated with the resource).
231
+
232
+ ```typescript
233
+ console.log("== Get Translations Status ==");
234
+ const client = createClient(endpoint, credentials);
235
+
236
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
237
+ const sourceInput = createSourceInput(sourceUrl);
238
+ const targetUrl = await createTargetContainer();
239
+ const targetInput = createTargetInput(targetUrl, "fr");
240
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
241
+
242
+ //Start translation
243
+ const batchRequests = {inputs: [batchRequest]};
244
+ const translationResponse = await StartTranslationAndWait(client, batchRequests);
245
+ const operationLocationUrl = translationResponse.headers["operation-location"]
246
+ const operationId = getTranslationOperationID(operationLocationUrl);
247
+
248
+ //get Translation Statusby ID filter
249
+ const queryParams = {
250
+ ids: [operationId]
251
+ };
252
+ const response = await client.path("/document/batches").get({
253
+ queryParameters: queryParams
254
+ });
255
+ if (isUnexpected(response)) {
256
+ throw response.body;
257
+ }
258
+ const responseBody = response.body;
259
+ for (const translationStatus of responseBody.value) {
260
+ console.log("Translation ID = " + translationStatus.id);
261
+ console.log("Translation Status = " + translationStatus.status);
262
+ console.log("Translation createdDateTimeUtc = " + translationStatus.createdDateTimeUtc);
263
+ console.log("Translation lastActionDateTimeUtc = " + translationStatus.lastActionDateTimeUtc);
264
+ console.log("Total documents submitted for translation = " + translationStatus.summary.total);
265
+ console.log("Total characters charged = " + translationStatus.summary.totalCharacterCharged);
266
+ }
267
+ ```
268
+
269
+ ### Get Translation Status
270
+ Used to request the status of a specific translation job. The response includes the overall job status and the status for documents that are being translated as part of that job.
271
+
272
+ ```typescript
273
+ console.log("== Get Translation Status ==");
274
+ const client = createClient(endpoint, credentials);
275
+
276
+ const sourceUrl = await createSourceContainer(ONE_TEST_DOCUMENTS);
277
+ const sourceInput = createSourceInput(sourceUrl);
278
+ const targetUrl = await createTargetContainer();
279
+ const targetInput = createTargetInput(targetUrl, "fr");
280
+ const batchRequest = createBatchRequest(sourceInput, [targetInput]);
281
+
282
+ //Start translation
283
+ const batchRequests = {inputs: [batchRequest]};
284
+ const translationResponse = await StartTranslationAndWait(client, batchRequests);
285
+
286
+ const operationLocationUrl = translationResponse.headers["operation-location"]
287
+ const operationId = getTranslationOperationID(operationLocationUrl);
288
+
289
+ //get Translation Status
290
+ const response = await client.path("/document/batches/{id}",operationId).get() as GetTranslationStatus200Response;
291
+ if (isUnexpected(response)) {
292
+ throw response.body;
293
+ }
294
+
295
+ console.log("Translation ID = " + response.body.id);
296
+ console.log("Translation Status = " + response.body.status);
297
+ console.log("Translation createdDateTimeUtc = " + response.body.createdDateTimeUtc);
298
+ console.log("Translation lastActionDateTimeUtc = " + response.body.lastActionDateTimeUtc);
299
+ console.log("Total documents submitted for translation = " + response.body.summary.total);
300
+ console.log("Total characters charged = " + response.body.summary.totalCharacterCharged);
301
+ ```
302
+
303
+
304
+ ### Get Supported Formats
305
+
306
+ This returns a list of document or glossary formats supported by the Document Translation feature. The list includes common file extensions and content-type if using the upload API.
307
+
308
+ ```typescript
309
+ console.log("== List Supported Format Types ==");
310
+
311
+ const documentTranslationClient = DocumentTranslationClient(endpoint);
312
+ const response = await documentTranslationClient.path("/document/formats").get();
313
+
314
+ const fileFormatTypes = response.body;
315
+ fileFormatTypes.value.forEach((fileFormatType: { format: any; contentTypes: any; fileExtensions: any; }) => {
316
+ console.log(fileFormatType.format);
317
+ console.log(fileFormatType.contentTypes);
318
+ console.log(fileFormatType.fileExtensions);
319
+ });
320
+ ```
321
+
322
+ ## Troubleshooting
323
+
324
+ When you interact with the Translator Service using the DocumentTranslator client library, errors returned by the Translator service correspond to the same HTTP status codes returned for REST API requests.
325
+
326
+ For example, if you submit a translation request without a target translate language, a `400` error is returned, indicating "Bad Request".
327
+
328
+ You can find the different error codes returned by the service in the [Service Documentation][service_errors].
329
+
330
+ ### Logging
331
+
332
+ Enabling logging may help uncover useful information about failures. In order to see a log of HTTP requests and responses, set the `AZURE_LOG_LEVEL` environment variable to `info`. Alternatively, logging can be enabled at runtime by calling `setLogLevel` in the `@azure/logger`:
333
+
334
+ ```javascript
335
+ const { setLogLevel } = require("@azure/logger");
336
+
337
+ setLogLevel("info");
338
+ ```
339
+
340
+ For more detailed instructions on how to enable logs, you can look at the [@azure/logger package docs](https://github.com/Azure/azure-sdk-for-js/tree/main/sdk/core/logger).
341
+ Please refer to the service documentation for a conceptual discussion of [languages][languages_doc].
342
+
343
+ [service_errors]: https://learn.microsoft.com/azure/ai-services/translator/document-translation/how-to-guides/use-rest-api-programmatically?tabs=csharp#common-http-status-codes
344
+ [translator_resource_create]: https://learn.microsoft.com/azure/cognitive-services/Translator/create-translator-resource
345
+ [documentTranslationClient_class]: https://github.com/Azure/azure-sdk-for-js/blob/main/sdk/translation/ai-translation-document-rest/src/documentTranslationClient.ts
346
+ [pre_requisities]: https://learn.microsoft.com/azure/ai-services/translator/document-translation/how-to-guides/use-rest-api-programmatically?tabs=csharp#prerequisites
package/dist/index.js ADDED
@@ -0,0 +1,299 @@
1
+ 'use strict';
2
+
3
+ Object.defineProperty(exports, '__esModule', { value: true });
4
+
5
+ var coreClient = require('@azure-rest/core-client');
6
+ var logger$1 = require('@azure/logger');
7
+ var corePaging = require('@azure/core-paging');
8
+ var coreLro = require('@azure/core-lro');
9
+ var coreRestPipeline = require('@azure/core-rest-pipeline');
10
+
11
+ // Copyright (c) Microsoft Corporation.
12
+ // Licensed under the MIT license.
13
+ const logger = logger$1.createClientLogger("ai-translation-document");
14
+
15
+ // Copyright (c) Microsoft Corporation.
16
+ // Licensed under the MIT license.
17
+ /**
18
+ * Initialize a new instance of `DocumentTranslationClient`
19
+ * @param endpointParam - Supported document Translation endpoint, protocol and hostname, for example: https://{TranslatorResourceName}.cognitiveservices.azure.com/translator.
20
+ * @param credentials - uniquely identify client credential
21
+ * @param options - the parameter for all optional parameters
22
+ */
23
+ function createClient(endpointParam, credentials, options = {}) {
24
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
25
+ const endpointUrl = (_b = (_a = options.endpoint) !== null && _a !== void 0 ? _a : options.baseUrl) !== null && _b !== void 0 ? _b : `${endpointParam}/translator`;
26
+ options.apiVersion = (_c = options.apiVersion) !== null && _c !== void 0 ? _c : "2024-05-01";
27
+ const userAgentInfo = `azsdk-js-ai-translation-document-rest/1.0.0-beta.1`;
28
+ const userAgentPrefix = options.userAgentOptions && options.userAgentOptions.userAgentPrefix
29
+ ? `${options.userAgentOptions.userAgentPrefix} ${userAgentInfo}`
30
+ : `${userAgentInfo}`;
31
+ options = Object.assign(Object.assign({}, options), { userAgentOptions: {
32
+ userAgentPrefix,
33
+ }, loggingOptions: {
34
+ logger: (_e = (_d = options.loggingOptions) === null || _d === void 0 ? void 0 : _d.logger) !== null && _e !== void 0 ? _e : logger.info,
35
+ }, credentials: {
36
+ scopes: (_g = (_f = options.credentials) === null || _f === void 0 ? void 0 : _f.scopes) !== null && _g !== void 0 ? _g : ["https://cognitiveservices.azure.com/.default"],
37
+ apiKeyHeaderName: (_j = (_h = options.credentials) === null || _h === void 0 ? void 0 : _h.apiKeyHeaderName) !== null && _j !== void 0 ? _j : "Ocp-Apim-Subscription-Key",
38
+ } });
39
+ const client = coreClient.getClient(endpointUrl, credentials, options);
40
+ return client;
41
+ }
42
+
43
+ // Copyright (c) Microsoft Corporation.
44
+ // Licensed under the MIT license.
45
+ const responseMap = {
46
+ "POST /document:translate": ["200"],
47
+ "GET /document/batches": ["200"],
48
+ "POST /document/batches": ["202"],
49
+ "GET /document/batches/{id}/documents/{documentId}": ["200"],
50
+ "GET /document/batches/{id}": ["200"],
51
+ "DELETE /document/batches/{id}": ["200"],
52
+ "GET /document/batches/{id}/documents": ["200"],
53
+ "GET /document/formats": ["200"],
54
+ };
55
+ function isUnexpected(response) {
56
+ const lroOriginal = response.headers["x-ms-original-url"];
57
+ const url = new URL(lroOriginal !== null && lroOriginal !== void 0 ? lroOriginal : response.request.url);
58
+ const method = response.request.method;
59
+ let pathDetails = responseMap[`${method} ${url.pathname}`];
60
+ if (!pathDetails) {
61
+ pathDetails = getParametrizedPathSuccess(method, url.pathname);
62
+ }
63
+ return !pathDetails.includes(response.status);
64
+ }
65
+ function getParametrizedPathSuccess(method, path) {
66
+ var _a, _b, _c, _d;
67
+ const pathParts = path.split("/");
68
+ // Traverse list to match the longest candidate
69
+ // matchedLen: the length of candidate path
70
+ // matchedValue: the matched status code array
71
+ let matchedLen = -1, matchedValue = [];
72
+ // Iterate the responseMap to find a match
73
+ for (const [key, value] of Object.entries(responseMap)) {
74
+ // Extracting the path from the map key which is in format
75
+ // GET /path/foo
76
+ if (!key.startsWith(method)) {
77
+ continue;
78
+ }
79
+ const candidatePath = getPathFromMapKey(key);
80
+ // Get each part of the url path
81
+ const candidateParts = candidatePath.split("/");
82
+ // track if we have found a match to return the values found.
83
+ let found = true;
84
+ for (let i = candidateParts.length - 1, j = pathParts.length - 1; i >= 1 && j >= 1; i--, j--) {
85
+ if (((_a = candidateParts[i]) === null || _a === void 0 ? void 0 : _a.startsWith("{")) && ((_b = candidateParts[i]) === null || _b === void 0 ? void 0 : _b.indexOf("}")) !== -1) {
86
+ const start = candidateParts[i].indexOf("}") + 1, end = (_c = candidateParts[i]) === null || _c === void 0 ? void 0 : _c.length;
87
+ // If the current part of the candidate is a "template" part
88
+ // Try to use the suffix of pattern to match the path
89
+ // {guid} ==> $
90
+ // {guid}:export ==> :export$
91
+ const isMatched = new RegExp(`${(_d = candidateParts[i]) === null || _d === void 0 ? void 0 : _d.slice(start, end)}`).test(pathParts[j] || "");
92
+ if (!isMatched) {
93
+ found = false;
94
+ break;
95
+ }
96
+ continue;
97
+ }
98
+ // If the candidate part is not a template and
99
+ // the parts don't match mark the candidate as not found
100
+ // to move on with the next candidate path.
101
+ if (candidateParts[i] !== pathParts[j]) {
102
+ found = false;
103
+ break;
104
+ }
105
+ }
106
+ // We finished evaluating the current candidate parts
107
+ // Update the matched value if and only if we found the longer pattern
108
+ if (found && candidatePath.length > matchedLen) {
109
+ matchedLen = candidatePath.length;
110
+ matchedValue = value;
111
+ }
112
+ }
113
+ return matchedValue;
114
+ }
115
+ function getPathFromMapKey(mapKey) {
116
+ const pathStart = mapKey.indexOf("/");
117
+ return mapKey.slice(pathStart);
118
+ }
119
+
120
+ // Copyright (c) Microsoft Corporation.
121
+ // Licensed under the MIT license.
122
+ /**
123
+ * Helper to paginate results from an initial response that follows the specification of Autorest `x-ms-pageable` extension
124
+ * @param client - Client to use for sending the next page requests
125
+ * @param initialResponse - Initial response containing the nextLink and current page of elements
126
+ * @param customGetPage - Optional - Function to define how to extract the page and next link to be used to paginate the results
127
+ * @returns - PagedAsyncIterableIterator to iterate the elements
128
+ */
129
+ function paginate(client, initialResponse, options = {}) {
130
+ let firstRun = true;
131
+ const itemName = "value";
132
+ const nextLinkName = "nextLink";
133
+ const { customGetPage } = options;
134
+ const pagedResult = {
135
+ firstPageLink: "",
136
+ getPage: typeof customGetPage === "function"
137
+ ? customGetPage
138
+ : async (pageLink) => {
139
+ const result = firstRun ? initialResponse : await client.pathUnchecked(pageLink).get();
140
+ firstRun = false;
141
+ checkPagingRequest(result);
142
+ const nextLink = getNextLink(result.body, nextLinkName);
143
+ const values = getElements(result.body, itemName);
144
+ return {
145
+ page: values,
146
+ nextPageLink: nextLink,
147
+ };
148
+ },
149
+ };
150
+ return corePaging.getPagedAsyncIterator(pagedResult);
151
+ }
152
+ /**
153
+ * Gets for the value of nextLink in the body
154
+ */
155
+ function getNextLink(body, nextLinkName) {
156
+ if (!nextLinkName) {
157
+ return undefined;
158
+ }
159
+ const nextLink = body[nextLinkName];
160
+ if (typeof nextLink !== "string" && typeof nextLink !== "undefined") {
161
+ throw new Error(`Body Property ${nextLinkName} should be a string or undefined`);
162
+ }
163
+ return nextLink;
164
+ }
165
+ /**
166
+ * Gets the elements of the current request in the body.
167
+ */
168
+ function getElements(body, itemName) {
169
+ const value = body[itemName];
170
+ // value has to be an array according to the x-ms-pageable extension.
171
+ // The fact that this must be an array is used above to calculate the
172
+ // type of elements in the page in PaginateReturn
173
+ if (!Array.isArray(value)) {
174
+ throw new Error(`Couldn't paginate response\n Body doesn't contain an array property with name: ${itemName}`);
175
+ }
176
+ return value !== null && value !== void 0 ? value : [];
177
+ }
178
+ /**
179
+ * Checks if a request failed
180
+ */
181
+ function checkPagingRequest(response) {
182
+ const Http2xxStatusCodes = ["200", "201", "202", "203", "204", "205", "206", "207", "208", "226"];
183
+ if (!Http2xxStatusCodes.includes(response.status)) {
184
+ throw coreClient.createRestError(`Pagination failed with unexpected statusCode ${response.status}`, response);
185
+ }
186
+ }
187
+
188
+ // Copyright (c) Microsoft Corporation.
189
+ // Licensed under the MIT license.
190
+ async function getLongRunningPoller(client, initialResponse, options = {}) {
191
+ var _a;
192
+ const abortController = new AbortController();
193
+ const poller = {
194
+ sendInitialRequest: async () => {
195
+ // In the case of Rest Clients we are building the LRO poller object from a response that's the reason
196
+ // we are not triggering the initial request here, just extracting the information from the
197
+ // response we were provided.
198
+ return getLroResponse(initialResponse);
199
+ },
200
+ sendPollRequest: async (path, sendPollRequestOptions) => {
201
+ // This is the callback that is going to be called to poll the service
202
+ // to get the latest status. We use the client provided and the polling path
203
+ // which is an opaque URL provided by caller, the service sends this in one of the following headers: operation-location, azure-asyncoperation or location
204
+ // depending on the lro pattern that the service implements. If non is provided we default to the initial path.
205
+ function abortListener() {
206
+ abortController.abort();
207
+ }
208
+ const inputAbortSignal = sendPollRequestOptions === null || sendPollRequestOptions === void 0 ? void 0 : sendPollRequestOptions.abortSignal;
209
+ const abortSignal = abortController.signal;
210
+ if (inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.aborted) {
211
+ abortController.abort();
212
+ }
213
+ else if (!abortSignal.aborted) {
214
+ inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.addEventListener("abort", abortListener, {
215
+ once: true,
216
+ });
217
+ }
218
+ let response;
219
+ try {
220
+ response = await client
221
+ .pathUnchecked(path !== null && path !== void 0 ? path : initialResponse.request.url)
222
+ .get({ abortSignal });
223
+ }
224
+ finally {
225
+ inputAbortSignal === null || inputAbortSignal === void 0 ? void 0 : inputAbortSignal.removeEventListener("abort", abortListener);
226
+ }
227
+ const lroResponse = getLroResponse(response);
228
+ lroResponse.rawResponse.headers["x-ms-original-url"] = initialResponse.request.url;
229
+ return lroResponse;
230
+ },
231
+ };
232
+ options.resolveOnUnsuccessful = (_a = options.resolveOnUnsuccessful) !== null && _a !== void 0 ? _a : true;
233
+ const httpPoller = coreLro.createHttpPoller(poller, options);
234
+ const simplePoller = {
235
+ isDone() {
236
+ return httpPoller.isDone;
237
+ },
238
+ isStopped() {
239
+ return httpPoller.isStopped;
240
+ },
241
+ getOperationState() {
242
+ if (!httpPoller.operationState) {
243
+ throw new Error("Operation state is not available. The poller may not have been started and you could await submitted() before calling getOperationState().");
244
+ }
245
+ return httpPoller.operationState;
246
+ },
247
+ getResult() {
248
+ return httpPoller.result;
249
+ },
250
+ toString() {
251
+ if (!httpPoller.operationState) {
252
+ throw new Error("Operation state is not available. The poller may not have been started and you could await submitted() before calling getOperationState().");
253
+ }
254
+ return JSON.stringify({
255
+ state: httpPoller.operationState,
256
+ });
257
+ },
258
+ stopPolling() {
259
+ abortController.abort();
260
+ },
261
+ onProgress: httpPoller.onProgress,
262
+ poll: httpPoller.poll,
263
+ pollUntilDone: httpPoller.pollUntilDone,
264
+ serialize: httpPoller.serialize,
265
+ submitted: httpPoller.submitted,
266
+ };
267
+ return simplePoller;
268
+ }
269
+ /**
270
+ * Converts a Rest Client response to a response that the LRO implementation understands
271
+ * @param response - a rest client http response
272
+ * @returns - An LRO response that the LRO implementation understands
273
+ */
274
+ function getLroResponse(response) {
275
+ if (Number.isNaN(response.status)) {
276
+ throw new TypeError(`Status code of the response is not a number. Value: ${response.status}`);
277
+ }
278
+ return {
279
+ flatResponse: response,
280
+ rawResponse: Object.assign(Object.assign({}, response), { statusCode: Number.parseInt(response.status), body: response.body }),
281
+ };
282
+ }
283
+
284
+ // Copyright (c) Microsoft Corporation.
285
+ // Licensed under the MIT license.
286
+
287
+ Object.defineProperty(exports, "createFile", {
288
+ enumerable: true,
289
+ get: function () { return coreRestPipeline.createFile; }
290
+ });
291
+ Object.defineProperty(exports, "createFileFromStream", {
292
+ enumerable: true,
293
+ get: function () { return coreRestPipeline.createFileFromStream; }
294
+ });
295
+ exports.default = createClient;
296
+ exports.getLongRunningPoller = getLongRunningPoller;
297
+ exports.isUnexpected = isUnexpected;
298
+ exports.paginate = paginate;
299
+ //# sourceMappingURL=index.js.map