sailpoint-oss / typescript-sdk

MIT License
9 stars 6 forks source link

Generator in addition to Paginator #29

Open yannick-beot-sp opened 9 months ago

yannick-beot-sp commented 9 months ago

JavaScript/TypeScript has the concept of Generator https://www.typescriptlang.org/docs/handbook/iterators-and-generators.html#handbook-content

It is also possible to have async generators.

Having generator would:

  1. reduce memory consumption. Instead of having big arrays of all data, we would be able to process small chunk of data
  2. speed things: instead of waiting to retrieve all data, we could start the processing as soon as the first item are retrieved.

A generic generator would share a lot of code with Paginator, as it would "just" yield data instead of concatenating/pushing data (cf. https://github.com/sailpoint-oss/typescript-sdk/blob/0956b793088998a23a74836b56eae183815589c1/sdk-output/paginator.ts#L65)

yannick-beot-sp commented 7 months ago

As an example, here is a generator:

    public async *getForms(filters: string | undefined = undefined): AsyncGenerator<FormBeta> {
        console.log("> getForms");
        const apiConfig = await this.getApiConfiguration();
        const api = new CustomFormsBetaApi(apiConfig);
        let args = {
            offset: 0,
            limit: DEFAULT_PAGINATION,
            filters
        }
        let count = -1
        do {
            const response = await api.searchFormDefinitionsByTenant(args)
            count = response.data.count
            if (response.data.results) {
                for (const f of response.data.results) {
                    yield f
                }
            }
            args.offset += DEFAULT_PAGINATION

            // if requesting an offset > text": "offset is greater than number of form definitions results"
            // By using this criteria, we may fall on some edge cases where the total number of forms is a muliple of 250
            // If using more than 200 Forms, the display would be slow, so it would mean that we would need to paginate like access profiles or roles.
            // For now, we will stay like this
        } while (count === DEFAULT_PAGINATION)
    }

And here is an example of usage:

const forms: FormTreeItem[] = []
for await (const form of client.getForms()) {
    forms.push(new FormTreeItem(
        this.tenantId,
        this.tenantName,
        this.tenantDisplayName,
        form.name,
        form.id
    ))
}