{"version":3,"sources":["../src/index.ts","../src/client.ts","../src/utils.ts","../src/errors.ts","../src/schemas.ts","../src/retry.ts","../src/webhook.ts"],"sourcesContent":["/**\n * # Marble SDK\n *\n * The official TypeScript SDK for interacting with Marble APIs.\n *\n * Features:\n * - Fully typed client for fetching posts, tags, categories, and authors\n * - Zod-powered runtime validation of API responses\n * - Webhook verification helpers with timestamp + HMAC checks\n * - Pagination and retry/backoff with sensible defaults\n *\n * @packageDocumentation\n */\n\n/**\n * Public type definitions used across the Marble SDK.\n *\n * Includes core models like {@link Post}, {@link Author}, and {@link Pagination},\n * as well as configuration types like {@link MarbleOptions}.\n */\nexport * from \"./types\";\n\n/**\n * Main API client for interacting with Marble.\n *\n * Provides typed methods to fetch posts, tags, categories, authors, and more.\n * See {@link MarbleClient}.\n */\nexport { MarbleClient } from \"./client\";\n\n/**\n * Error type thrown when HTTP requests fail.\n *\n * Wraps status, statusText, and (optionally) the response body.\n */\nexport { MarbleHttpError } from \"./errors\";\n\n/**\n * Webhook utilities:\n *\n * - {@link verifyMarbleSignature} — validate incoming webhook signatures\n * - {@link parseWebhookEvent} — safely parse webhook JSON payloads\n *\n * @example\n * ```ts\n * verifyMarbleSignature(body, headers, secret);\n * const event = parseWebhookEvent(body, (d) => d as { id: string });\n * ```\n */\nexport {\n  verifyMarbleSignature,\n  parseWebhookEvent,\n  type WebhookEvent,\n  type WebhookHeaders,\n  type VerifyOptions,\n} from \"./webhook\";\n","import { z } from \"zod\";\nimport type {\n  MarbleOptions,\n  RequestOptions,\n  PostsListParams,\n  MarblePostList,\n  MarblePost,\n  MarbleTagList,\n  MarbleCategoryList,\n  MarbleAuthorList,\n  Post,\n  Pagination,\n  PaginateOptions,\n  PostsScanParams,\n  RetryPolicy,\n} from \"./types\";\nimport { q, normalizeBaseUrl, mergeHeaders } from \"./utils\";\nimport { MarbleHttpError } from \"./errors\";\nimport {\n  ApiListAuthorsResponse,\n  ApiListCategoriesResponse,\n  ApiListPostsResponse,\n  ApiListTagsResponse,\n  ApiPost,\n} from \"./schemas\";\nimport { defaultRetryPolicy, sleep } from \"./retry\";\n\n/**\n * Main SDK entrypoint for interacting with the Marble API.\n *\n * Example:\n * ```ts\n * const marble = new MarbleClient({\n *   baseUrl: \"https://api.marble.io\",\n *   apiKey: \"sk_123\"\n * });\n * const posts = await marble.listPosts({ limit: 10 });\n * ```\n */\nexport class MarbleClient {\n  private readonly baseUrl: string;\n  private readonly apiKey: string | undefined;\n  private readonly fetcher: typeof fetch;\n  private readonly extraHeaders: Record<string, string>;\n  private readonly retryPolicy: RetryPolicy | null;\n\n  /**\n   * Create a new MarbleClient.\n   * @param opts Configuration options (baseUrl is required)\n   */\n  constructor(opts: MarbleOptions) {\n    if (!opts?.baseUrl) throw new Error(\"MarbleClient: baseUrl is required\");\n    this.baseUrl = normalizeBaseUrl(opts.baseUrl);\n    this.apiKey = opts.apiKey;\n    this.fetcher = opts.fetchImpl ?? fetch;\n    this.extraHeaders = opts.headers ?? {};\n    this.retryPolicy =\n      opts.retryPolicy === undefined ? defaultRetryPolicy : opts.retryPolicy;\n  }\n\n  /**\n   * List published posts with optional filters (pagination, tags, search, etc.).\n   *\n   * @param params Query params like `limit`, `page`, `tags`, etc.\n   * @param ro Optional request options (e.g. `AbortSignal`).\n   * @returns A list of posts plus pagination info.\n   */\n  async listPosts(\n    params: PostsListParams = {},\n    ro?: RequestOptions,\n  ): Promise<MarblePostList> {\n    const raw = await this.getJson(\n      `/posts${q(params)}`,\n      ApiListPostsResponse,\n      ro,\n    );\n    const rawPosts = raw.posts ?? raw.data ?? [];\n\n    const posts: Post[] = rawPosts.map((p) => ({\n      id: p.id,\n      slug: p.slug,\n      title: p.title,\n      content: p.content ?? \"\",\n      featured: p.featured,\n      description: p.description ?? \"\",\n      coverImage: p.coverImage ?? \"\",\n      publishedAt: new Date(p.publishedAt),\n      updatedAt: new Date(p.updatedAt ?? p.publishedAt),\n      authors: (p.authors ?? []).map((a) => ({\n        id: a.id,\n        name: a.name,\n        slug: \"\",\n        image: a.image ?? null,\n        bio: null,\n        role: null,\n        socials: [],\n      })),\n      category: {\n        id: p.category.id,\n        name: p.category.name,\n        slug: p.category.slug,\n        description: null,\n      },\n      tags: (p.tags ?? []).map((t) => ({\n        id: t.id,\n        name: t.name,\n        slug: t.slug,\n        description: null,\n      })),\n      attribution: p.attribution\n        ? { author: p.attribution.author ?? \"\", url: p.attribution.url ?? \"\" }\n        : null,\n    }));\n\n    const p1 = raw.pagination ?? raw.meta?.pagination;\n    const pagination: Pagination = p1\n      ? {\n          limit: p1.limit,\n          currentPage: p1.currentPage,\n          nextPage: p1.nextPage,\n          previousPage: p1.previousPage,\n          totalItems: p1.totalItems,\n          totalPages: p1.totalPages,\n        }\n      : {\n          limit: posts.length,\n          currentPage: params.page ?? 1,\n          nextPage: null,\n          previousPage: null,\n          totalItems: posts.length,\n          totalPages: 1,\n        };\n\n    return { posts, pagination };\n  }\n\n  /**\n   * Fetch a single post by its slug or ID.\n   *\n   * @param slugOrId Post slug or numeric ID.\n   * @param ro Optional request options (e.g. `AbortSignal`).\n   * @returns A single post object.\n   */\n  async getPost(slugOrId: string, ro?: RequestOptions): Promise<MarblePost> {\n    const raw = await this.getJson(\n      `/posts/${encodeURIComponent(slugOrId)}`,\n      ApiPost,\n      ro,\n    );\n    const post: Post = {\n      id: raw.id,\n      slug: raw.slug,\n      title: raw.title,\n      content: raw.content ?? \"\",\n      featured: raw.featured,\n      description: raw.description ?? \"\",\n      coverImage: raw.coverImage ?? \"\",\n      publishedAt: new Date(raw.publishedAt),\n      updatedAt: new Date(raw.updatedAt ?? raw.publishedAt),\n      authors: (raw.authors ?? []).map((a) => ({\n        id: a.id,\n        name: a.name,\n        slug: \"\",\n        image: a.image ?? null,\n        bio: null,\n        role: null,\n        socials: [],\n      })),\n      category: {\n        id: raw.category.id,\n        name: raw.category.name,\n        slug: raw.category.slug,\n        description: null,\n      },\n      tags: (raw.tags ?? []).map((t) => ({\n        id: t.id,\n        name: t.name,\n        slug: t.slug,\n        description: null,\n      })),\n      attribution: raw.attribution\n        ? {\n            author: raw.attribution.author ?? \"\",\n            url: raw.attribution.url ?? \"\",\n          }\n        : null,\n    };\n    return { post };\n  }\n\n  /**\n   * List tags (supports pagination if the API provides it).\n   *\n   * @param params Optional pagination params `{ page, limit }`.\n   * @param ro Optional request options.\n   * @returns A list of tags plus pagination info.\n   */\n  async listTags(\n    params: { page?: number; limit?: number } = {},\n    ro?: RequestOptions,\n  ): Promise<MarbleTagList> {\n    const raw = await this.getJson(\n      `/tags${q(params)}`,\n      ApiListTagsResponse,\n      ro,\n    );\n    const tags = (raw.tags ?? raw.data ?? []).map((t) => ({\n      id: t.id,\n      name: t.name,\n      slug: t.slug,\n      description: null,\n      count: { posts: 0 },\n    }));\n    const p2 = raw.pagination ?? raw.meta?.pagination;\n    const pagination: Pagination = p2\n      ? {\n          limit: p2.limit,\n          currentPage: p2.currentPage,\n          nextPage: p2.nextPage,\n          previousPage: p2.previousPage,\n          totalItems: p2.totalItems,\n          totalPages: p2.totalPages,\n        }\n      : {\n          limit: tags.length,\n          currentPage: params.page ?? 1,\n          nextPage: null,\n          previousPage: null,\n          totalItems: tags.length,\n          totalPages: 1,\n        };\n    return { tags, pagination };\n  }\n\n  /**\n   * List categories (supports pagination if the API provides it).\n   *\n   * @param params Optional pagination params `{ page, limit }`.\n   * @param ro Optional request options.\n   * @returns A list of categories plus pagination info.\n   */\n  async listCategories(\n    params: { page?: number; limit?: number } = {},\n    ro?: RequestOptions,\n  ): Promise<MarbleCategoryList> {\n    const raw = await this.getJson(\n      `/categories${q(params)}`,\n      ApiListCategoriesResponse,\n      ro,\n    );\n    const categories = (raw.categories ?? raw.data ?? []).map((c) => ({\n      id: c.id,\n      name: c.name,\n      slug: c.slug,\n      description: null,\n      count: { posts: 0 },\n    }));\n    const p3 = raw.pagination ?? raw.meta?.pagination;\n    const pagination: Pagination = p3\n      ? {\n          limit: p3.limit,\n          currentPage: p3.currentPage,\n          nextPage: p3.nextPage,\n          previousPage: p3.previousPage,\n          totalItems: p3.totalItems,\n          totalPages: p3.totalPages,\n        }\n      : {\n          limit: categories.length,\n          currentPage: params.page ?? 1,\n          nextPage: null,\n          previousPage: null,\n          totalItems: categories.length,\n          totalPages: 1,\n        };\n    return { categories, pagination };\n  }\n\n  /**\n   * List authors (supports pagination if the API provides it).\n   *\n   * @param params Optional pagination params `{ page, limit }`.\n   * @param ro Optional request options.\n   * @returns A list of authors plus pagination info.\n   */\n  async listAuthors(\n    params: { page?: number; limit?: number } = {},\n    ro?: RequestOptions,\n  ): Promise<MarbleAuthorList> {\n    const raw = await this.getJson(\n      `/authors${q(params)}`,\n      ApiListAuthorsResponse,\n      ro,\n    );\n    const authors = (raw.authors ?? raw.data ?? []).map((a) => ({\n      id: a.id,\n      name: a.name,\n      slug: \"\",\n      image: a.image ?? null,\n      bio: null,\n      role: null,\n      socials: [],\n    }));\n    const p4 = raw.pagination ?? raw.meta?.pagination;\n    const pagination: Pagination = p4\n      ? {\n          limit: p4.limit,\n          currentPage: p4.currentPage,\n          nextPage: p4.nextPage,\n          previousPage: p4.previousPage,\n          totalItems: p4.totalItems,\n          totalPages: p4.totalPages,\n        }\n      : {\n          limit: authors.length,\n          currentPage: params.page ?? 1,\n          nextPage: null,\n          previousPage: null,\n          totalItems: authors.length,\n          totalPages: 1,\n        };\n    return { authors, pagination };\n  }\n\n  /**\n   * Iterate through pages of posts.\n   *\n   * Useful for batch processing or background syncs.\n   */\n  async *iteratePostPages(\n    params: PostsScanParams = {},\n    opts: PaginateOptions = {},\n  ): AsyncGenerator<MarblePostList, void, unknown> {\n    const pageSize = opts.pageSize ?? 20;\n    let page = opts.startPage ?? 1;\n    let pagesRead = 0;\n\n    const ro = opts.signal !== undefined ? { signal: opts.signal } : undefined;\n\n    while (true) {\n      this.ensureNotAborted(opts.signal);\n\n      const pageData = await this.listPosts(\n        { ...params, page, limit: pageSize },\n        ro,\n      );\n\n      yield pageData;\n\n      pagesRead++;\n      const next = pageData.pagination.nextPage;\n      if (next == null) break;\n      if (opts.maxPages != null && pagesRead >= opts.maxPages) break;\n\n      page = next;\n    }\n  }\n\n  /**\n   * Iterate through all posts, flattening across pages.\n   *\n   * Use this if you want to process posts one-by-one without manual pagination.\n   */\n  async *paginatePosts(\n    params: PostsScanParams = {},\n    opts: PaginateOptions = {},\n  ): AsyncGenerator<Post, void, unknown> {\n    for await (const page of this.iteratePostPages(params, opts)) {\n      for (const post of page.posts) {\n        this.ensureNotAborted(opts.signal);\n        yield post;\n      }\n    }\n  }\n\n  /**\n   * Iterate through tag pages.\n   */\n  async *iterateTagPages(\n    opts: PaginateOptions = {},\n  ): AsyncGenerator<MarbleTagList, void, unknown> {\n    const pageSize = opts.pageSize ?? 50;\n    let page = opts.startPage ?? 1;\n    let pagesRead = 0;\n    const ro = opts.signal !== undefined ? { signal: opts.signal } : undefined;\n\n    while (true) {\n      this.ensureNotAborted(opts.signal);\n      const data = await this.listTags({ page, limit: pageSize }, ro);\n      yield data;\n\n      pagesRead++;\n      const next = data.pagination.nextPage;\n      if (next == null) break;\n      if (opts.maxPages != null && pagesRead >= opts.maxPages) break;\n\n      page = next;\n    }\n  }\n\n  /**\n   * Iterate through category pages.\n   */\n  async *iterateCategoryPages(\n    opts: PaginateOptions = {},\n  ): AsyncGenerator<MarbleCategoryList, void, unknown> {\n    const pageSize = opts.pageSize ?? 50;\n    let page = opts.startPage ?? 1;\n    let pagesRead = 0;\n    const ro = opts.signal !== undefined ? { signal: opts.signal } : undefined;\n\n    while (true) {\n      this.ensureNotAborted(opts.signal);\n      const data = await this.listCategories({ page, limit: pageSize }, ro);\n      yield data;\n\n      pagesRead++;\n      const next = data.pagination.nextPage;\n      if (next == null) break;\n      if (opts.maxPages != null && pagesRead >= opts.maxPages) break;\n\n      page = next;\n    }\n  }\n\n  /**\n   * Iterate through author pages.\n   */\n  async *iterateAuthorPages(\n    opts: PaginateOptions = {},\n  ): AsyncGenerator<MarbleAuthorList, void, unknown> {\n    const pageSize = opts.pageSize ?? 50;\n    let page = opts.startPage ?? 1;\n    let pagesRead = 0;\n    const ro = opts.signal !== undefined ? { signal: opts.signal } : undefined;\n\n    while (true) {\n      this.ensureNotAborted(opts.signal);\n      const data = await this.listAuthors({ page, limit: pageSize }, ro);\n      yield data;\n\n      pagesRead++;\n      const next = data.pagination.nextPage;\n      if (next == null) break;\n      if (opts.maxPages != null && pagesRead >= opts.maxPages) break;\n\n      page = next;\n    }\n  }\n\n  // ---- private helpers ----\n\n  private ensureNotAborted(signal: AbortSignal | null | undefined) {\n    if (signal?.aborted) throw new Error(\"Aborted\");\n  }\n\n  private async getJson<T extends z.ZodTypeAny>(\n    path: string,\n    schema: T,\n    ro?: RequestOptions,\n  ): Promise<z.infer<T>> {\n    const policy = this.retryPolicy;\n    const maxRetries = policy\n      ? (policy.maxRetries ?? defaultRetryPolicy.maxRetries)\n      : 0;\n\n    let attempt = 0;\n    while (true) {\n      attempt++;\n      try {\n        const init: RequestInit = {\n          method: \"GET\",\n          headers: this.headers(),\n        };\n        if (ro?.signal) init.signal = ro.signal;\n\n        const res = await this.fetcher(`${this.baseUrl}${path}`, init);\n        if (!res.ok) {\n          if (policy) {\n            const decision = policy.shouldRetry({ attempt, response: res });\n            if (decision && attempt <= maxRetries) {\n              await sleep(decision.delayMs, ro?.signal);\n              continue;\n            }\n          }\n          let body: unknown;\n          try {\n            body = await res.json();\n          } catch {\n            try {\n              body = await res.text();\n            } catch {}\n          }\n          throw new MarbleHttpError(\n            `GET ${path} failed: ${res.status} ${res.statusText}`,\n            {\n              status: res.status,\n              statusText: res.statusText,\n              body,\n            },\n          );\n        }\n        const data = await res.json();\n        return schema.parse(data);\n      } catch (err) {\n        if (policy) {\n          const decision = policy.shouldRetry({\n            attempt,\n            error: err as unknown,\n          });\n          if (decision && attempt <= maxRetries) {\n            await sleep(decision.delayMs, ro?.signal);\n            continue;\n          }\n        }\n        throw err;\n      }\n    }\n  }\n\n  private headers(): Record<string, string> {\n    const h = mergeHeaders(\n      { \"Content-Type\": \"application/json\" },\n      this.extraHeaders,\n    );\n    if (this.apiKey !== undefined) h.Authorization = `Bearer ${this.apiKey}`;\n    return h;\n  }\n}\n","/**\n * Build a query string from an object of parameters.\n * - Skips `undefined` and `null`.\n * - Joins array values with commas if the key is `\"tags\"`.\n * - Repeats array keys for other arrays.\n *\n * @example\n * q({ page: 2, tags: [\"js\", \"ts\"] })\n * // => \"?page=2&tags=js,ts\"\n */\nexport function q(params: Record<string, unknown>): string {\n  const usp = new URLSearchParams();\n  for (const [k, v] of Object.entries(params)) {\n    if (v === undefined || v === null) continue;\n    if (Array.isArray(v)) {\n      if (v.length === 0) continue;\n      if (k === \"tags\") usp.set(k, v.join(\",\"));\n      else v.forEach((val) => usp.append(k, String(val)));\n    } else {\n      usp.set(k, String(v));\n    }\n  }\n  const s = usp.toString();\n  return s ? `?${s}` : \"\";\n}\n\n/**\n * Strictly coerce an unknown value into a `Date`.\n * Throws if the value cannot be parsed into a valid date.\n *\n * @param v - The value to coerce (Date | string | number).\n * @param field - Field name for better error messages.\n */\nexport function toDateStrict(v: unknown, field: string): Date {\n  if (v instanceof Date) return v;\n  if (typeof v === \"string\" || typeof v === \"number\") {\n    const d = new Date(v);\n    if (!Number.isNaN(d.getTime())) return d;\n  }\n  throw new Error(`Invalid date for ${field}`);\n}\n\n/**\n * Normalize a base URL by trimming trailing slashes.\n *\n * @example\n * normalizeBaseUrl(\"https://api.example.com/\")\n * // => \"https://api.example.com\"\n */\nexport function normalizeBaseUrl(url: string): string {\n  return url.replace(/\\/+$/, \"\");\n}\n\n/**\n * Merge two header maps. Later headers overwrite earlier ones.\n */\nexport function mergeHeaders(\n  a: Record<string, string>,\n  b?: Record<string, string>,\n): Record<string, string> {\n  return { ...a, ...(b ?? {}) };\n}\n\n/**\n * Type guard: check if a value is a plain object.\n */\nexport function isRecord(x: unknown): x is Record<string, unknown> {\n  return typeof x === \"object\" && x !== null;\n}\n\n/**\n * Type guard: check if a value is a string.\n */\nexport function isString(x: unknown): x is string {\n  return typeof x === \"string\";\n}\n\n/**\n * Type guard: check if a value is a finite number.\n */\nexport function isNumber(x: unknown): x is number {\n  return typeof x === \"number\" && Number.isFinite(x);\n}\n\n/**\n * Convert a value to string if possible, otherwise use a fallback.\n */\nexport function asString(x: unknown, fallback = \"\"): string {\n  return isString(x) ? x : String(x ?? fallback);\n}\n\n/**\n * Convert a value into a number, returning `null` if conversion fails.\n */\nexport function asNullableNumber(x: unknown): number | null {\n  if (x === null || x === undefined) return null;\n  if (isNumber(x)) return x;\n  const n = Number(x);\n  return Number.isFinite(n) ? n : null;\n}\n\n/**\n * Safely convert an unknown array into a typed array using a mapper function.\n *\n * @example\n * asArray([\"1\", \"2\"], Number) // => [1, 2]\n */\nexport function asArray<T>(x: unknown, map: (item: unknown) => T): T[] {\n  if (!Array.isArray(x)) return [];\n  const out: T[] = [];\n  for (const item of x) out.push(map(item));\n  return out;\n}\n","/**\n * Error type thrown by the Marble SDK when an HTTP request fails.\n *\n * Includes HTTP status, statusText, and optionally the response body.\n *\n * Example:\n * ```ts\n * try {\n *   await client.listPosts();\n * } catch (err) {\n *   if (err instanceof MarbleHttpError) {\n *     console.error(\"Request failed:\", err.status, err.statusText, err.body);\n *   }\n * }\n * ```\n */\nexport class MarbleHttpError extends Error {\n  /** HTTP status code (e.g. `404`, `500`) */\n  readonly status: number;\n\n  /** HTTP status text (e.g. `\"Not Found\"`, `\"Internal Server Error\"`) */\n  readonly statusText: string;\n\n  /** Parsed response body (if available), can be JSON or string */\n  readonly body?: unknown;\n\n  /**\n   * @param message Error message\n   * @param init HTTP error details from the failed response\n   */\n  constructor(\n    message: string,\n    init: { status: number; statusText: string; body?: unknown },\n  ) {\n    super(message);\n    this.name = \"MarbleHttpError\";\n    this.status = init.status;\n    this.statusText = init.statusText;\n    this.body = init.body;\n  }\n}\n","import { z } from \"zod\";\n\n/**\n * @internal\n * Pagination envelope returned by the API.\n */\nexport const ApiPagination = z.object({\n  limit: z.number(),\n  currentPage: z.number(),\n  nextPage: z.number().nullable(),\n  previousPage: z.number().nullable(),\n  totalItems: z.number(),\n  totalPages: z.number(),\n});\nexport type ApiPagination = z.infer<typeof ApiPagination>;\n\n/**\n * @internal\n * Social platform enum for author socials.\n */\nexport const SocialPlatformSchema = z.enum([\n  \"x\",\n  \"github\",\n  \"facebook\",\n  \"instagram\",\n  \"youtube\",\n  \"tiktok\",\n  \"linkedin\",\n  \"website\",\n  \"onlyfans\",\n  \"discord\",\n  \"bluesky\"\n]);\n\n/**\n * @internal\n * Social link in author profiles.\n */\nexport const ApiSocial = z.object({\n  url: z.string(),\n  platform: SocialPlatformSchema,\n});\nexport type ApiSocial = z.infer<typeof ApiSocial>;\n\n/**\n * @internal\n * Author shape in API responses.\n */\nexport const ApiAuthor = z.object({\n  id: z.string(),\n  name: z.string(),\n  slug: z.string(),\n  image: z.string().nullable(),\n  bio: z.string().nullable(),\n  role: z.string().nullable(),\n  socials: z.array(ApiSocial),\n});\nexport type ApiAuthor = z.infer<typeof ApiAuthor>;\n\n/**\n * @internal\n * Tag shape in API responses.\n */\nexport const ApiTag = z.object({\n  id: z.string(),\n  name: z.string(),\n  slug: z.string(),\n  description: z.string().nullable(),\n  count: z.object({\n    posts: z.number(),\n  }),\n});\nexport type ApiTag = z.infer<typeof ApiTag>;\n\n/**\n * @internal\n * Category shape in API responses.\n */\nexport const ApiCategory = z.object({\n  id: z.string(),\n  name: z.string(),\n  slug: z.string(),\n  description: z.string().nullable(),\n  count: z.object({\n    posts: z.number(),\n  }),\n});\nexport type ApiCategory = z.infer<typeof ApiCategory>;\n\n/**\n * @internal\n * Post shape in API responses (wire format).\n * Dates are ISO-8601 strings; the client maps them to `Date` later.\n */\nexport const ApiPost = z.object({\n  id: z.string(),\n  slug: z.string(),\n  title: z.string(),\n  content: z.string(),\n  featured: z.boolean(),\n  description: z.string(),\n  coverImage: z.url(),\n  publishedAt: z.coerce.date(),\n  updatedAt: z.coerce.date(),\n  authors: z.array(ApiAuthor),\n  category: ApiCategory,\n  tags: z.array(ApiTag),\n  attribution: z\n    .object({\n      author: z.string(),\n      url: z.url(),\n    })\n    .nullable(),\n});\nexport type ApiPost = z.infer<typeof ApiPost>;\n\n/**\n * @internal\n * API response where posts may be under `posts` or `data`,\n * with optional pagination at `pagination` or `meta.pagination`.\n */\nexport const ApiListPostsResponse = z.object({\n  posts: z.array(ApiPost).optional(),\n  data: z.array(ApiPost).optional(),\n  pagination: ApiPagination.optional(),\n  meta: z.object({ pagination: ApiPagination.optional() }).optional(),\n});\nexport type ApiListPostsResponse = z.infer<typeof ApiListPostsResponse>;\n\n/**\n * @internal\n * API response for tags; supports either `tags` or `data` arrays.\n */\nexport const ApiListTagsResponse = z.object({\n  tags: z.array(ApiTag).optional(),\n  data: z.array(ApiTag).optional(),\n  pagination: ApiPagination.optional(),\n  meta: z.object({ pagination: ApiPagination.optional() }).optional(),\n});\nexport type ApiListTagsResponse = z.infer<typeof ApiListTagsResponse>;\n\n/**\n * @internal\n * API response for categories; supports either `categories` or `data` arrays.\n */\nexport const ApiListCategoriesResponse = z.object({\n  categories: z.array(ApiCategory).optional(),\n  data: z.array(ApiCategory).optional(),\n  pagination: ApiPagination.optional(),\n  meta: z.object({ pagination: ApiPagination.optional() }).optional(),\n});\nexport type ApiListCategoriesResponse = z.infer<\n  typeof ApiListCategoriesResponse\n>;\n\n/**\n * @internal\n * API response for authors; supports either `authors` or `data` arrays.\n */\nexport const ApiListAuthorsResponse = z.object({\n  authors: z.array(ApiAuthor).optional(),\n  data: z.array(ApiAuthor).optional(),\n  pagination: ApiPagination.optional(),\n  meta: z.object({ pagination: ApiPagination.optional() }).optional(),\n});\nexport type ApiListAuthorsResponse = z.infer<typeof ApiListAuthorsResponse>;\n","import type { RetryDecision, RetryPolicy, RetryContext } from \"./types\";\n\n/** @internal Clamp a number between min and max (inclusive). */\nfunction clamp(n: number, min: number, max: number): number {\n  return Math.min(max, Math.max(min, n));\n}\n\n/**\n * @internal Parse an HTTP `Retry-After` header into milliseconds.\n * Supports both delta-seconds (e.g. `\"3\"`) and HTTP-date values.\n * Returns `null` when the value cannot be parsed.\n */\nfunction parseRetryAfter(h: string): number | null {\n  const secs = Number(h);\n  if (Number.isFinite(secs)) return Math.max(0, secs * 1000);\n  const d = new Date(h);\n  const ms = d.getTime() - Date.now();\n  return Number.isFinite(ms) ? Math.max(0, ms) : null;\n}\n\n/**\n * Compute an exponential backoff delay with full jitter.\n *\n * Formula:\n * - raw: `baseDelayMs * 2^(attempt-1)` (attempt is 1-based)\n * - capped to `[baseDelayMs, maxDelayMs]`\n * - randomized uniformly in `[0, capped]`\n */\nexport function computeJitteredBackoff(\n  attempt: number,\n  baseDelayMs: number,\n  maxDelayMs: number,\n): number {\n  const exp = baseDelayMs * Math.pow(2, Math.max(0, attempt - 1));\n  const capped = clamp(exp, baseDelayMs, maxDelayMs);\n  return Math.floor(Math.random() * (capped + 1));\n}\n\n/**\n * Default retry policy:\n * - Retries on network errors\n * - Retries on `429` (honors `Retry-After`)\n * - Retries on `5xx`\n * - Jittered exponential backoff\n *\n * Limits:\n * - `maxRetries`: 3\n * - `baseDelayMs`: 250\n * - `maxDelayMs`: 8000\n */\nexport const defaultRetryPolicy: Required<RetryPolicy> = {\n  maxRetries: 3,\n  baseDelayMs: 250,\n  maxDelayMs: 8000,\n  shouldRetry: (ctx: RetryContext): RetryDecision | undefined => {\n    // Network / fetch errors (no response available)\n    if (ctx.error) {\n      const delayMs = computeJitteredBackoff(ctx.attempt, 250, 8000);\n      return { delayMs };\n    }\n\n    const res = ctx.response;\n    if (!res) return undefined;\n\n    // 429: honor Retry-After when present\n    if (res.status === 429) {\n      const ra = res.headers.get(\"retry-after\");\n      if (ra) {\n        const p = parseRetryAfter(ra);\n        if (p != null) return { delayMs: p };\n      }\n      return { delayMs: computeJitteredBackoff(ctx.attempt, 250, 8000) };\n    }\n\n    // 5xx series\n    if (res.status >= 500 && res.status <= 599) {\n      return { delayMs: computeJitteredBackoff(ctx.attempt, 250, 8000) };\n    }\n\n    return undefined;\n  },\n};\n\n/**\n * Sleep for the given duration, abortable via `AbortSignal`.\n *\n * Rejects with `\"Aborted\"` if the signal fires before the timeout completes.\n */\nexport async function sleep(\n  ms: number,\n  signal: AbortSignal | null | undefined,\n): Promise<void> {\n  if (ms <= 0) return;\n  if (signal?.aborted) throw new Error(\"Aborted\");\n  await new Promise<void>((resolve, reject) => {\n    const t = setTimeout(resolve, ms);\n    const onAbort = () => {\n      clearTimeout(t);\n      signal?.removeEventListener(\"abort\", onAbort);\n      reject(new Error(\"Aborted\"));\n    };\n    if (signal) signal.addEventListener(\"abort\", onAbort, { once: true });\n  });\n}\n","import { createHmac, timingSafeEqual } from \"node:crypto\";\nimport { isRecord, toDateStrict } from \"./utils\";\n\n/**\n * Envelope for a Marble webhook event.\n * Use {@link parseWebhookEvent} to safely parse and map the payload.\n */\nexport type WebhookEvent<T = unknown> = {\n  /** Event id generated by the server. */\n  id: string;\n  /** Event type (e.g. `\"post.published\"`). */\n  type: string;\n  /** Creation timestamp (parsed to `Date`). */\n  createdAt: Date;\n  /** Event-specific payload. */\n  data: T;\n};\n\n/**\n * Headers sent by Marble webhooks.\n * - `x-marble-signature`: either a raw hex HMAC, or `t=<unixSeconds>,v1=<hex>`\n * - `x-marble-timestamp`: optional; when present, signatures typically use `${t}.${rawBody}`\n */\nexport type WebhookHeaders = {\n  /** HMAC-SHA256 payload signature. */\n  \"x-marble-signature\": string;\n  /** UNIX seconds or an ISO timestamp (optional). */\n  \"x-marble-timestamp\"?: string;\n} & Record<string, string>;\n\n/** Options that affect webhook signature verification. */\nexport type VerifyOptions = {\n  /**\n   * When `true`, the signed payload is `${timestamp}.${rawBody}`.\n   * When `false`, the signed payload is `rawBody`.\n   * Default: inferred from the presence of a timestamp header.\n   */\n  includeTimestampInPayload?: boolean;\n  /**\n   * Acceptable clock skew (in seconds) when verifying timestamped signatures.\n   * Use `0` to disable the freshness check. Default: `300` (5 minutes).\n   */\n  toleranceSeconds?: number;\n};\n\n/** @internal Compute HMAC-SHA256 over the provided payload using the secret. */\nfunction computeSignature(secret: string, signedPayload: string): Buffer {\n  const h = createHmac(\"sha256\", secret);\n  h.update(signedPayload, \"utf8\");\n  return Buffer.from(h.digest(\"hex\"), \"hex\");\n}\n\n/**\n * @internal Parse signature header value.\n * Accepts either:\n *  - a raw hex string, or\n *  - `\"t=<timestamp>,v1=<hex>\"`\n */\nfunction parseProvidedSignature(sigHeader: string): {\n  ts?: string;\n  sigHex: string;\n} {\n  if (sigHeader.includes(\",\")) {\n    const parts = sigHeader.split(\",\").map((s) => s.trim());\n    let ts: string | undefined;\n    let sigHex = \"\";\n    for (const p of parts) {\n      if (p.startsWith(\"t=\")) ts = p.slice(2);\n      if (p.startsWith(\"v1=\")) sigHex = p.slice(3);\n    }\n    return ts !== undefined ? { ts, sigHex } : { sigHex };\n  }\n  return { sigHex: sigHeader };\n}\n\n/**\n * Verify a Marble webhook signature (HMAC-SHA256).\n *\n * - If a timestamp is present (or `includeTimestampInPayload` is `true`),\n *   the function signs `${timestamp}.${rawBody}` instead of `rawBody` alone.\n * - When timestamped, a freshness check is applied using `toleranceSeconds`.\n *\n * @param rawBody Raw request body **as received** (do not JSON.parse it first).\n * @param headers Request headers containing `x-marble-signature` (and optionally `x-marble-timestamp`).\n * @param secret Shared signing secret.\n * @param opts Verification options (timestamp behavior, tolerance).\n * @returns `true` if verification succeeds; otherwise throws an `Error`.\n * @throws If signature is missing/invalid or timestamp is outside tolerance.\n *\n * @remarks\n * This implementation uses Node's `crypto` module and is intended for server runtimes.\n * For edge/browser runtimes, use Web Crypto (SubtleCrypto) and adapt accordingly.\n */\nexport function verifyMarbleSignature(\n  rawBody: string,\n  headers: WebhookHeaders,\n  secret: string,\n  opts: VerifyOptions = {},\n): true {\n  const sigHeader = headers[\"x-marble-signature\"];\n  if (!sigHeader) throw new Error(\"Missing x-marble-signature header\");\n\n  const { ts, sigHex } = parseProvidedSignature(sigHeader);\n  const timestampHeader = headers[\"x-marble-timestamp\"] ?? ts;\n\n  const includeTs = opts.includeTimestampInPayload ?? Boolean(timestampHeader);\n  const tolerance = Math.max(0, opts.toleranceSeconds ?? 300);\n\n  let signedPayload = rawBody;\n  if (includeTs) {\n    const t = timestampHeader ?? \"\";\n    if (!t) throw new Error(\"Timestamp required for timestamped signatures\");\n    signedPayload = `${t}.${rawBody}`;\n\n    // Freshness check (optional)\n    if (tolerance > 0) {\n      const tsDate = Number.isFinite(Number(t))\n        ? new Date(Number(t) * 1000)\n        : new Date(t);\n      const tsMs = tsDate.getTime();\n      if (Number.isNaN(tsMs)) {\n        throw new Error(\"Invalid timestamp format\");\n      }\n      const skew = Math.abs(Date.now() - tsMs);\n      if (skew > tolerance * 1000) {\n        throw new Error(\"Timestamp outside tolerance window\");\n      }\n    }\n  }\n\n  const expected = computeSignature(secret, signedPayload);\n  const provided = Buffer.from(sigHex, \"hex\");\n  if (\n    expected.length !== provided.length ||\n    !timingSafeEqual(expected, provided)\n  ) {\n    throw new Error(\"Invalid webhook signature\");\n  }\n  return true;\n}\n\n/**\n * Parse a webhook JSON body into a typed {@link WebhookEvent}.\n *\n * @typeParam T - The desired type of the `data` payload after mapping.\n * @param jsonBody Raw JSON string of the webhook body.\n * @param mapData A mapper that converts/validates the unknown `data` into your type `T`.\n *\n * @example\n * ```ts\n * type PostCreated = { id: string };\n * const evt = parseWebhookEvent<PostCreated>(rawJson, (u) => {\n *   if (!u || typeof (u as any).id !== \"string\") throw new Error(\"bad data\");\n *   return u as PostCreated;\n * });\n * console.log(evt.type, evt.data.id);\n * ```\n */\nexport function parseWebhookEvent<T>(\n  jsonBody: string,\n  mapData: (u: unknown) => T,\n): WebhookEvent<T> {\n  const parsed = JSON.parse(jsonBody) as unknown;\n  if (!isRecord(parsed)) throw new Error(\"Invalid webhook envelope\");\n\n  const id = String(parsed[\"id\"] ?? \"\");\n  const type = String(parsed[\"type\"] ?? \"\");\n  const createdAt = toDateStrict(parsed[\"createdAt\"], \"createdAt\");\n  const dataUnknown = parsed[\"data\"];\n\n  return {\n    id,\n    type,\n    createdAt,\n    data: mapData(dataUnknown),\n  };\n}\n"],"mappings":"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","names":["import_zod"]}