export function createFeedReader()

in tools/gsuite-scanner/src/data/feed-reader.ts [34:82]


export function createFeedReader<T>(creds: Credentials, parser: (entry: any) => T): (url: string) => AsyncIterableIterator<T[]> {

    const { token_type, access_token } = creds;

    /**
     * Intakes the intial url of the feed to read, then uses the next link to read the entire results graph
     * translating the results via the supplied parser in the parent function closure
     */
    return async function* (url: string): AsyncIterableIterator<T[]> {

        while (typeof url !== "undefined") {

            log(`Making request to url ${url}`, LogLevel.Verbose);

            const response = await fetch(url, {
                headers: {
                    "Authorization": `${token_type} ${access_token}`,
                    "Gdata-version": "1.4",
                },
                method: "GET",
            });

            if (!response.ok) {

                const body = await response.text();
                throw Error(`Error retrieving sites: [${response.status}] ${response.statusText} (${body})`);
            }

            const xml = await response.text();

            // now we need to translate the raw response into something useful
            yield await new Promise<T[]>((resolve, reject) => {

                parseString(xml, (err, result) => {

                    if (err) {
                        reject(err);
                    }

                    // here we need to translate the raw json from xml response into what we care about
                    const _next = (<any[]>result.feed.link).filter((node: any) => node.$.rel === "next")[0];
                    url = _next ? _next.$.href : undefined;

                    resolve((<any[]>result.feed.entry).map(parser));
                });
            });
        }
    };
}