// Upskera API v1 — TypeScript client (generated 2026-10-11). Works in Node 18+ and browsers. export class UpskeraError extends Error { constructor(public status: number, public code: string, message: string) { super(message); } } export class Upskera { constructor(private apiKey: string, private baseUrl = "https://localhost:3400/api/v1") {} private async request(method: string, path: string, body?: unknown, query?: Record) { const qs = query && Object.keys(query).length ? "?" + new URLSearchParams(Object.entries(query).map(([k, v]) => [k, String(v)])).toString() : ""; const res = await fetch(this.baseUrl + path + qs, { method, headers: { Authorization: `Bearer ${this.apiKey}`, ...(body ? { "Content-Type": "application/json" } : {}) }, body: body ? JSON.stringify(body) : undefined }); const json = await res.json().catch(() => ({})); if (!res.ok) throw new UpskeraError(res.status, json?.error?.code ?? "HTTP_" + res.status, json?.error?.message ?? res.statusText); return json; } /** Iterate every page of a list endpoint. */ async *paginate(list: (query: Record) => Promise<{ data: unknown[]; nextCursor: string | null }>, limit = 100) { let cursor: string | null = null; do { const page: { data: unknown[]; nextCursor: string | null } = await list({ limit, ...(cursor ? { cursor } : {}) }); for (const item of page.data) yield item; cursor = page.nextCursor; } while (cursor); } /** List users (scope: users:read) */ listUsers(query: Record = {}) { return this.request("GET", `/users`, undefined, query); } /** Get a user (scope: users:read) */ getUsers(id: string) { return this.request("GET", `/users/${encodeURIComponent(id)}`, undefined); } /** Create or invite a user (scope: users:write) */ createUsers(body: Record) { return this.request("POST", `/users`, body); } /** Update a user (status, org unit, job role) (scope: users:write) */ updateUsers(id: string, body: Record) { return this.request("PATCH", `/users/${encodeURIComponent(id)}`, body); } /** List org units (scope: org-units:read) */ listOrgUnits(query: Record = {}) { return this.request("GET", `/org-units`, undefined, query); } /** Get an org unit (scope: org-units:read) */ getOrgUnits(id: string) { return this.request("GET", `/org-units/${encodeURIComponent(id)}`, undefined); } /** List groups (scope: groups:read) */ listGroups(query: Record = {}) { return this.request("GET", `/groups`, undefined, query); } /** Get a group with member ids (scope: groups:read) */ getGroups(id: string) { return this.request("GET", `/groups/${encodeURIComponent(id)}`, undefined); } /** Add members to a static group (scope: groups:write) */ addGroupsMembers(id: string, body: Record) { return this.request("POST", `/groups/${encodeURIComponent(id)}/members`, body); } /** List published courses (scope: courses:read) */ listCourses(query: Record = {}) { return this.request("GET", `/courses`, undefined, query); } /** Get a course (scope: courses:read) */ getCourses(id: string) { return this.request("GET", `/courses/${encodeURIComponent(id)}`, undefined); } /** List enrollments (scope: enrollments:read) */ listEnrollments(query: Record = {}) { return this.request("GET", `/enrollments`, undefined, query); } /** Enrol a user in a course (scope: enrollments:write) */ createEnrollments(body: Record) { return this.request("POST", `/enrollments`, body); } /** List course completions (scope: completions:read) */ listCompletions(query: Record = {}) { return this.request("GET", `/completions`, undefined, query); } /** List released exam results (scope: exams:read) */ listExamResults(query: Record = {}) { return this.request("GET", `/exam-results`, undefined, query); } /** List issued credentials (scope: credentials:read) */ listCredentials(query: Record = {}) { return this.request("GET", `/credentials`, undefined, query); } /** Get a credential (scope: credentials:read) */ getCredentials(id: string) { return this.request("GET", `/credentials/${encodeURIComponent(id)}`, undefined); } /** List orders (scope: orders:read) */ listOrders(query: Record = {}) { return this.request("GET", `/orders`, undefined, query); } /** Get an order (scope: orders:read) */ getOrders(id: string) { return this.request("GET", `/orders/${encodeURIComponent(id)}`, undefined); } }