UNPKG

@spotable/attio-sdk

Version:
119 lines (100 loc) 4.18 kB
import { AttioObject } from "../../helpers/fetchAttioSchema"; import { writeGeneratedFile } from "../../helpers/fs"; import { generateFileHeader } from "../types/fileHeader"; const FILE_NAME = "attioClient.ts"; export function generateAttioClient(outputDir: string, objects: AttioObject[], includeStandardTypes: boolean): void { const standardTypesImports = includeStandardTypes ? `import { AttioObjectFetcher } from "./fetchers/object"; import { AttioAttributeFetcher } from "./fetchers/attribute"; import { AttioListFetcher } from "./fetchers/list"; import { AttioListEntryFetcher } from "./fetchers/listEntry"; import { AttioNoteFetcher } from "./fetchers/note"; import { AttioTaskFetcher } from "./fetchers/task"; import { AttioWebhookFetcher } from "./fetchers/webhook"; import { AttioCommentFetcher } from "./fetchers/comment"; import { AttioWorkspaceMemberFetcher } from "./fetchers/workspaceMember";` : ""; const standardTypes = includeStandardTypes ? `objects: AttioObjectFetcher; attributes: AttioAttributeFetcher; lists: AttioListFetcher; listEntries: AttioListEntryFetcher; notes: AttioNoteFetcher; tasks: AttioTaskFetcher; webhooks: AttioWebhookFetcher; comments: AttioCommentFetcher; workspaceMembers: AttioWorkspaceMemberFetcher;` : ""; const content = `${generateFileHeader(FILE_NAME)} import fetch, { RequestInit, Response } from "node-fetch"; ${standardTypesImports} // We always import the record fetcher because it is used for all objects import { AttioRecordFetcher } from "./fetchers/record"; import { ${objects.map((object) => `${object.singular_noun}, ${object.singular_noun}Attributes, ${object.singular_noun}InputAttributes`).join(", ")} } from "./types"; const DEFAULT_ATTIO_API_URL = "https://api.attio.com/v2"; export interface AttioClientOptions { /** * The API key for authenticating with the Attio API. */ apiKey: string; /** * The base URL for the Attio API. Defaults to "https://api.attio.com/v2". */ apiUrl?: string; } type DoFetchOptions = Omit<RequestInit, "body"> & { query?: object; body?: Record<string, any>; }; export class AttioClient { private static options: AttioClientOptions; constructor(options: AttioClientOptions) { AttioClient.options = options; AttioClient.options.apiUrl = AttioClient.options.apiUrl || DEFAULT_ATTIO_API_URL; ${ includeStandardTypes ? ` this.objects = new AttioObjectFetcher(this); this.attributes = new AttioAttributeFetcher(this); this.lists = new AttioListFetcher(this); this.listEntries = new AttioListEntryFetcher(this); this.notes = new AttioNoteFetcher(this); this.tasks = new AttioTaskFetcher(this); this.webhooks = new AttioWebhookFetcher(this); this.comments = new AttioCommentFetcher(this); this.workspaceMembers = new AttioWorkspaceMemberFetcher(this)`.trim() : "" } ${objects.map((object) => `this.${object.api_slug} = new AttioRecordFetcher<${object.singular_noun}, ${object.singular_noun}InputAttributes, ${object.singular_noun}Attributes>(this, "${object.api_slug}");`).join("\n ")} } public async doFetch(uri: string, opts?: DoFetchOptions): Promise<Response> { const { query, body, ...init } = opts || {}; const queryString = query ? \`?$\{new URLSearchParams( Object.fromEntries( Object.entries(query) .filter(([_, v]) => v !== undefined) .map(([k, v]) => [k, String(v)]) ) ).toString()}\` : ""; const response = await fetch(\`$\{AttioClient.options.apiUrl}$\{uri}$\{queryString}\`, { ...init, body: body ? JSON.stringify(body) : undefined, headers: { ...init?.headers, Authorization: \`Bearer $\{AttioClient.options.apiKey}\`, "Content-Type": "application/json", }, }); return response; } ${standardTypes} ${objects .map((object) => `${object.api_slug}: AttioRecordFetcher<${object.singular_noun}, ${object.singular_noun}InputAttributes, ${object.singular_noun}Attributes>;`) .join("\n ") .trim()} } `; writeGeneratedFile(outputDir, FILE_NAME, content); }