spinupmail 0.1.0 → 0.1.1
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.
- package/dist/index.cjs +33 -6
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +33 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -274,7 +274,7 @@ var SpinupMailTimeoutError = class extends SpinupMailError {
|
|
|
274
274
|
//#region src/file.ts
|
|
275
275
|
const parseFilenameFromDisposition = (headerValue) => {
|
|
276
276
|
if (!headerValue) return null;
|
|
277
|
-
const utf8Match = headerValue.match(/filename\*=
|
|
277
|
+
const utf8Match = headerValue.match(/filename\*=[^']*'[^']*'([^;]+)/i);
|
|
278
278
|
if (utf8Match?.[1]) try {
|
|
279
279
|
return decodeURIComponent(utf8Match[1]);
|
|
280
280
|
} catch {
|
|
@@ -282,6 +282,8 @@ const parseFilenameFromDisposition = (headerValue) => {
|
|
|
282
282
|
}
|
|
283
283
|
const fallbackMatch = headerValue.match(/filename="([^"]+)"/i);
|
|
284
284
|
if (fallbackMatch?.[1]) return fallbackMatch[1];
|
|
285
|
+
const unquotedMatch = headerValue.match(/filename=([^;"]+)/i);
|
|
286
|
+
if (unquotedMatch?.[1]) return unquotedMatch[1].trim();
|
|
285
287
|
return null;
|
|
286
288
|
};
|
|
287
289
|
var SpinupMailFile = class {
|
|
@@ -295,7 +297,7 @@ var SpinupMailFile = class {
|
|
|
295
297
|
this.contentType = response.headers.get("content-type");
|
|
296
298
|
const contentLength = response.headers.get("content-length");
|
|
297
299
|
const parsed = contentLength ? Number(contentLength) : NaN;
|
|
298
|
-
this.contentLength = Number.
|
|
300
|
+
this.contentLength = Number.isInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
299
301
|
}
|
|
300
302
|
arrayBuffer() {
|
|
301
303
|
return this.response.clone().arrayBuffer();
|
|
@@ -380,8 +382,21 @@ const resolveOrganizationId = (context, organizationId, orgScoped) => {
|
|
|
380
382
|
};
|
|
381
383
|
const normalizeTimestamp = (value) => {
|
|
382
384
|
if (value === void 0) return void 0;
|
|
383
|
-
if (value
|
|
384
|
-
|
|
385
|
+
if (typeof value === "number") {
|
|
386
|
+
if (!Number.isFinite(value)) throw new SpinupMailValidationError({
|
|
387
|
+
message: "Invalid timestamp: number values must be finite.",
|
|
388
|
+
source: "request"
|
|
389
|
+
});
|
|
390
|
+
return String(value);
|
|
391
|
+
}
|
|
392
|
+
if (value instanceof Date) {
|
|
393
|
+
if (!Number.isFinite(value.getTime())) throw new SpinupMailValidationError({
|
|
394
|
+
message: "Invalid timestamp: Date values must be valid.",
|
|
395
|
+
source: "request"
|
|
396
|
+
});
|
|
397
|
+
return value.toISOString();
|
|
398
|
+
}
|
|
399
|
+
return value;
|
|
385
400
|
};
|
|
386
401
|
const normalizeText = (value) => (value ?? "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
387
402
|
const matchesText = (value, expected) => {
|
|
@@ -472,8 +487,18 @@ const requestBinary = async (context, options) => {
|
|
|
472
487
|
return new SpinupMailFile(response);
|
|
473
488
|
};
|
|
474
489
|
const ensureInboxSelector = (options) => {
|
|
475
|
-
if (
|
|
476
|
-
message: "
|
|
490
|
+
if (Boolean(options.address?.trim()) === Boolean(options.addressId?.trim())) throw new SpinupMailValidationError({
|
|
491
|
+
message: "Exactly one of address or addressId is required.",
|
|
492
|
+
source: "request"
|
|
493
|
+
});
|
|
494
|
+
};
|
|
495
|
+
const validatePollingTimingOptions = (options) => {
|
|
496
|
+
if (options.timeoutMs !== void 0 && (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)) throw new SpinupMailValidationError({
|
|
497
|
+
message: "invalid option: timeoutMs must be a finite number >= 0",
|
|
498
|
+
source: "request"
|
|
499
|
+
});
|
|
500
|
+
if (options.intervalMs !== void 0 && (!Number.isFinite(options.intervalMs) || options.intervalMs <= 0)) throw new SpinupMailValidationError({
|
|
501
|
+
message: "invalid option: intervalMs must be a finite number > 0",
|
|
477
502
|
source: "request"
|
|
478
503
|
});
|
|
479
504
|
};
|
|
@@ -524,6 +549,7 @@ const sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
524
549
|
});
|
|
525
550
|
const runPollingLoop = async (emails, options, args) => {
|
|
526
551
|
ensureInboxSelector(options);
|
|
552
|
+
validatePollingTimingOptions(options);
|
|
527
553
|
validateListEmailsOptions({
|
|
528
554
|
address: options.address,
|
|
529
555
|
addressId: options.addressId,
|
|
@@ -590,6 +616,7 @@ const runPollingLoop = async (emails, options, args) => {
|
|
|
590
616
|
};
|
|
591
617
|
const waitForEmailDetail = async (emails, options) => {
|
|
592
618
|
ensureInboxSelector(options);
|
|
619
|
+
validatePollingTimingOptions(options);
|
|
593
620
|
validateListEmailsOptions({
|
|
594
621
|
address: options.address,
|
|
595
622
|
addressId: options.addressId,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["z"],"sources":["../../contracts/src/index.ts","../src/errors.ts","../src/file.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const apiErrorSchema = z.object({\n error: z.string().min(1),\n details: z.string().min(1).optional(),\n});\n\nexport const sortDirectionSchema = z.enum([\"asc\", \"desc\"]);\nexport const emailAddressSortBySchema = z.enum([\n \"createdAt\",\n \"address\",\n \"lastReceivedAt\",\n]);\nexport const recentAddressActivitySortBySchema = z.enum([\n \"recentActivity\",\n \"createdAt\",\n]);\nexport const maxReceivedEmailActionSchema = z.enum([\n \"cleanAll\",\n \"rejectNew\",\n]);\nexport const emailOrderSchema = sortDirectionSchema;\n\nexport const inboundRatePolicySchema = z\n .object({\n senderDomainSoftMax: z.number().int().positive().optional(),\n senderDomainSoftWindowSeconds: z.number().int().positive().optional(),\n senderDomainBlockMax: z.number().int().positive().optional(),\n senderDomainBlockWindowSeconds: z.number().int().positive().optional(),\n senderAddressBlockMax: z.number().int().positive().optional(),\n senderAddressBlockWindowSeconds: z.number().int().positive().optional(),\n inboxBlockMax: z.number().int().positive().optional(),\n inboxBlockWindowSeconds: z.number().int().positive().optional(),\n dedupeWindowSeconds: z.number().int().positive().optional(),\n initialBlockSeconds: z.number().int().positive().optional(),\n maxBlockSeconds: z.number().int().positive().optional(),\n })\n .partial();\n\nexport const domainConfigSchema = z.object({\n items: z.array(z.string().min(1)),\n default: z.string().nullable(),\n forcedLocalPartPrefix: z.string().nullable(),\n maxReceivedEmailsPerOrganization: z.number().int().positive(),\n maxReceivedEmailsPerAddress: z.number().int().positive(),\n});\n\nexport const organizationStatsItemSchema = z.object({\n organizationId: z.string().min(1),\n memberCount: z.number().int().nonnegative(),\n addressCount: z.number().int().nonnegative(),\n emailCount: z.number().int().nonnegative(),\n});\n\nexport const organizationStatsResponseSchema = z.object({\n items: z.array(organizationStatsItemSchema),\n});\n\nexport const emailAddressSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n localPart: z.string().min(1),\n domain: z.string().min(1),\n meta: z.unknown().optional(),\n emailCount: z.number().int().nonnegative(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.nullable(),\n createdAt: z.string().nullable(),\n createdAtMs: z.number().nullable(),\n expiresAt: z.string().nullable(),\n expiresAtMs: z.number().nullable(),\n lastReceivedAt: z.string().nullable(),\n lastReceivedAtMs: z.number().nullable(),\n});\n\nexport const createEmailAddressResponseSchema = emailAddressSchema;\n\nexport const emailAddressListResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalItems: z.number().int().nonnegative(),\n addressLimit: z.number().int().positive(),\n totalPages: z.number().int().positive(),\n sortBy: emailAddressSortBySchema,\n sortDirection: sortDirectionSchema,\n});\n\nexport const listEmailAddressesParamsSchema = z.object({\n page: z.number().int().positive().optional(),\n pageSize: z.number().int().positive().optional(),\n search: z.string().optional(),\n sortBy: emailAddressSortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const listRecentAddressActivityParamsSchema = z.object({\n limit: z.number().int().positive().optional(),\n cursor: z.string().min(1).optional(),\n search: z.string().optional(),\n sortBy: recentAddressActivitySortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const recentAddressActivityResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n nextCursor: z.string().nullable(),\n totalItems: z.number().int().nonnegative(),\n});\n\nexport const createEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1),\n ttlMinutes: z.number().int().positive().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.optional(),\n maxReceivedEmailCount: z.number().int().positive().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n acceptedRiskNotice: z.literal(true),\n});\n\nexport const updateEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1).optional(),\n ttlMinutes: z.number().int().positive().nullable().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).nullable().optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n});\n\nexport const deleteEmailAddressResponseSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailAttachmentSchema = z.object({\n id: z.string().min(1),\n filename: z.string().min(1),\n contentType: z.string().min(1),\n size: z.number().int().nonnegative(),\n disposition: z.string().nullable(),\n contentId: z.string().nullable(),\n inlinePath: z.string().min(1),\n downloadPath: z.string().min(1),\n});\n\nexport const emailListItemSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n hasHtml: z.boolean(),\n hasText: z.boolean(),\n attachmentCount: z.number().int().nonnegative(),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const emailListResponseSchema = z.object({\n address: z.string().min(1),\n addressId: z.string().min(1),\n items: z.array(emailListItemSchema),\n});\n\nexport const listEmailsParamsSchema = z.object({\n address: z.string().min(1).optional(),\n addressId: z.string().min(1).optional(),\n search: z.string().max(30).optional(),\n limit: z.number().int().positive().optional(),\n order: emailOrderSchema.optional(),\n after: z.union([z.string(), z.number()]).optional(),\n before: z.union([z.string(), z.number()]).optional(),\n});\n\nexport const emailDetailSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n address: z.string().min(1).optional(),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n headers: z.unknown(),\n html: z.string().nullable().optional(),\n text: z.string().nullable().optional(),\n raw: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n rawDownloadPath: z.string().optional(),\n attachments: z.array(emailAttachmentSchema),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const deleteEmailResponseSchema = z.object({\n id: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailActivityDaySchema = z.object({\n date: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const emailActivityResponseSchema = z.object({\n timezone: z.string().min(1),\n daily: z.array(emailActivityDaySchema),\n});\n\nexport const emailSummaryDomainSchema = z.object({\n domain: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const busiestInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const dormantInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n createdAt: z.string().nullable(),\n});\n\nexport const emailSummaryResponseSchema = z.object({\n totalEmailCount: z.number().int().nonnegative(),\n attachmentCount: z.number().int().nonnegative(),\n attachmentSizeTotal: z.number().int().nonnegative(),\n attachmentSizeLimit: z.number().int().nonnegative(),\n topDomains: z.array(emailSummaryDomainSchema),\n busiestInboxes: z.array(busiestInboxSchema),\n dormantInboxes: z.array(dormantInboxSchema),\n});\n\nexport const organizationPickerItemSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n logo: z.string().nullable().optional(),\n});\n\nexport const extensionBootstrapUserSchema = z.object({\n id: z.string().min(1),\n email: z.string().email().nullable(),\n name: z.string().nullable(),\n image: z.string().nullable(),\n emailVerified: z.boolean(),\n});\n\nexport const extensionBootstrapResponseSchema = z.object({\n user: extensionBootstrapUserSchema,\n organizations: z.array(organizationPickerItemSchema),\n defaultOrganizationId: z.string().min(1).nullable(),\n});\n\nexport type ApiError = z.infer<typeof apiErrorSchema>;\nexport type SortDirection = z.infer<typeof sortDirectionSchema>;\nexport type EmailAddressSortBy = z.infer<typeof emailAddressSortBySchema>;\nexport type RecentAddressActivitySortBy = z.infer<\n typeof recentAddressActivitySortBySchema\n>;\nexport type MaxReceivedEmailAction = z.infer<\n typeof maxReceivedEmailActionSchema\n>;\nexport type InboundRatePolicy = z.infer<typeof inboundRatePolicySchema>;\nexport type DomainConfig = z.infer<typeof domainConfigSchema>;\nexport type OrganizationStatsItem = z.infer<typeof organizationStatsItemSchema>;\nexport type OrganizationStatsResponse = z.infer<\n typeof organizationStatsResponseSchema\n>;\nexport type EmailAddress = z.infer<typeof emailAddressSchema>;\nexport type EmailAddressListResponse = z.infer<\n typeof emailAddressListResponseSchema\n>;\nexport type ListEmailAddressesParams = z.infer<\n typeof listEmailAddressesParamsSchema\n>;\nexport type ListRecentAddressActivityParams = z.infer<\n typeof listRecentAddressActivityParamsSchema\n>;\nexport type RecentAddressActivityResponse = z.infer<\n typeof recentAddressActivityResponseSchema\n>;\nexport type CreateEmailAddressRequest = z.infer<\n typeof createEmailAddressRequestSchema\n>;\nexport type CreateEmailAddressResponse = z.infer<\n typeof createEmailAddressResponseSchema\n>;\nexport type UpdateEmailAddressRequest = z.infer<\n typeof updateEmailAddressRequestSchema\n>;\nexport type DeleteEmailAddressResponse = z.infer<\n typeof deleteEmailAddressResponseSchema\n>;\nexport type EmailAttachment = z.infer<typeof emailAttachmentSchema>;\nexport type EmailListItem = z.infer<typeof emailListItemSchema>;\nexport type EmailListResponse = z.infer<typeof emailListResponseSchema>;\nexport type ListEmailsParams = z.infer<typeof listEmailsParamsSchema>;\nexport type EmailDetail = z.infer<typeof emailDetailSchema>;\nexport type DeleteEmailResponse = z.infer<typeof deleteEmailResponseSchema>;\nexport type EmailActivityDay = z.infer<typeof emailActivityDaySchema>;\nexport type EmailActivityResponse = z.infer<typeof emailActivityResponseSchema>;\nexport type EmailSummaryResponse = z.infer<typeof emailSummaryResponseSchema>;\n","export class SpinupMailError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class SpinupMailValidationError extends SpinupMailError {\n readonly source: \"request\" | \"response\";\n readonly issues: string[];\n\n constructor(args: {\n message: string;\n source: \"request\" | \"response\";\n issues?: string[];\n cause?: unknown;\n }) {\n super(args.message, args.cause ? { cause: args.cause } : undefined);\n this.source = args.source;\n this.issues = args.issues ?? [];\n }\n}\n\nexport class SpinupMailApiError extends SpinupMailError {\n readonly status: number;\n readonly response: Response;\n readonly body?: unknown;\n\n constructor(args: {\n message: string;\n status: number;\n response: Response;\n body?: unknown;\n }) {\n super(args.message);\n this.status = args.status;\n this.response = args.response;\n this.body = args.body;\n }\n}\n\nexport class SpinupMailTimeoutError extends SpinupMailError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, options?: ErrorOptions) {\n super(message, options);\n this.timeoutMs = timeoutMs;\n }\n}\n","const parseFilenameFromDisposition = (headerValue: string | null) => {\n if (!headerValue) return null;\n\n const utf8Match = headerValue.match(/filename\\*=UTF-8''([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n\n const fallbackMatch = headerValue.match(/filename=\"([^\"]+)\"/i);\n if (fallbackMatch?.[1]) return fallbackMatch[1];\n\n return null;\n};\n\nexport class SpinupMailFile {\n readonly filename: string | null;\n readonly contentType: string | null;\n readonly contentLength: number | null;\n readonly response: Response;\n\n constructor(response: Response) {\n this.response = response;\n this.filename = parseFilenameFromDisposition(\n response.headers.get(\"content-disposition\")\n );\n this.contentType = response.headers.get(\"content-type\");\n\n const contentLength = response.headers.get(\"content-length\");\n const parsed = contentLength ? Number(contentLength) : Number.NaN;\n this.contentLength = Number.isFinite(parsed) ? parsed : null;\n }\n\n arrayBuffer() {\n return this.response.clone().arrayBuffer();\n }\n\n text() {\n return this.response.clone().text();\n }\n\n blob() {\n const clone = this.response.clone() as Response & {\n blob?: () => Promise<Blob>;\n };\n\n if (typeof clone.blob !== \"function\") {\n throw new Error(\"Response.blob() is not available in this runtime.\");\n }\n\n return clone.blob();\n }\n}\n","import type { ZodType } from \"zod\";\nimport {\n apiErrorSchema,\n createEmailAddressRequestSchema,\n createEmailAddressResponseSchema,\n deleteEmailAddressResponseSchema,\n deleteEmailResponseSchema,\n domainConfigSchema,\n emailActivityResponseSchema,\n emailDetailSchema,\n emailListResponseSchema,\n emailSummaryResponseSchema,\n listEmailAddressesParamsSchema,\n listEmailsParamsSchema,\n listRecentAddressActivityParamsSchema,\n recentAddressActivityResponseSchema,\n updateEmailAddressRequestSchema,\n emailAddressListResponseSchema,\n emailAddressSchema,\n type CreateEmailAddressRequest,\n type CreateEmailAddressResponse,\n type DeleteEmailAddressResponse,\n type DeleteEmailResponse,\n type DomainConfig,\n type EmailActivityResponse,\n type EmailAddress,\n type EmailAddressListResponse,\n type EmailDetail,\n type EmailListItem,\n type EmailListResponse,\n type EmailSummaryResponse,\n type ListEmailAddressesParams,\n type ListEmailsParams,\n type ListRecentAddressActivityParams,\n type RecentAddressActivityResponse,\n type UpdateEmailAddressRequest,\n} from \"@/contracts\";\nimport {\n SpinupMailApiError,\n SpinupMailTimeoutError,\n SpinupMailValidationError,\n} from \"@/errors\";\nimport { SpinupMailFile } from \"@/file\";\n\ntype FetchLike = typeof fetch;\ntype OrganizationScopedOptions = {\n organizationId?: string;\n signal?: AbortSignal;\n};\n\ntype InboxAddressSelector = {\n address?: string;\n addressId?: string;\n};\n\nexport type CreateSpinupMailClientOptions = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/**\n * Initializes the SpinupMail SDK.\n *\n * `apiKey` defaults to `process.env.SPINUPMAIL_API_KEY`.\n * `baseUrl` defaults to `process.env.SPINUPMAIL_BASE_URL` or `https://api.spinupmail.com`.\n * `organizationId` defaults to `process.env.SPINUPMAIL_ORGANIZATION_ID` or `process.env.SPINUPMAIL_ORG_ID`.\n */\nexport type SpinupMailOptions = {\n apiKey?: string;\n baseUrl?: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/** Lists and paginates inbox addresses in the active organization. */\nexport type ListEmailAddressesOptions = ListEmailAddressesParams &\n OrganizationScopedOptions;\n\n/** Reads the recent-activity inbox feed in the active organization. */\nexport type ListRecentAddressActivityOptions =\n ListRecentAddressActivityParams & OrganizationScopedOptions;\n\n/** Fetches a single inbox address by ID. */\nexport type GetEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox creation. */\nexport type CreateEmailAddressOptions = OrganizationScopedOptions;\n\n/**\n * Creates a SpinupMail inbox.\n *\n * If `localPart` is omitted, the SDK generates a random valid local part\n * before sending the request.\n */\nexport type CreateEmailAddressInput = Omit<\n CreateEmailAddressRequest,\n \"localPart\"\n> & {\n localPart?: string;\n};\n\n/** Per-call options for inbox updates. */\nexport type UpdateEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox deletion. */\nexport type DeleteEmailAddressOptions = OrganizationScopedOptions;\n\n/** Lists emails for a single inbox, optionally filtered by received time. */\nexport type ListEmailsOptions = Omit<ListEmailsParams, \"after\" | \"before\"> &\n OrganizationScopedOptions & {\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n };\n\n/** Fetches a single stored email. */\nexport type GetEmailOptions = OrganizationScopedOptions & {\n raw?: boolean;\n};\n\n/** Deletes a single stored email. */\nexport type DeleteEmailOptions = OrganizationScopedOptions;\n\n/** Downloads the raw MIME source for an email. */\nexport type GetEmailRawOptions = OrganizationScopedOptions;\n\n/** Downloads one attachment from a stored email. */\nexport type GetEmailAttachmentOptions = OrganizationScopedOptions & {\n inline?: boolean;\n};\n\n/** Fetches organization email activity stats. */\nexport type GetEmailActivityOptions = OrganizationScopedOptions & {\n days?: number;\n timezone?: string;\n};\n\n/** Fetches organization email summary stats. */\nexport type GetEmailSummaryOptions = OrganizationScopedOptions;\n\n/** Timestamp filter accepted by inbox listing and polling helpers. */\nexport type EmailTimestampFilter = string | number | Date;\n\n/**\n * Polls an inbox until a matching email appears or the timeout is reached.\n *\n * Provide either `address` or `addressId`.\n */\nexport type InboxPollOptions = InboxAddressSelector &\n OrganizationScopedOptions & {\n search?: string;\n limit?: number;\n order?: \"asc\" | \"desc\";\n /** Case-insensitive substring match against the email subject. */\n subjectIncludes?: string;\n /** Case-insensitive substring match against the recipient address. */\n toIncludes?: string;\n /** Case-insensitive substring match against `from`, `sender`, or `senderLabel`. */\n fromIncludes?: string;\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n timeoutMs?: number;\n intervalMs?: number;\n match?: (email: EmailListItem) => boolean;\n };\n\n/**\n * Waits for a matching email and optionally filters against the fetched body.\n *\n * `bodyIncludes` and `matchDetail` are evaluated after the SDK fetches email\n * detail for candidate messages that already passed the list-level filters.\n */\nexport type WaitForEmailOptions = InboxPollOptions & {\n /** Case-insensitive substring match against the concatenated HTML and text body. */\n bodyIncludes?: string;\n /** Deletes the email after fetching the matching detail payload. */\n deleteAfterRead?: boolean;\n /** Additional predicate evaluated against the fetched email detail payload. */\n matchDetail?: (email: EmailDetail) => boolean;\n};\n\n/** Result returned by `inboxes.poll()`. */\nexport type InboxPollResult = {\n response: EmailListResponse;\n items: EmailListItem[];\n freshItems: EmailListItem[];\n matchedEmail: EmailListItem | null;\n timedOut: boolean;\n attempts: number;\n elapsedMs: number;\n polledAt: string;\n};\n\ntype ClientContext = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch: FetchLike;\n headers?: HeadersInit;\n};\n\nexport interface SpinupMailDomainsApi {\n /** Fetches configured receiving domains and retention limits. */\n get(): Promise<DomainConfig>;\n}\n\nexport interface SpinupMailAddressesApi {\n /** Lists inbox addresses in the current organization. */\n list(options?: ListEmailAddressesOptions): Promise<EmailAddressListResponse>;\n /** Fetches all inbox addresses by following all pages. */\n listAll(options?: ListEmailAddressesOptions): Promise<EmailAddress[]>;\n /** Lists inboxes ordered by recent activity using cursor pagination. */\n listRecentActivity(\n options?: ListRecentAddressActivityOptions\n ): Promise<RecentAddressActivityResponse>;\n /** Fetches a single inbox address by ID. */\n get(addressId: string, options?: GetEmailAddressOptions): Promise<EmailAddress>;\n /** Creates an inbox address in the current organization. */\n create(\n payload: CreateEmailAddressInput,\n options?: CreateEmailAddressOptions\n ): Promise<CreateEmailAddressResponse>;\n /** Updates an existing inbox address. */\n update(\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options?: UpdateEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Deletes an inbox address and its stored contents. */\n delete(\n addressId: string,\n options?: DeleteEmailAddressOptions\n ): Promise<DeleteEmailAddressResponse>;\n}\n\nexport interface SpinupMailEmailsApi {\n /** Lists emails for a single inbox. */\n list(options: ListEmailsOptions): Promise<EmailListResponse>;\n /** Fetches one parsed email including bodies and attachment metadata. */\n get(emailId: string, options?: GetEmailOptions): Promise<EmailDetail>;\n /** Deletes one stored email. */\n delete(emailId: string, options?: DeleteEmailOptions): Promise<DeleteEmailResponse>;\n /** Downloads the raw MIME source for an email. */\n getRaw(emailId: string, options?: GetEmailRawOptions): Promise<SpinupMailFile>;\n /** Downloads an attachment from an email. */\n getAttachment(\n emailId: string,\n attachmentId: string,\n options?: GetEmailAttachmentOptions\n ): Promise<SpinupMailFile>;\n}\n\nexport interface SpinupMailStatsApi {\n /** Returns daily email activity counts for the organization. */\n getEmailActivity(options?: GetEmailActivityOptions): Promise<EmailActivityResponse>;\n /** Returns aggregate storage and inbox summary stats for the organization. */\n getEmailSummary(options?: GetEmailSummaryOptions): Promise<EmailSummaryResponse>;\n}\n\nexport interface SpinupMailInboxesApi {\n /** Polls an inbox and returns the latest response plus polling metadata. */\n poll(options: InboxPollOptions): Promise<InboxPollResult>;\n /** Waits until a matching email arrives, then returns the fetched email detail. */\n waitForEmail(options: WaitForEmailOptions): Promise<EmailDetail>;\n}\n\nexport interface SpinupMailClient {\n /** Domain and retention configuration endpoints. */\n domains: SpinupMailDomainsApi;\n /** Inbox address lifecycle endpoints. */\n addresses: SpinupMailAddressesApi;\n /** Email retrieval and download endpoints. */\n emails: SpinupMailEmailsApi;\n /** Organization-level reporting endpoints. */\n stats: SpinupMailStatsApi;\n /** High-level inbox polling helpers. */\n inboxes: SpinupMailInboxesApi;\n}\n\nconst DEFAULT_LIST_ALL_PAGE_SIZE = 50;\nconst MAX_LIST_ALL_PAGES = 200;\nconst DEFAULT_WAIT_TIMEOUT_MS = 30_000;\nconst DEFAULT_POLL_INTERVAL_MS = 1_000;\nconst DEFAULT_SPINUPMAIL_BASE_URL = \"https://api.spinupmail.com\";\nconst RANDOM_LOCAL_PART_PREFIX = \"sum\";\nconst RANDOM_LOCAL_PART_SIZE = 12;\n\nconst issuePathToString = (path: PropertyKey[]) =>\n path.length === 0 ? \"<root>\" : path.map(String).join(\".\");\n\nconst formatSchemaIssues = (\n issues: Array<{ path: PropertyKey[]; message: string }>\n) => issues.map(issue => `${issuePathToString(issue.path)}: ${issue.message}`);\n\nconst validateWithSchema = <T>(\n schema: ZodType<T>,\n value: unknown,\n source: \"request\" | \"response\",\n message: string\n) => {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new SpinupMailValidationError({\n message,\n source,\n issues: formatSchemaIssues(parsed.error.issues),\n cause: parsed.error,\n });\n }\n\n return parsed.data;\n};\n\nconst normalizeString = (value: string, label: string) => {\n const normalized = value.trim();\n if (!normalized) {\n throw new SpinupMailValidationError({\n message: `${label} is required.`,\n source: \"request\",\n });\n }\n return normalized;\n};\n\nconst resolveFetch = (candidate?: FetchLike) => {\n if (candidate) return candidate;\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis) as FetchLike;\n }\n\n throw new SpinupMailValidationError({\n message: \"A fetch implementation is required in this runtime.\",\n source: \"request\",\n });\n};\n\nconst normalizeBaseUrl = (baseUrl: string) =>\n normalizeString(baseUrl, \"baseUrl\").replace(/\\/+$/, \"\");\n\nconst getProcessEnv = () => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env === \"object\" &&\n process.env !== null\n ) {\n return process.env;\n }\n\n return undefined;\n};\n\nconst readEnvValue = (keys: string[]) => {\n const env = getProcessEnv();\n if (!env) return undefined;\n\n for (const key of keys) {\n const value = env[key]?.trim();\n if (value) return value;\n }\n\n return undefined;\n};\n\nconst createRandomBytes = (size: number) => {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n return crypto.getRandomValues(new Uint8Array(size));\n }\n\n return Uint8Array.from(\n Array.from({ length: size }, () => Math.floor(Math.random() * 256))\n );\n};\n\nconst generateRandomLocalPart = () => {\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const bytes = createRandomBytes(RANDOM_LOCAL_PART_SIZE);\n let suffix = \"\";\n\n for (const byte of bytes) {\n suffix += alphabet[byte % alphabet.length];\n }\n\n return `${RANDOM_LOCAL_PART_PREFIX}-${suffix}`;\n};\n\nconst resolveOrganizationId = (\n context: ClientContext,\n organizationId: string | undefined,\n orgScoped: boolean\n) => {\n if (!orgScoped) return undefined;\n\n const resolved = organizationId ?? context.organizationId;\n if (!resolved?.trim()) {\n throw new SpinupMailValidationError({\n message:\n \"organizationId is required for this SpinupMail API method when using API keys.\",\n source: \"request\",\n });\n }\n\n return resolved.trim();\n};\n\nconst normalizeTimestamp = (value: EmailTimestampFilter | undefined) => {\n if (value === undefined) return undefined;\n if (value instanceof Date) return value.toISOString();\n return typeof value === \"number\" ? String(value) : value;\n};\n\nconst normalizeText = (value: string | null | undefined) =>\n (value ?? \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n\nconst matchesText = (\n value: string | null | undefined,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return normalizeText(value).includes(normalizeText(expected));\n};\n\nconst matchesAnyText = (\n values: Array<string | null | undefined>,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return values.some(value => matchesText(value, expected));\n};\n\nconst createQueryString = (\n values: Record<string, string | number | boolean | undefined>\n) => {\n const query = new URLSearchParams();\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) continue;\n query.set(key, String(value));\n }\n\n const serialized = query.toString();\n return serialized.length > 0 ? `?${serialized}` : \"\";\n};\n\nconst parseErrorPayload = async (response: Response) => {\n try {\n const payload = await response.clone().json();\n const parsed = apiErrorSchema.safeParse(payload);\n if (parsed.success) return parsed.data;\n return payload;\n } catch {\n const text = await response.clone().text();\n return text ? { error: text } : undefined;\n }\n};\n\nconst requestJson = async <T>(\n context: ClientContext,\n options: {\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n responseSchema: ZodType<T>;\n body?: unknown;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n headers.set(\"accept\", \"application/json\");\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n let body: BodyInit | undefined;\n if (options.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n body = JSON.stringify(options.body);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: options.method ?? \"GET\",\n headers,\n body,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n let payload: unknown;\n try {\n payload = await response.json();\n } catch (error) {\n throw new SpinupMailValidationError({\n message: \"SpinupMail returned a non-JSON success response.\",\n source: \"response\",\n cause: error,\n });\n }\n\n return validateWithSchema(\n options.responseSchema,\n payload,\n \"response\",\n \"SpinupMail returned an unexpected response shape.\"\n );\n};\n\nconst requestBinary = async (\n context: ClientContext,\n options: {\n path: string;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: \"GET\",\n headers,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n return new SpinupMailFile(response);\n};\n\nconst ensureInboxSelector = (options: InboxAddressSelector) => {\n if (!options.address && !options.addressId) {\n throw new SpinupMailValidationError({\n message: \"Either address or addressId is required.\",\n source: \"request\",\n });\n }\n};\n\nconst validateListEmailsOptions = (options: ListEmailsOptions) => {\n ensureInboxSelector(options);\n validateWithSchema(\n listEmailsParamsSchema,\n {\n ...options,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n },\n \"request\",\n \"Invalid listEmails options.\"\n );\n\n if (\n options.search &&\n (options.after !== undefined ||\n options.before !== undefined ||\n options.order === \"asc\")\n ) {\n throw new SpinupMailValidationError({\n message:\n \"search does not support after, before, or order='asc' parameters.\",\n source: \"request\",\n });\n }\n};\n\nconst matchesListItemFilters = (\n item: EmailListItem,\n options: InboxPollOptions\n) => {\n if (!matchesText(item.subject, options.subjectIncludes)) return false;\n if (!matchesText(item.to, options.toIncludes)) return false;\n if (\n !matchesAnyText(\n [item.from, item.sender, item.senderLabel],\n options.fromIncludes\n )\n ) {\n return false;\n }\n\n return options.match ? options.match(item) : true;\n};\n\nconst matchesDetailFilters = (detail: EmailDetail, options: WaitForEmailOptions) => {\n const bodyText = `${detail.html ?? \"\"}\\n${detail.text ?? \"\"}`;\n\n if (!matchesText(bodyText, options.bodyIncludes)) return false;\n return options.matchDetail ? options.matchDetail(detail) : true;\n};\n\nconst sleep = (ms: number, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"The operation was aborted.\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n cleanup();\n reject(signal?.reason ?? new Error(\"The operation was aborted.\"));\n };\n\n const cleanup = () => {\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\nconst runPollingLoop = async (\n emails: {\n list: (options: ListEmailsOptions) => Promise<EmailListResponse>;\n },\n options: InboxPollOptions,\n args: {\n timeoutMs: number;\n throwOnTimeout: boolean;\n }\n): Promise<InboxPollResult> => {\n ensureInboxSelector(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n const startedAt = Date.now();\n const deadline =\n args.timeoutMs > 0 ? startedAt + args.timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n let attempts = 0;\n let lastResponse!: EmailListResponse;\n let lastFreshItems!: EmailListItem[];\n\n while (true) {\n attempts += 1;\n\n lastResponse = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n lastFreshItems = lastResponse.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return true;\n });\n\n const matchedEmail =\n lastFreshItems.find(item => matchesListItemFilters(item, options)) ?? null;\n if (matchedEmail) {\n return {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail,\n timedOut: false,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n }\n\n if (args.timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n const result: InboxPollResult = {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail: null,\n timedOut: args.timeoutMs > 0,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n\n if (args.throwOnTimeout) {\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${args.timeoutMs}ms timeout elapsed.`,\n args.timeoutMs\n );\n }\n\n return result;\n};\n\nconst waitForEmailDetail = async (\n emails: Pick<SpinupMailEmailsApi, \"list\" | \"get\" | \"delete\">,\n options: WaitForEmailOptions\n) => {\n ensureInboxSelector(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const deadline =\n timeoutMs > 0 ? startedAt + timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n\n while (true) {\n const response = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const freshCandidates = response.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return matchesListItemFilters(item, options);\n });\n\n for (const item of freshCandidates) {\n const detail = await emails.get(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n if (!matchesDetailFilters(detail, options)) {\n continue;\n }\n\n if (options.deleteAfterRead) {\n await emails.delete(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n }\n\n return detail;\n }\n\n if (timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${timeoutMs}ms timeout elapsed.`,\n timeoutMs\n );\n};\n\nconst createSpinupMailClient = (\n options: CreateSpinupMailClientOptions\n): SpinupMailClient => {\n const context: ClientContext = {\n baseUrl: normalizeBaseUrl(options.baseUrl),\n apiKey: normalizeString(options.apiKey, \"apiKey\"),\n organizationId: options.organizationId?.trim() || undefined,\n fetch: resolveFetch(options.fetch),\n headers: options.headers,\n };\n\n const addresses: SpinupMailAddressesApi = {\n list: async (options: ListEmailAddressesOptions = {}) => {\n const validated = validateWithSchema(\n listEmailAddressesParamsSchema,\n options,\n \"request\",\n \"Invalid listEmailAddresses options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses${createQueryString({\n page: validated.page,\n pageSize: validated.pageSize,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: emailAddressListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n listAll: async (options: ListEmailAddressesOptions = {}) => {\n const items: EmailAddress[] = [];\n let page = 1;\n let totalPages = 1;\n\n while (page <= totalPages) {\n if (page > MAX_LIST_ALL_PAGES) {\n throw new SpinupMailValidationError({\n message: `Address pagination exceeded the safety limit of ${MAX_LIST_ALL_PAGES} pages.`,\n source: \"request\",\n });\n }\n\n const response = await addresses.list({\n ...options,\n page,\n pageSize: options.pageSize ?? DEFAULT_LIST_ALL_PAGE_SIZE,\n });\n\n items.push(...response.items);\n totalPages = response.totalPages;\n page += 1;\n }\n\n return items;\n },\n listRecentActivity: async (\n options: ListRecentAddressActivityOptions = {}\n ) => {\n const validated = validateWithSchema(\n listRecentAddressActivityParamsSchema,\n options,\n \"request\",\n \"Invalid listRecentAddressActivity options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses/recent-activity${createQueryString({\n limit: validated.limit,\n cursor: validated.cursor,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: recentAddressActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (addressId: string, options: GetEmailAddressOptions = {}) =>\n requestJson(context, {\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n create: (\n payload: CreateEmailAddressInput,\n options: CreateEmailAddressOptions = {}\n ) => {\n const requestPayload = validateWithSchema(\n createEmailAddressRequestSchema,\n {\n ...payload,\n localPart: payload.localPart?.trim() || generateRandomLocalPart(),\n },\n \"request\",\n \"Invalid createEmailAddress payload.\"\n );\n\n return requestJson(context, {\n method: \"POST\",\n path: \"/api/email-addresses\",\n responseSchema: createEmailAddressResponseSchema,\n body: requestPayload,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n update: (\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options: UpdateEmailAddressOptions = {}\n ) =>\n requestJson(context, {\n method: \"PATCH\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n body: validateWithSchema(\n updateEmailAddressRequestSchema,\n payload,\n \"request\",\n \"Invalid updateEmailAddress payload.\"\n ),\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (addressId: string, options: DeleteEmailAddressOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: deleteEmailAddressResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const emails: SpinupMailEmailsApi = {\n list: async (options: ListEmailsOptions) => {\n validateListEmailsOptions(options);\n\n return requestJson(context, {\n path: `/api/emails${createQueryString({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n })}`,\n responseSchema: emailListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (emailId: string, options: GetEmailOptions = {}) =>\n requestJson(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}${createQueryString({ raw: options.raw ? 1 : undefined })}`,\n responseSchema: emailDetailSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (emailId: string, options: DeleteEmailOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}`,\n responseSchema: deleteEmailResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getRaw: (emailId: string, options: GetEmailRawOptions = {}) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/raw`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getAttachment: (\n emailId: string,\n attachmentId: string,\n options: GetEmailAttachmentOptions = {}\n ) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/attachments/${encodeURIComponent(\n normalizeString(attachmentId, \"attachmentId\")\n )}${createQueryString({ inline: options.inline ? 1 : undefined })}`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const stats: SpinupMailStatsApi = {\n getEmailActivity: (options: GetEmailActivityOptions = {}) =>\n requestJson(context, {\n path: `/api/organizations/stats/email-activity${createQueryString({\n days: options.days,\n timezone: options.timezone,\n })}`,\n responseSchema: emailActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getEmailSummary: (options: GetEmailSummaryOptions = {}) =>\n requestJson(context, {\n path: \"/api/organizations/stats/email-summary\",\n responseSchema: emailSummaryResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const inboxes: SpinupMailInboxesApi = {\n poll: (options: InboxPollOptions) =>\n runPollingLoop(emails, options, {\n timeoutMs: options.timeoutMs ?? 0,\n throwOnTimeout: false,\n }),\n waitForEmail: (options: WaitForEmailOptions) =>\n waitForEmailDetail(emails, options),\n };\n\n return {\n domains: {\n get: () =>\n requestJson(context, {\n path: \"/api/domains\",\n responseSchema: domainConfigSchema,\n }),\n } satisfies SpinupMailDomainsApi,\n addresses,\n emails,\n stats,\n inboxes,\n };\n};\n\n/**\n * API-key SDK for SpinupMail.\n *\n * Typical usage:\n *\n * ```ts\n * const spinupmail = new SpinupMail();\n * const address = await spinupmail.addresses.create({ acceptedRiskNotice: true });\n * const email = await spinupmail.inboxes.waitForEmail({ addressId: address.id });\n * ```\n */\nexport class SpinupMail {\n readonly domains: SpinupMailClient[\"domains\"];\n readonly addresses: SpinupMailClient[\"addresses\"];\n readonly emails: SpinupMailClient[\"emails\"];\n readonly stats: SpinupMailClient[\"stats\"];\n readonly inboxes: SpinupMailClient[\"inboxes\"];\n\n /** Creates a new SDK client using constructor options or environment defaults. */\n constructor(options: string | SpinupMailOptions = {}) {\n const resolvedOptions =\n typeof options === \"string\" ? { apiKey: options } : options;\n const apiKey =\n resolvedOptions.apiKey ?? readEnvValue([\"SPINUPMAIL_API_KEY\"]);\n const baseUrl =\n resolvedOptions.baseUrl ??\n readEnvValue([\"SPINUPMAIL_BASE_URL\"]) ??\n DEFAULT_SPINUPMAIL_BASE_URL;\n const organizationId =\n resolvedOptions.organizationId ??\n readEnvValue([\n \"SPINUPMAIL_ORGANIZATION_ID\",\n \"SPINUPMAIL_ORG_ID\",\n ]);\n\n const client = createSpinupMailClient({\n baseUrl,\n apiKey: normalizeString(apiKey ?? \"\", \"apiKey\"),\n organizationId,\n fetch: resolvedOptions.fetch,\n headers: resolvedOptions.headers,\n });\n\n this.domains = client.domains;\n this.addresses = client.addresses;\n this.emails = client.emails;\n this.stats = client.stats;\n this.inboxes = client.inboxes;\n }\n}\nexport type {\n CreateEmailAddressRequest,\n CreateEmailAddressResponse,\n DeleteEmailAddressResponse,\n DeleteEmailResponse,\n DomainConfig,\n EmailActivityResponse,\n EmailAddress,\n EmailAddressListResponse,\n EmailDetail,\n EmailListItem,\n EmailListResponse,\n EmailSummaryResponse,\n ListEmailAddressesParams,\n ListEmailsParams,\n ListRecentAddressActivityParams,\n RecentAddressActivityResponse,\n UpdateEmailAddressRequest,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["z"],"sources":["../../contracts/src/index.ts","../src/errors.ts","../src/file.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const apiErrorSchema = z.object({\n error: z.string().min(1),\n details: z.string().min(1).optional(),\n});\n\nexport const sortDirectionSchema = z.enum([\"asc\", \"desc\"]);\nexport const emailAddressSortBySchema = z.enum([\n \"createdAt\",\n \"address\",\n \"lastReceivedAt\",\n]);\nexport const recentAddressActivitySortBySchema = z.enum([\n \"recentActivity\",\n \"createdAt\",\n]);\nexport const maxReceivedEmailActionSchema = z.enum([\"cleanAll\", \"rejectNew\"]);\nexport const emailOrderSchema = sortDirectionSchema;\n\nexport const inboundRatePolicySchema = z\n .object({\n senderDomainSoftMax: z.number().int().positive().optional(),\n senderDomainSoftWindowSeconds: z.number().int().positive().optional(),\n senderDomainBlockMax: z.number().int().positive().optional(),\n senderDomainBlockWindowSeconds: z.number().int().positive().optional(),\n senderAddressBlockMax: z.number().int().positive().optional(),\n senderAddressBlockWindowSeconds: z.number().int().positive().optional(),\n inboxBlockMax: z.number().int().positive().optional(),\n inboxBlockWindowSeconds: z.number().int().positive().optional(),\n dedupeWindowSeconds: z.number().int().positive().optional(),\n initialBlockSeconds: z.number().int().positive().optional(),\n maxBlockSeconds: z.number().int().positive().optional(),\n })\n .partial();\n\nexport const domainConfigSchema = z.object({\n items: z.array(z.string().min(1)),\n default: z.string().nullable(),\n forcedLocalPartPrefix: z.string().nullable(),\n maxReceivedEmailsPerOrganization: z.number().int().positive(),\n maxReceivedEmailsPerAddress: z.number().int().positive(),\n});\n\nexport const organizationStatsItemSchema = z.object({\n organizationId: z.string().min(1),\n memberCount: z.number().int().nonnegative(),\n addressCount: z.number().int().nonnegative(),\n emailCount: z.number().int().nonnegative(),\n});\n\nexport const organizationStatsResponseSchema = z.object({\n items: z.array(organizationStatsItemSchema),\n});\n\nexport const emailAddressSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n localPart: z.string().min(1),\n domain: z.string().min(1),\n meta: z.unknown().optional(),\n emailCount: z.number().int().nonnegative(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.nullable(),\n createdAt: z.string().nullable(),\n createdAtMs: z.number().nullable(),\n expiresAt: z.string().nullable(),\n expiresAtMs: z.number().nullable(),\n lastReceivedAt: z.string().nullable(),\n lastReceivedAtMs: z.number().nullable(),\n});\n\nexport const createEmailAddressResponseSchema = emailAddressSchema;\n\nexport const emailAddressListResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalItems: z.number().int().nonnegative(),\n addressLimit: z.number().int().positive(),\n totalPages: z.number().int().positive(),\n sortBy: emailAddressSortBySchema,\n sortDirection: sortDirectionSchema,\n});\n\nexport const listEmailAddressesParamsSchema = z.object({\n page: z.number().int().positive().optional(),\n pageSize: z.number().int().positive().optional(),\n search: z.string().optional(),\n sortBy: emailAddressSortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const listRecentAddressActivityParamsSchema = z.object({\n limit: z.number().int().positive().optional(),\n cursor: z.string().min(1).optional(),\n search: z.string().optional(),\n sortBy: recentAddressActivitySortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const recentAddressActivityResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n nextCursor: z.string().nullable(),\n totalItems: z.number().int().nonnegative(),\n});\n\nexport const createEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1),\n ttlMinutes: z.number().int().positive().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.optional(),\n maxReceivedEmailCount: z.number().int().positive().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n acceptedRiskNotice: z.literal(true),\n});\n\nexport const updateEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1).optional(),\n ttlMinutes: z.number().int().positive().nullable().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).nullable().optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n});\n\nexport const deleteEmailAddressResponseSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailAttachmentSchema = z.object({\n id: z.string().min(1),\n filename: z.string().min(1),\n contentType: z.string().min(1),\n size: z.number().int().nonnegative(),\n disposition: z.string().nullable(),\n contentId: z.string().nullable(),\n inlinePath: z.string().min(1),\n downloadPath: z.string().min(1),\n});\n\nexport const emailListItemSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n hasHtml: z.boolean(),\n hasText: z.boolean(),\n attachmentCount: z.number().int().nonnegative(),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const emailListResponseSchema = z.object({\n address: z.string().min(1),\n addressId: z.string().min(1),\n items: z.array(emailListItemSchema),\n});\n\nexport const listEmailsParamsSchema = z.object({\n address: z.string().min(1).optional(),\n addressId: z.string().min(1).optional(),\n search: z.string().max(30).optional(),\n limit: z.number().int().positive().optional(),\n order: emailOrderSchema.optional(),\n after: z.union([z.string(), z.number()]).optional(),\n before: z.union([z.string(), z.number()]).optional(),\n});\n\nexport const emailDetailSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n address: z.string().min(1).optional(),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n headers: z.unknown(),\n html: z.string().nullable().optional(),\n text: z.string().nullable().optional(),\n raw: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n rawDownloadPath: z.string().optional(),\n attachments: z.array(emailAttachmentSchema),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const deleteEmailResponseSchema = z.object({\n id: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailActivityDaySchema = z.object({\n date: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const emailActivityResponseSchema = z.object({\n timezone: z.string().min(1),\n daily: z.array(emailActivityDaySchema),\n});\n\nexport const emailSummaryDomainSchema = z.object({\n domain: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const busiestInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const dormantInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n createdAt: z.string().nullable(),\n});\n\nexport const emailSummaryResponseSchema = z.object({\n totalEmailCount: z.number().int().nonnegative(),\n attachmentCount: z.number().int().nonnegative(),\n attachmentSizeTotal: z.number().int().nonnegative(),\n attachmentSizeLimit: z.number().int().nonnegative(),\n topDomains: z.array(emailSummaryDomainSchema),\n busiestInboxes: z.array(busiestInboxSchema),\n dormantInboxes: z.array(dormantInboxSchema),\n});\n\nexport const organizationPickerItemSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n logo: z.string().nullable().optional(),\n});\n\nexport const extensionBootstrapUserSchema = z.object({\n id: z.string().min(1),\n email: z.string().email().nullable(),\n name: z.string().nullable(),\n image: z.string().nullable(),\n emailVerified: z.boolean(),\n});\n\nexport const extensionBootstrapResponseSchema = z.object({\n user: extensionBootstrapUserSchema,\n organizations: z.array(organizationPickerItemSchema),\n defaultOrganizationId: z.string().min(1).nullable(),\n});\n\nexport type ApiError = z.infer<typeof apiErrorSchema>;\nexport type SortDirection = z.infer<typeof sortDirectionSchema>;\nexport type EmailAddressSortBy = z.infer<typeof emailAddressSortBySchema>;\nexport type RecentAddressActivitySortBy = z.infer<\n typeof recentAddressActivitySortBySchema\n>;\nexport type MaxReceivedEmailAction = z.infer<\n typeof maxReceivedEmailActionSchema\n>;\nexport type InboundRatePolicy = z.infer<typeof inboundRatePolicySchema>;\nexport type DomainConfig = z.infer<typeof domainConfigSchema>;\nexport type OrganizationStatsItem = z.infer<typeof organizationStatsItemSchema>;\nexport type OrganizationStatsResponse = z.infer<\n typeof organizationStatsResponseSchema\n>;\nexport type EmailAddress = z.infer<typeof emailAddressSchema>;\nexport type EmailAddressListResponse = z.infer<\n typeof emailAddressListResponseSchema\n>;\nexport type ListEmailAddressesParams = z.infer<\n typeof listEmailAddressesParamsSchema\n>;\nexport type ListRecentAddressActivityParams = z.infer<\n typeof listRecentAddressActivityParamsSchema\n>;\nexport type RecentAddressActivityResponse = z.infer<\n typeof recentAddressActivityResponseSchema\n>;\nexport type CreateEmailAddressRequest = z.infer<\n typeof createEmailAddressRequestSchema\n>;\nexport type CreateEmailAddressResponse = z.infer<\n typeof createEmailAddressResponseSchema\n>;\nexport type UpdateEmailAddressRequest = z.infer<\n typeof updateEmailAddressRequestSchema\n>;\nexport type DeleteEmailAddressResponse = z.infer<\n typeof deleteEmailAddressResponseSchema\n>;\nexport type EmailAttachment = z.infer<typeof emailAttachmentSchema>;\nexport type EmailListItem = z.infer<typeof emailListItemSchema>;\nexport type EmailListResponse = z.infer<typeof emailListResponseSchema>;\nexport type ListEmailsParams = z.infer<typeof listEmailsParamsSchema>;\nexport type EmailDetail = z.infer<typeof emailDetailSchema>;\nexport type DeleteEmailResponse = z.infer<typeof deleteEmailResponseSchema>;\nexport type EmailActivityDay = z.infer<typeof emailActivityDaySchema>;\nexport type EmailActivityResponse = z.infer<typeof emailActivityResponseSchema>;\nexport type EmailSummaryDomain = z.infer<typeof emailSummaryDomainSchema>;\nexport type BusiestInbox = z.infer<typeof busiestInboxSchema>;\nexport type DormantInbox = z.infer<typeof dormantInboxSchema>;\nexport type EmailSummaryResponse = z.infer<typeof emailSummaryResponseSchema>;\nexport type OrganizationPickerItem = z.infer<\n typeof organizationPickerItemSchema\n>;\nexport type ExtensionBootstrapUser = z.infer<\n typeof extensionBootstrapUserSchema\n>;\nexport type ExtensionBootstrapResponse = z.infer<\n typeof extensionBootstrapResponseSchema\n>;\n","export class SpinupMailError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class SpinupMailValidationError extends SpinupMailError {\n readonly source: \"request\" | \"response\";\n readonly issues: string[];\n\n constructor(args: {\n message: string;\n source: \"request\" | \"response\";\n issues?: string[];\n cause?: unknown;\n }) {\n super(args.message, args.cause ? { cause: args.cause } : undefined);\n this.source = args.source;\n this.issues = args.issues ?? [];\n }\n}\n\nexport class SpinupMailApiError extends SpinupMailError {\n readonly status: number;\n readonly response: Response;\n readonly body?: unknown;\n\n constructor(args: {\n message: string;\n status: number;\n response: Response;\n body?: unknown;\n }) {\n super(args.message);\n this.status = args.status;\n this.response = args.response;\n this.body = args.body;\n }\n}\n\nexport class SpinupMailTimeoutError extends SpinupMailError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, options?: ErrorOptions) {\n super(message, options);\n this.timeoutMs = timeoutMs;\n }\n}\n","const parseFilenameFromDisposition = (headerValue: string | null) => {\n if (!headerValue) return null;\n\n const utf8Match = headerValue.match(/filename\\*=[^']*'[^']*'([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n\n const fallbackMatch = headerValue.match(/filename=\"([^\"]+)\"/i);\n if (fallbackMatch?.[1]) return fallbackMatch[1];\n\n const unquotedMatch = headerValue.match(/filename=([^;\"]+)/i);\n if (unquotedMatch?.[1]) return unquotedMatch[1].trim();\n\n return null;\n};\n\nexport class SpinupMailFile {\n readonly filename: string | null;\n readonly contentType: string | null;\n readonly contentLength: number | null;\n readonly response: Response;\n\n constructor(response: Response) {\n this.response = response;\n this.filename = parseFilenameFromDisposition(\n response.headers.get(\"content-disposition\")\n );\n this.contentType = response.headers.get(\"content-type\");\n\n const contentLength = response.headers.get(\"content-length\");\n const parsed = contentLength ? Number(contentLength) : Number.NaN;\n this.contentLength =\n Number.isInteger(parsed) && parsed >= 0 ? parsed : null;\n }\n\n arrayBuffer() {\n return this.response.clone().arrayBuffer();\n }\n\n text() {\n return this.response.clone().text();\n }\n\n blob() {\n const clone = this.response.clone() as Response & {\n blob?: () => Promise<Blob>;\n };\n\n if (typeof clone.blob !== \"function\") {\n throw new Error(\"Response.blob() is not available in this runtime.\");\n }\n\n return clone.blob();\n }\n}\n","import type { ZodType } from \"zod\";\nimport {\n apiErrorSchema,\n createEmailAddressRequestSchema,\n createEmailAddressResponseSchema,\n deleteEmailAddressResponseSchema,\n deleteEmailResponseSchema,\n domainConfigSchema,\n emailActivityResponseSchema,\n emailDetailSchema,\n emailListResponseSchema,\n emailSummaryResponseSchema,\n listEmailAddressesParamsSchema,\n listEmailsParamsSchema,\n listRecentAddressActivityParamsSchema,\n recentAddressActivityResponseSchema,\n updateEmailAddressRequestSchema,\n emailAddressListResponseSchema,\n emailAddressSchema,\n type CreateEmailAddressRequest,\n type CreateEmailAddressResponse,\n type DeleteEmailAddressResponse,\n type DeleteEmailResponse,\n type DomainConfig,\n type EmailActivityResponse,\n type EmailAddress,\n type EmailAddressListResponse,\n type EmailDetail,\n type EmailListItem,\n type EmailListResponse,\n type EmailSummaryResponse,\n type ListEmailAddressesParams,\n type ListEmailsParams,\n type ListRecentAddressActivityParams,\n type RecentAddressActivityResponse,\n type UpdateEmailAddressRequest,\n} from \"@/contracts\";\nimport {\n SpinupMailApiError,\n SpinupMailTimeoutError,\n SpinupMailValidationError,\n} from \"@/errors\";\nimport { SpinupMailFile } from \"@/file\";\n\ntype FetchLike = typeof fetch;\ntype OrganizationScopedOptions = {\n organizationId?: string;\n signal?: AbortSignal;\n};\n\ntype InboxAddressSelector = {\n address?: string;\n addressId?: string;\n};\n\nexport type CreateSpinupMailClientOptions = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/**\n * Initializes the SpinupMail SDK.\n *\n * `apiKey` defaults to `process.env.SPINUPMAIL_API_KEY`.\n * `baseUrl` defaults to `process.env.SPINUPMAIL_BASE_URL` or `https://api.spinupmail.com`.\n * `organizationId` defaults to `process.env.SPINUPMAIL_ORGANIZATION_ID` or `process.env.SPINUPMAIL_ORG_ID`.\n */\nexport type SpinupMailOptions = {\n apiKey?: string;\n baseUrl?: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/** Lists and paginates inbox addresses in the active organization. */\nexport type ListEmailAddressesOptions = ListEmailAddressesParams &\n OrganizationScopedOptions;\n\n/** Reads the recent-activity inbox feed in the active organization. */\nexport type ListRecentAddressActivityOptions = ListRecentAddressActivityParams &\n OrganizationScopedOptions;\n\n/** Fetches a single inbox address by ID. */\nexport type GetEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox creation. */\nexport type CreateEmailAddressOptions = OrganizationScopedOptions;\n\n/**\n * Creates a SpinupMail inbox.\n *\n * If `localPart` is omitted, the SDK generates a random valid local part\n * before sending the request.\n */\nexport type CreateEmailAddressInput = Omit<\n CreateEmailAddressRequest,\n \"localPart\"\n> & {\n localPart?: string;\n};\n\n/** Per-call options for inbox updates. */\nexport type UpdateEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox deletion. */\nexport type DeleteEmailAddressOptions = OrganizationScopedOptions;\n\n/** Lists emails for a single inbox, optionally filtered by received time. */\nexport type ListEmailsOptions = Omit<ListEmailsParams, \"after\" | \"before\"> &\n OrganizationScopedOptions & {\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n };\n\n/** Fetches a single stored email. */\nexport type GetEmailOptions = OrganizationScopedOptions & {\n raw?: boolean;\n};\n\n/** Deletes a single stored email. */\nexport type DeleteEmailOptions = OrganizationScopedOptions;\n\n/** Downloads the raw MIME source for an email. */\nexport type GetEmailRawOptions = OrganizationScopedOptions;\n\n/** Downloads one attachment from a stored email. */\nexport type GetEmailAttachmentOptions = OrganizationScopedOptions & {\n inline?: boolean;\n};\n\n/** Fetches organization email activity stats. */\nexport type GetEmailActivityOptions = OrganizationScopedOptions & {\n days?: number;\n timezone?: string;\n};\n\n/** Fetches organization email summary stats. */\nexport type GetEmailSummaryOptions = OrganizationScopedOptions;\n\n/** Timestamp filter accepted by inbox listing and polling helpers. */\nexport type EmailTimestampFilter = string | number | Date;\n\n/**\n * Polls an inbox until a matching email appears or the timeout is reached.\n *\n * Provide either `address` or `addressId`.\n */\nexport type InboxPollOptions = InboxAddressSelector &\n OrganizationScopedOptions & {\n search?: string;\n limit?: number;\n order?: \"asc\" | \"desc\";\n /** Case-insensitive substring match against the email subject. */\n subjectIncludes?: string;\n /** Case-insensitive substring match against the recipient address. */\n toIncludes?: string;\n /** Case-insensitive substring match against `from`, `sender`, or `senderLabel`. */\n fromIncludes?: string;\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n timeoutMs?: number;\n intervalMs?: number;\n match?: (email: EmailListItem) => boolean;\n };\n\n/**\n * Waits for a matching email and optionally filters against the fetched body.\n *\n * `bodyIncludes` and `matchDetail` are evaluated after the SDK fetches email\n * detail for candidate messages that already passed the list-level filters.\n */\nexport type WaitForEmailOptions = InboxPollOptions & {\n /** Case-insensitive substring match against the concatenated HTML and text body. */\n bodyIncludes?: string;\n /** Deletes the email after fetching the matching detail payload. */\n deleteAfterRead?: boolean;\n /** Additional predicate evaluated against the fetched email detail payload. */\n matchDetail?: (email: EmailDetail) => boolean;\n};\n\n/** Result returned by `inboxes.poll()`. */\nexport type InboxPollResult = {\n response: EmailListResponse;\n items: EmailListItem[];\n freshItems: EmailListItem[];\n matchedEmail: EmailListItem | null;\n timedOut: boolean;\n attempts: number;\n elapsedMs: number;\n polledAt: string;\n};\n\ntype ClientContext = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch: FetchLike;\n headers?: HeadersInit;\n};\n\nexport interface SpinupMailDomainsApi {\n /** Fetches configured receiving domains and retention limits. */\n get(): Promise<DomainConfig>;\n}\n\nexport interface SpinupMailAddressesApi {\n /** Lists inbox addresses in the current organization. */\n list(options?: ListEmailAddressesOptions): Promise<EmailAddressListResponse>;\n /** Fetches all inbox addresses by following all pages. */\n listAll(options?: ListEmailAddressesOptions): Promise<EmailAddress[]>;\n /** Lists inboxes ordered by recent activity using cursor pagination. */\n listRecentActivity(\n options?: ListRecentAddressActivityOptions\n ): Promise<RecentAddressActivityResponse>;\n /** Fetches a single inbox address by ID. */\n get(\n addressId: string,\n options?: GetEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Creates an inbox address in the current organization. */\n create(\n payload: CreateEmailAddressInput,\n options?: CreateEmailAddressOptions\n ): Promise<CreateEmailAddressResponse>;\n /** Updates an existing inbox address. */\n update(\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options?: UpdateEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Deletes an inbox address and its stored contents. */\n delete(\n addressId: string,\n options?: DeleteEmailAddressOptions\n ): Promise<DeleteEmailAddressResponse>;\n}\n\nexport interface SpinupMailEmailsApi {\n /** Lists emails for a single inbox. */\n list(options: ListEmailsOptions): Promise<EmailListResponse>;\n /** Fetches one parsed email including bodies and attachment metadata. */\n get(emailId: string, options?: GetEmailOptions): Promise<EmailDetail>;\n /** Deletes one stored email. */\n delete(\n emailId: string,\n options?: DeleteEmailOptions\n ): Promise<DeleteEmailResponse>;\n /** Downloads the raw MIME source for an email. */\n getRaw(\n emailId: string,\n options?: GetEmailRawOptions\n ): Promise<SpinupMailFile>;\n /** Downloads an attachment from an email. */\n getAttachment(\n emailId: string,\n attachmentId: string,\n options?: GetEmailAttachmentOptions\n ): Promise<SpinupMailFile>;\n}\n\nexport interface SpinupMailStatsApi {\n /** Returns daily email activity counts for the organization. */\n getEmailActivity(\n options?: GetEmailActivityOptions\n ): Promise<EmailActivityResponse>;\n /** Returns aggregate storage and inbox summary stats for the organization. */\n getEmailSummary(\n options?: GetEmailSummaryOptions\n ): Promise<EmailSummaryResponse>;\n}\n\nexport interface SpinupMailInboxesApi {\n /** Polls an inbox and returns the latest response plus polling metadata. */\n poll(options: InboxPollOptions): Promise<InboxPollResult>;\n /** Waits until a matching email arrives, then returns the fetched email detail. */\n waitForEmail(options: WaitForEmailOptions): Promise<EmailDetail>;\n}\n\nexport interface SpinupMailClient {\n /** Domain and retention configuration endpoints. */\n domains: SpinupMailDomainsApi;\n /** Inbox address lifecycle endpoints. */\n addresses: SpinupMailAddressesApi;\n /** Email retrieval and download endpoints. */\n emails: SpinupMailEmailsApi;\n /** Organization-level reporting endpoints. */\n stats: SpinupMailStatsApi;\n /** High-level inbox polling helpers. */\n inboxes: SpinupMailInboxesApi;\n}\n\nconst DEFAULT_LIST_ALL_PAGE_SIZE = 50;\nconst MAX_LIST_ALL_PAGES = 200;\nconst DEFAULT_WAIT_TIMEOUT_MS = 30_000;\nconst DEFAULT_POLL_INTERVAL_MS = 1_000;\nconst DEFAULT_SPINUPMAIL_BASE_URL = \"https://api.spinupmail.com\";\nconst RANDOM_LOCAL_PART_PREFIX = \"sum\";\nconst RANDOM_LOCAL_PART_SIZE = 12;\n\nconst issuePathToString = (path: PropertyKey[]) =>\n path.length === 0 ? \"<root>\" : path.map(String).join(\".\");\n\nconst formatSchemaIssues = (\n issues: Array<{ path: PropertyKey[]; message: string }>\n) => issues.map(issue => `${issuePathToString(issue.path)}: ${issue.message}`);\n\nconst validateWithSchema = <T>(\n schema: ZodType<T>,\n value: unknown,\n source: \"request\" | \"response\",\n message: string\n) => {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new SpinupMailValidationError({\n message,\n source,\n issues: formatSchemaIssues(parsed.error.issues),\n cause: parsed.error,\n });\n }\n\n return parsed.data;\n};\n\nconst normalizeString = (value: string, label: string) => {\n const normalized = value.trim();\n if (!normalized) {\n throw new SpinupMailValidationError({\n message: `${label} is required.`,\n source: \"request\",\n });\n }\n return normalized;\n};\n\nconst resolveFetch = (candidate?: FetchLike) => {\n if (candidate) return candidate;\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis) as FetchLike;\n }\n\n throw new SpinupMailValidationError({\n message: \"A fetch implementation is required in this runtime.\",\n source: \"request\",\n });\n};\n\nconst normalizeBaseUrl = (baseUrl: string) =>\n normalizeString(baseUrl, \"baseUrl\").replace(/\\/+$/, \"\");\n\nconst getProcessEnv = () => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env === \"object\" &&\n process.env !== null\n ) {\n return process.env;\n }\n\n return undefined;\n};\n\nconst readEnvValue = (keys: string[]) => {\n const env = getProcessEnv();\n if (!env) return undefined;\n\n for (const key of keys) {\n const value = env[key]?.trim();\n if (value) return value;\n }\n\n return undefined;\n};\n\nconst createRandomBytes = (size: number) => {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n return crypto.getRandomValues(new Uint8Array(size));\n }\n\n return Uint8Array.from(\n Array.from({ length: size }, () => Math.floor(Math.random() * 256))\n );\n};\n\nconst generateRandomLocalPart = () => {\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const bytes = createRandomBytes(RANDOM_LOCAL_PART_SIZE);\n let suffix = \"\";\n\n for (const byte of bytes) {\n suffix += alphabet[byte % alphabet.length];\n }\n\n return `${RANDOM_LOCAL_PART_PREFIX}-${suffix}`;\n};\n\nconst resolveOrganizationId = (\n context: ClientContext,\n organizationId: string | undefined,\n orgScoped: boolean\n) => {\n if (!orgScoped) return undefined;\n\n const resolved = organizationId ?? context.organizationId;\n if (!resolved?.trim()) {\n throw new SpinupMailValidationError({\n message:\n \"organizationId is required for this SpinupMail API method when using API keys.\",\n source: \"request\",\n });\n }\n\n return resolved.trim();\n};\n\nconst normalizeTimestamp = (value: EmailTimestampFilter | undefined) => {\n if (value === undefined) return undefined;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new SpinupMailValidationError({\n message: \"Invalid timestamp: number values must be finite.\",\n source: \"request\",\n });\n }\n\n return String(value);\n }\n\n if (value instanceof Date) {\n if (!Number.isFinite(value.getTime())) {\n throw new SpinupMailValidationError({\n message: \"Invalid timestamp: Date values must be valid.\",\n source: \"request\",\n });\n }\n\n return value.toISOString();\n }\n\n return value;\n};\n\nconst normalizeText = (value: string | null | undefined) =>\n (value ?? \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n\nconst matchesText = (\n value: string | null | undefined,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return normalizeText(value).includes(normalizeText(expected));\n};\n\nconst matchesAnyText = (\n values: Array<string | null | undefined>,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return values.some(value => matchesText(value, expected));\n};\n\nconst createQueryString = (\n values: Record<string, string | number | boolean | undefined>\n) => {\n const query = new URLSearchParams();\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) continue;\n query.set(key, String(value));\n }\n\n const serialized = query.toString();\n return serialized.length > 0 ? `?${serialized}` : \"\";\n};\n\nconst parseErrorPayload = async (response: Response) => {\n try {\n const payload = await response.clone().json();\n const parsed = apiErrorSchema.safeParse(payload);\n if (parsed.success) return parsed.data;\n return payload;\n } catch {\n const text = await response.clone().text();\n return text ? { error: text } : undefined;\n }\n};\n\nconst requestJson = async <T>(\n context: ClientContext,\n options: {\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n responseSchema: ZodType<T>;\n body?: unknown;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n headers.set(\"accept\", \"application/json\");\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n let body: BodyInit | undefined;\n if (options.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n body = JSON.stringify(options.body);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: options.method ?? \"GET\",\n headers,\n body,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n let payload: unknown;\n try {\n payload = await response.json();\n } catch (error) {\n throw new SpinupMailValidationError({\n message: \"SpinupMail returned a non-JSON success response.\",\n source: \"response\",\n cause: error,\n });\n }\n\n return validateWithSchema(\n options.responseSchema,\n payload,\n \"response\",\n \"SpinupMail returned an unexpected response shape.\"\n );\n};\n\nconst requestBinary = async (\n context: ClientContext,\n options: {\n path: string;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: \"GET\",\n headers,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n return new SpinupMailFile(response);\n};\n\nconst ensureInboxSelector = (options: InboxAddressSelector) => {\n const hasAddress = Boolean(options.address?.trim());\n const hasAddressId = Boolean(options.addressId?.trim());\n\n if (hasAddress === hasAddressId) {\n throw new SpinupMailValidationError({\n message: \"Exactly one of address or addressId is required.\",\n source: \"request\",\n });\n }\n};\n\nconst validatePollingTimingOptions = (options: {\n timeoutMs?: number;\n intervalMs?: number;\n}) => {\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)\n ) {\n throw new SpinupMailValidationError({\n message: \"invalid option: timeoutMs must be a finite number >= 0\",\n source: \"request\",\n });\n }\n\n if (\n options.intervalMs !== undefined &&\n (!Number.isFinite(options.intervalMs) || options.intervalMs <= 0)\n ) {\n throw new SpinupMailValidationError({\n message: \"invalid option: intervalMs must be a finite number > 0\",\n source: \"request\",\n });\n }\n};\n\nconst validateListEmailsOptions = (options: ListEmailsOptions) => {\n ensureInboxSelector(options);\n validateWithSchema(\n listEmailsParamsSchema,\n {\n ...options,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n },\n \"request\",\n \"Invalid listEmails options.\"\n );\n\n if (\n options.search &&\n (options.after !== undefined ||\n options.before !== undefined ||\n options.order === \"asc\")\n ) {\n throw new SpinupMailValidationError({\n message:\n \"search does not support after, before, or order='asc' parameters.\",\n source: \"request\",\n });\n }\n};\n\nconst matchesListItemFilters = (\n item: EmailListItem,\n options: InboxPollOptions\n) => {\n if (!matchesText(item.subject, options.subjectIncludes)) return false;\n if (!matchesText(item.to, options.toIncludes)) return false;\n if (\n !matchesAnyText(\n [item.from, item.sender, item.senderLabel],\n options.fromIncludes\n )\n ) {\n return false;\n }\n\n return options.match ? options.match(item) : true;\n};\n\nconst matchesDetailFilters = (\n detail: EmailDetail,\n options: WaitForEmailOptions\n) => {\n const bodyText = `${detail.html ?? \"\"}\\n${detail.text ?? \"\"}`;\n\n if (!matchesText(bodyText, options.bodyIncludes)) return false;\n return options.matchDetail ? options.matchDetail(detail) : true;\n};\n\nconst sleep = (ms: number, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"The operation was aborted.\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n cleanup();\n reject(signal?.reason ?? new Error(\"The operation was aborted.\"));\n };\n\n const cleanup = () => {\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\nconst runPollingLoop = async (\n emails: {\n list: (options: ListEmailsOptions) => Promise<EmailListResponse>;\n },\n options: InboxPollOptions,\n args: {\n timeoutMs: number;\n throwOnTimeout: boolean;\n }\n): Promise<InboxPollResult> => {\n ensureInboxSelector(options);\n validatePollingTimingOptions(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n const startedAt = Date.now();\n const deadline =\n args.timeoutMs > 0 ? startedAt + args.timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n let attempts = 0;\n let lastResponse!: EmailListResponse;\n let lastFreshItems!: EmailListItem[];\n\n while (true) {\n attempts += 1;\n\n lastResponse = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n lastFreshItems = lastResponse.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return true;\n });\n\n const matchedEmail =\n lastFreshItems.find(item => matchesListItemFilters(item, options)) ??\n null;\n if (matchedEmail) {\n return {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail,\n timedOut: false,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n }\n\n if (args.timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n const result: InboxPollResult = {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail: null,\n timedOut: args.timeoutMs > 0,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n\n if (args.throwOnTimeout) {\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${args.timeoutMs}ms timeout elapsed.`,\n args.timeoutMs\n );\n }\n\n return result;\n};\n\nconst waitForEmailDetail = async (\n emails: Pick<SpinupMailEmailsApi, \"list\" | \"get\" | \"delete\">,\n options: WaitForEmailOptions\n) => {\n ensureInboxSelector(options);\n validatePollingTimingOptions(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const deadline =\n timeoutMs > 0 ? startedAt + timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n\n while (true) {\n const response = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const freshCandidates = response.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return matchesListItemFilters(item, options);\n });\n\n for (const item of freshCandidates) {\n const detail = await emails.get(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n if (!matchesDetailFilters(detail, options)) {\n continue;\n }\n\n if (options.deleteAfterRead) {\n await emails.delete(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n }\n\n return detail;\n }\n\n if (timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${timeoutMs}ms timeout elapsed.`,\n timeoutMs\n );\n};\n\nconst createSpinupMailClient = (\n options: CreateSpinupMailClientOptions\n): SpinupMailClient => {\n const context: ClientContext = {\n baseUrl: normalizeBaseUrl(options.baseUrl),\n apiKey: normalizeString(options.apiKey, \"apiKey\"),\n organizationId: options.organizationId?.trim() || undefined,\n fetch: resolveFetch(options.fetch),\n headers: options.headers,\n };\n\n const addresses: SpinupMailAddressesApi = {\n list: async (options: ListEmailAddressesOptions = {}) => {\n const validated = validateWithSchema(\n listEmailAddressesParamsSchema,\n options,\n \"request\",\n \"Invalid listEmailAddresses options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses${createQueryString({\n page: validated.page,\n pageSize: validated.pageSize,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: emailAddressListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n listAll: async (options: ListEmailAddressesOptions = {}) => {\n const items: EmailAddress[] = [];\n let page = 1;\n let totalPages = 1;\n\n while (page <= totalPages) {\n if (page > MAX_LIST_ALL_PAGES) {\n throw new SpinupMailValidationError({\n message: `Address pagination exceeded the safety limit of ${MAX_LIST_ALL_PAGES} pages.`,\n source: \"request\",\n });\n }\n\n const response = await addresses.list({\n ...options,\n page,\n pageSize: options.pageSize ?? DEFAULT_LIST_ALL_PAGE_SIZE,\n });\n\n items.push(...response.items);\n totalPages = response.totalPages;\n page += 1;\n }\n\n return items;\n },\n listRecentActivity: async (\n options: ListRecentAddressActivityOptions = {}\n ) => {\n const validated = validateWithSchema(\n listRecentAddressActivityParamsSchema,\n options,\n \"request\",\n \"Invalid listRecentAddressActivity options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses/recent-activity${createQueryString({\n limit: validated.limit,\n cursor: validated.cursor,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: recentAddressActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (addressId: string, options: GetEmailAddressOptions = {}) =>\n requestJson(context, {\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n create: (\n payload: CreateEmailAddressInput,\n options: CreateEmailAddressOptions = {}\n ) => {\n const requestPayload = validateWithSchema(\n createEmailAddressRequestSchema,\n {\n ...payload,\n localPart: payload.localPart?.trim() || generateRandomLocalPart(),\n },\n \"request\",\n \"Invalid createEmailAddress payload.\"\n );\n\n return requestJson(context, {\n method: \"POST\",\n path: \"/api/email-addresses\",\n responseSchema: createEmailAddressResponseSchema,\n body: requestPayload,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n update: (\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options: UpdateEmailAddressOptions = {}\n ) =>\n requestJson(context, {\n method: \"PATCH\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n body: validateWithSchema(\n updateEmailAddressRequestSchema,\n payload,\n \"request\",\n \"Invalid updateEmailAddress payload.\"\n ),\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (addressId: string, options: DeleteEmailAddressOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: deleteEmailAddressResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const emails: SpinupMailEmailsApi = {\n list: async (options: ListEmailsOptions) => {\n validateListEmailsOptions(options);\n\n return requestJson(context, {\n path: `/api/emails${createQueryString({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n })}`,\n responseSchema: emailListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (emailId: string, options: GetEmailOptions = {}) =>\n requestJson(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}${createQueryString({ raw: options.raw ? 1 : undefined })}`,\n responseSchema: emailDetailSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (emailId: string, options: DeleteEmailOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}`,\n responseSchema: deleteEmailResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getRaw: (emailId: string, options: GetEmailRawOptions = {}) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/raw`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getAttachment: (\n emailId: string,\n attachmentId: string,\n options: GetEmailAttachmentOptions = {}\n ) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/attachments/${encodeURIComponent(\n normalizeString(attachmentId, \"attachmentId\")\n )}${createQueryString({ inline: options.inline ? 1 : undefined })}`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const stats: SpinupMailStatsApi = {\n getEmailActivity: (options: GetEmailActivityOptions = {}) =>\n requestJson(context, {\n path: `/api/organizations/stats/email-activity${createQueryString({\n days: options.days,\n timezone: options.timezone,\n })}`,\n responseSchema: emailActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getEmailSummary: (options: GetEmailSummaryOptions = {}) =>\n requestJson(context, {\n path: \"/api/organizations/stats/email-summary\",\n responseSchema: emailSummaryResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const inboxes: SpinupMailInboxesApi = {\n poll: (options: InboxPollOptions) =>\n runPollingLoop(emails, options, {\n timeoutMs: options.timeoutMs ?? 0,\n throwOnTimeout: false,\n }),\n waitForEmail: (options: WaitForEmailOptions) =>\n waitForEmailDetail(emails, options),\n };\n\n return {\n domains: {\n get: () =>\n requestJson(context, {\n path: \"/api/domains\",\n responseSchema: domainConfigSchema,\n }),\n } satisfies SpinupMailDomainsApi,\n addresses,\n emails,\n stats,\n inboxes,\n };\n};\n\n/**\n * API-key SDK for SpinupMail.\n *\n * Typical usage:\n *\n * ```ts\n * const spinupmail = new SpinupMail();\n * const address = await spinupmail.addresses.create({ acceptedRiskNotice: true });\n * const email = await spinupmail.inboxes.waitForEmail({ addressId: address.id });\n * ```\n */\nexport class SpinupMail {\n readonly domains: SpinupMailClient[\"domains\"];\n readonly addresses: SpinupMailClient[\"addresses\"];\n readonly emails: SpinupMailClient[\"emails\"];\n readonly stats: SpinupMailClient[\"stats\"];\n readonly inboxes: SpinupMailClient[\"inboxes\"];\n\n /** Creates a new SDK client using constructor options or environment defaults. */\n constructor(options: string | SpinupMailOptions = {}) {\n const resolvedOptions =\n typeof options === \"string\" ? { apiKey: options } : options;\n const apiKey =\n resolvedOptions.apiKey ?? readEnvValue([\"SPINUPMAIL_API_KEY\"]);\n const baseUrl =\n resolvedOptions.baseUrl ??\n readEnvValue([\"SPINUPMAIL_BASE_URL\"]) ??\n DEFAULT_SPINUPMAIL_BASE_URL;\n const organizationId =\n resolvedOptions.organizationId ??\n readEnvValue([\"SPINUPMAIL_ORGANIZATION_ID\", \"SPINUPMAIL_ORG_ID\"]);\n\n const client = createSpinupMailClient({\n baseUrl,\n apiKey: normalizeString(apiKey ?? \"\", \"apiKey\"),\n organizationId,\n fetch: resolvedOptions.fetch,\n headers: resolvedOptions.headers,\n });\n\n this.domains = client.domains;\n this.addresses = client.addresses;\n this.emails = client.emails;\n this.stats = client.stats;\n this.inboxes = client.inboxes;\n }\n}\nexport type {\n CreateEmailAddressRequest,\n CreateEmailAddressResponse,\n DeleteEmailAddressResponse,\n DeleteEmailResponse,\n DomainConfig,\n EmailActivityResponse,\n EmailAddress,\n EmailAddressListResponse,\n EmailDetail,\n EmailListItem,\n EmailListResponse,\n EmailSummaryResponse,\n ListEmailAddressesParams,\n ListEmailsParams,\n ListRecentAddressActivityParams,\n RecentAddressActivityResponse,\n UpdateEmailAddressRequest,\n};\n"],"mappings":"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"}
|
package/dist/index.mjs
CHANGED
|
@@ -273,7 +273,7 @@ var SpinupMailTimeoutError = class extends SpinupMailError {
|
|
|
273
273
|
//#region src/file.ts
|
|
274
274
|
const parseFilenameFromDisposition = (headerValue) => {
|
|
275
275
|
if (!headerValue) return null;
|
|
276
|
-
const utf8Match = headerValue.match(/filename\*=
|
|
276
|
+
const utf8Match = headerValue.match(/filename\*=[^']*'[^']*'([^;]+)/i);
|
|
277
277
|
if (utf8Match?.[1]) try {
|
|
278
278
|
return decodeURIComponent(utf8Match[1]);
|
|
279
279
|
} catch {
|
|
@@ -281,6 +281,8 @@ const parseFilenameFromDisposition = (headerValue) => {
|
|
|
281
281
|
}
|
|
282
282
|
const fallbackMatch = headerValue.match(/filename="([^"]+)"/i);
|
|
283
283
|
if (fallbackMatch?.[1]) return fallbackMatch[1];
|
|
284
|
+
const unquotedMatch = headerValue.match(/filename=([^;"]+)/i);
|
|
285
|
+
if (unquotedMatch?.[1]) return unquotedMatch[1].trim();
|
|
284
286
|
return null;
|
|
285
287
|
};
|
|
286
288
|
var SpinupMailFile = class {
|
|
@@ -294,7 +296,7 @@ var SpinupMailFile = class {
|
|
|
294
296
|
this.contentType = response.headers.get("content-type");
|
|
295
297
|
const contentLength = response.headers.get("content-length");
|
|
296
298
|
const parsed = contentLength ? Number(contentLength) : NaN;
|
|
297
|
-
this.contentLength = Number.
|
|
299
|
+
this.contentLength = Number.isInteger(parsed) && parsed >= 0 ? parsed : null;
|
|
298
300
|
}
|
|
299
301
|
arrayBuffer() {
|
|
300
302
|
return this.response.clone().arrayBuffer();
|
|
@@ -379,8 +381,21 @@ const resolveOrganizationId = (context, organizationId, orgScoped) => {
|
|
|
379
381
|
};
|
|
380
382
|
const normalizeTimestamp = (value) => {
|
|
381
383
|
if (value === void 0) return void 0;
|
|
382
|
-
if (value
|
|
383
|
-
|
|
384
|
+
if (typeof value === "number") {
|
|
385
|
+
if (!Number.isFinite(value)) throw new SpinupMailValidationError({
|
|
386
|
+
message: "Invalid timestamp: number values must be finite.",
|
|
387
|
+
source: "request"
|
|
388
|
+
});
|
|
389
|
+
return String(value);
|
|
390
|
+
}
|
|
391
|
+
if (value instanceof Date) {
|
|
392
|
+
if (!Number.isFinite(value.getTime())) throw new SpinupMailValidationError({
|
|
393
|
+
message: "Invalid timestamp: Date values must be valid.",
|
|
394
|
+
source: "request"
|
|
395
|
+
});
|
|
396
|
+
return value.toISOString();
|
|
397
|
+
}
|
|
398
|
+
return value;
|
|
384
399
|
};
|
|
385
400
|
const normalizeText = (value) => (value ?? "").replace(/\s+/g, " ").trim().toLowerCase();
|
|
386
401
|
const matchesText = (value, expected) => {
|
|
@@ -471,8 +486,18 @@ const requestBinary = async (context, options) => {
|
|
|
471
486
|
return new SpinupMailFile(response);
|
|
472
487
|
};
|
|
473
488
|
const ensureInboxSelector = (options) => {
|
|
474
|
-
if (
|
|
475
|
-
message: "
|
|
489
|
+
if (Boolean(options.address?.trim()) === Boolean(options.addressId?.trim())) throw new SpinupMailValidationError({
|
|
490
|
+
message: "Exactly one of address or addressId is required.",
|
|
491
|
+
source: "request"
|
|
492
|
+
});
|
|
493
|
+
};
|
|
494
|
+
const validatePollingTimingOptions = (options) => {
|
|
495
|
+
if (options.timeoutMs !== void 0 && (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)) throw new SpinupMailValidationError({
|
|
496
|
+
message: "invalid option: timeoutMs must be a finite number >= 0",
|
|
497
|
+
source: "request"
|
|
498
|
+
});
|
|
499
|
+
if (options.intervalMs !== void 0 && (!Number.isFinite(options.intervalMs) || options.intervalMs <= 0)) throw new SpinupMailValidationError({
|
|
500
|
+
message: "invalid option: intervalMs must be a finite number > 0",
|
|
476
501
|
source: "request"
|
|
477
502
|
});
|
|
478
503
|
};
|
|
@@ -523,6 +548,7 @@ const sleep = (ms, signal) => new Promise((resolve, reject) => {
|
|
|
523
548
|
});
|
|
524
549
|
const runPollingLoop = async (emails, options, args) => {
|
|
525
550
|
ensureInboxSelector(options);
|
|
551
|
+
validatePollingTimingOptions(options);
|
|
526
552
|
validateListEmailsOptions({
|
|
527
553
|
address: options.address,
|
|
528
554
|
addressId: options.addressId,
|
|
@@ -589,6 +615,7 @@ const runPollingLoop = async (emails, options, args) => {
|
|
|
589
615
|
};
|
|
590
616
|
const waitForEmailDetail = async (emails, options) => {
|
|
591
617
|
ensureInboxSelector(options);
|
|
618
|
+
validatePollingTimingOptions(options);
|
|
592
619
|
validateListEmailsOptions({
|
|
593
620
|
address: options.address,
|
|
594
621
|
addressId: options.addressId,
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../../contracts/src/index.ts","../src/errors.ts","../src/file.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const apiErrorSchema = z.object({\n error: z.string().min(1),\n details: z.string().min(1).optional(),\n});\n\nexport const sortDirectionSchema = z.enum([\"asc\", \"desc\"]);\nexport const emailAddressSortBySchema = z.enum([\n \"createdAt\",\n \"address\",\n \"lastReceivedAt\",\n]);\nexport const recentAddressActivitySortBySchema = z.enum([\n \"recentActivity\",\n \"createdAt\",\n]);\nexport const maxReceivedEmailActionSchema = z.enum([\n \"cleanAll\",\n \"rejectNew\",\n]);\nexport const emailOrderSchema = sortDirectionSchema;\n\nexport const inboundRatePolicySchema = z\n .object({\n senderDomainSoftMax: z.number().int().positive().optional(),\n senderDomainSoftWindowSeconds: z.number().int().positive().optional(),\n senderDomainBlockMax: z.number().int().positive().optional(),\n senderDomainBlockWindowSeconds: z.number().int().positive().optional(),\n senderAddressBlockMax: z.number().int().positive().optional(),\n senderAddressBlockWindowSeconds: z.number().int().positive().optional(),\n inboxBlockMax: z.number().int().positive().optional(),\n inboxBlockWindowSeconds: z.number().int().positive().optional(),\n dedupeWindowSeconds: z.number().int().positive().optional(),\n initialBlockSeconds: z.number().int().positive().optional(),\n maxBlockSeconds: z.number().int().positive().optional(),\n })\n .partial();\n\nexport const domainConfigSchema = z.object({\n items: z.array(z.string().min(1)),\n default: z.string().nullable(),\n forcedLocalPartPrefix: z.string().nullable(),\n maxReceivedEmailsPerOrganization: z.number().int().positive(),\n maxReceivedEmailsPerAddress: z.number().int().positive(),\n});\n\nexport const organizationStatsItemSchema = z.object({\n organizationId: z.string().min(1),\n memberCount: z.number().int().nonnegative(),\n addressCount: z.number().int().nonnegative(),\n emailCount: z.number().int().nonnegative(),\n});\n\nexport const organizationStatsResponseSchema = z.object({\n items: z.array(organizationStatsItemSchema),\n});\n\nexport const emailAddressSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n localPart: z.string().min(1),\n domain: z.string().min(1),\n meta: z.unknown().optional(),\n emailCount: z.number().int().nonnegative(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.nullable(),\n createdAt: z.string().nullable(),\n createdAtMs: z.number().nullable(),\n expiresAt: z.string().nullable(),\n expiresAtMs: z.number().nullable(),\n lastReceivedAt: z.string().nullable(),\n lastReceivedAtMs: z.number().nullable(),\n});\n\nexport const createEmailAddressResponseSchema = emailAddressSchema;\n\nexport const emailAddressListResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalItems: z.number().int().nonnegative(),\n addressLimit: z.number().int().positive(),\n totalPages: z.number().int().positive(),\n sortBy: emailAddressSortBySchema,\n sortDirection: sortDirectionSchema,\n});\n\nexport const listEmailAddressesParamsSchema = z.object({\n page: z.number().int().positive().optional(),\n pageSize: z.number().int().positive().optional(),\n search: z.string().optional(),\n sortBy: emailAddressSortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const listRecentAddressActivityParamsSchema = z.object({\n limit: z.number().int().positive().optional(),\n cursor: z.string().min(1).optional(),\n search: z.string().optional(),\n sortBy: recentAddressActivitySortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const recentAddressActivityResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n nextCursor: z.string().nullable(),\n totalItems: z.number().int().nonnegative(),\n});\n\nexport const createEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1),\n ttlMinutes: z.number().int().positive().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.optional(),\n maxReceivedEmailCount: z.number().int().positive().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n acceptedRiskNotice: z.literal(true),\n});\n\nexport const updateEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1).optional(),\n ttlMinutes: z.number().int().positive().nullable().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).nullable().optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n});\n\nexport const deleteEmailAddressResponseSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailAttachmentSchema = z.object({\n id: z.string().min(1),\n filename: z.string().min(1),\n contentType: z.string().min(1),\n size: z.number().int().nonnegative(),\n disposition: z.string().nullable(),\n contentId: z.string().nullable(),\n inlinePath: z.string().min(1),\n downloadPath: z.string().min(1),\n});\n\nexport const emailListItemSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n hasHtml: z.boolean(),\n hasText: z.boolean(),\n attachmentCount: z.number().int().nonnegative(),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const emailListResponseSchema = z.object({\n address: z.string().min(1),\n addressId: z.string().min(1),\n items: z.array(emailListItemSchema),\n});\n\nexport const listEmailsParamsSchema = z.object({\n address: z.string().min(1).optional(),\n addressId: z.string().min(1).optional(),\n search: z.string().max(30).optional(),\n limit: z.number().int().positive().optional(),\n order: emailOrderSchema.optional(),\n after: z.union([z.string(), z.number()]).optional(),\n before: z.union([z.string(), z.number()]).optional(),\n});\n\nexport const emailDetailSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n address: z.string().min(1).optional(),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n headers: z.unknown(),\n html: z.string().nullable().optional(),\n text: z.string().nullable().optional(),\n raw: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n rawDownloadPath: z.string().optional(),\n attachments: z.array(emailAttachmentSchema),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const deleteEmailResponseSchema = z.object({\n id: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailActivityDaySchema = z.object({\n date: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const emailActivityResponseSchema = z.object({\n timezone: z.string().min(1),\n daily: z.array(emailActivityDaySchema),\n});\n\nexport const emailSummaryDomainSchema = z.object({\n domain: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const busiestInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const dormantInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n createdAt: z.string().nullable(),\n});\n\nexport const emailSummaryResponseSchema = z.object({\n totalEmailCount: z.number().int().nonnegative(),\n attachmentCount: z.number().int().nonnegative(),\n attachmentSizeTotal: z.number().int().nonnegative(),\n attachmentSizeLimit: z.number().int().nonnegative(),\n topDomains: z.array(emailSummaryDomainSchema),\n busiestInboxes: z.array(busiestInboxSchema),\n dormantInboxes: z.array(dormantInboxSchema),\n});\n\nexport const organizationPickerItemSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n logo: z.string().nullable().optional(),\n});\n\nexport const extensionBootstrapUserSchema = z.object({\n id: z.string().min(1),\n email: z.string().email().nullable(),\n name: z.string().nullable(),\n image: z.string().nullable(),\n emailVerified: z.boolean(),\n});\n\nexport const extensionBootstrapResponseSchema = z.object({\n user: extensionBootstrapUserSchema,\n organizations: z.array(organizationPickerItemSchema),\n defaultOrganizationId: z.string().min(1).nullable(),\n});\n\nexport type ApiError = z.infer<typeof apiErrorSchema>;\nexport type SortDirection = z.infer<typeof sortDirectionSchema>;\nexport type EmailAddressSortBy = z.infer<typeof emailAddressSortBySchema>;\nexport type RecentAddressActivitySortBy = z.infer<\n typeof recentAddressActivitySortBySchema\n>;\nexport type MaxReceivedEmailAction = z.infer<\n typeof maxReceivedEmailActionSchema\n>;\nexport type InboundRatePolicy = z.infer<typeof inboundRatePolicySchema>;\nexport type DomainConfig = z.infer<typeof domainConfigSchema>;\nexport type OrganizationStatsItem = z.infer<typeof organizationStatsItemSchema>;\nexport type OrganizationStatsResponse = z.infer<\n typeof organizationStatsResponseSchema\n>;\nexport type EmailAddress = z.infer<typeof emailAddressSchema>;\nexport type EmailAddressListResponse = z.infer<\n typeof emailAddressListResponseSchema\n>;\nexport type ListEmailAddressesParams = z.infer<\n typeof listEmailAddressesParamsSchema\n>;\nexport type ListRecentAddressActivityParams = z.infer<\n typeof listRecentAddressActivityParamsSchema\n>;\nexport type RecentAddressActivityResponse = z.infer<\n typeof recentAddressActivityResponseSchema\n>;\nexport type CreateEmailAddressRequest = z.infer<\n typeof createEmailAddressRequestSchema\n>;\nexport type CreateEmailAddressResponse = z.infer<\n typeof createEmailAddressResponseSchema\n>;\nexport type UpdateEmailAddressRequest = z.infer<\n typeof updateEmailAddressRequestSchema\n>;\nexport type DeleteEmailAddressResponse = z.infer<\n typeof deleteEmailAddressResponseSchema\n>;\nexport type EmailAttachment = z.infer<typeof emailAttachmentSchema>;\nexport type EmailListItem = z.infer<typeof emailListItemSchema>;\nexport type EmailListResponse = z.infer<typeof emailListResponseSchema>;\nexport type ListEmailsParams = z.infer<typeof listEmailsParamsSchema>;\nexport type EmailDetail = z.infer<typeof emailDetailSchema>;\nexport type DeleteEmailResponse = z.infer<typeof deleteEmailResponseSchema>;\nexport type EmailActivityDay = z.infer<typeof emailActivityDaySchema>;\nexport type EmailActivityResponse = z.infer<typeof emailActivityResponseSchema>;\nexport type EmailSummaryResponse = z.infer<typeof emailSummaryResponseSchema>;\n","export class SpinupMailError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class SpinupMailValidationError extends SpinupMailError {\n readonly source: \"request\" | \"response\";\n readonly issues: string[];\n\n constructor(args: {\n message: string;\n source: \"request\" | \"response\";\n issues?: string[];\n cause?: unknown;\n }) {\n super(args.message, args.cause ? { cause: args.cause } : undefined);\n this.source = args.source;\n this.issues = args.issues ?? [];\n }\n}\n\nexport class SpinupMailApiError extends SpinupMailError {\n readonly status: number;\n readonly response: Response;\n readonly body?: unknown;\n\n constructor(args: {\n message: string;\n status: number;\n response: Response;\n body?: unknown;\n }) {\n super(args.message);\n this.status = args.status;\n this.response = args.response;\n this.body = args.body;\n }\n}\n\nexport class SpinupMailTimeoutError extends SpinupMailError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, options?: ErrorOptions) {\n super(message, options);\n this.timeoutMs = timeoutMs;\n }\n}\n","const parseFilenameFromDisposition = (headerValue: string | null) => {\n if (!headerValue) return null;\n\n const utf8Match = headerValue.match(/filename\\*=UTF-8''([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n\n const fallbackMatch = headerValue.match(/filename=\"([^\"]+)\"/i);\n if (fallbackMatch?.[1]) return fallbackMatch[1];\n\n return null;\n};\n\nexport class SpinupMailFile {\n readonly filename: string | null;\n readonly contentType: string | null;\n readonly contentLength: number | null;\n readonly response: Response;\n\n constructor(response: Response) {\n this.response = response;\n this.filename = parseFilenameFromDisposition(\n response.headers.get(\"content-disposition\")\n );\n this.contentType = response.headers.get(\"content-type\");\n\n const contentLength = response.headers.get(\"content-length\");\n const parsed = contentLength ? Number(contentLength) : Number.NaN;\n this.contentLength = Number.isFinite(parsed) ? parsed : null;\n }\n\n arrayBuffer() {\n return this.response.clone().arrayBuffer();\n }\n\n text() {\n return this.response.clone().text();\n }\n\n blob() {\n const clone = this.response.clone() as Response & {\n blob?: () => Promise<Blob>;\n };\n\n if (typeof clone.blob !== \"function\") {\n throw new Error(\"Response.blob() is not available in this runtime.\");\n }\n\n return clone.blob();\n }\n}\n","import type { ZodType } from \"zod\";\nimport {\n apiErrorSchema,\n createEmailAddressRequestSchema,\n createEmailAddressResponseSchema,\n deleteEmailAddressResponseSchema,\n deleteEmailResponseSchema,\n domainConfigSchema,\n emailActivityResponseSchema,\n emailDetailSchema,\n emailListResponseSchema,\n emailSummaryResponseSchema,\n listEmailAddressesParamsSchema,\n listEmailsParamsSchema,\n listRecentAddressActivityParamsSchema,\n recentAddressActivityResponseSchema,\n updateEmailAddressRequestSchema,\n emailAddressListResponseSchema,\n emailAddressSchema,\n type CreateEmailAddressRequest,\n type CreateEmailAddressResponse,\n type DeleteEmailAddressResponse,\n type DeleteEmailResponse,\n type DomainConfig,\n type EmailActivityResponse,\n type EmailAddress,\n type EmailAddressListResponse,\n type EmailDetail,\n type EmailListItem,\n type EmailListResponse,\n type EmailSummaryResponse,\n type ListEmailAddressesParams,\n type ListEmailsParams,\n type ListRecentAddressActivityParams,\n type RecentAddressActivityResponse,\n type UpdateEmailAddressRequest,\n} from \"@/contracts\";\nimport {\n SpinupMailApiError,\n SpinupMailTimeoutError,\n SpinupMailValidationError,\n} from \"@/errors\";\nimport { SpinupMailFile } from \"@/file\";\n\ntype FetchLike = typeof fetch;\ntype OrganizationScopedOptions = {\n organizationId?: string;\n signal?: AbortSignal;\n};\n\ntype InboxAddressSelector = {\n address?: string;\n addressId?: string;\n};\n\nexport type CreateSpinupMailClientOptions = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/**\n * Initializes the SpinupMail SDK.\n *\n * `apiKey` defaults to `process.env.SPINUPMAIL_API_KEY`.\n * `baseUrl` defaults to `process.env.SPINUPMAIL_BASE_URL` or `https://api.spinupmail.com`.\n * `organizationId` defaults to `process.env.SPINUPMAIL_ORGANIZATION_ID` or `process.env.SPINUPMAIL_ORG_ID`.\n */\nexport type SpinupMailOptions = {\n apiKey?: string;\n baseUrl?: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/** Lists and paginates inbox addresses in the active organization. */\nexport type ListEmailAddressesOptions = ListEmailAddressesParams &\n OrganizationScopedOptions;\n\n/** Reads the recent-activity inbox feed in the active organization. */\nexport type ListRecentAddressActivityOptions =\n ListRecentAddressActivityParams & OrganizationScopedOptions;\n\n/** Fetches a single inbox address by ID. */\nexport type GetEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox creation. */\nexport type CreateEmailAddressOptions = OrganizationScopedOptions;\n\n/**\n * Creates a SpinupMail inbox.\n *\n * If `localPart` is omitted, the SDK generates a random valid local part\n * before sending the request.\n */\nexport type CreateEmailAddressInput = Omit<\n CreateEmailAddressRequest,\n \"localPart\"\n> & {\n localPart?: string;\n};\n\n/** Per-call options for inbox updates. */\nexport type UpdateEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox deletion. */\nexport type DeleteEmailAddressOptions = OrganizationScopedOptions;\n\n/** Lists emails for a single inbox, optionally filtered by received time. */\nexport type ListEmailsOptions = Omit<ListEmailsParams, \"after\" | \"before\"> &\n OrganizationScopedOptions & {\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n };\n\n/** Fetches a single stored email. */\nexport type GetEmailOptions = OrganizationScopedOptions & {\n raw?: boolean;\n};\n\n/** Deletes a single stored email. */\nexport type DeleteEmailOptions = OrganizationScopedOptions;\n\n/** Downloads the raw MIME source for an email. */\nexport type GetEmailRawOptions = OrganizationScopedOptions;\n\n/** Downloads one attachment from a stored email. */\nexport type GetEmailAttachmentOptions = OrganizationScopedOptions & {\n inline?: boolean;\n};\n\n/** Fetches organization email activity stats. */\nexport type GetEmailActivityOptions = OrganizationScopedOptions & {\n days?: number;\n timezone?: string;\n};\n\n/** Fetches organization email summary stats. */\nexport type GetEmailSummaryOptions = OrganizationScopedOptions;\n\n/** Timestamp filter accepted by inbox listing and polling helpers. */\nexport type EmailTimestampFilter = string | number | Date;\n\n/**\n * Polls an inbox until a matching email appears or the timeout is reached.\n *\n * Provide either `address` or `addressId`.\n */\nexport type InboxPollOptions = InboxAddressSelector &\n OrganizationScopedOptions & {\n search?: string;\n limit?: number;\n order?: \"asc\" | \"desc\";\n /** Case-insensitive substring match against the email subject. */\n subjectIncludes?: string;\n /** Case-insensitive substring match against the recipient address. */\n toIncludes?: string;\n /** Case-insensitive substring match against `from`, `sender`, or `senderLabel`. */\n fromIncludes?: string;\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n timeoutMs?: number;\n intervalMs?: number;\n match?: (email: EmailListItem) => boolean;\n };\n\n/**\n * Waits for a matching email and optionally filters against the fetched body.\n *\n * `bodyIncludes` and `matchDetail` are evaluated after the SDK fetches email\n * detail for candidate messages that already passed the list-level filters.\n */\nexport type WaitForEmailOptions = InboxPollOptions & {\n /** Case-insensitive substring match against the concatenated HTML and text body. */\n bodyIncludes?: string;\n /** Deletes the email after fetching the matching detail payload. */\n deleteAfterRead?: boolean;\n /** Additional predicate evaluated against the fetched email detail payload. */\n matchDetail?: (email: EmailDetail) => boolean;\n};\n\n/** Result returned by `inboxes.poll()`. */\nexport type InboxPollResult = {\n response: EmailListResponse;\n items: EmailListItem[];\n freshItems: EmailListItem[];\n matchedEmail: EmailListItem | null;\n timedOut: boolean;\n attempts: number;\n elapsedMs: number;\n polledAt: string;\n};\n\ntype ClientContext = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch: FetchLike;\n headers?: HeadersInit;\n};\n\nexport interface SpinupMailDomainsApi {\n /** Fetches configured receiving domains and retention limits. */\n get(): Promise<DomainConfig>;\n}\n\nexport interface SpinupMailAddressesApi {\n /** Lists inbox addresses in the current organization. */\n list(options?: ListEmailAddressesOptions): Promise<EmailAddressListResponse>;\n /** Fetches all inbox addresses by following all pages. */\n listAll(options?: ListEmailAddressesOptions): Promise<EmailAddress[]>;\n /** Lists inboxes ordered by recent activity using cursor pagination. */\n listRecentActivity(\n options?: ListRecentAddressActivityOptions\n ): Promise<RecentAddressActivityResponse>;\n /** Fetches a single inbox address by ID. */\n get(addressId: string, options?: GetEmailAddressOptions): Promise<EmailAddress>;\n /** Creates an inbox address in the current organization. */\n create(\n payload: CreateEmailAddressInput,\n options?: CreateEmailAddressOptions\n ): Promise<CreateEmailAddressResponse>;\n /** Updates an existing inbox address. */\n update(\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options?: UpdateEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Deletes an inbox address and its stored contents. */\n delete(\n addressId: string,\n options?: DeleteEmailAddressOptions\n ): Promise<DeleteEmailAddressResponse>;\n}\n\nexport interface SpinupMailEmailsApi {\n /** Lists emails for a single inbox. */\n list(options: ListEmailsOptions): Promise<EmailListResponse>;\n /** Fetches one parsed email including bodies and attachment metadata. */\n get(emailId: string, options?: GetEmailOptions): Promise<EmailDetail>;\n /** Deletes one stored email. */\n delete(emailId: string, options?: DeleteEmailOptions): Promise<DeleteEmailResponse>;\n /** Downloads the raw MIME source for an email. */\n getRaw(emailId: string, options?: GetEmailRawOptions): Promise<SpinupMailFile>;\n /** Downloads an attachment from an email. */\n getAttachment(\n emailId: string,\n attachmentId: string,\n options?: GetEmailAttachmentOptions\n ): Promise<SpinupMailFile>;\n}\n\nexport interface SpinupMailStatsApi {\n /** Returns daily email activity counts for the organization. */\n getEmailActivity(options?: GetEmailActivityOptions): Promise<EmailActivityResponse>;\n /** Returns aggregate storage and inbox summary stats for the organization. */\n getEmailSummary(options?: GetEmailSummaryOptions): Promise<EmailSummaryResponse>;\n}\n\nexport interface SpinupMailInboxesApi {\n /** Polls an inbox and returns the latest response plus polling metadata. */\n poll(options: InboxPollOptions): Promise<InboxPollResult>;\n /** Waits until a matching email arrives, then returns the fetched email detail. */\n waitForEmail(options: WaitForEmailOptions): Promise<EmailDetail>;\n}\n\nexport interface SpinupMailClient {\n /** Domain and retention configuration endpoints. */\n domains: SpinupMailDomainsApi;\n /** Inbox address lifecycle endpoints. */\n addresses: SpinupMailAddressesApi;\n /** Email retrieval and download endpoints. */\n emails: SpinupMailEmailsApi;\n /** Organization-level reporting endpoints. */\n stats: SpinupMailStatsApi;\n /** High-level inbox polling helpers. */\n inboxes: SpinupMailInboxesApi;\n}\n\nconst DEFAULT_LIST_ALL_PAGE_SIZE = 50;\nconst MAX_LIST_ALL_PAGES = 200;\nconst DEFAULT_WAIT_TIMEOUT_MS = 30_000;\nconst DEFAULT_POLL_INTERVAL_MS = 1_000;\nconst DEFAULT_SPINUPMAIL_BASE_URL = \"https://api.spinupmail.com\";\nconst RANDOM_LOCAL_PART_PREFIX = \"sum\";\nconst RANDOM_LOCAL_PART_SIZE = 12;\n\nconst issuePathToString = (path: PropertyKey[]) =>\n path.length === 0 ? \"<root>\" : path.map(String).join(\".\");\n\nconst formatSchemaIssues = (\n issues: Array<{ path: PropertyKey[]; message: string }>\n) => issues.map(issue => `${issuePathToString(issue.path)}: ${issue.message}`);\n\nconst validateWithSchema = <T>(\n schema: ZodType<T>,\n value: unknown,\n source: \"request\" | \"response\",\n message: string\n) => {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new SpinupMailValidationError({\n message,\n source,\n issues: formatSchemaIssues(parsed.error.issues),\n cause: parsed.error,\n });\n }\n\n return parsed.data;\n};\n\nconst normalizeString = (value: string, label: string) => {\n const normalized = value.trim();\n if (!normalized) {\n throw new SpinupMailValidationError({\n message: `${label} is required.`,\n source: \"request\",\n });\n }\n return normalized;\n};\n\nconst resolveFetch = (candidate?: FetchLike) => {\n if (candidate) return candidate;\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis) as FetchLike;\n }\n\n throw new SpinupMailValidationError({\n message: \"A fetch implementation is required in this runtime.\",\n source: \"request\",\n });\n};\n\nconst normalizeBaseUrl = (baseUrl: string) =>\n normalizeString(baseUrl, \"baseUrl\").replace(/\\/+$/, \"\");\n\nconst getProcessEnv = () => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env === \"object\" &&\n process.env !== null\n ) {\n return process.env;\n }\n\n return undefined;\n};\n\nconst readEnvValue = (keys: string[]) => {\n const env = getProcessEnv();\n if (!env) return undefined;\n\n for (const key of keys) {\n const value = env[key]?.trim();\n if (value) return value;\n }\n\n return undefined;\n};\n\nconst createRandomBytes = (size: number) => {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n return crypto.getRandomValues(new Uint8Array(size));\n }\n\n return Uint8Array.from(\n Array.from({ length: size }, () => Math.floor(Math.random() * 256))\n );\n};\n\nconst generateRandomLocalPart = () => {\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const bytes = createRandomBytes(RANDOM_LOCAL_PART_SIZE);\n let suffix = \"\";\n\n for (const byte of bytes) {\n suffix += alphabet[byte % alphabet.length];\n }\n\n return `${RANDOM_LOCAL_PART_PREFIX}-${suffix}`;\n};\n\nconst resolveOrganizationId = (\n context: ClientContext,\n organizationId: string | undefined,\n orgScoped: boolean\n) => {\n if (!orgScoped) return undefined;\n\n const resolved = organizationId ?? context.organizationId;\n if (!resolved?.trim()) {\n throw new SpinupMailValidationError({\n message:\n \"organizationId is required for this SpinupMail API method when using API keys.\",\n source: \"request\",\n });\n }\n\n return resolved.trim();\n};\n\nconst normalizeTimestamp = (value: EmailTimestampFilter | undefined) => {\n if (value === undefined) return undefined;\n if (value instanceof Date) return value.toISOString();\n return typeof value === \"number\" ? String(value) : value;\n};\n\nconst normalizeText = (value: string | null | undefined) =>\n (value ?? \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n\nconst matchesText = (\n value: string | null | undefined,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return normalizeText(value).includes(normalizeText(expected));\n};\n\nconst matchesAnyText = (\n values: Array<string | null | undefined>,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return values.some(value => matchesText(value, expected));\n};\n\nconst createQueryString = (\n values: Record<string, string | number | boolean | undefined>\n) => {\n const query = new URLSearchParams();\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) continue;\n query.set(key, String(value));\n }\n\n const serialized = query.toString();\n return serialized.length > 0 ? `?${serialized}` : \"\";\n};\n\nconst parseErrorPayload = async (response: Response) => {\n try {\n const payload = await response.clone().json();\n const parsed = apiErrorSchema.safeParse(payload);\n if (parsed.success) return parsed.data;\n return payload;\n } catch {\n const text = await response.clone().text();\n return text ? { error: text } : undefined;\n }\n};\n\nconst requestJson = async <T>(\n context: ClientContext,\n options: {\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n responseSchema: ZodType<T>;\n body?: unknown;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n headers.set(\"accept\", \"application/json\");\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n let body: BodyInit | undefined;\n if (options.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n body = JSON.stringify(options.body);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: options.method ?? \"GET\",\n headers,\n body,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n let payload: unknown;\n try {\n payload = await response.json();\n } catch (error) {\n throw new SpinupMailValidationError({\n message: \"SpinupMail returned a non-JSON success response.\",\n source: \"response\",\n cause: error,\n });\n }\n\n return validateWithSchema(\n options.responseSchema,\n payload,\n \"response\",\n \"SpinupMail returned an unexpected response shape.\"\n );\n};\n\nconst requestBinary = async (\n context: ClientContext,\n options: {\n path: string;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: \"GET\",\n headers,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n return new SpinupMailFile(response);\n};\n\nconst ensureInboxSelector = (options: InboxAddressSelector) => {\n if (!options.address && !options.addressId) {\n throw new SpinupMailValidationError({\n message: \"Either address or addressId is required.\",\n source: \"request\",\n });\n }\n};\n\nconst validateListEmailsOptions = (options: ListEmailsOptions) => {\n ensureInboxSelector(options);\n validateWithSchema(\n listEmailsParamsSchema,\n {\n ...options,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n },\n \"request\",\n \"Invalid listEmails options.\"\n );\n\n if (\n options.search &&\n (options.after !== undefined ||\n options.before !== undefined ||\n options.order === \"asc\")\n ) {\n throw new SpinupMailValidationError({\n message:\n \"search does not support after, before, or order='asc' parameters.\",\n source: \"request\",\n });\n }\n};\n\nconst matchesListItemFilters = (\n item: EmailListItem,\n options: InboxPollOptions\n) => {\n if (!matchesText(item.subject, options.subjectIncludes)) return false;\n if (!matchesText(item.to, options.toIncludes)) return false;\n if (\n !matchesAnyText(\n [item.from, item.sender, item.senderLabel],\n options.fromIncludes\n )\n ) {\n return false;\n }\n\n return options.match ? options.match(item) : true;\n};\n\nconst matchesDetailFilters = (detail: EmailDetail, options: WaitForEmailOptions) => {\n const bodyText = `${detail.html ?? \"\"}\\n${detail.text ?? \"\"}`;\n\n if (!matchesText(bodyText, options.bodyIncludes)) return false;\n return options.matchDetail ? options.matchDetail(detail) : true;\n};\n\nconst sleep = (ms: number, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"The operation was aborted.\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n cleanup();\n reject(signal?.reason ?? new Error(\"The operation was aborted.\"));\n };\n\n const cleanup = () => {\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\nconst runPollingLoop = async (\n emails: {\n list: (options: ListEmailsOptions) => Promise<EmailListResponse>;\n },\n options: InboxPollOptions,\n args: {\n timeoutMs: number;\n throwOnTimeout: boolean;\n }\n): Promise<InboxPollResult> => {\n ensureInboxSelector(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n const startedAt = Date.now();\n const deadline =\n args.timeoutMs > 0 ? startedAt + args.timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n let attempts = 0;\n let lastResponse!: EmailListResponse;\n let lastFreshItems!: EmailListItem[];\n\n while (true) {\n attempts += 1;\n\n lastResponse = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n lastFreshItems = lastResponse.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return true;\n });\n\n const matchedEmail =\n lastFreshItems.find(item => matchesListItemFilters(item, options)) ?? null;\n if (matchedEmail) {\n return {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail,\n timedOut: false,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n }\n\n if (args.timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n const result: InboxPollResult = {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail: null,\n timedOut: args.timeoutMs > 0,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n\n if (args.throwOnTimeout) {\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${args.timeoutMs}ms timeout elapsed.`,\n args.timeoutMs\n );\n }\n\n return result;\n};\n\nconst waitForEmailDetail = async (\n emails: Pick<SpinupMailEmailsApi, \"list\" | \"get\" | \"delete\">,\n options: WaitForEmailOptions\n) => {\n ensureInboxSelector(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const deadline =\n timeoutMs > 0 ? startedAt + timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n\n while (true) {\n const response = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const freshCandidates = response.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return matchesListItemFilters(item, options);\n });\n\n for (const item of freshCandidates) {\n const detail = await emails.get(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n if (!matchesDetailFilters(detail, options)) {\n continue;\n }\n\n if (options.deleteAfterRead) {\n await emails.delete(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n }\n\n return detail;\n }\n\n if (timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${timeoutMs}ms timeout elapsed.`,\n timeoutMs\n );\n};\n\nconst createSpinupMailClient = (\n options: CreateSpinupMailClientOptions\n): SpinupMailClient => {\n const context: ClientContext = {\n baseUrl: normalizeBaseUrl(options.baseUrl),\n apiKey: normalizeString(options.apiKey, \"apiKey\"),\n organizationId: options.organizationId?.trim() || undefined,\n fetch: resolveFetch(options.fetch),\n headers: options.headers,\n };\n\n const addresses: SpinupMailAddressesApi = {\n list: async (options: ListEmailAddressesOptions = {}) => {\n const validated = validateWithSchema(\n listEmailAddressesParamsSchema,\n options,\n \"request\",\n \"Invalid listEmailAddresses options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses${createQueryString({\n page: validated.page,\n pageSize: validated.pageSize,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: emailAddressListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n listAll: async (options: ListEmailAddressesOptions = {}) => {\n const items: EmailAddress[] = [];\n let page = 1;\n let totalPages = 1;\n\n while (page <= totalPages) {\n if (page > MAX_LIST_ALL_PAGES) {\n throw new SpinupMailValidationError({\n message: `Address pagination exceeded the safety limit of ${MAX_LIST_ALL_PAGES} pages.`,\n source: \"request\",\n });\n }\n\n const response = await addresses.list({\n ...options,\n page,\n pageSize: options.pageSize ?? DEFAULT_LIST_ALL_PAGE_SIZE,\n });\n\n items.push(...response.items);\n totalPages = response.totalPages;\n page += 1;\n }\n\n return items;\n },\n listRecentActivity: async (\n options: ListRecentAddressActivityOptions = {}\n ) => {\n const validated = validateWithSchema(\n listRecentAddressActivityParamsSchema,\n options,\n \"request\",\n \"Invalid listRecentAddressActivity options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses/recent-activity${createQueryString({\n limit: validated.limit,\n cursor: validated.cursor,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: recentAddressActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (addressId: string, options: GetEmailAddressOptions = {}) =>\n requestJson(context, {\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n create: (\n payload: CreateEmailAddressInput,\n options: CreateEmailAddressOptions = {}\n ) => {\n const requestPayload = validateWithSchema(\n createEmailAddressRequestSchema,\n {\n ...payload,\n localPart: payload.localPart?.trim() || generateRandomLocalPart(),\n },\n \"request\",\n \"Invalid createEmailAddress payload.\"\n );\n\n return requestJson(context, {\n method: \"POST\",\n path: \"/api/email-addresses\",\n responseSchema: createEmailAddressResponseSchema,\n body: requestPayload,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n update: (\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options: UpdateEmailAddressOptions = {}\n ) =>\n requestJson(context, {\n method: \"PATCH\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n body: validateWithSchema(\n updateEmailAddressRequestSchema,\n payload,\n \"request\",\n \"Invalid updateEmailAddress payload.\"\n ),\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (addressId: string, options: DeleteEmailAddressOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: deleteEmailAddressResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const emails: SpinupMailEmailsApi = {\n list: async (options: ListEmailsOptions) => {\n validateListEmailsOptions(options);\n\n return requestJson(context, {\n path: `/api/emails${createQueryString({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n })}`,\n responseSchema: emailListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (emailId: string, options: GetEmailOptions = {}) =>\n requestJson(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}${createQueryString({ raw: options.raw ? 1 : undefined })}`,\n responseSchema: emailDetailSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (emailId: string, options: DeleteEmailOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}`,\n responseSchema: deleteEmailResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getRaw: (emailId: string, options: GetEmailRawOptions = {}) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/raw`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getAttachment: (\n emailId: string,\n attachmentId: string,\n options: GetEmailAttachmentOptions = {}\n ) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/attachments/${encodeURIComponent(\n normalizeString(attachmentId, \"attachmentId\")\n )}${createQueryString({ inline: options.inline ? 1 : undefined })}`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const stats: SpinupMailStatsApi = {\n getEmailActivity: (options: GetEmailActivityOptions = {}) =>\n requestJson(context, {\n path: `/api/organizations/stats/email-activity${createQueryString({\n days: options.days,\n timezone: options.timezone,\n })}`,\n responseSchema: emailActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getEmailSummary: (options: GetEmailSummaryOptions = {}) =>\n requestJson(context, {\n path: \"/api/organizations/stats/email-summary\",\n responseSchema: emailSummaryResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const inboxes: SpinupMailInboxesApi = {\n poll: (options: InboxPollOptions) =>\n runPollingLoop(emails, options, {\n timeoutMs: options.timeoutMs ?? 0,\n throwOnTimeout: false,\n }),\n waitForEmail: (options: WaitForEmailOptions) =>\n waitForEmailDetail(emails, options),\n };\n\n return {\n domains: {\n get: () =>\n requestJson(context, {\n path: \"/api/domains\",\n responseSchema: domainConfigSchema,\n }),\n } satisfies SpinupMailDomainsApi,\n addresses,\n emails,\n stats,\n inboxes,\n };\n};\n\n/**\n * API-key SDK for SpinupMail.\n *\n * Typical usage:\n *\n * ```ts\n * const spinupmail = new SpinupMail();\n * const address = await spinupmail.addresses.create({ acceptedRiskNotice: true });\n * const email = await spinupmail.inboxes.waitForEmail({ addressId: address.id });\n * ```\n */\nexport class SpinupMail {\n readonly domains: SpinupMailClient[\"domains\"];\n readonly addresses: SpinupMailClient[\"addresses\"];\n readonly emails: SpinupMailClient[\"emails\"];\n readonly stats: SpinupMailClient[\"stats\"];\n readonly inboxes: SpinupMailClient[\"inboxes\"];\n\n /** Creates a new SDK client using constructor options or environment defaults. */\n constructor(options: string | SpinupMailOptions = {}) {\n const resolvedOptions =\n typeof options === \"string\" ? { apiKey: options } : options;\n const apiKey =\n resolvedOptions.apiKey ?? readEnvValue([\"SPINUPMAIL_API_KEY\"]);\n const baseUrl =\n resolvedOptions.baseUrl ??\n readEnvValue([\"SPINUPMAIL_BASE_URL\"]) ??\n DEFAULT_SPINUPMAIL_BASE_URL;\n const organizationId =\n resolvedOptions.organizationId ??\n readEnvValue([\n \"SPINUPMAIL_ORGANIZATION_ID\",\n \"SPINUPMAIL_ORG_ID\",\n ]);\n\n const client = createSpinupMailClient({\n baseUrl,\n apiKey: normalizeString(apiKey ?? \"\", \"apiKey\"),\n organizationId,\n fetch: resolvedOptions.fetch,\n headers: resolvedOptions.headers,\n });\n\n this.domains = client.domains;\n this.addresses = client.addresses;\n this.emails = client.emails;\n this.stats = client.stats;\n this.inboxes = client.inboxes;\n }\n}\nexport type {\n CreateEmailAddressRequest,\n CreateEmailAddressResponse,\n DeleteEmailAddressResponse,\n DeleteEmailResponse,\n DomainConfig,\n EmailActivityResponse,\n EmailAddress,\n EmailAddressListResponse,\n EmailDetail,\n EmailListItem,\n EmailListResponse,\n EmailSummaryResponse,\n ListEmailAddressesParams,\n ListEmailsParams,\n ListRecentAddressActivityParams,\n RecentAddressActivityResponse,\n UpdateEmailAddressRequest,\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../../contracts/src/index.ts","../src/errors.ts","../src/file.ts","../src/client.ts"],"sourcesContent":["import { z } from \"zod\";\n\nexport const apiErrorSchema = z.object({\n error: z.string().min(1),\n details: z.string().min(1).optional(),\n});\n\nexport const sortDirectionSchema = z.enum([\"asc\", \"desc\"]);\nexport const emailAddressSortBySchema = z.enum([\n \"createdAt\",\n \"address\",\n \"lastReceivedAt\",\n]);\nexport const recentAddressActivitySortBySchema = z.enum([\n \"recentActivity\",\n \"createdAt\",\n]);\nexport const maxReceivedEmailActionSchema = z.enum([\"cleanAll\", \"rejectNew\"]);\nexport const emailOrderSchema = sortDirectionSchema;\n\nexport const inboundRatePolicySchema = z\n .object({\n senderDomainSoftMax: z.number().int().positive().optional(),\n senderDomainSoftWindowSeconds: z.number().int().positive().optional(),\n senderDomainBlockMax: z.number().int().positive().optional(),\n senderDomainBlockWindowSeconds: z.number().int().positive().optional(),\n senderAddressBlockMax: z.number().int().positive().optional(),\n senderAddressBlockWindowSeconds: z.number().int().positive().optional(),\n inboxBlockMax: z.number().int().positive().optional(),\n inboxBlockWindowSeconds: z.number().int().positive().optional(),\n dedupeWindowSeconds: z.number().int().positive().optional(),\n initialBlockSeconds: z.number().int().positive().optional(),\n maxBlockSeconds: z.number().int().positive().optional(),\n })\n .partial();\n\nexport const domainConfigSchema = z.object({\n items: z.array(z.string().min(1)),\n default: z.string().nullable(),\n forcedLocalPartPrefix: z.string().nullable(),\n maxReceivedEmailsPerOrganization: z.number().int().positive(),\n maxReceivedEmailsPerAddress: z.number().int().positive(),\n});\n\nexport const organizationStatsItemSchema = z.object({\n organizationId: z.string().min(1),\n memberCount: z.number().int().nonnegative(),\n addressCount: z.number().int().nonnegative(),\n emailCount: z.number().int().nonnegative(),\n});\n\nexport const organizationStatsResponseSchema = z.object({\n items: z.array(organizationStatsItemSchema),\n});\n\nexport const emailAddressSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n localPart: z.string().min(1),\n domain: z.string().min(1),\n meta: z.unknown().optional(),\n emailCount: z.number().int().nonnegative(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.nullable(),\n createdAt: z.string().nullable(),\n createdAtMs: z.number().nullable(),\n expiresAt: z.string().nullable(),\n expiresAtMs: z.number().nullable(),\n lastReceivedAt: z.string().nullable(),\n lastReceivedAtMs: z.number().nullable(),\n});\n\nexport const createEmailAddressResponseSchema = emailAddressSchema;\n\nexport const emailAddressListResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n page: z.number().int().positive(),\n pageSize: z.number().int().positive(),\n totalItems: z.number().int().nonnegative(),\n addressLimit: z.number().int().positive(),\n totalPages: z.number().int().positive(),\n sortBy: emailAddressSortBySchema,\n sortDirection: sortDirectionSchema,\n});\n\nexport const listEmailAddressesParamsSchema = z.object({\n page: z.number().int().positive().optional(),\n pageSize: z.number().int().positive().optional(),\n search: z.string().optional(),\n sortBy: emailAddressSortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const listRecentAddressActivityParamsSchema = z.object({\n limit: z.number().int().positive().optional(),\n cursor: z.string().min(1).optional(),\n search: z.string().optional(),\n sortBy: recentAddressActivitySortBySchema.optional(),\n sortDirection: sortDirectionSchema.optional(),\n});\n\nexport const recentAddressActivityResponseSchema = z.object({\n items: z.array(emailAddressSchema),\n nextCursor: z.string().nullable(),\n totalItems: z.number().int().nonnegative(),\n});\n\nexport const createEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1),\n ttlMinutes: z.number().int().positive().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).optional(),\n inboundRatePolicy: inboundRatePolicySchema.optional(),\n maxReceivedEmailCount: z.number().int().positive().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n acceptedRiskNotice: z.literal(true),\n});\n\nexport const updateEmailAddressRequestSchema = z.object({\n localPart: z.string().min(1).optional(),\n ttlMinutes: z.number().int().positive().nullable().optional(),\n meta: z.unknown().optional(),\n domain: z.string().min(1).optional(),\n allowedFromDomains: z.array(z.string().min(1)).optional(),\n blockedSenderDomains: z.array(z.string().min(1)).nullable().optional(),\n inboundRatePolicy: inboundRatePolicySchema.nullable().optional(),\n maxReceivedEmailCount: z.number().int().positive().nullable().optional(),\n maxReceivedEmailAction: maxReceivedEmailActionSchema.optional(),\n});\n\nexport const deleteEmailAddressResponseSchema = z.object({\n id: z.string().min(1),\n address: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailAttachmentSchema = z.object({\n id: z.string().min(1),\n filename: z.string().min(1),\n contentType: z.string().min(1),\n size: z.number().int().nonnegative(),\n disposition: z.string().nullable(),\n contentId: z.string().nullable(),\n inlinePath: z.string().min(1),\n downloadPath: z.string().min(1),\n});\n\nexport const emailListItemSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n hasHtml: z.boolean(),\n hasText: z.boolean(),\n attachmentCount: z.number().int().nonnegative(),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const emailListResponseSchema = z.object({\n address: z.string().min(1),\n addressId: z.string().min(1),\n items: z.array(emailListItemSchema),\n});\n\nexport const listEmailsParamsSchema = z.object({\n address: z.string().min(1).optional(),\n addressId: z.string().min(1).optional(),\n search: z.string().max(30).optional(),\n limit: z.number().int().positive().optional(),\n order: emailOrderSchema.optional(),\n after: z.union([z.string(), z.number()]).optional(),\n before: z.union([z.string(), z.number()]).optional(),\n});\n\nexport const emailDetailSchema = z.object({\n id: z.string().min(1),\n addressId: z.string().min(1),\n address: z.string().min(1).optional(),\n to: z.string().min(1),\n from: z.string().min(1),\n sender: z.string().nullable().optional(),\n senderLabel: z.string().min(1),\n subject: z.string().nullable().optional(),\n messageId: z.string().nullable().optional(),\n headers: z.unknown(),\n html: z.string().nullable().optional(),\n text: z.string().nullable().optional(),\n raw: z.string().nullable().optional(),\n rawSize: z.number().nullable().optional(),\n rawTruncated: z.boolean(),\n isSample: z.boolean(),\n rawDownloadPath: z.string().optional(),\n attachments: z.array(emailAttachmentSchema),\n receivedAt: z.string().nullable(),\n receivedAtMs: z.number().nullable(),\n});\n\nexport const deleteEmailResponseSchema = z.object({\n id: z.string().min(1),\n deleted: z.literal(true),\n});\n\nexport const emailActivityDaySchema = z.object({\n date: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const emailActivityResponseSchema = z.object({\n timezone: z.string().min(1),\n daily: z.array(emailActivityDaySchema),\n});\n\nexport const emailSummaryDomainSchema = z.object({\n domain: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const busiestInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n count: z.number().int().nonnegative(),\n});\n\nexport const dormantInboxSchema = z.object({\n addressId: z.string().min(1),\n address: z.string().min(1),\n createdAt: z.string().nullable(),\n});\n\nexport const emailSummaryResponseSchema = z.object({\n totalEmailCount: z.number().int().nonnegative(),\n attachmentCount: z.number().int().nonnegative(),\n attachmentSizeTotal: z.number().int().nonnegative(),\n attachmentSizeLimit: z.number().int().nonnegative(),\n topDomains: z.array(emailSummaryDomainSchema),\n busiestInboxes: z.array(busiestInboxSchema),\n dormantInboxes: z.array(dormantInboxSchema),\n});\n\nexport const organizationPickerItemSchema = z.object({\n id: z.string().min(1),\n name: z.string().min(1),\n slug: z.string().min(1),\n logo: z.string().nullable().optional(),\n});\n\nexport const extensionBootstrapUserSchema = z.object({\n id: z.string().min(1),\n email: z.string().email().nullable(),\n name: z.string().nullable(),\n image: z.string().nullable(),\n emailVerified: z.boolean(),\n});\n\nexport const extensionBootstrapResponseSchema = z.object({\n user: extensionBootstrapUserSchema,\n organizations: z.array(organizationPickerItemSchema),\n defaultOrganizationId: z.string().min(1).nullable(),\n});\n\nexport type ApiError = z.infer<typeof apiErrorSchema>;\nexport type SortDirection = z.infer<typeof sortDirectionSchema>;\nexport type EmailAddressSortBy = z.infer<typeof emailAddressSortBySchema>;\nexport type RecentAddressActivitySortBy = z.infer<\n typeof recentAddressActivitySortBySchema\n>;\nexport type MaxReceivedEmailAction = z.infer<\n typeof maxReceivedEmailActionSchema\n>;\nexport type InboundRatePolicy = z.infer<typeof inboundRatePolicySchema>;\nexport type DomainConfig = z.infer<typeof domainConfigSchema>;\nexport type OrganizationStatsItem = z.infer<typeof organizationStatsItemSchema>;\nexport type OrganizationStatsResponse = z.infer<\n typeof organizationStatsResponseSchema\n>;\nexport type EmailAddress = z.infer<typeof emailAddressSchema>;\nexport type EmailAddressListResponse = z.infer<\n typeof emailAddressListResponseSchema\n>;\nexport type ListEmailAddressesParams = z.infer<\n typeof listEmailAddressesParamsSchema\n>;\nexport type ListRecentAddressActivityParams = z.infer<\n typeof listRecentAddressActivityParamsSchema\n>;\nexport type RecentAddressActivityResponse = z.infer<\n typeof recentAddressActivityResponseSchema\n>;\nexport type CreateEmailAddressRequest = z.infer<\n typeof createEmailAddressRequestSchema\n>;\nexport type CreateEmailAddressResponse = z.infer<\n typeof createEmailAddressResponseSchema\n>;\nexport type UpdateEmailAddressRequest = z.infer<\n typeof updateEmailAddressRequestSchema\n>;\nexport type DeleteEmailAddressResponse = z.infer<\n typeof deleteEmailAddressResponseSchema\n>;\nexport type EmailAttachment = z.infer<typeof emailAttachmentSchema>;\nexport type EmailListItem = z.infer<typeof emailListItemSchema>;\nexport type EmailListResponse = z.infer<typeof emailListResponseSchema>;\nexport type ListEmailsParams = z.infer<typeof listEmailsParamsSchema>;\nexport type EmailDetail = z.infer<typeof emailDetailSchema>;\nexport type DeleteEmailResponse = z.infer<typeof deleteEmailResponseSchema>;\nexport type EmailActivityDay = z.infer<typeof emailActivityDaySchema>;\nexport type EmailActivityResponse = z.infer<typeof emailActivityResponseSchema>;\nexport type EmailSummaryDomain = z.infer<typeof emailSummaryDomainSchema>;\nexport type BusiestInbox = z.infer<typeof busiestInboxSchema>;\nexport type DormantInbox = z.infer<typeof dormantInboxSchema>;\nexport type EmailSummaryResponse = z.infer<typeof emailSummaryResponseSchema>;\nexport type OrganizationPickerItem = z.infer<\n typeof organizationPickerItemSchema\n>;\nexport type ExtensionBootstrapUser = z.infer<\n typeof extensionBootstrapUserSchema\n>;\nexport type ExtensionBootstrapResponse = z.infer<\n typeof extensionBootstrapResponseSchema\n>;\n","export class SpinupMailError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = new.target.name;\n }\n}\n\nexport class SpinupMailValidationError extends SpinupMailError {\n readonly source: \"request\" | \"response\";\n readonly issues: string[];\n\n constructor(args: {\n message: string;\n source: \"request\" | \"response\";\n issues?: string[];\n cause?: unknown;\n }) {\n super(args.message, args.cause ? { cause: args.cause } : undefined);\n this.source = args.source;\n this.issues = args.issues ?? [];\n }\n}\n\nexport class SpinupMailApiError extends SpinupMailError {\n readonly status: number;\n readonly response: Response;\n readonly body?: unknown;\n\n constructor(args: {\n message: string;\n status: number;\n response: Response;\n body?: unknown;\n }) {\n super(args.message);\n this.status = args.status;\n this.response = args.response;\n this.body = args.body;\n }\n}\n\nexport class SpinupMailTimeoutError extends SpinupMailError {\n readonly timeoutMs: number;\n\n constructor(message: string, timeoutMs: number, options?: ErrorOptions) {\n super(message, options);\n this.timeoutMs = timeoutMs;\n }\n}\n","const parseFilenameFromDisposition = (headerValue: string | null) => {\n if (!headerValue) return null;\n\n const utf8Match = headerValue.match(/filename\\*=[^']*'[^']*'([^;]+)/i);\n if (utf8Match?.[1]) {\n try {\n return decodeURIComponent(utf8Match[1]);\n } catch {\n return utf8Match[1];\n }\n }\n\n const fallbackMatch = headerValue.match(/filename=\"([^\"]+)\"/i);\n if (fallbackMatch?.[1]) return fallbackMatch[1];\n\n const unquotedMatch = headerValue.match(/filename=([^;\"]+)/i);\n if (unquotedMatch?.[1]) return unquotedMatch[1].trim();\n\n return null;\n};\n\nexport class SpinupMailFile {\n readonly filename: string | null;\n readonly contentType: string | null;\n readonly contentLength: number | null;\n readonly response: Response;\n\n constructor(response: Response) {\n this.response = response;\n this.filename = parseFilenameFromDisposition(\n response.headers.get(\"content-disposition\")\n );\n this.contentType = response.headers.get(\"content-type\");\n\n const contentLength = response.headers.get(\"content-length\");\n const parsed = contentLength ? Number(contentLength) : Number.NaN;\n this.contentLength =\n Number.isInteger(parsed) && parsed >= 0 ? parsed : null;\n }\n\n arrayBuffer() {\n return this.response.clone().arrayBuffer();\n }\n\n text() {\n return this.response.clone().text();\n }\n\n blob() {\n const clone = this.response.clone() as Response & {\n blob?: () => Promise<Blob>;\n };\n\n if (typeof clone.blob !== \"function\") {\n throw new Error(\"Response.blob() is not available in this runtime.\");\n }\n\n return clone.blob();\n }\n}\n","import type { ZodType } from \"zod\";\nimport {\n apiErrorSchema,\n createEmailAddressRequestSchema,\n createEmailAddressResponseSchema,\n deleteEmailAddressResponseSchema,\n deleteEmailResponseSchema,\n domainConfigSchema,\n emailActivityResponseSchema,\n emailDetailSchema,\n emailListResponseSchema,\n emailSummaryResponseSchema,\n listEmailAddressesParamsSchema,\n listEmailsParamsSchema,\n listRecentAddressActivityParamsSchema,\n recentAddressActivityResponseSchema,\n updateEmailAddressRequestSchema,\n emailAddressListResponseSchema,\n emailAddressSchema,\n type CreateEmailAddressRequest,\n type CreateEmailAddressResponse,\n type DeleteEmailAddressResponse,\n type DeleteEmailResponse,\n type DomainConfig,\n type EmailActivityResponse,\n type EmailAddress,\n type EmailAddressListResponse,\n type EmailDetail,\n type EmailListItem,\n type EmailListResponse,\n type EmailSummaryResponse,\n type ListEmailAddressesParams,\n type ListEmailsParams,\n type ListRecentAddressActivityParams,\n type RecentAddressActivityResponse,\n type UpdateEmailAddressRequest,\n} from \"@/contracts\";\nimport {\n SpinupMailApiError,\n SpinupMailTimeoutError,\n SpinupMailValidationError,\n} from \"@/errors\";\nimport { SpinupMailFile } from \"@/file\";\n\ntype FetchLike = typeof fetch;\ntype OrganizationScopedOptions = {\n organizationId?: string;\n signal?: AbortSignal;\n};\n\ntype InboxAddressSelector = {\n address?: string;\n addressId?: string;\n};\n\nexport type CreateSpinupMailClientOptions = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/**\n * Initializes the SpinupMail SDK.\n *\n * `apiKey` defaults to `process.env.SPINUPMAIL_API_KEY`.\n * `baseUrl` defaults to `process.env.SPINUPMAIL_BASE_URL` or `https://api.spinupmail.com`.\n * `organizationId` defaults to `process.env.SPINUPMAIL_ORGANIZATION_ID` or `process.env.SPINUPMAIL_ORG_ID`.\n */\nexport type SpinupMailOptions = {\n apiKey?: string;\n baseUrl?: string;\n organizationId?: string;\n fetch?: FetchLike;\n headers?: HeadersInit;\n};\n\n/** Lists and paginates inbox addresses in the active organization. */\nexport type ListEmailAddressesOptions = ListEmailAddressesParams &\n OrganizationScopedOptions;\n\n/** Reads the recent-activity inbox feed in the active organization. */\nexport type ListRecentAddressActivityOptions = ListRecentAddressActivityParams &\n OrganizationScopedOptions;\n\n/** Fetches a single inbox address by ID. */\nexport type GetEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox creation. */\nexport type CreateEmailAddressOptions = OrganizationScopedOptions;\n\n/**\n * Creates a SpinupMail inbox.\n *\n * If `localPart` is omitted, the SDK generates a random valid local part\n * before sending the request.\n */\nexport type CreateEmailAddressInput = Omit<\n CreateEmailAddressRequest,\n \"localPart\"\n> & {\n localPart?: string;\n};\n\n/** Per-call options for inbox updates. */\nexport type UpdateEmailAddressOptions = OrganizationScopedOptions;\n\n/** Per-call options for inbox deletion. */\nexport type DeleteEmailAddressOptions = OrganizationScopedOptions;\n\n/** Lists emails for a single inbox, optionally filtered by received time. */\nexport type ListEmailsOptions = Omit<ListEmailsParams, \"after\" | \"before\"> &\n OrganizationScopedOptions & {\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n };\n\n/** Fetches a single stored email. */\nexport type GetEmailOptions = OrganizationScopedOptions & {\n raw?: boolean;\n};\n\n/** Deletes a single stored email. */\nexport type DeleteEmailOptions = OrganizationScopedOptions;\n\n/** Downloads the raw MIME source for an email. */\nexport type GetEmailRawOptions = OrganizationScopedOptions;\n\n/** Downloads one attachment from a stored email. */\nexport type GetEmailAttachmentOptions = OrganizationScopedOptions & {\n inline?: boolean;\n};\n\n/** Fetches organization email activity stats. */\nexport type GetEmailActivityOptions = OrganizationScopedOptions & {\n days?: number;\n timezone?: string;\n};\n\n/** Fetches organization email summary stats. */\nexport type GetEmailSummaryOptions = OrganizationScopedOptions;\n\n/** Timestamp filter accepted by inbox listing and polling helpers. */\nexport type EmailTimestampFilter = string | number | Date;\n\n/**\n * Polls an inbox until a matching email appears or the timeout is reached.\n *\n * Provide either `address` or `addressId`.\n */\nexport type InboxPollOptions = InboxAddressSelector &\n OrganizationScopedOptions & {\n search?: string;\n limit?: number;\n order?: \"asc\" | \"desc\";\n /** Case-insensitive substring match against the email subject. */\n subjectIncludes?: string;\n /** Case-insensitive substring match against the recipient address. */\n toIncludes?: string;\n /** Case-insensitive substring match against `from`, `sender`, or `senderLabel`. */\n fromIncludes?: string;\n /** Only include emails received after this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n after?: EmailTimestampFilter;\n /** Only include emails received before this timestamp. Accepts ISO strings, epoch milliseconds, or `Date`. */\n before?: EmailTimestampFilter;\n timeoutMs?: number;\n intervalMs?: number;\n match?: (email: EmailListItem) => boolean;\n };\n\n/**\n * Waits for a matching email and optionally filters against the fetched body.\n *\n * `bodyIncludes` and `matchDetail` are evaluated after the SDK fetches email\n * detail for candidate messages that already passed the list-level filters.\n */\nexport type WaitForEmailOptions = InboxPollOptions & {\n /** Case-insensitive substring match against the concatenated HTML and text body. */\n bodyIncludes?: string;\n /** Deletes the email after fetching the matching detail payload. */\n deleteAfterRead?: boolean;\n /** Additional predicate evaluated against the fetched email detail payload. */\n matchDetail?: (email: EmailDetail) => boolean;\n};\n\n/** Result returned by `inboxes.poll()`. */\nexport type InboxPollResult = {\n response: EmailListResponse;\n items: EmailListItem[];\n freshItems: EmailListItem[];\n matchedEmail: EmailListItem | null;\n timedOut: boolean;\n attempts: number;\n elapsedMs: number;\n polledAt: string;\n};\n\ntype ClientContext = {\n baseUrl: string;\n apiKey: string;\n organizationId?: string;\n fetch: FetchLike;\n headers?: HeadersInit;\n};\n\nexport interface SpinupMailDomainsApi {\n /** Fetches configured receiving domains and retention limits. */\n get(): Promise<DomainConfig>;\n}\n\nexport interface SpinupMailAddressesApi {\n /** Lists inbox addresses in the current organization. */\n list(options?: ListEmailAddressesOptions): Promise<EmailAddressListResponse>;\n /** Fetches all inbox addresses by following all pages. */\n listAll(options?: ListEmailAddressesOptions): Promise<EmailAddress[]>;\n /** Lists inboxes ordered by recent activity using cursor pagination. */\n listRecentActivity(\n options?: ListRecentAddressActivityOptions\n ): Promise<RecentAddressActivityResponse>;\n /** Fetches a single inbox address by ID. */\n get(\n addressId: string,\n options?: GetEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Creates an inbox address in the current organization. */\n create(\n payload: CreateEmailAddressInput,\n options?: CreateEmailAddressOptions\n ): Promise<CreateEmailAddressResponse>;\n /** Updates an existing inbox address. */\n update(\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options?: UpdateEmailAddressOptions\n ): Promise<EmailAddress>;\n /** Deletes an inbox address and its stored contents. */\n delete(\n addressId: string,\n options?: DeleteEmailAddressOptions\n ): Promise<DeleteEmailAddressResponse>;\n}\n\nexport interface SpinupMailEmailsApi {\n /** Lists emails for a single inbox. */\n list(options: ListEmailsOptions): Promise<EmailListResponse>;\n /** Fetches one parsed email including bodies and attachment metadata. */\n get(emailId: string, options?: GetEmailOptions): Promise<EmailDetail>;\n /** Deletes one stored email. */\n delete(\n emailId: string,\n options?: DeleteEmailOptions\n ): Promise<DeleteEmailResponse>;\n /** Downloads the raw MIME source for an email. */\n getRaw(\n emailId: string,\n options?: GetEmailRawOptions\n ): Promise<SpinupMailFile>;\n /** Downloads an attachment from an email. */\n getAttachment(\n emailId: string,\n attachmentId: string,\n options?: GetEmailAttachmentOptions\n ): Promise<SpinupMailFile>;\n}\n\nexport interface SpinupMailStatsApi {\n /** Returns daily email activity counts for the organization. */\n getEmailActivity(\n options?: GetEmailActivityOptions\n ): Promise<EmailActivityResponse>;\n /** Returns aggregate storage and inbox summary stats for the organization. */\n getEmailSummary(\n options?: GetEmailSummaryOptions\n ): Promise<EmailSummaryResponse>;\n}\n\nexport interface SpinupMailInboxesApi {\n /** Polls an inbox and returns the latest response plus polling metadata. */\n poll(options: InboxPollOptions): Promise<InboxPollResult>;\n /** Waits until a matching email arrives, then returns the fetched email detail. */\n waitForEmail(options: WaitForEmailOptions): Promise<EmailDetail>;\n}\n\nexport interface SpinupMailClient {\n /** Domain and retention configuration endpoints. */\n domains: SpinupMailDomainsApi;\n /** Inbox address lifecycle endpoints. */\n addresses: SpinupMailAddressesApi;\n /** Email retrieval and download endpoints. */\n emails: SpinupMailEmailsApi;\n /** Organization-level reporting endpoints. */\n stats: SpinupMailStatsApi;\n /** High-level inbox polling helpers. */\n inboxes: SpinupMailInboxesApi;\n}\n\nconst DEFAULT_LIST_ALL_PAGE_SIZE = 50;\nconst MAX_LIST_ALL_PAGES = 200;\nconst DEFAULT_WAIT_TIMEOUT_MS = 30_000;\nconst DEFAULT_POLL_INTERVAL_MS = 1_000;\nconst DEFAULT_SPINUPMAIL_BASE_URL = \"https://api.spinupmail.com\";\nconst RANDOM_LOCAL_PART_PREFIX = \"sum\";\nconst RANDOM_LOCAL_PART_SIZE = 12;\n\nconst issuePathToString = (path: PropertyKey[]) =>\n path.length === 0 ? \"<root>\" : path.map(String).join(\".\");\n\nconst formatSchemaIssues = (\n issues: Array<{ path: PropertyKey[]; message: string }>\n) => issues.map(issue => `${issuePathToString(issue.path)}: ${issue.message}`);\n\nconst validateWithSchema = <T>(\n schema: ZodType<T>,\n value: unknown,\n source: \"request\" | \"response\",\n message: string\n) => {\n const parsed = schema.safeParse(value);\n if (!parsed.success) {\n throw new SpinupMailValidationError({\n message,\n source,\n issues: formatSchemaIssues(parsed.error.issues),\n cause: parsed.error,\n });\n }\n\n return parsed.data;\n};\n\nconst normalizeString = (value: string, label: string) => {\n const normalized = value.trim();\n if (!normalized) {\n throw new SpinupMailValidationError({\n message: `${label} is required.`,\n source: \"request\",\n });\n }\n return normalized;\n};\n\nconst resolveFetch = (candidate?: FetchLike) => {\n if (candidate) return candidate;\n if (typeof globalThis.fetch === \"function\") {\n return globalThis.fetch.bind(globalThis) as FetchLike;\n }\n\n throw new SpinupMailValidationError({\n message: \"A fetch implementation is required in this runtime.\",\n source: \"request\",\n });\n};\n\nconst normalizeBaseUrl = (baseUrl: string) =>\n normalizeString(baseUrl, \"baseUrl\").replace(/\\/+$/, \"\");\n\nconst getProcessEnv = () => {\n if (\n typeof process !== \"undefined\" &&\n typeof process.env === \"object\" &&\n process.env !== null\n ) {\n return process.env;\n }\n\n return undefined;\n};\n\nconst readEnvValue = (keys: string[]) => {\n const env = getProcessEnv();\n if (!env) return undefined;\n\n for (const key of keys) {\n const value = env[key]?.trim();\n if (value) return value;\n }\n\n return undefined;\n};\n\nconst createRandomBytes = (size: number) => {\n if (\n typeof crypto !== \"undefined\" &&\n typeof crypto.getRandomValues === \"function\"\n ) {\n return crypto.getRandomValues(new Uint8Array(size));\n }\n\n return Uint8Array.from(\n Array.from({ length: size }, () => Math.floor(Math.random() * 256))\n );\n};\n\nconst generateRandomLocalPart = () => {\n const alphabet = \"abcdefghijklmnopqrstuvwxyz0123456789\";\n const bytes = createRandomBytes(RANDOM_LOCAL_PART_SIZE);\n let suffix = \"\";\n\n for (const byte of bytes) {\n suffix += alphabet[byte % alphabet.length];\n }\n\n return `${RANDOM_LOCAL_PART_PREFIX}-${suffix}`;\n};\n\nconst resolveOrganizationId = (\n context: ClientContext,\n organizationId: string | undefined,\n orgScoped: boolean\n) => {\n if (!orgScoped) return undefined;\n\n const resolved = organizationId ?? context.organizationId;\n if (!resolved?.trim()) {\n throw new SpinupMailValidationError({\n message:\n \"organizationId is required for this SpinupMail API method when using API keys.\",\n source: \"request\",\n });\n }\n\n return resolved.trim();\n};\n\nconst normalizeTimestamp = (value: EmailTimestampFilter | undefined) => {\n if (value === undefined) return undefined;\n\n if (typeof value === \"number\") {\n if (!Number.isFinite(value)) {\n throw new SpinupMailValidationError({\n message: \"Invalid timestamp: number values must be finite.\",\n source: \"request\",\n });\n }\n\n return String(value);\n }\n\n if (value instanceof Date) {\n if (!Number.isFinite(value.getTime())) {\n throw new SpinupMailValidationError({\n message: \"Invalid timestamp: Date values must be valid.\",\n source: \"request\",\n });\n }\n\n return value.toISOString();\n }\n\n return value;\n};\n\nconst normalizeText = (value: string | null | undefined) =>\n (value ?? \"\").replace(/\\s+/g, \" \").trim().toLowerCase();\n\nconst matchesText = (\n value: string | null | undefined,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return normalizeText(value).includes(normalizeText(expected));\n};\n\nconst matchesAnyText = (\n values: Array<string | null | undefined>,\n expected: string | undefined\n) => {\n if (!expected?.trim()) return true;\n return values.some(value => matchesText(value, expected));\n};\n\nconst createQueryString = (\n values: Record<string, string | number | boolean | undefined>\n) => {\n const query = new URLSearchParams();\n\n for (const [key, value] of Object.entries(values)) {\n if (value === undefined) continue;\n query.set(key, String(value));\n }\n\n const serialized = query.toString();\n return serialized.length > 0 ? `?${serialized}` : \"\";\n};\n\nconst parseErrorPayload = async (response: Response) => {\n try {\n const payload = await response.clone().json();\n const parsed = apiErrorSchema.safeParse(payload);\n if (parsed.success) return parsed.data;\n return payload;\n } catch {\n const text = await response.clone().text();\n return text ? { error: text } : undefined;\n }\n};\n\nconst requestJson = async <T>(\n context: ClientContext,\n options: {\n method?: \"GET\" | \"POST\" | \"PATCH\" | \"DELETE\";\n path: string;\n responseSchema: ZodType<T>;\n body?: unknown;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n headers.set(\"accept\", \"application/json\");\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n let body: BodyInit | undefined;\n if (options.body !== undefined) {\n headers.set(\"content-type\", \"application/json\");\n body = JSON.stringify(options.body);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: options.method ?? \"GET\",\n headers,\n body,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n let payload: unknown;\n try {\n payload = await response.json();\n } catch (error) {\n throw new SpinupMailValidationError({\n message: \"SpinupMail returned a non-JSON success response.\",\n source: \"response\",\n cause: error,\n });\n }\n\n return validateWithSchema(\n options.responseSchema,\n payload,\n \"response\",\n \"SpinupMail returned an unexpected response shape.\"\n );\n};\n\nconst requestBinary = async (\n context: ClientContext,\n options: {\n path: string;\n organizationId?: string;\n orgScoped?: boolean;\n signal?: AbortSignal;\n }\n) => {\n const headers = new Headers(context.headers);\n headers.set(\"x-api-key\", context.apiKey);\n\n const resolvedOrganizationId = resolveOrganizationId(\n context,\n options.organizationId,\n options.orgScoped ?? false\n );\n\n if (resolvedOrganizationId) {\n headers.set(\"x-org-id\", resolvedOrganizationId);\n }\n\n const response = await context.fetch(`${context.baseUrl}${options.path}`, {\n method: \"GET\",\n headers,\n signal: options.signal,\n });\n\n if (!response.ok) {\n const errorBody = await parseErrorPayload(response);\n const message =\n typeof errorBody === \"object\" &&\n errorBody !== null &&\n \"error\" in errorBody &&\n typeof errorBody.error === \"string\"\n ? errorBody.error\n : response.statusText || \"SpinupMail request failed\";\n\n throw new SpinupMailApiError({\n message,\n status: response.status,\n response,\n body: errorBody,\n });\n }\n\n return new SpinupMailFile(response);\n};\n\nconst ensureInboxSelector = (options: InboxAddressSelector) => {\n const hasAddress = Boolean(options.address?.trim());\n const hasAddressId = Boolean(options.addressId?.trim());\n\n if (hasAddress === hasAddressId) {\n throw new SpinupMailValidationError({\n message: \"Exactly one of address or addressId is required.\",\n source: \"request\",\n });\n }\n};\n\nconst validatePollingTimingOptions = (options: {\n timeoutMs?: number;\n intervalMs?: number;\n}) => {\n if (\n options.timeoutMs !== undefined &&\n (!Number.isFinite(options.timeoutMs) || options.timeoutMs < 0)\n ) {\n throw new SpinupMailValidationError({\n message: \"invalid option: timeoutMs must be a finite number >= 0\",\n source: \"request\",\n });\n }\n\n if (\n options.intervalMs !== undefined &&\n (!Number.isFinite(options.intervalMs) || options.intervalMs <= 0)\n ) {\n throw new SpinupMailValidationError({\n message: \"invalid option: intervalMs must be a finite number > 0\",\n source: \"request\",\n });\n }\n};\n\nconst validateListEmailsOptions = (options: ListEmailsOptions) => {\n ensureInboxSelector(options);\n validateWithSchema(\n listEmailsParamsSchema,\n {\n ...options,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n },\n \"request\",\n \"Invalid listEmails options.\"\n );\n\n if (\n options.search &&\n (options.after !== undefined ||\n options.before !== undefined ||\n options.order === \"asc\")\n ) {\n throw new SpinupMailValidationError({\n message:\n \"search does not support after, before, or order='asc' parameters.\",\n source: \"request\",\n });\n }\n};\n\nconst matchesListItemFilters = (\n item: EmailListItem,\n options: InboxPollOptions\n) => {\n if (!matchesText(item.subject, options.subjectIncludes)) return false;\n if (!matchesText(item.to, options.toIncludes)) return false;\n if (\n !matchesAnyText(\n [item.from, item.sender, item.senderLabel],\n options.fromIncludes\n )\n ) {\n return false;\n }\n\n return options.match ? options.match(item) : true;\n};\n\nconst matchesDetailFilters = (\n detail: EmailDetail,\n options: WaitForEmailOptions\n) => {\n const bodyText = `${detail.html ?? \"\"}\\n${detail.text ?? \"\"}`;\n\n if (!matchesText(bodyText, options.bodyIncludes)) return false;\n return options.matchDetail ? options.matchDetail(detail) : true;\n};\n\nconst sleep = (ms: number, signal?: AbortSignal) =>\n new Promise<void>((resolve, reject) => {\n if (signal?.aborted) {\n reject(signal.reason ?? new Error(\"The operation was aborted.\"));\n return;\n }\n\n const timeoutId = setTimeout(() => {\n cleanup();\n resolve();\n }, ms);\n\n const onAbort = () => {\n clearTimeout(timeoutId);\n cleanup();\n reject(signal?.reason ?? new Error(\"The operation was aborted.\"));\n };\n\n const cleanup = () => {\n signal?.removeEventListener(\"abort\", onAbort);\n };\n\n signal?.addEventListener(\"abort\", onAbort, { once: true });\n });\n\nconst runPollingLoop = async (\n emails: {\n list: (options: ListEmailsOptions) => Promise<EmailListResponse>;\n },\n options: InboxPollOptions,\n args: {\n timeoutMs: number;\n throwOnTimeout: boolean;\n }\n): Promise<InboxPollResult> => {\n ensureInboxSelector(options);\n validatePollingTimingOptions(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n const startedAt = Date.now();\n const deadline =\n args.timeoutMs > 0 ? startedAt + args.timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n let attempts = 0;\n let lastResponse!: EmailListResponse;\n let lastFreshItems!: EmailListItem[];\n\n while (true) {\n attempts += 1;\n\n lastResponse = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n lastFreshItems = lastResponse.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return true;\n });\n\n const matchedEmail =\n lastFreshItems.find(item => matchesListItemFilters(item, options)) ??\n null;\n if (matchedEmail) {\n return {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail,\n timedOut: false,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n }\n\n if (args.timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n const result: InboxPollResult = {\n response: lastResponse,\n items: lastResponse.items,\n freshItems: lastFreshItems,\n matchedEmail: null,\n timedOut: args.timeoutMs > 0,\n attempts,\n elapsedMs: Date.now() - startedAt,\n polledAt: new Date().toISOString(),\n };\n\n if (args.throwOnTimeout) {\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${args.timeoutMs}ms timeout elapsed.`,\n args.timeoutMs\n );\n }\n\n return result;\n};\n\nconst waitForEmailDetail = async (\n emails: Pick<SpinupMailEmailsApi, \"list\" | \"get\" | \"delete\">,\n options: WaitForEmailOptions\n) => {\n ensureInboxSelector(options);\n validatePollingTimingOptions(options);\n validateListEmailsOptions({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const startedAt = Date.now();\n const timeoutMs = options.timeoutMs ?? DEFAULT_WAIT_TIMEOUT_MS;\n const deadline =\n timeoutMs > 0 ? startedAt + timeoutMs : Number.NEGATIVE_INFINITY;\n const seenEmailIds = new Set<string>();\n\n while (true) {\n const response = await emails.list({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: options.after,\n before: options.before,\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n const freshCandidates = response.items.filter(item => {\n if (seenEmailIds.has(item.id)) return false;\n seenEmailIds.add(item.id);\n return matchesListItemFilters(item, options);\n });\n\n for (const item of freshCandidates) {\n const detail = await emails.get(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n\n if (!matchesDetailFilters(detail, options)) {\n continue;\n }\n\n if (options.deleteAfterRead) {\n await emails.delete(item.id, {\n organizationId: options.organizationId,\n signal: options.signal,\n });\n }\n\n return detail;\n }\n\n if (timeoutMs <= 0 || Date.now() >= deadline) {\n break;\n }\n\n const remainingMs = deadline - Date.now();\n if (remainingMs <= 0) break;\n\n await sleep(\n Math.min(options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS, remainingMs),\n options.signal\n );\n }\n\n throw new SpinupMailTimeoutError(\n `No matching email arrived before the ${timeoutMs}ms timeout elapsed.`,\n timeoutMs\n );\n};\n\nconst createSpinupMailClient = (\n options: CreateSpinupMailClientOptions\n): SpinupMailClient => {\n const context: ClientContext = {\n baseUrl: normalizeBaseUrl(options.baseUrl),\n apiKey: normalizeString(options.apiKey, \"apiKey\"),\n organizationId: options.organizationId?.trim() || undefined,\n fetch: resolveFetch(options.fetch),\n headers: options.headers,\n };\n\n const addresses: SpinupMailAddressesApi = {\n list: async (options: ListEmailAddressesOptions = {}) => {\n const validated = validateWithSchema(\n listEmailAddressesParamsSchema,\n options,\n \"request\",\n \"Invalid listEmailAddresses options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses${createQueryString({\n page: validated.page,\n pageSize: validated.pageSize,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: emailAddressListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n listAll: async (options: ListEmailAddressesOptions = {}) => {\n const items: EmailAddress[] = [];\n let page = 1;\n let totalPages = 1;\n\n while (page <= totalPages) {\n if (page > MAX_LIST_ALL_PAGES) {\n throw new SpinupMailValidationError({\n message: `Address pagination exceeded the safety limit of ${MAX_LIST_ALL_PAGES} pages.`,\n source: \"request\",\n });\n }\n\n const response = await addresses.list({\n ...options,\n page,\n pageSize: options.pageSize ?? DEFAULT_LIST_ALL_PAGE_SIZE,\n });\n\n items.push(...response.items);\n totalPages = response.totalPages;\n page += 1;\n }\n\n return items;\n },\n listRecentActivity: async (\n options: ListRecentAddressActivityOptions = {}\n ) => {\n const validated = validateWithSchema(\n listRecentAddressActivityParamsSchema,\n options,\n \"request\",\n \"Invalid listRecentAddressActivity options.\"\n );\n\n return requestJson(context, {\n path: `/api/email-addresses/recent-activity${createQueryString({\n limit: validated.limit,\n cursor: validated.cursor,\n search: validated.search,\n sortBy: validated.sortBy,\n sortDirection: validated.sortDirection,\n })}`,\n responseSchema: recentAddressActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (addressId: string, options: GetEmailAddressOptions = {}) =>\n requestJson(context, {\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n create: (\n payload: CreateEmailAddressInput,\n options: CreateEmailAddressOptions = {}\n ) => {\n const requestPayload = validateWithSchema(\n createEmailAddressRequestSchema,\n {\n ...payload,\n localPart: payload.localPart?.trim() || generateRandomLocalPart(),\n },\n \"request\",\n \"Invalid createEmailAddress payload.\"\n );\n\n return requestJson(context, {\n method: \"POST\",\n path: \"/api/email-addresses\",\n responseSchema: createEmailAddressResponseSchema,\n body: requestPayload,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n update: (\n addressId: string,\n payload: UpdateEmailAddressRequest,\n options: UpdateEmailAddressOptions = {}\n ) =>\n requestJson(context, {\n method: \"PATCH\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: emailAddressSchema,\n body: validateWithSchema(\n updateEmailAddressRequestSchema,\n payload,\n \"request\",\n \"Invalid updateEmailAddress payload.\"\n ),\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (addressId: string, options: DeleteEmailAddressOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/email-addresses/${encodeURIComponent(\n normalizeString(addressId, \"addressId\")\n )}`,\n responseSchema: deleteEmailAddressResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const emails: SpinupMailEmailsApi = {\n list: async (options: ListEmailsOptions) => {\n validateListEmailsOptions(options);\n\n return requestJson(context, {\n path: `/api/emails${createQueryString({\n address: options.address,\n addressId: options.addressId,\n search: options.search,\n limit: options.limit,\n order: options.order,\n after: normalizeTimestamp(options.after),\n before: normalizeTimestamp(options.before),\n })}`,\n responseSchema: emailListResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n });\n },\n get: (emailId: string, options: GetEmailOptions = {}) =>\n requestJson(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}${createQueryString({ raw: options.raw ? 1 : undefined })}`,\n responseSchema: emailDetailSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n delete: (emailId: string, options: DeleteEmailOptions = {}) =>\n requestJson(context, {\n method: \"DELETE\",\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}`,\n responseSchema: deleteEmailResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getRaw: (emailId: string, options: GetEmailRawOptions = {}) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/raw`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getAttachment: (\n emailId: string,\n attachmentId: string,\n options: GetEmailAttachmentOptions = {}\n ) =>\n requestBinary(context, {\n path: `/api/emails/${encodeURIComponent(\n normalizeString(emailId, \"emailId\")\n )}/attachments/${encodeURIComponent(\n normalizeString(attachmentId, \"attachmentId\")\n )}${createQueryString({ inline: options.inline ? 1 : undefined })}`,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const stats: SpinupMailStatsApi = {\n getEmailActivity: (options: GetEmailActivityOptions = {}) =>\n requestJson(context, {\n path: `/api/organizations/stats/email-activity${createQueryString({\n days: options.days,\n timezone: options.timezone,\n })}`,\n responseSchema: emailActivityResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n getEmailSummary: (options: GetEmailSummaryOptions = {}) =>\n requestJson(context, {\n path: \"/api/organizations/stats/email-summary\",\n responseSchema: emailSummaryResponseSchema,\n organizationId: options.organizationId,\n orgScoped: true,\n signal: options.signal,\n }),\n };\n\n const inboxes: SpinupMailInboxesApi = {\n poll: (options: InboxPollOptions) =>\n runPollingLoop(emails, options, {\n timeoutMs: options.timeoutMs ?? 0,\n throwOnTimeout: false,\n }),\n waitForEmail: (options: WaitForEmailOptions) =>\n waitForEmailDetail(emails, options),\n };\n\n return {\n domains: {\n get: () =>\n requestJson(context, {\n path: \"/api/domains\",\n responseSchema: domainConfigSchema,\n }),\n } satisfies SpinupMailDomainsApi,\n addresses,\n emails,\n stats,\n inboxes,\n };\n};\n\n/**\n * API-key SDK for SpinupMail.\n *\n * Typical usage:\n *\n * ```ts\n * const spinupmail = new SpinupMail();\n * const address = await spinupmail.addresses.create({ acceptedRiskNotice: true });\n * const email = await spinupmail.inboxes.waitForEmail({ addressId: address.id });\n * ```\n */\nexport class SpinupMail {\n readonly domains: SpinupMailClient[\"domains\"];\n readonly addresses: SpinupMailClient[\"addresses\"];\n readonly emails: SpinupMailClient[\"emails\"];\n readonly stats: SpinupMailClient[\"stats\"];\n readonly inboxes: SpinupMailClient[\"inboxes\"];\n\n /** Creates a new SDK client using constructor options or environment defaults. */\n constructor(options: string | SpinupMailOptions = {}) {\n const resolvedOptions =\n typeof options === \"string\" ? { apiKey: options } : options;\n const apiKey =\n resolvedOptions.apiKey ?? readEnvValue([\"SPINUPMAIL_API_KEY\"]);\n const baseUrl =\n resolvedOptions.baseUrl ??\n readEnvValue([\"SPINUPMAIL_BASE_URL\"]) ??\n DEFAULT_SPINUPMAIL_BASE_URL;\n const organizationId =\n resolvedOptions.organizationId ??\n readEnvValue([\"SPINUPMAIL_ORGANIZATION_ID\", \"SPINUPMAIL_ORG_ID\"]);\n\n const client = createSpinupMailClient({\n baseUrl,\n apiKey: normalizeString(apiKey ?? \"\", \"apiKey\"),\n organizationId,\n fetch: resolvedOptions.fetch,\n headers: resolvedOptions.headers,\n });\n\n this.domains = client.domains;\n this.addresses = client.addresses;\n this.emails = client.emails;\n this.stats = client.stats;\n this.inboxes = client.inboxes;\n }\n}\nexport type {\n CreateEmailAddressRequest,\n CreateEmailAddressResponse,\n DeleteEmailAddressResponse,\n DeleteEmailResponse,\n DomainConfig,\n EmailActivityResponse,\n EmailAddress,\n EmailAddressListResponse,\n EmailDetail,\n EmailListItem,\n EmailListResponse,\n EmailSummaryResponse,\n ListEmailAddressesParams,\n ListEmailsParams,\n ListRecentAddressActivityParams,\n RecentAddressActivityResponse,\n UpdateEmailAddressRequest,\n};\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "spinupmail",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1",
|
|
4
4
|
"description": "SpinupMail TypeScript SDK for creating and reading temporary email addresses.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -21,20 +21,20 @@
|
|
|
21
21
|
}
|
|
22
22
|
},
|
|
23
23
|
"publishConfig": {
|
|
24
|
-
"access": "public"
|
|
25
|
-
"provenance": true
|
|
24
|
+
"access": "public"
|
|
26
25
|
},
|
|
27
26
|
"dependencies": {
|
|
28
27
|
"zod": "^4.3.6"
|
|
29
28
|
},
|
|
30
29
|
"devDependencies": {
|
|
31
30
|
"@types/node": "^24.10.11",
|
|
31
|
+
"@typescript/native-preview": "7.0.0-dev.20260222.1",
|
|
32
32
|
"tsdown": "^0.21.7",
|
|
33
33
|
"typescript": "^5.9.3"
|
|
34
34
|
},
|
|
35
35
|
"scripts": {
|
|
36
36
|
"build": "tsdown --config tsdown.config.ts",
|
|
37
|
-
"typecheck": "
|
|
37
|
+
"typecheck": "tsgo --noEmit -p tsconfig.test.json && tsgo --noEmit -p tests/tsconfig.json",
|
|
38
38
|
"test": "vitest run --config vitest.config.ts",
|
|
39
39
|
"test:package": "node ./scripts/smoke-package.mjs"
|
|
40
40
|
}
|