@forge/cli

14.1.0-next.1-experimental-13c2f8d14.1.0-next.21-experimental-554d417
out/service/identity/identity-client.js
+out/service/identity/identity-client.jsNew file
+77
Index: package/out/service/identity/identity-client.js
===================================================================
--- package/out/service/identity/identity-client.js
+++ package/out/service/identity/identity-client.js
@@ -0,0 +1,77 @@
+"use strict";
+Object.defineProperty(exports, "__esModule", { value: true });
+exports.IdentityClient = exports.getIdentityBaseUrl = void 0;
+const cli_shared_1 = require("@forge/cli-shared");
+const dedupeById = (items) => [
+    ...new Map(items.map((item) => [item.id, item])).values()
+];
+const IDENTITY_BASE_URLS = {
+    DEV: 'https://api.dev.atlassian.com/identity',
+    STG: 'https://api.stg.atlassian.com/identity',
+    PROD: 'https://api.atlassian.com/identity',
+    FEDRAMP_MODERATE_STAGING: 'https://api.stg.atlassian-us-gov-mod.com/identity',
+    FEDRAMP_MODERATE_PROD: 'https://api.atlassian-us-gov-mod.com/identity'
+};
+const getIdentityBaseUrl = () => process.env.FORGE_IDENTITY_API_URL || (0, cli_shared_1.getEnvironmentConfig)(IDENTITY_BASE_URLS);
+exports.getIdentityBaseUrl = getIdentityBaseUrl;
+class IdentityClient {
+    authenticator;
+    getUserId;
+    baseUrl;
+    logger;
+    fetchImpl;
+    constructor(authenticator, getUserId, baseUrl = (0, exports.getIdentityBaseUrl)(), logger = cli_shared_1.NullLogger, fetchImpl = fetch) {
+        this.authenticator = authenticator;
+        this.getUserId = getUserId;
+        this.baseUrl = baseUrl;
+        this.logger = logger;
+        this.fetchImpl = fetchImpl;
+    }
+    userIdPromise;
+    resolveUserId() {
+        return (this.userIdPromise ??= this.getUserId());
+    }
+    async getAllOrgs() {
+        const userId = await this.resolveUserId();
+        const orgs = await this.fetchAll((cursor) => `${this.baseUrl}/v1/users/${encodeURIComponent(userId)}/orgs${this.query(cursor)}`, (body) => {
+            const { organizations, links } = body;
+            return { items: organizations ?? [], nextCursor: links?.next };
+        });
+        return dedupeById(orgs);
+    }
+    async getAllUnits(orgId) {
+        const userId = await this.resolveUserId();
+        const units = await this.fetchAll((cursor) => `${this.baseUrl}/v1/users/${encodeURIComponent(userId)}/orgs/${encodeURIComponent(orgId)}/units${this.query(cursor)}`, (body) => {
+            const { units, paging } = body;
+            return { items: units ?? [], nextCursor: paging?.nextCursor };
+        });
+        return dedupeById(units);
+    }
+    query(cursor) {
+        if (!cursor) {
+            return '';
+        }
+        return `?${new URLSearchParams({ cursor }).toString()}`;
+    }
+    async fetchAll(buildUrl, extract) {
+        const { authorization } = await this.authenticator.getAuthorizationHeader();
+        const all = [];
+        let cursor;
+        do {
+            const url = buildUrl(cursor);
+            const res = await this.fetchImpl(url, {
+                headers: { Authorization: authorization, Accept: 'application/json' }
+            });
+            if (!res.ok) {
+                this.logger.debug(`Identity API request to ${url} failed with status ${res.status}`);
+                throw new cli_shared_1.UserError(cli_shared_1.Text.install.global.error.identityRequestFailed(res.status));
+            }
+            const { items, nextCursor } = extract(await res.json());
+            all.push(...items);
+            cursor = nextCursor ?? undefined;
+        } while (cursor);
+        return all;
+    }
+}
+exports.IdentityClient = IdentityClient;
+//# sourceMappingURL=identity-client.js.map
\ No newline at end of file