@medalsocial/sdk 1.1.6 → 1.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import Medal, { ApiResponse, EmailSendResult, ContactCreateResult, ContactNoteResult, ConsentResult, DealCreateResult } from '../src/index.mjs';
1
+ import { Medal, ApiResponse, EmailSendResult, ContactCreateResult, ContactNoteResult, ConsentResult, DealCreateResult } from '../src/index.mjs';
2
2
  import { z } from 'zod';
3
3
 
4
4
  declare const SendEmailSchema: z.ZodObject<{
@@ -1,4 +1,4 @@
1
- import Medal, { ApiResponse, EmailSendResult, ContactCreateResult, ContactNoteResult, ConsentResult, DealCreateResult } from '../src/index.js';
1
+ import { Medal, ApiResponse, EmailSendResult, ContactCreateResult, ContactNoteResult, ConsentResult, DealCreateResult } from '../src/index.js';
2
2
  import { z } from 'zod';
3
3
 
4
4
  declare const SendEmailSchema: z.ZodObject<{
package/dist/src/index.js CHANGED
@@ -151,6 +151,7 @@ var Contacts = class {
151
151
  constructor(client) {
152
152
  this.client = client;
153
153
  }
154
+ client;
154
155
  /** List contacts with cursor-based pagination and optional filters. */
155
156
  async list(options) {
156
157
  const params = {};
@@ -200,6 +201,7 @@ var Deals = class {
200
201
  constructor(client) {
201
202
  this.client = client;
202
203
  }
204
+ client;
203
205
  /** List deals with cursor-based pagination and optional filters. */
204
206
  async list(options) {
205
207
  const params = {};
@@ -232,6 +234,7 @@ var EmailTemplates = class {
232
234
  constructor(client) {
233
235
  this.client = client;
234
236
  }
237
+ client;
235
238
  /** List all active email templates in the workspace. */
236
239
  async list() {
237
240
  return this.client.get("/api/v1/emails/templates");
@@ -249,6 +252,7 @@ var Emails = class {
249
252
  this.client = client;
250
253
  this.templates = new EmailTemplates(client);
251
254
  }
255
+ client;
252
256
  templates;
253
257
  /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */
254
258
  async send(input) {
@@ -269,6 +273,7 @@ var Gdpr = class {
269
273
  constructor(client) {
270
274
  this.client = client;
271
275
  }
276
+ client;
272
277
  /** Request a workspace data export. Runs asynchronously. */
273
278
  async requestExport() {
274
279
  return this.client.post("/api/v1/gdpr/export");
@@ -300,6 +305,7 @@ var Posts = class {
300
305
  constructor(client) {
301
306
  this.client = client;
302
307
  }
308
+ client;
303
309
  /** List posts with cursor-based pagination and optional filters. */
304
310
  async list(options) {
305
311
  const params = {};
@@ -344,6 +350,7 @@ var Workspaces = class {
344
350
  constructor(client) {
345
351
  this.client = client;
346
352
  }
353
+ client;
347
354
  /** List workspaces accessible to the current API key or OAuth token. */
348
355
  async list() {
349
356
  return this.client.get("/api/v1/me/workspaces");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/index.ts","../../src/types/common.ts","../../src/client.ts","../../src/resources/contacts.ts","../../src/resources/deals.ts","../../src/resources/emails.ts","../../src/resources/gdpr.ts","../../src/resources/posts.ts","../../src/resources/workspaces.ts"],"sourcesContent":["/**\n * Official TypeScript SDK for the Medal Social API.\n *\n * Provides typed access to posts, emails, contacts, deals, GDPR compliance,\n * and workspace management. Works in Node.js, Deno, Bun, Cloudflare Workers,\n * and modern browsers.\n *\n * @example\n * ```ts\n * import { Medal } from \"@medalsocial/sdk\";\n *\n * const medal = new Medal(\"medal_xxx\");\n * const { data: post } = await medal.posts.create({\n * content: \"Hello world!\",\n * channel_ids: [\"ch_1\"],\n * });\n * ```\n *\n * @module\n */\nimport { BaseClient } from \"./client\";\nimport { Contacts } from \"./resources/contacts\";\nimport { Deals } from \"./resources/deals\";\nimport { Emails } from \"./resources/emails\";\nimport { Gdpr } from \"./resources/gdpr\";\nimport { Posts } from \"./resources/posts\";\nimport { Workspaces } from \"./resources/workspaces\";\n\n/** Options for configuring the {@link Medal} client. */\nexport interface MedalOptions {\n /** Override the base URL (defaults to https://io.medalsocial.com). */\n baseUrl?: string;\n /** Request timeout in ms (default 30000). */\n timeout?: number;\n /**\n * Workspace ID — required for OAuth access tokens, ignored for API keys.\n * API keys are scoped to a single workspace, so the workspace is inferred.\n * OAuth tokens can access multiple workspaces, so you must specify which one.\n */\n workspaceId?: string;\n}\n\n/**\n * Medal Social SDK client.\n *\n * Supports both API key and OAuth access token authentication:\n *\n * @example API Key (recommended for server-side)\n * ```ts\n * import { Medal } from '@medalsocial/sdk';\n *\n * // API keys start with medal_ and are scoped to one workspace\n * const medal = new Medal('medal_xxx');\n * ```\n *\n * @example OAuth Access Token\n * ```ts\n * // OAuth tokens require a workspaceId\n * const medal = new Medal('oauth_access_token', {\n * workspaceId: 'workspace_id_here',\n * });\n * ```\n *\n * @example Full usage\n * ```ts\n * const medal = new Medal('medal_xxx');\n *\n * // Posts — create, schedule, publish\n * const { data: post } = await medal.posts.create({\n * content: 'Hello world!',\n * channel_ids: ['ch_1'],\n * });\n * await medal.posts.schedule(post.id, { scheduled_at: '2026-03-15T10:00:00Z' });\n *\n * // Emails — send transactional emails\n * await medal.emails.send({\n * template_slug: 'welcome',\n * to: 'user@example.com',\n * variables: { name: 'John' },\n * });\n *\n * // Contacts, Deals, GDPR, Workspaces\n * const contacts = await medal.contacts.list({ status: 'lead' });\n * const { data: deal } = await medal.deals.create({ title: 'Acme', value: 50000 });\n * await medal.gdpr.recordConsent({ email: 'u@x.com', consent_type: 'marketing_email', granted: true });\n * const { data: workspaces } = await medal.workspaces.list();\n * ```\n */\nexport class Medal {\n readonly emails: Emails;\n readonly contacts: Contacts;\n readonly deals: Deals;\n readonly gdpr: Gdpr;\n readonly posts: Posts;\n readonly workspaces: Workspaces;\n\n constructor(token: string, options?: MedalOptions) {\n if (!token) {\n throw new Error(\n \"Authentication token is required. Pass your medal_xxx API key or OAuth access token as the first argument.\",\n );\n }\n\n const client = new BaseClient({\n baseUrl: (options?.baseUrl ?? \"https://io.medalsocial.com\").replace(/\\/$/, \"\"),\n token,\n workspaceId: options?.workspaceId,\n timeout: options?.timeout ?? 30000,\n userAgent: \"medalsocial-sdk/1.0.0 (+https://github.com/Medal-Social/MedalSocial)\",\n });\n\n this.emails = new Emails(client);\n this.contacts = new Contacts(client);\n this.deals = new Deals(client);\n this.gdpr = new Gdpr(client);\n this.posts = new Posts(client);\n this.workspaces = new Workspaces(client);\n }\n}\n\n// Re-export all types\nexport { MedalApiError } from \"./types/common\";\nexport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"./types/common\";\nexport type {\n SendEmailInput,\n EmailSendResult,\n EmailSend,\n BatchSendInput,\n BatchSendSummary,\n BatchSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n} from \"./types/emails\";\nexport type {\n Contact,\n ContactCreateResult,\n ContactUpdateResult,\n ContactRemoveResult,\n ContactNoteResult,\n ContactStatus,\n EmailStatus,\n CreateContactInput,\n UpdateContactInput,\n ListContactsOptions,\n ImportContactInput,\n ImportContactsResult,\n Activity,\n AddNoteInput,\n} from \"./types/contacts\";\nexport type {\n Deal,\n DealCreateResult,\n DealUpdateResult,\n DealRemoveResult,\n DealStatus,\n CreateDealInput,\n UpdateDealInput,\n ListDealsOptions,\n} from \"./types/deals\";\nexport type {\n GdprExport,\n ConsentType,\n RecordConsentInput,\n ConsentRecord,\n ConsentResult,\n ContactConsents,\n CookieConsentInput,\n CookieCategoryConsent,\n} from \"./types/gdpr\";\nexport type {\n Post,\n PostType,\n PostVariant,\n PostDetail,\n Channel,\n CreatePostInput,\n UpdatePostInput,\n SchedulePostInput,\n ListPostsOptions,\n ScheduleResult,\n PublishResult,\n} from \"./types/posts\";\nexport type { Workspace } from \"./types/workspaces\";\n\n// Resource class re-exports (for advanced usage)\nexport { Emails } from \"./resources/emails\";\nexport { Contacts } from \"./resources/contacts\";\nexport { Deals } from \"./resources/deals\";\nexport { Gdpr } from \"./resources/gdpr\";\nexport { Posts } from \"./resources/posts\";\nexport { Workspaces } from \"./resources/workspaces\";\nexport { BaseClient } from \"./client\";\n\n/** Convenience factory — equivalent to `new Medal(apiKey, options)`. */\nexport function createMedalClient(apiKey: string, options?: MedalOptions): Medal {\n return new Medal(apiKey, options);\n}\n\nexport default Medal;\n","/** Successful API response wrapper */\nexport interface ApiResponse<T> {\n data: T;\n}\n\n/** Paginated API response */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n has_more: boolean;\n next_cursor: string | null;\n };\n}\n\n/** API error thrown by the client */\nexport class MedalApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"MedalApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n/** Pagination options for list endpoints */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n","import { MedalApiError } from \"./types/common\";\n\n/** Configuration for the low-level HTTP client. */\nexport interface ClientConfig {\n baseUrl: string;\n token: string;\n workspaceId?: string;\n timeout: number;\n userAgent: string;\n}\n\n/**\n * Low-level HTTP client used by all resource classes.\n * Handles authentication, retries, timeout, and error parsing.\n */\nexport class BaseClient {\n /** Resolved client configuration. */\n readonly config: ClientConfig;\n\n constructor(config: ClientConfig) {\n this.config = config;\n }\n\n /** Execute an authenticated GET request and return the parsed JSON body. */\n async get<T>(path: string, params?: Record<string, string | undefined>): Promise<T> {\n const url = this.buildUrl(path, params);\n return this.request<T>(url, { method: \"GET\" });\n }\n\n /** Execute an authenticated POST request with a JSON body. */\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n /** Execute an authenticated PATCH request with a JSON body. */\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n /** Execute an authenticated DELETE request. */\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(this.buildUrl(path), { method: \"DELETE\" });\n }\n\n private buildUrl(path: string, params?: Record<string, string | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const maxAttempts = 3;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${this.config.token}`);\n if (this.config.workspaceId) {\n headers.set(\"x-workspace-id\", this.config.workspaceId);\n }\n try {\n headers.set(\"user-agent\", this.config.userAgent);\n } catch {\n // Browsers disallow setting user-agent\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n let res: Response;\n try {\n res = await fetch(url, { ...init, headers, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n\n // Retry on 429 / 5xx (but not on the final attempt)\n if (\n (res.status === 429 || (res.status >= 500 && res.status <= 599)) &&\n attempt < maxAttempts\n ) {\n const retryAfter = res.headers.get(\"retry-after\");\n let delayMs = 0;\n if (retryAfter) {\n const seconds = Number(retryAfter);\n delayMs = Number.isFinite(seconds) ? seconds * 1000 : 0;\n }\n if (delayMs <= 0) {\n delayMs = 250 * attempt;\n }\n await new Promise((r) => setTimeout(r, delayMs));\n continue;\n }\n\n // Parse response\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n if (!res.ok) {\n const body = parsed as\n | { error?: { code?: string; message?: string; details?: unknown } }\n | undefined;\n throw new MedalApiError(\n res.status,\n body?.error?.code ?? \"UNKNOWN_ERROR\",\n body?.error?.message ?? `HTTP ${res.status}: ${res.statusText}`,\n body?.error?.details,\n );\n }\n\n return parsed as T;\n }\n\n /* v8 ignore next -- unreachable: loop always returns or throws */\n throw new Error(\"Request failed after retries\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"../types/common\";\nimport type {\n Activity,\n AddNoteInput,\n Contact,\n ContactCreateResult,\n ContactNoteResult,\n ContactRemoveResult,\n ContactUpdateResult,\n CreateContactInput,\n ImportContactInput,\n ImportContactsResult,\n ListContactsOptions,\n UpdateContactInput,\n} from \"../types/contacts\";\n\n/** Manage contacts in the workspace CRM. */\nexport class Contacts {\n constructor(private client: BaseClient) {}\n\n /** List contacts with cursor-based pagination and optional filters. */\n async list(options?: ListContactsOptions): Promise<PaginatedResponse<Contact>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.email_status) params.email_status = options.email_status;\n if (options?.label_ids) params.label_ids = options.label_ids.join(\",\");\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/contacts\", params);\n }\n\n /** Create a new contact. Email must be unique in the workspace. */\n async create(input: CreateContactInput): Promise<ApiResponse<ContactCreateResult>> {\n return this.client.post(\"/api/v1/contacts\", input);\n }\n\n /** Get a contact by ID. */\n async get(id: string): Promise<ApiResponse<Contact>> {\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a contact. */\n async update(id: string, input: UpdateContactInput): Promise<ApiResponse<ContactUpdateResult>> {\n return this.client.patch(`/api/v1/contacts/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a contact. */\n async remove(id: string): Promise<ApiResponse<ContactRemoveResult>> {\n return this.client.delete(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Get the activity timeline for a contact. */\n async activities(id: string, options?: PaginationOptions): Promise<PaginatedResponse<Activity>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}/activities`, params);\n }\n\n /** Add a note to a contact's timeline. */\n async addNote(id: string, input: AddNoteInput): Promise<ApiResponse<ContactNoteResult>> {\n return this.client.post(`/api/v1/contacts/${encodeURIComponent(id)}/notes`, input);\n }\n\n /** Bulk import contacts (max 500). Duplicates are skipped. */\n async import(contacts: ImportContactInput[]): Promise<ApiResponse<ImportContactsResult>> {\n return this.client.post(\"/api/v1/contacts/import\", { contacts });\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n CreateDealInput,\n Deal,\n DealCreateResult,\n DealRemoveResult,\n DealUpdateResult,\n ListDealsOptions,\n UpdateDealInput,\n} from \"../types/deals\";\n\n/** Manage sponsorship deals in the workspace. */\nexport class Deals {\n constructor(private client: BaseClient) {}\n\n /** List deals with cursor-based pagination and optional filters. */\n async list(options?: ListDealsOptions): Promise<PaginatedResponse<Deal>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/deals\", params);\n }\n\n /** Create a new deal. */\n async create(input: CreateDealInput): Promise<ApiResponse<DealCreateResult>> {\n return this.client.post(\"/api/v1/deals\", input);\n }\n\n /** Get a deal by ID. */\n async get(id: string): Promise<ApiResponse<Deal>> {\n return this.client.get(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a deal. Set contact_id to null to unlink. */\n async update(id: string, input: UpdateDealInput): Promise<ApiResponse<DealUpdateResult>> {\n return this.client.patch(`/api/v1/deals/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a deal. */\n async remove(id: string): Promise<ApiResponse<DealRemoveResult>> {\n return this.client.delete(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n BatchSendInput,\n BatchSendSummary,\n EmailSend,\n EmailSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n SendEmailInput,\n} from \"../types/emails\";\n\n/** Manage email templates stored in the workspace. */\nclass EmailTemplates {\n constructor(private client: BaseClient) {}\n\n /** List all active email templates in the workspace. */\n async list(): Promise<ApiResponse<EmailTemplate[]>> {\n return this.client.get(\"/api/v1/emails/templates\");\n }\n\n /** Get a specific email template by slug, optionally with locale resolution. */\n async get(slug: string, options?: GetTemplateOptions): Promise<ApiResponse<EmailTemplateDetail>> {\n const params: Record<string, string | undefined> = {};\n if (options?.locale) params.locale = options.locale;\n if (options?.fallback_locale) params.fallback_locale = options.fallback_locale;\n return this.client.get(`/api/v1/emails/templates/${encodeURIComponent(slug)}`, params);\n }\n}\n\n/** Send transactional emails and manage templates. */\nexport class Emails {\n readonly templates: EmailTemplates;\n\n constructor(private client: BaseClient) {\n this.templates = new EmailTemplates(client);\n }\n\n /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */\n async send(input: SendEmailInput): Promise<ApiResponse<EmailSendResult>> {\n return this.client.post(\"/api/v1/emails\", input);\n }\n\n /** Get the delivery status of a sent email. */\n async get(id: string): Promise<ApiResponse<EmailSend>> {\n return this.client.get(`/api/v1/emails/${encodeURIComponent(id)}`);\n }\n\n /** Send the same template to multiple recipients (max 100). Returns HTTP 202. */\n async batch(input: BatchSendInput): Promise<ApiResponse<BatchSendSummary>> {\n return this.client.post(\"/api/v1/emails/batch\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n ConsentRecord,\n ConsentResult,\n CookieConsentInput,\n GdprExport,\n RecordConsentInput,\n} from \"../types/gdpr\";\n\n/** Manage GDPR compliance — data exports, consent records, and cookie consent. */\nexport class Gdpr {\n constructor(private client: BaseClient) {}\n\n /** Request a workspace data export. Runs asynchronously. */\n async requestExport(): Promise<ApiResponse<{ request_id: string; status: string }>> {\n return this.client.post(\"/api/v1/gdpr/export\");\n }\n\n /** List all workspace export requests. */\n async listExports(): Promise<ApiResponse<GdprExport[]>> {\n return this.client.get(\"/api/v1/gdpr/exports\");\n }\n\n /** Get the status of a specific export. */\n async getExport(id: string): Promise<ApiResponse<GdprExport>> {\n return this.client.get(`/api/v1/gdpr/exports/${encodeURIComponent(id)}`);\n }\n\n /** Record a GDPR consent decision for a contact by email. */\n async recordConsent(input: RecordConsentInput): Promise<ApiResponse<ConsentResult>> {\n return this.client.post(\"/api/v1/gdpr/consent\", input);\n }\n\n /** Get all consent records for a contact by email. */\n async getConsent(email: string): Promise<ApiResponse<ConsentRecord[]>> {\n return this.client.get(`/api/v1/gdpr/consent/${encodeURIComponent(email)}`);\n }\n\n /** Record cookie consent from an external site (legacy endpoint). */\n async cookieConsent(input: CookieConsentInput): Promise<{ success: boolean; logId?: string }> {\n return this.client.post(\"/api/cookie-consent\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n Channel,\n CreatePostInput,\n ListPostsOptions,\n Post,\n PostDetail,\n PublishResult,\n SchedulePostInput,\n ScheduleResult,\n UpdatePostInput,\n} from \"../types/posts\";\n\n/** Create and publish posts across connected channels. */\nexport class Posts {\n constructor(private client: BaseClient) {}\n\n /** List posts with cursor-based pagination and optional filters. */\n async list(options?: ListPostsOptions): Promise<PaginatedResponse<Post>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.type) params.type = options.type;\n return this.client.get(\"/api/v1/posts\", params);\n }\n\n /** Create a new post with content and target channels. */\n async create(input: CreatePostInput): Promise<ApiResponse<{ id: string }>> {\n return this.client.post(\"/api/v1/posts\", input);\n }\n\n /** Get a post by ID, including its per-channel variants. */\n async get(id: string): Promise<ApiResponse<PostDetail>> {\n return this.client.get(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Update a draft post's title or content. */\n async update(id: string, input: UpdatePostInput): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.patch(`/api/v1/posts/${encodeURIComponent(id)}`, input);\n }\n\n /** Delete a post. */\n async remove(id: string): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.delete(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Schedule a post for future publication. */\n async schedule(id: string, input: SchedulePostInput): Promise<ApiResponse<ScheduleResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/schedule`, input);\n }\n\n /** Publish a post immediately to all target channels. */\n async publish(id: string): Promise<ApiResponse<PublishResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/publish`);\n }\n\n /** List connected publishing channels for this workspace. */\n async channels(): Promise<ApiResponse<Channel[]>> {\n return this.client.get(\"/api/v1/posts/channels\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type { Workspace } from \"../types/workspaces\";\n\n/** Access workspaces for the authenticated credential. */\nexport class Workspaces {\n constructor(private client: BaseClient) {}\n\n /** List workspaces accessible to the current API key or OAuth token. */\n async list(): Promise<ApiResponse<Workspace[]>> {\n return this.client.get(\"/api/v1/me/workspaces\");\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/index.ts","../../src/types/common.ts","../../src/client.ts","../../src/resources/contacts.ts","../../src/resources/deals.ts","../../src/resources/emails.ts","../../src/resources/gdpr.ts","../../src/resources/posts.ts","../../src/resources/workspaces.ts"],"sourcesContent":["/**\n * Official TypeScript SDK for the Medal Social API.\n *\n * Provides typed access to posts, emails, contacts, deals, GDPR compliance,\n * and workspace management. Works in Node.js, Deno, Bun, Cloudflare Workers,\n * and modern browsers.\n *\n * @example\n * ```ts\n * import { Medal } from \"@medalsocial/sdk\";\n *\n * const medal = new Medal(\"medal_xxx\");\n * const { data: post } = await medal.posts.create({\n * content: \"Hello world!\",\n * channel_ids: [\"ch_1\"],\n * });\n * ```\n *\n * @module\n */\nimport { BaseClient } from \"./client\";\nimport { Contacts } from \"./resources/contacts\";\nimport { Deals } from \"./resources/deals\";\nimport { Emails } from \"./resources/emails\";\nimport { Gdpr } from \"./resources/gdpr\";\nimport { Posts } from \"./resources/posts\";\nimport { Workspaces } from \"./resources/workspaces\";\n\n/** Options for configuring the {@link Medal} client. */\nexport interface MedalOptions {\n /** Override the base URL (defaults to https://io.medalsocial.com). */\n baseUrl?: string;\n /** Request timeout in ms (default 30000). */\n timeout?: number;\n /**\n * Workspace ID — required for OAuth access tokens, ignored for API keys.\n * API keys are scoped to a single workspace, so the workspace is inferred.\n * OAuth tokens can access multiple workspaces, so you must specify which one.\n */\n workspaceId?: string;\n}\n\n/**\n * Medal Social SDK client.\n *\n * Supports both API key and OAuth access token authentication:\n *\n * @example API Key (recommended for server-side)\n * ```ts\n * import { Medal } from '@medalsocial/sdk';\n *\n * // API keys start with medal_ and are scoped to one workspace\n * const medal = new Medal('medal_xxx');\n * ```\n *\n * @example OAuth Access Token\n * ```ts\n * // OAuth tokens require a workspaceId\n * const medal = new Medal('oauth_access_token', {\n * workspaceId: 'workspace_id_here',\n * });\n * ```\n *\n * @example Full usage\n * ```ts\n * const medal = new Medal('medal_xxx');\n *\n * // Posts — create, schedule, publish\n * const { data: post } = await medal.posts.create({\n * content: 'Hello world!',\n * channel_ids: ['ch_1'],\n * });\n * await medal.posts.schedule(post.id, { scheduled_at: '2026-03-15T10:00:00Z' });\n *\n * // Emails — send transactional emails\n * await medal.emails.send({\n * template_slug: 'welcome',\n * to: 'user@example.com',\n * variables: { name: 'John' },\n * });\n *\n * // Contacts, Deals, GDPR, Workspaces\n * const contacts = await medal.contacts.list({ status: 'lead' });\n * const { data: deal } = await medal.deals.create({ title: 'Acme', value: 50000 });\n * await medal.gdpr.recordConsent({ email: 'u@x.com', consent_type: 'marketing_email', granted: true });\n * const { data: workspaces } = await medal.workspaces.list();\n * ```\n */\nexport class Medal {\n readonly emails: Emails;\n readonly contacts: Contacts;\n readonly deals: Deals;\n readonly gdpr: Gdpr;\n readonly posts: Posts;\n readonly workspaces: Workspaces;\n\n constructor(token: string, options?: MedalOptions) {\n if (!token) {\n throw new Error(\n \"Authentication token is required. Pass your medal_xxx API key or OAuth access token as the first argument.\",\n );\n }\n\n const client = new BaseClient({\n baseUrl: (options?.baseUrl ?? \"https://io.medalsocial.com\").replace(/\\/$/, \"\"),\n token,\n workspaceId: options?.workspaceId,\n timeout: options?.timeout ?? 30000,\n userAgent: \"medalsocial-sdk/1.0.0 (+https://github.com/Medal-Social/MedalSocial)\",\n });\n\n this.emails = new Emails(client);\n this.contacts = new Contacts(client);\n this.deals = new Deals(client);\n this.gdpr = new Gdpr(client);\n this.posts = new Posts(client);\n this.workspaces = new Workspaces(client);\n }\n}\n\n// Re-export all types\nexport { MedalApiError } from \"./types/common\";\nexport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"./types/common\";\nexport type {\n SendEmailInput,\n EmailSendResult,\n EmailSend,\n BatchSendInput,\n BatchSendSummary,\n BatchSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n} from \"./types/emails\";\nexport type {\n Contact,\n ContactCreateResult,\n ContactUpdateResult,\n ContactRemoveResult,\n ContactNoteResult,\n ContactStatus,\n EmailStatus,\n CreateContactInput,\n UpdateContactInput,\n ListContactsOptions,\n ImportContactInput,\n ImportContactsResult,\n Activity,\n AddNoteInput,\n} from \"./types/contacts\";\nexport type {\n Deal,\n DealCreateResult,\n DealUpdateResult,\n DealRemoveResult,\n DealStatus,\n CreateDealInput,\n UpdateDealInput,\n ListDealsOptions,\n} from \"./types/deals\";\nexport type {\n GdprExport,\n ConsentType,\n RecordConsentInput,\n ConsentRecord,\n ConsentResult,\n ContactConsents,\n CookieConsentInput,\n CookieCategoryConsent,\n} from \"./types/gdpr\";\nexport type {\n Post,\n PostType,\n PostVariant,\n PostDetail,\n Channel,\n CreatePostInput,\n UpdatePostInput,\n SchedulePostInput,\n ListPostsOptions,\n ScheduleResult,\n PublishResult,\n} from \"./types/posts\";\nexport type { Workspace } from \"./types/workspaces\";\n\n// Resource class re-exports (for advanced usage)\nexport { Emails } from \"./resources/emails\";\nexport { Contacts } from \"./resources/contacts\";\nexport { Deals } from \"./resources/deals\";\nexport { Gdpr } from \"./resources/gdpr\";\nexport { Posts } from \"./resources/posts\";\nexport { Workspaces } from \"./resources/workspaces\";\nexport { BaseClient } from \"./client\";\n\n/** Convenience factory — equivalent to `new Medal(apiKey, options)`. */\nexport function createMedalClient(apiKey: string, options?: MedalOptions): Medal {\n return new Medal(apiKey, options);\n}\n\nexport default Medal;\n","/** Successful API response wrapper */\nexport interface ApiResponse<T> {\n data: T;\n}\n\n/** Paginated API response */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n has_more: boolean;\n next_cursor: string | null;\n };\n}\n\n/** API error thrown by the client */\nexport class MedalApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"MedalApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n/** Pagination options for list endpoints */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n","import { MedalApiError } from \"./types/common\";\n\n/** Configuration for the low-level HTTP client. */\nexport interface ClientConfig {\n baseUrl: string;\n token: string;\n workspaceId?: string;\n timeout: number;\n userAgent: string;\n}\n\n/**\n * Low-level HTTP client used by all resource classes.\n * Handles authentication, retries, timeout, and error parsing.\n */\nexport class BaseClient {\n /** Resolved client configuration. */\n readonly config: ClientConfig;\n\n constructor(config: ClientConfig) {\n this.config = config;\n }\n\n /** Execute an authenticated GET request and return the parsed JSON body. */\n async get<T>(path: string, params?: Record<string, string | undefined>): Promise<T> {\n const url = this.buildUrl(path, params);\n return this.request<T>(url, { method: \"GET\" });\n }\n\n /** Execute an authenticated POST request with a JSON body. */\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n /** Execute an authenticated PATCH request with a JSON body. */\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n /** Execute an authenticated DELETE request. */\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(this.buildUrl(path), { method: \"DELETE\" });\n }\n\n private buildUrl(path: string, params?: Record<string, string | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const maxAttempts = 3;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${this.config.token}`);\n if (this.config.workspaceId) {\n headers.set(\"x-workspace-id\", this.config.workspaceId);\n }\n try {\n headers.set(\"user-agent\", this.config.userAgent);\n } catch {\n // Browsers disallow setting user-agent\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n let res: Response;\n try {\n res = await fetch(url, { ...init, headers, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n\n // Retry on 429 / 5xx (but not on the final attempt)\n if (\n (res.status === 429 || (res.status >= 500 && res.status <= 599)) &&\n attempt < maxAttempts\n ) {\n const retryAfter = res.headers.get(\"retry-after\");\n let delayMs = 0;\n if (retryAfter) {\n const seconds = Number(retryAfter);\n delayMs = Number.isFinite(seconds) ? seconds * 1000 : 0;\n }\n if (delayMs <= 0) {\n delayMs = 250 * attempt;\n }\n await new Promise((r) => setTimeout(r, delayMs));\n continue;\n }\n\n // Parse response\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n if (!res.ok) {\n const body = parsed as\n | { error?: { code?: string; message?: string; details?: unknown } }\n | undefined;\n throw new MedalApiError(\n res.status,\n body?.error?.code ?? \"UNKNOWN_ERROR\",\n body?.error?.message ?? `HTTP ${res.status}: ${res.statusText}`,\n body?.error?.details,\n );\n }\n\n return parsed as T;\n }\n\n /* v8 ignore next -- unreachable: loop always returns or throws */\n throw new Error(\"Request failed after retries\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"../types/common\";\nimport type {\n Activity,\n AddNoteInput,\n Contact,\n ContactCreateResult,\n ContactNoteResult,\n ContactRemoveResult,\n ContactUpdateResult,\n CreateContactInput,\n ImportContactInput,\n ImportContactsResult,\n ListContactsOptions,\n UpdateContactInput,\n} from \"../types/contacts\";\n\n/** Manage contacts in the workspace CRM. */\nexport class Contacts {\n constructor(private client: BaseClient) {}\n\n /** List contacts with cursor-based pagination and optional filters. */\n async list(options?: ListContactsOptions): Promise<PaginatedResponse<Contact>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.email_status) params.email_status = options.email_status;\n if (options?.label_ids) params.label_ids = options.label_ids.join(\",\");\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/contacts\", params);\n }\n\n /** Create a new contact. Email must be unique in the workspace. */\n async create(input: CreateContactInput): Promise<ApiResponse<ContactCreateResult>> {\n return this.client.post(\"/api/v1/contacts\", input);\n }\n\n /** Get a contact by ID. */\n async get(id: string): Promise<ApiResponse<Contact>> {\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a contact. */\n async update(id: string, input: UpdateContactInput): Promise<ApiResponse<ContactUpdateResult>> {\n return this.client.patch(`/api/v1/contacts/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a contact. */\n async remove(id: string): Promise<ApiResponse<ContactRemoveResult>> {\n return this.client.delete(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Get the activity timeline for a contact. */\n async activities(id: string, options?: PaginationOptions): Promise<PaginatedResponse<Activity>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}/activities`, params);\n }\n\n /** Add a note to a contact's timeline. */\n async addNote(id: string, input: AddNoteInput): Promise<ApiResponse<ContactNoteResult>> {\n return this.client.post(`/api/v1/contacts/${encodeURIComponent(id)}/notes`, input);\n }\n\n /** Bulk import contacts (max 500). Duplicates are skipped. */\n async import(contacts: ImportContactInput[]): Promise<ApiResponse<ImportContactsResult>> {\n return this.client.post(\"/api/v1/contacts/import\", { contacts });\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n CreateDealInput,\n Deal,\n DealCreateResult,\n DealRemoveResult,\n DealUpdateResult,\n ListDealsOptions,\n UpdateDealInput,\n} from \"../types/deals\";\n\n/** Manage sponsorship deals in the workspace. */\nexport class Deals {\n constructor(private client: BaseClient) {}\n\n /** List deals with cursor-based pagination and optional filters. */\n async list(options?: ListDealsOptions): Promise<PaginatedResponse<Deal>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/deals\", params);\n }\n\n /** Create a new deal. */\n async create(input: CreateDealInput): Promise<ApiResponse<DealCreateResult>> {\n return this.client.post(\"/api/v1/deals\", input);\n }\n\n /** Get a deal by ID. */\n async get(id: string): Promise<ApiResponse<Deal>> {\n return this.client.get(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a deal. Set contact_id to null to unlink. */\n async update(id: string, input: UpdateDealInput): Promise<ApiResponse<DealUpdateResult>> {\n return this.client.patch(`/api/v1/deals/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a deal. */\n async remove(id: string): Promise<ApiResponse<DealRemoveResult>> {\n return this.client.delete(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n BatchSendInput,\n BatchSendSummary,\n EmailSend,\n EmailSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n SendEmailInput,\n} from \"../types/emails\";\n\n/** Manage email templates stored in the workspace. */\nclass EmailTemplates {\n constructor(private client: BaseClient) {}\n\n /** List all active email templates in the workspace. */\n async list(): Promise<ApiResponse<EmailTemplate[]>> {\n return this.client.get(\"/api/v1/emails/templates\");\n }\n\n /** Get a specific email template by slug, optionally with locale resolution. */\n async get(slug: string, options?: GetTemplateOptions): Promise<ApiResponse<EmailTemplateDetail>> {\n const params: Record<string, string | undefined> = {};\n if (options?.locale) params.locale = options.locale;\n if (options?.fallback_locale) params.fallback_locale = options.fallback_locale;\n return this.client.get(`/api/v1/emails/templates/${encodeURIComponent(slug)}`, params);\n }\n}\n\n/** Send transactional emails and manage templates. */\nexport class Emails {\n readonly templates: EmailTemplates;\n\n constructor(private client: BaseClient) {\n this.templates = new EmailTemplates(client);\n }\n\n /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */\n async send(input: SendEmailInput): Promise<ApiResponse<EmailSendResult>> {\n return this.client.post(\"/api/v1/emails\", input);\n }\n\n /** Get the delivery status of a sent email. */\n async get(id: string): Promise<ApiResponse<EmailSend>> {\n return this.client.get(`/api/v1/emails/${encodeURIComponent(id)}`);\n }\n\n /** Send the same template to multiple recipients (max 100). Returns HTTP 202. */\n async batch(input: BatchSendInput): Promise<ApiResponse<BatchSendSummary>> {\n return this.client.post(\"/api/v1/emails/batch\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n ConsentRecord,\n ConsentResult,\n CookieConsentInput,\n GdprExport,\n RecordConsentInput,\n} from \"../types/gdpr\";\n\n/** Manage GDPR compliance — data exports, consent records, and cookie consent. */\nexport class Gdpr {\n constructor(private client: BaseClient) {}\n\n /** Request a workspace data export. Runs asynchronously. */\n async requestExport(): Promise<ApiResponse<{ request_id: string; status: string }>> {\n return this.client.post(\"/api/v1/gdpr/export\");\n }\n\n /** List all workspace export requests. */\n async listExports(): Promise<ApiResponse<GdprExport[]>> {\n return this.client.get(\"/api/v1/gdpr/exports\");\n }\n\n /** Get the status of a specific export. */\n async getExport(id: string): Promise<ApiResponse<GdprExport>> {\n return this.client.get(`/api/v1/gdpr/exports/${encodeURIComponent(id)}`);\n }\n\n /** Record a GDPR consent decision for a contact by email. */\n async recordConsent(input: RecordConsentInput): Promise<ApiResponse<ConsentResult>> {\n return this.client.post(\"/api/v1/gdpr/consent\", input);\n }\n\n /** Get all consent records for a contact by email. */\n async getConsent(email: string): Promise<ApiResponse<ConsentRecord[]>> {\n return this.client.get(`/api/v1/gdpr/consent/${encodeURIComponent(email)}`);\n }\n\n /** Record cookie consent from an external site (legacy endpoint). */\n async cookieConsent(input: CookieConsentInput): Promise<{ success: boolean; logId?: string }> {\n return this.client.post(\"/api/cookie-consent\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n Channel,\n CreatePostInput,\n ListPostsOptions,\n Post,\n PostDetail,\n PublishResult,\n SchedulePostInput,\n ScheduleResult,\n UpdatePostInput,\n} from \"../types/posts\";\n\n/** Create and publish posts across connected channels. */\nexport class Posts {\n constructor(private client: BaseClient) {}\n\n /** List posts with cursor-based pagination and optional filters. */\n async list(options?: ListPostsOptions): Promise<PaginatedResponse<Post>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.type) params.type = options.type;\n return this.client.get(\"/api/v1/posts\", params);\n }\n\n /** Create a new post with content and target channels. */\n async create(input: CreatePostInput): Promise<ApiResponse<{ id: string }>> {\n return this.client.post(\"/api/v1/posts\", input);\n }\n\n /** Get a post by ID, including its per-channel variants. */\n async get(id: string): Promise<ApiResponse<PostDetail>> {\n return this.client.get(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Update a draft post's title or content. */\n async update(id: string, input: UpdatePostInput): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.patch(`/api/v1/posts/${encodeURIComponent(id)}`, input);\n }\n\n /** Delete a post. */\n async remove(id: string): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.delete(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Schedule a post for future publication. */\n async schedule(id: string, input: SchedulePostInput): Promise<ApiResponse<ScheduleResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/schedule`, input);\n }\n\n /** Publish a post immediately to all target channels. */\n async publish(id: string): Promise<ApiResponse<PublishResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/publish`);\n }\n\n /** List connected publishing channels for this workspace. */\n async channels(): Promise<ApiResponse<Channel[]>> {\n return this.client.get(\"/api/v1/posts/channels\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type { Workspace } from \"../types/workspaces\";\n\n/** Access workspaces for the authenticated credential. */\nexport class Workspaces {\n constructor(private client: BaseClient) {}\n\n /** List workspaces accessible to the current API key or OAuth token. */\n async list(): Promise<ApiResponse<Workspace[]>> {\n return this.client.get(\"/api/v1/me/workspaces\");\n }\n}\n"],"mappings":"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","names":[]}
@@ -115,6 +115,7 @@ var Contacts = class {
115
115
  constructor(client) {
116
116
  this.client = client;
117
117
  }
118
+ client;
118
119
  /** List contacts with cursor-based pagination and optional filters. */
119
120
  async list(options) {
120
121
  const params = {};
@@ -164,6 +165,7 @@ var Deals = class {
164
165
  constructor(client) {
165
166
  this.client = client;
166
167
  }
168
+ client;
167
169
  /** List deals with cursor-based pagination and optional filters. */
168
170
  async list(options) {
169
171
  const params = {};
@@ -196,6 +198,7 @@ var EmailTemplates = class {
196
198
  constructor(client) {
197
199
  this.client = client;
198
200
  }
201
+ client;
199
202
  /** List all active email templates in the workspace. */
200
203
  async list() {
201
204
  return this.client.get("/api/v1/emails/templates");
@@ -213,6 +216,7 @@ var Emails = class {
213
216
  this.client = client;
214
217
  this.templates = new EmailTemplates(client);
215
218
  }
219
+ client;
216
220
  templates;
217
221
  /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */
218
222
  async send(input) {
@@ -233,6 +237,7 @@ var Gdpr = class {
233
237
  constructor(client) {
234
238
  this.client = client;
235
239
  }
240
+ client;
236
241
  /** Request a workspace data export. Runs asynchronously. */
237
242
  async requestExport() {
238
243
  return this.client.post("/api/v1/gdpr/export");
@@ -264,6 +269,7 @@ var Posts = class {
264
269
  constructor(client) {
265
270
  this.client = client;
266
271
  }
272
+ client;
267
273
  /** List posts with cursor-based pagination and optional filters. */
268
274
  async list(options) {
269
275
  const params = {};
@@ -308,6 +314,7 @@ var Workspaces = class {
308
314
  constructor(client) {
309
315
  this.client = client;
310
316
  }
317
+ client;
311
318
  /** List workspaces accessible to the current API key or OAuth token. */
312
319
  async list() {
313
320
  return this.client.get("/api/v1/me/workspaces");
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/types/common.ts","../../src/client.ts","../../src/resources/contacts.ts","../../src/resources/deals.ts","../../src/resources/emails.ts","../../src/resources/gdpr.ts","../../src/resources/posts.ts","../../src/resources/workspaces.ts","../../src/index.ts"],"sourcesContent":["/** Successful API response wrapper */\nexport interface ApiResponse<T> {\n data: T;\n}\n\n/** Paginated API response */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n has_more: boolean;\n next_cursor: string | null;\n };\n}\n\n/** API error thrown by the client */\nexport class MedalApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"MedalApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n/** Pagination options for list endpoints */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n","import { MedalApiError } from \"./types/common\";\n\n/** Configuration for the low-level HTTP client. */\nexport interface ClientConfig {\n baseUrl: string;\n token: string;\n workspaceId?: string;\n timeout: number;\n userAgent: string;\n}\n\n/**\n * Low-level HTTP client used by all resource classes.\n * Handles authentication, retries, timeout, and error parsing.\n */\nexport class BaseClient {\n /** Resolved client configuration. */\n readonly config: ClientConfig;\n\n constructor(config: ClientConfig) {\n this.config = config;\n }\n\n /** Execute an authenticated GET request and return the parsed JSON body. */\n async get<T>(path: string, params?: Record<string, string | undefined>): Promise<T> {\n const url = this.buildUrl(path, params);\n return this.request<T>(url, { method: \"GET\" });\n }\n\n /** Execute an authenticated POST request with a JSON body. */\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n /** Execute an authenticated PATCH request with a JSON body. */\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n /** Execute an authenticated DELETE request. */\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(this.buildUrl(path), { method: \"DELETE\" });\n }\n\n private buildUrl(path: string, params?: Record<string, string | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const maxAttempts = 3;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${this.config.token}`);\n if (this.config.workspaceId) {\n headers.set(\"x-workspace-id\", this.config.workspaceId);\n }\n try {\n headers.set(\"user-agent\", this.config.userAgent);\n } catch {\n // Browsers disallow setting user-agent\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n let res: Response;\n try {\n res = await fetch(url, { ...init, headers, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n\n // Retry on 429 / 5xx (but not on the final attempt)\n if (\n (res.status === 429 || (res.status >= 500 && res.status <= 599)) &&\n attempt < maxAttempts\n ) {\n const retryAfter = res.headers.get(\"retry-after\");\n let delayMs = 0;\n if (retryAfter) {\n const seconds = Number(retryAfter);\n delayMs = Number.isFinite(seconds) ? seconds * 1000 : 0;\n }\n if (delayMs <= 0) {\n delayMs = 250 * attempt;\n }\n await new Promise((r) => setTimeout(r, delayMs));\n continue;\n }\n\n // Parse response\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n if (!res.ok) {\n const body = parsed as\n | { error?: { code?: string; message?: string; details?: unknown } }\n | undefined;\n throw new MedalApiError(\n res.status,\n body?.error?.code ?? \"UNKNOWN_ERROR\",\n body?.error?.message ?? `HTTP ${res.status}: ${res.statusText}`,\n body?.error?.details,\n );\n }\n\n return parsed as T;\n }\n\n /* v8 ignore next -- unreachable: loop always returns or throws */\n throw new Error(\"Request failed after retries\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"../types/common\";\nimport type {\n Activity,\n AddNoteInput,\n Contact,\n ContactCreateResult,\n ContactNoteResult,\n ContactRemoveResult,\n ContactUpdateResult,\n CreateContactInput,\n ImportContactInput,\n ImportContactsResult,\n ListContactsOptions,\n UpdateContactInput,\n} from \"../types/contacts\";\n\n/** Manage contacts in the workspace CRM. */\nexport class Contacts {\n constructor(private client: BaseClient) {}\n\n /** List contacts with cursor-based pagination and optional filters. */\n async list(options?: ListContactsOptions): Promise<PaginatedResponse<Contact>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.email_status) params.email_status = options.email_status;\n if (options?.label_ids) params.label_ids = options.label_ids.join(\",\");\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/contacts\", params);\n }\n\n /** Create a new contact. Email must be unique in the workspace. */\n async create(input: CreateContactInput): Promise<ApiResponse<ContactCreateResult>> {\n return this.client.post(\"/api/v1/contacts\", input);\n }\n\n /** Get a contact by ID. */\n async get(id: string): Promise<ApiResponse<Contact>> {\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a contact. */\n async update(id: string, input: UpdateContactInput): Promise<ApiResponse<ContactUpdateResult>> {\n return this.client.patch(`/api/v1/contacts/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a contact. */\n async remove(id: string): Promise<ApiResponse<ContactRemoveResult>> {\n return this.client.delete(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Get the activity timeline for a contact. */\n async activities(id: string, options?: PaginationOptions): Promise<PaginatedResponse<Activity>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}/activities`, params);\n }\n\n /** Add a note to a contact's timeline. */\n async addNote(id: string, input: AddNoteInput): Promise<ApiResponse<ContactNoteResult>> {\n return this.client.post(`/api/v1/contacts/${encodeURIComponent(id)}/notes`, input);\n }\n\n /** Bulk import contacts (max 500). Duplicates are skipped. */\n async import(contacts: ImportContactInput[]): Promise<ApiResponse<ImportContactsResult>> {\n return this.client.post(\"/api/v1/contacts/import\", { contacts });\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n CreateDealInput,\n Deal,\n DealCreateResult,\n DealRemoveResult,\n DealUpdateResult,\n ListDealsOptions,\n UpdateDealInput,\n} from \"../types/deals\";\n\n/** Manage sponsorship deals in the workspace. */\nexport class Deals {\n constructor(private client: BaseClient) {}\n\n /** List deals with cursor-based pagination and optional filters. */\n async list(options?: ListDealsOptions): Promise<PaginatedResponse<Deal>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/deals\", params);\n }\n\n /** Create a new deal. */\n async create(input: CreateDealInput): Promise<ApiResponse<DealCreateResult>> {\n return this.client.post(\"/api/v1/deals\", input);\n }\n\n /** Get a deal by ID. */\n async get(id: string): Promise<ApiResponse<Deal>> {\n return this.client.get(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a deal. Set contact_id to null to unlink. */\n async update(id: string, input: UpdateDealInput): Promise<ApiResponse<DealUpdateResult>> {\n return this.client.patch(`/api/v1/deals/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a deal. */\n async remove(id: string): Promise<ApiResponse<DealRemoveResult>> {\n return this.client.delete(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n BatchSendInput,\n BatchSendSummary,\n EmailSend,\n EmailSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n SendEmailInput,\n} from \"../types/emails\";\n\n/** Manage email templates stored in the workspace. */\nclass EmailTemplates {\n constructor(private client: BaseClient) {}\n\n /** List all active email templates in the workspace. */\n async list(): Promise<ApiResponse<EmailTemplate[]>> {\n return this.client.get(\"/api/v1/emails/templates\");\n }\n\n /** Get a specific email template by slug, optionally with locale resolution. */\n async get(slug: string, options?: GetTemplateOptions): Promise<ApiResponse<EmailTemplateDetail>> {\n const params: Record<string, string | undefined> = {};\n if (options?.locale) params.locale = options.locale;\n if (options?.fallback_locale) params.fallback_locale = options.fallback_locale;\n return this.client.get(`/api/v1/emails/templates/${encodeURIComponent(slug)}`, params);\n }\n}\n\n/** Send transactional emails and manage templates. */\nexport class Emails {\n readonly templates: EmailTemplates;\n\n constructor(private client: BaseClient) {\n this.templates = new EmailTemplates(client);\n }\n\n /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */\n async send(input: SendEmailInput): Promise<ApiResponse<EmailSendResult>> {\n return this.client.post(\"/api/v1/emails\", input);\n }\n\n /** Get the delivery status of a sent email. */\n async get(id: string): Promise<ApiResponse<EmailSend>> {\n return this.client.get(`/api/v1/emails/${encodeURIComponent(id)}`);\n }\n\n /** Send the same template to multiple recipients (max 100). Returns HTTP 202. */\n async batch(input: BatchSendInput): Promise<ApiResponse<BatchSendSummary>> {\n return this.client.post(\"/api/v1/emails/batch\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n ConsentRecord,\n ConsentResult,\n CookieConsentInput,\n GdprExport,\n RecordConsentInput,\n} from \"../types/gdpr\";\n\n/** Manage GDPR compliance — data exports, consent records, and cookie consent. */\nexport class Gdpr {\n constructor(private client: BaseClient) {}\n\n /** Request a workspace data export. Runs asynchronously. */\n async requestExport(): Promise<ApiResponse<{ request_id: string; status: string }>> {\n return this.client.post(\"/api/v1/gdpr/export\");\n }\n\n /** List all workspace export requests. */\n async listExports(): Promise<ApiResponse<GdprExport[]>> {\n return this.client.get(\"/api/v1/gdpr/exports\");\n }\n\n /** Get the status of a specific export. */\n async getExport(id: string): Promise<ApiResponse<GdprExport>> {\n return this.client.get(`/api/v1/gdpr/exports/${encodeURIComponent(id)}`);\n }\n\n /** Record a GDPR consent decision for a contact by email. */\n async recordConsent(input: RecordConsentInput): Promise<ApiResponse<ConsentResult>> {\n return this.client.post(\"/api/v1/gdpr/consent\", input);\n }\n\n /** Get all consent records for a contact by email. */\n async getConsent(email: string): Promise<ApiResponse<ConsentRecord[]>> {\n return this.client.get(`/api/v1/gdpr/consent/${encodeURIComponent(email)}`);\n }\n\n /** Record cookie consent from an external site (legacy endpoint). */\n async cookieConsent(input: CookieConsentInput): Promise<{ success: boolean; logId?: string }> {\n return this.client.post(\"/api/cookie-consent\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n Channel,\n CreatePostInput,\n ListPostsOptions,\n Post,\n PostDetail,\n PublishResult,\n SchedulePostInput,\n ScheduleResult,\n UpdatePostInput,\n} from \"../types/posts\";\n\n/** Create and publish posts across connected channels. */\nexport class Posts {\n constructor(private client: BaseClient) {}\n\n /** List posts with cursor-based pagination and optional filters. */\n async list(options?: ListPostsOptions): Promise<PaginatedResponse<Post>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.type) params.type = options.type;\n return this.client.get(\"/api/v1/posts\", params);\n }\n\n /** Create a new post with content and target channels. */\n async create(input: CreatePostInput): Promise<ApiResponse<{ id: string }>> {\n return this.client.post(\"/api/v1/posts\", input);\n }\n\n /** Get a post by ID, including its per-channel variants. */\n async get(id: string): Promise<ApiResponse<PostDetail>> {\n return this.client.get(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Update a draft post's title or content. */\n async update(id: string, input: UpdatePostInput): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.patch(`/api/v1/posts/${encodeURIComponent(id)}`, input);\n }\n\n /** Delete a post. */\n async remove(id: string): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.delete(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Schedule a post for future publication. */\n async schedule(id: string, input: SchedulePostInput): Promise<ApiResponse<ScheduleResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/schedule`, input);\n }\n\n /** Publish a post immediately to all target channels. */\n async publish(id: string): Promise<ApiResponse<PublishResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/publish`);\n }\n\n /** List connected publishing channels for this workspace. */\n async channels(): Promise<ApiResponse<Channel[]>> {\n return this.client.get(\"/api/v1/posts/channels\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type { Workspace } from \"../types/workspaces\";\n\n/** Access workspaces for the authenticated credential. */\nexport class Workspaces {\n constructor(private client: BaseClient) {}\n\n /** List workspaces accessible to the current API key or OAuth token. */\n async list(): Promise<ApiResponse<Workspace[]>> {\n return this.client.get(\"/api/v1/me/workspaces\");\n }\n}\n","/**\n * Official TypeScript SDK for the Medal Social API.\n *\n * Provides typed access to posts, emails, contacts, deals, GDPR compliance,\n * and workspace management. Works in Node.js, Deno, Bun, Cloudflare Workers,\n * and modern browsers.\n *\n * @example\n * ```ts\n * import { Medal } from \"@medalsocial/sdk\";\n *\n * const medal = new Medal(\"medal_xxx\");\n * const { data: post } = await medal.posts.create({\n * content: \"Hello world!\",\n * channel_ids: [\"ch_1\"],\n * });\n * ```\n *\n * @module\n */\nimport { BaseClient } from \"./client\";\nimport { Contacts } from \"./resources/contacts\";\nimport { Deals } from \"./resources/deals\";\nimport { Emails } from \"./resources/emails\";\nimport { Gdpr } from \"./resources/gdpr\";\nimport { Posts } from \"./resources/posts\";\nimport { Workspaces } from \"./resources/workspaces\";\n\n/** Options for configuring the {@link Medal} client. */\nexport interface MedalOptions {\n /** Override the base URL (defaults to https://io.medalsocial.com). */\n baseUrl?: string;\n /** Request timeout in ms (default 30000). */\n timeout?: number;\n /**\n * Workspace ID — required for OAuth access tokens, ignored for API keys.\n * API keys are scoped to a single workspace, so the workspace is inferred.\n * OAuth tokens can access multiple workspaces, so you must specify which one.\n */\n workspaceId?: string;\n}\n\n/**\n * Medal Social SDK client.\n *\n * Supports both API key and OAuth access token authentication:\n *\n * @example API Key (recommended for server-side)\n * ```ts\n * import { Medal } from '@medalsocial/sdk';\n *\n * // API keys start with medal_ and are scoped to one workspace\n * const medal = new Medal('medal_xxx');\n * ```\n *\n * @example OAuth Access Token\n * ```ts\n * // OAuth tokens require a workspaceId\n * const medal = new Medal('oauth_access_token', {\n * workspaceId: 'workspace_id_here',\n * });\n * ```\n *\n * @example Full usage\n * ```ts\n * const medal = new Medal('medal_xxx');\n *\n * // Posts — create, schedule, publish\n * const { data: post } = await medal.posts.create({\n * content: 'Hello world!',\n * channel_ids: ['ch_1'],\n * });\n * await medal.posts.schedule(post.id, { scheduled_at: '2026-03-15T10:00:00Z' });\n *\n * // Emails — send transactional emails\n * await medal.emails.send({\n * template_slug: 'welcome',\n * to: 'user@example.com',\n * variables: { name: 'John' },\n * });\n *\n * // Contacts, Deals, GDPR, Workspaces\n * const contacts = await medal.contacts.list({ status: 'lead' });\n * const { data: deal } = await medal.deals.create({ title: 'Acme', value: 50000 });\n * await medal.gdpr.recordConsent({ email: 'u@x.com', consent_type: 'marketing_email', granted: true });\n * const { data: workspaces } = await medal.workspaces.list();\n * ```\n */\nexport class Medal {\n readonly emails: Emails;\n readonly contacts: Contacts;\n readonly deals: Deals;\n readonly gdpr: Gdpr;\n readonly posts: Posts;\n readonly workspaces: Workspaces;\n\n constructor(token: string, options?: MedalOptions) {\n if (!token) {\n throw new Error(\n \"Authentication token is required. Pass your medal_xxx API key or OAuth access token as the first argument.\",\n );\n }\n\n const client = new BaseClient({\n baseUrl: (options?.baseUrl ?? \"https://io.medalsocial.com\").replace(/\\/$/, \"\"),\n token,\n workspaceId: options?.workspaceId,\n timeout: options?.timeout ?? 30000,\n userAgent: \"medalsocial-sdk/1.0.0 (+https://github.com/Medal-Social/MedalSocial)\",\n });\n\n this.emails = new Emails(client);\n this.contacts = new Contacts(client);\n this.deals = new Deals(client);\n this.gdpr = new Gdpr(client);\n this.posts = new Posts(client);\n this.workspaces = new Workspaces(client);\n }\n}\n\n// Re-export all types\nexport { MedalApiError } from \"./types/common\";\nexport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"./types/common\";\nexport type {\n SendEmailInput,\n EmailSendResult,\n EmailSend,\n BatchSendInput,\n BatchSendSummary,\n BatchSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n} from \"./types/emails\";\nexport type {\n Contact,\n ContactCreateResult,\n ContactUpdateResult,\n ContactRemoveResult,\n ContactNoteResult,\n ContactStatus,\n EmailStatus,\n CreateContactInput,\n UpdateContactInput,\n ListContactsOptions,\n ImportContactInput,\n ImportContactsResult,\n Activity,\n AddNoteInput,\n} from \"./types/contacts\";\nexport type {\n Deal,\n DealCreateResult,\n DealUpdateResult,\n DealRemoveResult,\n DealStatus,\n CreateDealInput,\n UpdateDealInput,\n ListDealsOptions,\n} from \"./types/deals\";\nexport type {\n GdprExport,\n ConsentType,\n RecordConsentInput,\n ConsentRecord,\n ConsentResult,\n ContactConsents,\n CookieConsentInput,\n CookieCategoryConsent,\n} from \"./types/gdpr\";\nexport type {\n Post,\n PostType,\n PostVariant,\n PostDetail,\n Channel,\n CreatePostInput,\n UpdatePostInput,\n SchedulePostInput,\n ListPostsOptions,\n ScheduleResult,\n PublishResult,\n} from \"./types/posts\";\nexport type { Workspace } from \"./types/workspaces\";\n\n// Resource class re-exports (for advanced usage)\nexport { Emails } from \"./resources/emails\";\nexport { Contacts } from \"./resources/contacts\";\nexport { Deals } from \"./resources/deals\";\nexport { Gdpr } from \"./resources/gdpr\";\nexport { Posts } from \"./resources/posts\";\nexport { Workspaces } from \"./resources/workspaces\";\nexport { BaseClient } from \"./client\";\n\n/** Convenience factory — equivalent to `new Medal(apiKey, options)`. */\nexport function createMedalClient(apiKey: string, options?: MedalOptions): Medal {\n return new Medal(apiKey, options);\n}\n\nexport default Medal;\n"],"mappings":";AAeO,IAAM,gBAAN,cAA4B,MAAM;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,MAAc,SAAiB,SAAmB;AAC5E,UAAM,OAAO;AACb,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,OAAO;AACZ,SAAK,UAAU;AAAA,EACjB;AACF;;;ACZO,IAAM,aAAN,MAAiB;AAAA;AAAA,EAEb;AAAA,EAET,YAAY,QAAsB;AAChC,SAAK,SAAS;AAAA,EAChB;AAAA;AAAA,EAGA,MAAM,IAAO,MAAc,QAAyD;AAClF,UAAM,MAAM,KAAK,SAAS,MAAM,MAAM;AACtC,WAAO,KAAK,QAAW,KAAK,EAAE,QAAQ,MAAM,CAAC;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,KAAQ,MAAc,MAA4B;AACtD,WAAO,KAAK,QAAW,KAAK,SAAS,IAAI,GAAG;AAAA,MAC1C,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,SAAS,SAAY,KAAK,UAAU,IAAI,IAAI;AAAA,IACpD,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,MAAS,MAAc,MAA2B;AACtD,WAAO,KAAK,QAAW,KAAK,SAAS,IAAI,GAAG;AAAA,MAC1C,QAAQ;AAAA,MACR,SAAS,EAAE,gBAAgB,mBAAmB;AAAA,MAC9C,MAAM,KAAK,UAAU,IAAI;AAAA,IAC3B,CAAC;AAAA,EACH;AAAA;AAAA,EAGA,MAAM,OAAU,MAA0B;AACxC,WAAO,KAAK,QAAW,KAAK,SAAS,IAAI,GAAG,EAAE,QAAQ,SAAS,CAAC;AAAA,EAClE;AAAA,EAEQ,SAAS,MAAc,QAAqD;AAClF,UAAM,MAAM,IAAI,IAAI,GAAG,KAAK,OAAO,OAAO,GAAG,IAAI,EAAE;AACnD,QAAI,QAAQ;AACV,iBAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,YAAI,UAAU,QAAW;AACvB,cAAI,aAAa,IAAI,KAAK,KAAK;AAAA,QACjC;AAAA,MACF;AAAA,IACF;AACA,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA,EAEA,MAAc,QAAW,KAAa,MAA+B;AACnE,UAAM,cAAc;AAEpB,aAAS,UAAU,GAAG,WAAW,aAAa,WAAW;AACvD,YAAM,UAAU,IAAI,QAAQ,KAAK,OAAO;AACxC,cAAQ,IAAI,iBAAiB,UAAU,KAAK,OAAO,KAAK,EAAE;AAC1D,UAAI,KAAK,OAAO,aAAa;AAC3B,gBAAQ,IAAI,kBAAkB,KAAK,OAAO,WAAW;AAAA,MACvD;AACA,UAAI;AACF,gBAAQ,IAAI,cAAc,KAAK,OAAO,SAAS;AAAA,MACjD,QAAQ;AAAA,MAER;AAEA,YAAM,aAAa,IAAI,gBAAgB;AACvC,YAAM,UAAU,WAAW,MAAM,WAAW,MAAM,GAAG,KAAK,OAAO,OAAO;AAExE,UAAI;AACJ,UAAI;AACF,cAAM,MAAM,MAAM,KAAK,EAAE,GAAG,MAAM,SAAS,QAAQ,WAAW,OAAO,CAAC;AAAA,MACxE,UAAE;AACA,qBAAa,OAAO;AAAA,MACtB;AAGA,WACG,IAAI,WAAW,OAAQ,IAAI,UAAU,OAAO,IAAI,UAAU,QAC3D,UAAU,aACV;AACA,cAAM,aAAa,IAAI,QAAQ,IAAI,aAAa;AAChD,YAAI,UAAU;AACd,YAAI,YAAY;AACd,gBAAM,UAAU,OAAO,UAAU;AACjC,oBAAU,OAAO,SAAS,OAAO,IAAI,UAAU,MAAO;AAAA,QACxD;AACA,YAAI,WAAW,GAAG;AAChB,oBAAU,MAAM;AAAA,QAClB;AACA,cAAM,IAAI,QAAQ,CAAC,MAAM,WAAW,GAAG,OAAO,CAAC;AAC/C;AAAA,MACF;AAGA,YAAM,OAAO,MAAM,IAAI,KAAK;AAC5B,UAAI;AACJ,UAAI;AACF,iBAAS,OAAO,KAAK,MAAM,IAAI,IAAI;AAAA,MACrC,QAAQ;AACN,iBAAS;AAAA,MACX;AAEA,UAAI,CAAC,IAAI,IAAI;AACX,cAAM,OAAO;AAGb,cAAM,IAAI;AAAA,UACR,IAAI;AAAA,UACJ,MAAM,OAAO,QAAQ;AAAA,UACrB,MAAM,OAAO,WAAW,QAAQ,IAAI,MAAM,KAAK,IAAI,UAAU;AAAA,UAC7D,MAAM,OAAO;AAAA,QACf;AAAA,MACF;AAEA,aAAO;AAAA,IACT;AAGA,UAAM,IAAI,MAAM,8BAA8B;AAAA,EAChD;AACF;;;ACpHO,IAAM,WAAN,MAAe;AAAA,EACpB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,KAAK,SAAoE;AAC7E,UAAM,SAA6C,CAAC;AACpD,QAAI,SAAS,UAAU,OAAW,QAAO,QAAQ,OAAO,QAAQ,KAAK;AACrE,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,aAAc,QAAO,eAAe,QAAQ;AACzD,QAAI,SAAS,UAAW,QAAO,YAAY,QAAQ,UAAU,KAAK,GAAG;AACrE,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,WAAO,KAAK,OAAO,IAAI,oBAAoB,MAAM;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,OAAO,OAAsE;AACjF,WAAO,KAAK,OAAO,KAAK,oBAAoB,KAAK;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,IAAI,IAA2C;AACnD,WAAO,KAAK,OAAO,IAAI,oBAAoB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,OAAsE;AAC7F,WAAO,KAAK,OAAO,MAAM,oBAAoB,mBAAmB,EAAE,CAAC,IAAI,KAAK;AAAA,EAC9E;AAAA;AAAA,EAGA,MAAM,OAAO,IAAuD;AAClE,WAAO,KAAK,OAAO,OAAO,oBAAoB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACxE;AAAA;AAAA,EAGA,MAAM,WAAW,IAAY,SAAmE;AAC9F,UAAM,SAA6C,CAAC;AACpD,QAAI,SAAS,UAAU,OAAW,QAAO,QAAQ,OAAO,QAAQ,KAAK;AACrE,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,WAAO,KAAK,OAAO,IAAI,oBAAoB,mBAAmB,EAAE,CAAC,eAAe,MAAM;AAAA,EACxF;AAAA;AAAA,EAGA,MAAM,QAAQ,IAAY,OAA8D;AACtF,WAAO,KAAK,OAAO,KAAK,oBAAoB,mBAAmB,EAAE,CAAC,UAAU,KAAK;AAAA,EACnF;AAAA;AAAA,EAGA,MAAM,OAAO,UAA4E;AACvF,WAAO,KAAK,OAAO,KAAK,2BAA2B,EAAE,SAAS,CAAC;AAAA,EACjE;AACF;;;ACzDO,IAAM,QAAN,MAAY;AAAA,EACjB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,KAAK,SAA8D;AACvE,UAAM,SAA6C,CAAC;AACpD,QAAI,SAAS,UAAU,OAAW,QAAO,QAAQ,OAAO,QAAQ,KAAK;AACrE,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,WAAO,KAAK,OAAO,IAAI,iBAAiB,MAAM;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,OAAO,OAAgE;AAC3E,WAAO,KAAK,OAAO,KAAK,iBAAiB,KAAK;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,IAAI,IAAwC;AAChD,WAAO,KAAK,OAAO,IAAI,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,OAAgE;AACvF,WAAO,KAAK,OAAO,MAAM,iBAAiB,mBAAmB,EAAE,CAAC,IAAI,KAAK;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,OAAO,IAAoD;AAC/D,WAAO,KAAK,OAAO,OAAO,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACrE;AACF;;;AC/BA,IAAM,iBAAN,MAAqB;AAAA,EACnB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,OAA8C;AAClD,WAAO,KAAK,OAAO,IAAI,0BAA0B;AAAA,EACnD;AAAA;AAAA,EAGA,MAAM,IAAI,MAAc,SAAyE;AAC/F,UAAM,SAA6C,CAAC;AACpD,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,gBAAiB,QAAO,kBAAkB,QAAQ;AAC/D,WAAO,KAAK,OAAO,IAAI,4BAA4B,mBAAmB,IAAI,CAAC,IAAI,MAAM;AAAA,EACvF;AACF;AAGO,IAAM,SAAN,MAAa;AAAA,EAGlB,YAAoB,QAAoB;AAApB;AAClB,SAAK,YAAY,IAAI,eAAe,MAAM;AAAA,EAC5C;AAAA,EAJS;AAAA;AAAA,EAOT,MAAM,KAAK,OAA8D;AACvE,WAAO,KAAK,OAAO,KAAK,kBAAkB,KAAK;AAAA,EACjD;AAAA;AAAA,EAGA,MAAM,IAAI,IAA6C;AACrD,WAAO,KAAK,OAAO,IAAI,kBAAkB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACnE;AAAA;AAAA,EAGA,MAAM,MAAM,OAA+D;AACzE,WAAO,KAAK,OAAO,KAAK,wBAAwB,KAAK;AAAA,EACvD;AACF;;;AC1CO,IAAM,OAAN,MAAW;AAAA,EAChB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,gBAA8E;AAClF,WAAO,KAAK,OAAO,KAAK,qBAAqB;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,cAAkD;AACtD,WAAO,KAAK,OAAO,IAAI,sBAAsB;AAAA,EAC/C;AAAA;AAAA,EAGA,MAAM,UAAU,IAA8C;AAC5D,WAAO,KAAK,OAAO,IAAI,wBAAwB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACzE;AAAA;AAAA,EAGA,MAAM,cAAc,OAAgE;AAClF,WAAO,KAAK,OAAO,KAAK,wBAAwB,KAAK;AAAA,EACvD;AAAA;AAAA,EAGA,MAAM,WAAW,OAAsD;AACrE,WAAO,KAAK,OAAO,IAAI,wBAAwB,mBAAmB,KAAK,CAAC,EAAE;AAAA,EAC5E;AAAA;AAAA,EAGA,MAAM,cAAc,OAA0E;AAC5F,WAAO,KAAK,OAAO,KAAK,uBAAuB,KAAK;AAAA,EACtD;AACF;;;AC5BO,IAAM,QAAN,MAAY;AAAA,EACjB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,KAAK,SAA8D;AACvE,UAAM,SAA6C,CAAC;AACpD,QAAI,SAAS,UAAU,OAAW,QAAO,QAAQ,OAAO,QAAQ,KAAK;AACrE,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,OAAQ,QAAO,SAAS,QAAQ;AAC7C,QAAI,SAAS,KAAM,QAAO,OAAO,QAAQ;AACzC,WAAO,KAAK,OAAO,IAAI,iBAAiB,MAAM;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,OAAO,OAA8D;AACzE,WAAO,KAAK,OAAO,KAAK,iBAAiB,KAAK;AAAA,EAChD;AAAA;AAAA,EAGA,MAAM,IAAI,IAA8C;AACtD,WAAO,KAAK,OAAO,IAAI,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EAClE;AAAA;AAAA,EAGA,MAAM,OAAO,IAAY,OAAoE;AAC3F,WAAO,KAAK,OAAO,MAAM,iBAAiB,mBAAmB,EAAE,CAAC,IAAI,KAAK;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,OAAO,IAAwD;AACnE,WAAO,KAAK,OAAO,OAAO,iBAAiB,mBAAmB,EAAE,CAAC,EAAE;AAAA,EACrE;AAAA;AAAA,EAGA,MAAM,SAAS,IAAY,OAAgE;AACzF,WAAO,KAAK,OAAO,KAAK,iBAAiB,mBAAmB,EAAE,CAAC,aAAa,KAAK;AAAA,EACnF;AAAA;AAAA,EAGA,MAAM,QAAQ,IAAiD;AAC7D,WAAO,KAAK,OAAO,KAAK,iBAAiB,mBAAmB,EAAE,CAAC,UAAU;AAAA,EAC3E;AAAA;AAAA,EAGA,MAAM,WAA4C;AAChD,WAAO,KAAK,OAAO,IAAI,wBAAwB;AAAA,EACjD;AACF;;;ACzDO,IAAM,aAAN,MAAiB;AAAA,EACtB,YAAoB,QAAoB;AAApB;AAAA,EAAqB;AAAA;AAAA,EAGzC,MAAM,OAA0C;AAC9C,WAAO,KAAK,OAAO,IAAI,uBAAuB;AAAA,EAChD;AACF;;;AC4EO,IAAM,QAAN,MAAY;AAAA,EACR;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,OAAe,SAAwB;AACjD,QAAI,CAAC,OAAO;AACV,YAAM,IAAI;AAAA,QACR;AAAA,MACF;AAAA,IACF;AAEA,UAAM,SAAS,IAAI,WAAW;AAAA,MAC5B,UAAU,SAAS,WAAW,8BAA8B,QAAQ,OAAO,EAAE;AAAA,MAC7E;AAAA,MACA,aAAa,SAAS;AAAA,MACtB,SAAS,SAAS,WAAW;AAAA,MAC7B,WAAW;AAAA,IACb,CAAC;AAED,SAAK,SAAS,IAAI,OAAO,MAAM;AAC/B,SAAK,WAAW,IAAI,SAAS,MAAM;AACnC,SAAK,QAAQ,IAAI,MAAM,MAAM;AAC7B,SAAK,OAAO,IAAI,KAAK,MAAM;AAC3B,SAAK,QAAQ,IAAI,MAAM,MAAM;AAC7B,SAAK,aAAa,IAAI,WAAW,MAAM;AAAA,EACzC;AACF;AA6EO,SAAS,kBAAkB,QAAgB,SAA+B;AAC/E,SAAO,IAAI,MAAM,QAAQ,OAAO;AAClC;AAEA,IAAO,cAAQ;","names":[]}
1
+ {"version":3,"sources":["../../src/types/common.ts","../../src/client.ts","../../src/resources/contacts.ts","../../src/resources/deals.ts","../../src/resources/emails.ts","../../src/resources/gdpr.ts","../../src/resources/posts.ts","../../src/resources/workspaces.ts","../../src/index.ts"],"sourcesContent":["/** Successful API response wrapper */\nexport interface ApiResponse<T> {\n data: T;\n}\n\n/** Paginated API response */\nexport interface PaginatedResponse<T> {\n data: T[];\n pagination: {\n has_more: boolean;\n next_cursor: string | null;\n };\n}\n\n/** API error thrown by the client */\nexport class MedalApiError extends Error {\n readonly status: number;\n readonly code: string;\n readonly details?: unknown;\n\n constructor(status: number, code: string, message: string, details?: unknown) {\n super(message);\n this.name = \"MedalApiError\";\n this.status = status;\n this.code = code;\n this.details = details;\n }\n}\n\n/** Pagination options for list endpoints */\nexport interface PaginationOptions {\n limit?: number;\n cursor?: string;\n}\n","import { MedalApiError } from \"./types/common\";\n\n/** Configuration for the low-level HTTP client. */\nexport interface ClientConfig {\n baseUrl: string;\n token: string;\n workspaceId?: string;\n timeout: number;\n userAgent: string;\n}\n\n/**\n * Low-level HTTP client used by all resource classes.\n * Handles authentication, retries, timeout, and error parsing.\n */\nexport class BaseClient {\n /** Resolved client configuration. */\n readonly config: ClientConfig;\n\n constructor(config: ClientConfig) {\n this.config = config;\n }\n\n /** Execute an authenticated GET request and return the parsed JSON body. */\n async get<T>(path: string, params?: Record<string, string | undefined>): Promise<T> {\n const url = this.buildUrl(path, params);\n return this.request<T>(url, { method: \"GET\" });\n }\n\n /** Execute an authenticated POST request with a JSON body. */\n async post<T>(path: string, body?: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"POST\",\n headers: { \"content-type\": \"application/json\" },\n body: body !== undefined ? JSON.stringify(body) : undefined,\n });\n }\n\n /** Execute an authenticated PATCH request with a JSON body. */\n async patch<T>(path: string, body: unknown): Promise<T> {\n return this.request<T>(this.buildUrl(path), {\n method: \"PATCH\",\n headers: { \"content-type\": \"application/json\" },\n body: JSON.stringify(body),\n });\n }\n\n /** Execute an authenticated DELETE request. */\n async delete<T>(path: string): Promise<T> {\n return this.request<T>(this.buildUrl(path), { method: \"DELETE\" });\n }\n\n private buildUrl(path: string, params?: Record<string, string | undefined>): string {\n const url = new URL(`${this.config.baseUrl}${path}`);\n if (params) {\n for (const [key, value] of Object.entries(params)) {\n if (value !== undefined) {\n url.searchParams.set(key, value);\n }\n }\n }\n return url.toString();\n }\n\n private async request<T>(url: string, init: RequestInit): Promise<T> {\n const maxAttempts = 3;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const headers = new Headers(init.headers);\n headers.set(\"authorization\", `Bearer ${this.config.token}`);\n if (this.config.workspaceId) {\n headers.set(\"x-workspace-id\", this.config.workspaceId);\n }\n try {\n headers.set(\"user-agent\", this.config.userAgent);\n } catch {\n // Browsers disallow setting user-agent\n }\n\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), this.config.timeout);\n\n let res: Response;\n try {\n res = await fetch(url, { ...init, headers, signal: controller.signal });\n } finally {\n clearTimeout(timeout);\n }\n\n // Retry on 429 / 5xx (but not on the final attempt)\n if (\n (res.status === 429 || (res.status >= 500 && res.status <= 599)) &&\n attempt < maxAttempts\n ) {\n const retryAfter = res.headers.get(\"retry-after\");\n let delayMs = 0;\n if (retryAfter) {\n const seconds = Number(retryAfter);\n delayMs = Number.isFinite(seconds) ? seconds * 1000 : 0;\n }\n if (delayMs <= 0) {\n delayMs = 250 * attempt;\n }\n await new Promise((r) => setTimeout(r, delayMs));\n continue;\n }\n\n // Parse response\n const text = await res.text();\n let parsed: unknown;\n try {\n parsed = text ? JSON.parse(text) : undefined;\n } catch {\n parsed = text;\n }\n\n if (!res.ok) {\n const body = parsed as\n | { error?: { code?: string; message?: string; details?: unknown } }\n | undefined;\n throw new MedalApiError(\n res.status,\n body?.error?.code ?? \"UNKNOWN_ERROR\",\n body?.error?.message ?? `HTTP ${res.status}: ${res.statusText}`,\n body?.error?.details,\n );\n }\n\n return parsed as T;\n }\n\n /* v8 ignore next -- unreachable: loop always returns or throws */\n throw new Error(\"Request failed after retries\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"../types/common\";\nimport type {\n Activity,\n AddNoteInput,\n Contact,\n ContactCreateResult,\n ContactNoteResult,\n ContactRemoveResult,\n ContactUpdateResult,\n CreateContactInput,\n ImportContactInput,\n ImportContactsResult,\n ListContactsOptions,\n UpdateContactInput,\n} from \"../types/contacts\";\n\n/** Manage contacts in the workspace CRM. */\nexport class Contacts {\n constructor(private client: BaseClient) {}\n\n /** List contacts with cursor-based pagination and optional filters. */\n async list(options?: ListContactsOptions): Promise<PaginatedResponse<Contact>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.email_status) params.email_status = options.email_status;\n if (options?.label_ids) params.label_ids = options.label_ids.join(\",\");\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/contacts\", params);\n }\n\n /** Create a new contact. Email must be unique in the workspace. */\n async create(input: CreateContactInput): Promise<ApiResponse<ContactCreateResult>> {\n return this.client.post(\"/api/v1/contacts\", input);\n }\n\n /** Get a contact by ID. */\n async get(id: string): Promise<ApiResponse<Contact>> {\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a contact. */\n async update(id: string, input: UpdateContactInput): Promise<ApiResponse<ContactUpdateResult>> {\n return this.client.patch(`/api/v1/contacts/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a contact. */\n async remove(id: string): Promise<ApiResponse<ContactRemoveResult>> {\n return this.client.delete(`/api/v1/contacts/${encodeURIComponent(id)}`);\n }\n\n /** Get the activity timeline for a contact. */\n async activities(id: string, options?: PaginationOptions): Promise<PaginatedResponse<Activity>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n return this.client.get(`/api/v1/contacts/${encodeURIComponent(id)}/activities`, params);\n }\n\n /** Add a note to a contact's timeline. */\n async addNote(id: string, input: AddNoteInput): Promise<ApiResponse<ContactNoteResult>> {\n return this.client.post(`/api/v1/contacts/${encodeURIComponent(id)}/notes`, input);\n }\n\n /** Bulk import contacts (max 500). Duplicates are skipped. */\n async import(contacts: ImportContactInput[]): Promise<ApiResponse<ImportContactsResult>> {\n return this.client.post(\"/api/v1/contacts/import\", { contacts });\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n CreateDealInput,\n Deal,\n DealCreateResult,\n DealRemoveResult,\n DealUpdateResult,\n ListDealsOptions,\n UpdateDealInput,\n} from \"../types/deals\";\n\n/** Manage sponsorship deals in the workspace. */\nexport class Deals {\n constructor(private client: BaseClient) {}\n\n /** List deals with cursor-based pagination and optional filters. */\n async list(options?: ListDealsOptions): Promise<PaginatedResponse<Deal>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.search) params.search = options.search;\n return this.client.get(\"/api/v1/deals\", params);\n }\n\n /** Create a new deal. */\n async create(input: CreateDealInput): Promise<ApiResponse<DealCreateResult>> {\n return this.client.post(\"/api/v1/deals\", input);\n }\n\n /** Get a deal by ID. */\n async get(id: string): Promise<ApiResponse<Deal>> {\n return this.client.get(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n\n /** Update one or more fields on a deal. Set contact_id to null to unlink. */\n async update(id: string, input: UpdateDealInput): Promise<ApiResponse<DealUpdateResult>> {\n return this.client.patch(`/api/v1/deals/${encodeURIComponent(id)}`, input);\n }\n\n /** Permanently delete a deal. */\n async remove(id: string): Promise<ApiResponse<DealRemoveResult>> {\n return this.client.delete(`/api/v1/deals/${encodeURIComponent(id)}`);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n BatchSendInput,\n BatchSendSummary,\n EmailSend,\n EmailSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n SendEmailInput,\n} from \"../types/emails\";\n\n/** Manage email templates stored in the workspace. */\nclass EmailTemplates {\n constructor(private client: BaseClient) {}\n\n /** List all active email templates in the workspace. */\n async list(): Promise<ApiResponse<EmailTemplate[]>> {\n return this.client.get(\"/api/v1/emails/templates\");\n }\n\n /** Get a specific email template by slug, optionally with locale resolution. */\n async get(slug: string, options?: GetTemplateOptions): Promise<ApiResponse<EmailTemplateDetail>> {\n const params: Record<string, string | undefined> = {};\n if (options?.locale) params.locale = options.locale;\n if (options?.fallback_locale) params.fallback_locale = options.fallback_locale;\n return this.client.get(`/api/v1/emails/templates/${encodeURIComponent(slug)}`, params);\n }\n}\n\n/** Send transactional emails and manage templates. */\nexport class Emails {\n readonly templates: EmailTemplates;\n\n constructor(private client: BaseClient) {\n this.templates = new EmailTemplates(client);\n }\n\n /** Send a transactional email using a template. Returns a queued job ID (HTTP 202). */\n async send(input: SendEmailInput): Promise<ApiResponse<EmailSendResult>> {\n return this.client.post(\"/api/v1/emails\", input);\n }\n\n /** Get the delivery status of a sent email. */\n async get(id: string): Promise<ApiResponse<EmailSend>> {\n return this.client.get(`/api/v1/emails/${encodeURIComponent(id)}`);\n }\n\n /** Send the same template to multiple recipients (max 100). Returns HTTP 202. */\n async batch(input: BatchSendInput): Promise<ApiResponse<BatchSendSummary>> {\n return this.client.post(\"/api/v1/emails/batch\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type {\n ConsentRecord,\n ConsentResult,\n CookieConsentInput,\n GdprExport,\n RecordConsentInput,\n} from \"../types/gdpr\";\n\n/** Manage GDPR compliance — data exports, consent records, and cookie consent. */\nexport class Gdpr {\n constructor(private client: BaseClient) {}\n\n /** Request a workspace data export. Runs asynchronously. */\n async requestExport(): Promise<ApiResponse<{ request_id: string; status: string }>> {\n return this.client.post(\"/api/v1/gdpr/export\");\n }\n\n /** List all workspace export requests. */\n async listExports(): Promise<ApiResponse<GdprExport[]>> {\n return this.client.get(\"/api/v1/gdpr/exports\");\n }\n\n /** Get the status of a specific export. */\n async getExport(id: string): Promise<ApiResponse<GdprExport>> {\n return this.client.get(`/api/v1/gdpr/exports/${encodeURIComponent(id)}`);\n }\n\n /** Record a GDPR consent decision for a contact by email. */\n async recordConsent(input: RecordConsentInput): Promise<ApiResponse<ConsentResult>> {\n return this.client.post(\"/api/v1/gdpr/consent\", input);\n }\n\n /** Get all consent records for a contact by email. */\n async getConsent(email: string): Promise<ApiResponse<ConsentRecord[]>> {\n return this.client.get(`/api/v1/gdpr/consent/${encodeURIComponent(email)}`);\n }\n\n /** Record cookie consent from an external site (legacy endpoint). */\n async cookieConsent(input: CookieConsentInput): Promise<{ success: boolean; logId?: string }> {\n return this.client.post(\"/api/cookie-consent\", input);\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse, PaginatedResponse } from \"../types/common\";\nimport type {\n Channel,\n CreatePostInput,\n ListPostsOptions,\n Post,\n PostDetail,\n PublishResult,\n SchedulePostInput,\n ScheduleResult,\n UpdatePostInput,\n} from \"../types/posts\";\n\n/** Create and publish posts across connected channels. */\nexport class Posts {\n constructor(private client: BaseClient) {}\n\n /** List posts with cursor-based pagination and optional filters. */\n async list(options?: ListPostsOptions): Promise<PaginatedResponse<Post>> {\n const params: Record<string, string | undefined> = {};\n if (options?.limit !== undefined) params.limit = String(options.limit);\n if (options?.cursor) params.cursor = options.cursor;\n if (options?.status) params.status = options.status;\n if (options?.type) params.type = options.type;\n return this.client.get(\"/api/v1/posts\", params);\n }\n\n /** Create a new post with content and target channels. */\n async create(input: CreatePostInput): Promise<ApiResponse<{ id: string }>> {\n return this.client.post(\"/api/v1/posts\", input);\n }\n\n /** Get a post by ID, including its per-channel variants. */\n async get(id: string): Promise<ApiResponse<PostDetail>> {\n return this.client.get(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Update a draft post's title or content. */\n async update(id: string, input: UpdatePostInput): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.patch(`/api/v1/posts/${encodeURIComponent(id)}`, input);\n }\n\n /** Delete a post. */\n async remove(id: string): Promise<ApiResponse<{ success: boolean }>> {\n return this.client.delete(`/api/v1/posts/${encodeURIComponent(id)}`);\n }\n\n /** Schedule a post for future publication. */\n async schedule(id: string, input: SchedulePostInput): Promise<ApiResponse<ScheduleResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/schedule`, input);\n }\n\n /** Publish a post immediately to all target channels. */\n async publish(id: string): Promise<ApiResponse<PublishResult>> {\n return this.client.post(`/api/v1/posts/${encodeURIComponent(id)}/publish`);\n }\n\n /** List connected publishing channels for this workspace. */\n async channels(): Promise<ApiResponse<Channel[]>> {\n return this.client.get(\"/api/v1/posts/channels\");\n }\n}\n","import type { BaseClient } from \"../client\";\nimport type { ApiResponse } from \"../types/common\";\nimport type { Workspace } from \"../types/workspaces\";\n\n/** Access workspaces for the authenticated credential. */\nexport class Workspaces {\n constructor(private client: BaseClient) {}\n\n /** List workspaces accessible to the current API key or OAuth token. */\n async list(): Promise<ApiResponse<Workspace[]>> {\n return this.client.get(\"/api/v1/me/workspaces\");\n }\n}\n","/**\n * Official TypeScript SDK for the Medal Social API.\n *\n * Provides typed access to posts, emails, contacts, deals, GDPR compliance,\n * and workspace management. Works in Node.js, Deno, Bun, Cloudflare Workers,\n * and modern browsers.\n *\n * @example\n * ```ts\n * import { Medal } from \"@medalsocial/sdk\";\n *\n * const medal = new Medal(\"medal_xxx\");\n * const { data: post } = await medal.posts.create({\n * content: \"Hello world!\",\n * channel_ids: [\"ch_1\"],\n * });\n * ```\n *\n * @module\n */\nimport { BaseClient } from \"./client\";\nimport { Contacts } from \"./resources/contacts\";\nimport { Deals } from \"./resources/deals\";\nimport { Emails } from \"./resources/emails\";\nimport { Gdpr } from \"./resources/gdpr\";\nimport { Posts } from \"./resources/posts\";\nimport { Workspaces } from \"./resources/workspaces\";\n\n/** Options for configuring the {@link Medal} client. */\nexport interface MedalOptions {\n /** Override the base URL (defaults to https://io.medalsocial.com). */\n baseUrl?: string;\n /** Request timeout in ms (default 30000). */\n timeout?: number;\n /**\n * Workspace ID — required for OAuth access tokens, ignored for API keys.\n * API keys are scoped to a single workspace, so the workspace is inferred.\n * OAuth tokens can access multiple workspaces, so you must specify which one.\n */\n workspaceId?: string;\n}\n\n/**\n * Medal Social SDK client.\n *\n * Supports both API key and OAuth access token authentication:\n *\n * @example API Key (recommended for server-side)\n * ```ts\n * import { Medal } from '@medalsocial/sdk';\n *\n * // API keys start with medal_ and are scoped to one workspace\n * const medal = new Medal('medal_xxx');\n * ```\n *\n * @example OAuth Access Token\n * ```ts\n * // OAuth tokens require a workspaceId\n * const medal = new Medal('oauth_access_token', {\n * workspaceId: 'workspace_id_here',\n * });\n * ```\n *\n * @example Full usage\n * ```ts\n * const medal = new Medal('medal_xxx');\n *\n * // Posts — create, schedule, publish\n * const { data: post } = await medal.posts.create({\n * content: 'Hello world!',\n * channel_ids: ['ch_1'],\n * });\n * await medal.posts.schedule(post.id, { scheduled_at: '2026-03-15T10:00:00Z' });\n *\n * // Emails — send transactional emails\n * await medal.emails.send({\n * template_slug: 'welcome',\n * to: 'user@example.com',\n * variables: { name: 'John' },\n * });\n *\n * // Contacts, Deals, GDPR, Workspaces\n * const contacts = await medal.contacts.list({ status: 'lead' });\n * const { data: deal } = await medal.deals.create({ title: 'Acme', value: 50000 });\n * await medal.gdpr.recordConsent({ email: 'u@x.com', consent_type: 'marketing_email', granted: true });\n * const { data: workspaces } = await medal.workspaces.list();\n * ```\n */\nexport class Medal {\n readonly emails: Emails;\n readonly contacts: Contacts;\n readonly deals: Deals;\n readonly gdpr: Gdpr;\n readonly posts: Posts;\n readonly workspaces: Workspaces;\n\n constructor(token: string, options?: MedalOptions) {\n if (!token) {\n throw new Error(\n \"Authentication token is required. Pass your medal_xxx API key or OAuth access token as the first argument.\",\n );\n }\n\n const client = new BaseClient({\n baseUrl: (options?.baseUrl ?? \"https://io.medalsocial.com\").replace(/\\/$/, \"\"),\n token,\n workspaceId: options?.workspaceId,\n timeout: options?.timeout ?? 30000,\n userAgent: \"medalsocial-sdk/1.0.0 (+https://github.com/Medal-Social/MedalSocial)\",\n });\n\n this.emails = new Emails(client);\n this.contacts = new Contacts(client);\n this.deals = new Deals(client);\n this.gdpr = new Gdpr(client);\n this.posts = new Posts(client);\n this.workspaces = new Workspaces(client);\n }\n}\n\n// Re-export all types\nexport { MedalApiError } from \"./types/common\";\nexport type { ApiResponse, PaginatedResponse, PaginationOptions } from \"./types/common\";\nexport type {\n SendEmailInput,\n EmailSendResult,\n EmailSend,\n BatchSendInput,\n BatchSendSummary,\n BatchSendResult,\n EmailTemplate,\n EmailTemplateDetail,\n GetTemplateOptions,\n} from \"./types/emails\";\nexport type {\n Contact,\n ContactCreateResult,\n ContactUpdateResult,\n ContactRemoveResult,\n ContactNoteResult,\n ContactStatus,\n EmailStatus,\n CreateContactInput,\n UpdateContactInput,\n ListContactsOptions,\n ImportContactInput,\n ImportContactsResult,\n Activity,\n AddNoteInput,\n} from \"./types/contacts\";\nexport type {\n Deal,\n DealCreateResult,\n DealUpdateResult,\n DealRemoveResult,\n DealStatus,\n CreateDealInput,\n UpdateDealInput,\n ListDealsOptions,\n} from \"./types/deals\";\nexport type {\n GdprExport,\n ConsentType,\n RecordConsentInput,\n ConsentRecord,\n ConsentResult,\n ContactConsents,\n CookieConsentInput,\n CookieCategoryConsent,\n} from \"./types/gdpr\";\nexport type {\n Post,\n PostType,\n PostVariant,\n PostDetail,\n Channel,\n CreatePostInput,\n UpdatePostInput,\n SchedulePostInput,\n ListPostsOptions,\n ScheduleResult,\n PublishResult,\n} from \"./types/posts\";\nexport type { Workspace } from \"./types/workspaces\";\n\n// Resource class re-exports (for advanced usage)\nexport { Emails } from \"./resources/emails\";\nexport { Contacts } from \"./resources/contacts\";\nexport { Deals } from \"./resources/deals\";\nexport { Gdpr } from \"./resources/gdpr\";\nexport { Posts } from \"./resources/posts\";\nexport { Workspaces } from \"./resources/workspaces\";\nexport { BaseClient } from \"./client\";\n\n/** Convenience factory — equivalent to `new Medal(apiKey, options)`. */\nexport function createMedalClient(apiKey: string, options?: MedalOptions): Medal {\n return new Medal(apiKey, options);\n}\n\nexport default Medal;\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@medalsocial/sdk",
3
- "version": "1.1.6",
3
+ "version": "1.1.7",
4
4
  "description": "TypeScript SDK for Medal Social API — posts, emails, contacts, deals, and GDPR compliance",
5
5
  "license": "Apache-2.0",
6
6
  "author": "Medal Social / Ali Aljumaili",