@azure-rest/arm-appservice
Version:
167 lines • 7.27 kB
JavaScript
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
import { __asyncDelegator, __asyncGenerator, __asyncValues, __await } from "tslib";
import { createRestError } from "@azure-rest/core-client";
/**
* returns an async iterator that iterates over results. It also has a `byPage`
* method that returns pages of items at once.
*
* @param pagedResult - an object that specifies how to get pages.
* @returns a paged async iterator that iterates over results.
*/
function getPagedAsyncIterator(pagedResult) {
var _a;
const iter = getItemAsyncIterator(pagedResult);
return {
next() {
return iter.next();
},
[Symbol.asyncIterator]() {
return this;
},
byPage: (_a = pagedResult === null || pagedResult === void 0 ? void 0 : pagedResult.byPage) !== null && _a !== void 0 ? _a : ((settings) => {
const { continuationToken } = settings !== null && settings !== void 0 ? settings : {};
return getPageAsyncIterator(pagedResult, {
pageLink: continuationToken,
});
}),
};
}
function getItemAsyncIterator(pagedResult) {
return __asyncGenerator(this, arguments, function* getItemAsyncIterator_1() {
var _a, e_1, _b, _c, _d, e_2, _e, _f;
const pages = getPageAsyncIterator(pagedResult);
const firstVal = yield __await(pages.next());
// if the result does not have an array shape, i.e. TPage = TElement, then we return it as is
if (!Array.isArray(firstVal.value)) {
// can extract elements from this page
const { toElements } = pagedResult;
if (toElements) {
yield __await(yield* __asyncDelegator(__asyncValues(toElements(firstVal.value))));
try {
for (var _g = true, pages_1 = __asyncValues(pages), pages_1_1; pages_1_1 = yield __await(pages_1.next()), _a = pages_1_1.done, !_a; _g = true) {
_c = pages_1_1.value;
_g = false;
const page = _c;
yield __await(yield* __asyncDelegator(__asyncValues(toElements(page))));
}
}
catch (e_1_1) { e_1 = { error: e_1_1 }; }
finally {
try {
if (!_g && !_a && (_b = pages_1.return)) yield __await(_b.call(pages_1));
}
finally { if (e_1) throw e_1.error; }
}
}
else {
yield yield __await(firstVal.value);
// `pages` is of type `AsyncIterableIterator<TPage>` but TPage = TElement in this case
yield __await(yield* __asyncDelegator(__asyncValues(pages)));
}
}
else {
yield __await(yield* __asyncDelegator(__asyncValues(firstVal.value)));
try {
for (var _h = true, pages_2 = __asyncValues(pages), pages_2_1; pages_2_1 = yield __await(pages_2.next()), _d = pages_2_1.done, !_d; _h = true) {
_f = pages_2_1.value;
_h = false;
const page = _f;
// pages is of type `AsyncIterableIterator<TPage>` so `page` is of type `TPage`. In this branch,
// it must be the case that `TPage = TElement[]`
yield __await(yield* __asyncDelegator(__asyncValues(page)));
}
}
catch (e_2_1) { e_2 = { error: e_2_1 }; }
finally {
try {
if (!_h && !_d && (_e = pages_2.return)) yield __await(_e.call(pages_2));
}
finally { if (e_2) throw e_2.error; }
}
}
});
}
function getPageAsyncIterator(pagedResult_1) {
return __asyncGenerator(this, arguments, function* getPageAsyncIterator_1(pagedResult, options = {}) {
const { pageLink } = options;
let response = yield __await(pagedResult.getPage(pageLink !== null && pageLink !== void 0 ? pageLink : pagedResult.firstPageLink));
if (!response) {
return yield __await(void 0);
}
yield yield __await(response.page);
while (response.nextPageLink) {
response = yield __await(pagedResult.getPage(response.nextPageLink));
if (!response) {
return yield __await(void 0);
}
yield yield __await(response.page);
}
});
}
/**
* Helper to paginate results from an initial response that follows the specification of Autorest `x-ms-pageable` extension
* @param client - Client to use for sending the next page requests
* @param initialResponse - Initial response containing the nextLink and current page of elements
* @param customGetPage - Optional - Function to define how to extract the page and next link to be used to paginate the results
* @returns - PagedAsyncIterableIterator to iterate the elements
*/
export function paginate(client, initialResponse, options = {}) {
let firstRun = true;
const itemName = "value";
const nextLinkName = "nextLink";
const { customGetPage } = options;
const pagedResult = {
firstPageLink: "",
getPage: typeof customGetPage === "function"
? customGetPage
: async (pageLink) => {
const result = firstRun ? initialResponse : await client.pathUnchecked(pageLink).get();
firstRun = false;
checkPagingRequest(result);
const nextLink = getNextLink(result.body, nextLinkName);
const values = getElements(result.body, itemName);
return {
page: values,
nextPageLink: nextLink,
};
},
};
return getPagedAsyncIterator(pagedResult);
}
/**
* Gets for the value of nextLink in the body
*/
function getNextLink(body, nextLinkName) {
if (!nextLinkName) {
return undefined;
}
const nextLink = body[nextLinkName];
if (typeof nextLink !== "string" && typeof nextLink !== "undefined") {
throw new Error(`Body Property ${nextLinkName} should be a string or undefined`);
}
return nextLink;
}
/**
* Gets the elements of the current request in the body.
*/
function getElements(body, itemName) {
const value = body[itemName];
// value has to be an array according to the x-ms-pageable extension.
// The fact that this must be an array is used above to calculate the
// type of elements in the page in PaginateReturn
if (!Array.isArray(value)) {
throw new Error(`Couldn't paginate response\n Body doesn't contain an array property with name: ${itemName}`);
}
return value !== null && value !== void 0 ? value : [];
}
/**
* Checks if a request failed
*/
function checkPagingRequest(response) {
const Http2xxStatusCodes = ["200", "201", "202", "203", "204", "205", "206", "207", "208", "226"];
if (!Http2xxStatusCodes.includes(response.status)) {
throw createRestError(`Pagination failed with unexpected statusCode ${response.status}`, response);
}
}
//# sourceMappingURL=paginateHelper.js.map