@postbrix/sdk 1.0.0

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.
@@ -0,0 +1,361 @@
1
+ /**
2
+ * Configuration options for PostBrix client
3
+ */
4
+ interface PostBrixConfig {
5
+ /** API key for authentication (required) */
6
+ apiKey: string;
7
+ /** Base URL for API endpoint (default: https://api.postbrix.com/v1) */
8
+ baseURL?: string;
9
+ /** Request timeout in milliseconds (default: 30000) */
10
+ timeout?: number;
11
+ /** Maximum number of retry attempts for transient errors (default: 2) */
12
+ maxRetries?: number;
13
+ }
14
+ /**
15
+ * Output format for rendered templates
16
+ */
17
+ type RenderFormat = "html" | "mjml" | "both";
18
+ /**
19
+ * Options for render request
20
+ *
21
+ * @typeParam TFormat - Desired output format (default: RenderFormat)
22
+ */
23
+ interface RenderOptions<TFormat extends RenderFormat = RenderFormat> {
24
+ /** Output format (default: "html") */
25
+ format?: TFormat;
26
+ }
27
+ /**
28
+ * Render request body
29
+ */
30
+ interface RenderRequest {
31
+ variables?: Record<string, unknown>;
32
+ format: RenderFormat;
33
+ }
34
+ /**
35
+ * HTML render response
36
+ */
37
+ interface HtmlRenderResponse {
38
+ format: "html";
39
+ html: string;
40
+ mjml?: never;
41
+ }
42
+ /**
43
+ * MJML render response
44
+ */
45
+ interface MjmlRenderResponse {
46
+ format: "mjml";
47
+ mjml: string;
48
+ html?: never;
49
+ }
50
+ /**
51
+ * Both formats render response
52
+ */
53
+ interface BothFormatsRenderResponse {
54
+ format: "both";
55
+ html: string;
56
+ mjml: string;
57
+ }
58
+ /**
59
+ * Render response discriminated union
60
+ */
61
+ type RenderResponse = HtmlRenderResponse | MjmlRenderResponse | BothFormatsRenderResponse;
62
+ /**
63
+ * Resolves concrete return type based on requested format:
64
+ * - "html" -> HtmlRenderResponse (guaranteed .html: string)
65
+ * - "mjml" -> MjmlRenderResponse (guaranteed .mjml: string)
66
+ * - "both" -> BothFormatsRenderResponse (guaranteed .html: string, .mjml: string)
67
+ * - RenderFormat / union -> RenderResponse (discriminated union)
68
+ */
69
+ type RenderResult<TFormat extends RenderFormat = "html"> = [
70
+ TFormat
71
+ ] extends ["mjml"] ? MjmlRenderResponse : [TFormat] extends ["both"] ? BothFormatsRenderResponse : [TFormat] extends ["html"] ? HtmlRenderResponse : RenderResponse;
72
+ /**
73
+ * API error response from server
74
+ */
75
+ interface ApiErrorResponse {
76
+ message?: string;
77
+ error?: string;
78
+ code?: string;
79
+ statusCode?: number;
80
+ requestId?: string;
81
+ details?: unknown;
82
+ }
83
+ /**
84
+ * HTTP response wrapper
85
+ */
86
+ interface HttpResponse<T> {
87
+ data: T;
88
+ status: number;
89
+ headers: Record<string, string>;
90
+ }
91
+
92
+ /**
93
+ * PostBrix SDK Client
94
+ *
95
+ * Main entry point for interacting with the PostBrix Template Render API.
96
+ * Provides zero-dependency, strongly typed template rendering with built-in
97
+ * exponential jitter retries, timeout management, and comprehensive error handling.
98
+ */
99
+ declare class PostBrix {
100
+ private readonly apiKey;
101
+ private readonly baseURL;
102
+ private readonly timeout;
103
+ private readonly maxRetries;
104
+ private static readonly DEFAULT_BASE_URL;
105
+ private static readonly DEFAULT_TIMEOUT;
106
+ private static readonly DEFAULT_MAX_RETRIES;
107
+ /**
108
+ * Initialize a new PostBrix SDK client instance.
109
+ *
110
+ * @param config - Configuration options for the client
111
+ * @param config.apiKey - PostBrix API key for authentication (starts with `pb_live_` or `pb_test_`)
112
+ * @param config.baseURL - Base URL for the PostBrix API (default: `https://api.postbrix.com/v1`)
113
+ * @param config.timeout - Request timeout in milliseconds (default: `30000`)
114
+ * @param config.maxRetries - Maximum retry attempts for transient errors (default: `2`)
115
+ *
116
+ * @example
117
+ * ```ts
118
+ * import { PostBrix } from "@postbrix/sdk";
119
+ *
120
+ * // Standard initialization
121
+ * const postbrix = new PostBrix({
122
+ * apiKey: process.env.POSTBRIX_API_KEY!,
123
+ * });
124
+ *
125
+ * // Custom timeout and retries
126
+ * const postbrix = new PostBrix({
127
+ * apiKey: "pb_live_xxxxxxxxxxxxxxxxxxxxxxxx",
128
+ * baseURL: "https://api.postbrix.com/v1",
129
+ * timeout: 10000,
130
+ * maxRetries: 3,
131
+ * });
132
+ * ```
133
+ *
134
+ * @throws {PostBrixValidationError} If any configuration parameter is invalid
135
+ */
136
+ constructor(config: PostBrixConfig);
137
+ /**
138
+ * Validate configuration options in detail
139
+ *
140
+ * @param config - Configuration object to validate
141
+ * @throws {PostBrixValidationError} If configuration is missing or invalid
142
+ */
143
+ private validateConfig;
144
+ /**
145
+ * Returns active client configuration with sensitive secrets securely masked.
146
+ * Useful for debugging, logging, and environment verification.
147
+ *
148
+ * @returns Read-only sanitized configuration object
149
+ *
150
+ * @example
151
+ * ```ts
152
+ * const config = postbrix.getConfig();
153
+ * console.log(config);
154
+ * // { baseURL: 'https://api.postbrix.com/v1', timeout: 30000, maxRetries: 2, apiKey: 'pb_live...[REDACTED]' }
155
+ * ```
156
+ */
157
+ getConfig(): Readonly<{
158
+ baseURL: string;
159
+ timeout: number;
160
+ maxRetries: number;
161
+ apiKey: string;
162
+ }>;
163
+ /**
164
+ * Render an email template with dynamic variables.
165
+ *
166
+ * @typeParam TVariables - Shape of dynamic variables passed to the template
167
+ * @typeParam TFormat - Desired output format: "html" (default), "mjml", or "both"
168
+ *
169
+ * @param templateId - Template identifier or slug (e.g. "welcome-email")
170
+ * @param variables - Key-value variables to substitute into template tags (must be JSON-serializable)
171
+ * @param options - Configuration options for rendering (e.g. `{ format: "html" }`)
172
+ * @returns Promise resolving to the rendered template output matching the requested format
173
+ *
174
+ * @example
175
+ * ```ts
176
+ * // 1. Render HTML (default - returns { format: "html", html: string })
177
+ * const result = await postbrix.render("welcome-email", { name: "Alex" });
178
+ * console.log(result.html);
179
+ *
180
+ * // 2. Render MJML (returns { format: "mjml", mjml: string })
181
+ * const mjmlResult = await postbrix.render("welcome-email", { name: "Alex" }, { format: "mjml" });
182
+ * console.log(mjmlResult.mjml);
183
+ *
184
+ * // 3. Render Both (returns { format: "both", html: string, mjml: string })
185
+ * const bothResult = await postbrix.render("welcome-email", { name: "Alex" }, { format: "both" });
186
+ * console.log(bothResult.html, bothResult.mjml);
187
+ * ```
188
+ *
189
+ * @throws {PostBrixValidationError} If templateId, variables, format, or circular data are invalid
190
+ * @throws {PostBrixAuthenticationError} If the API key is missing or invalid (401)
191
+ * @throws {PostBrixForbiddenError} If API key lacks permissions (403)
192
+ * @throws {PostBrixNotFoundError} If templateId does not exist (404)
193
+ * @throws {PostBrixRateLimitError} If rate limit is exceeded (429)
194
+ * @throws {PostBrixServerError} If server encounters an internal error (500, 502, 503, 504)
195
+ * @throws {PostBrixTimeoutError} If request times out
196
+ * @throws {PostBrixNetworkError} If network connection fails
197
+ */
198
+ render<TVariables extends Record<string, unknown> = Record<string, unknown>, TFormat extends RenderFormat = "html">(templateId: string, variables?: TVariables, options?: RenderOptions<TFormat>): Promise<RenderResult<TFormat>>;
199
+ /**
200
+ * Internal request method with retry logic
201
+ */
202
+ private request;
203
+ /**
204
+ * Execute a single request
205
+ */
206
+ private executeRequest;
207
+ /**
208
+ * Build request headers
209
+ */
210
+ private buildHeaders;
211
+ /**
212
+ * Handle successful response with schema validation and backend unwrap
213
+ */
214
+ private handleSuccessResponse;
215
+ /**
216
+ * Handle error response
217
+ */
218
+ private handleErrorResponse;
219
+ /**
220
+ * Determine if error is retryable
221
+ */
222
+ private isRetryableError;
223
+ }
224
+
225
+ /**
226
+ * Base error class for all PostBrix SDK errors
227
+ */
228
+ declare class PostBrixError extends Error {
229
+ readonly statusCode?: number;
230
+ readonly requestId?: string;
231
+ readonly code: string;
232
+ readonly retryable: boolean;
233
+ readonly details?: unknown;
234
+ readonly cause?: Error;
235
+ constructor(message: string, options?: {
236
+ statusCode?: number;
237
+ requestId?: string;
238
+ code?: string;
239
+ retryable?: boolean;
240
+ details?: unknown;
241
+ cause?: Error;
242
+ });
243
+ }
244
+ /**
245
+ * Error thrown when request times out
246
+ */
247
+ declare class PostBrixTimeoutError extends PostBrixError {
248
+ constructor(timeoutMs: number, options?: {
249
+ requestId?: string;
250
+ cause?: Error;
251
+ });
252
+ }
253
+ /**
254
+ * Error thrown for network issues
255
+ */
256
+ declare class PostBrixNetworkError extends PostBrixError {
257
+ constructor(message: string, options?: {
258
+ requestId?: string;
259
+ retryable?: boolean;
260
+ cause?: Error;
261
+ });
262
+ }
263
+ /**
264
+ * Error thrown for validation issues
265
+ */
266
+ declare class PostBrixValidationError extends PostBrixError {
267
+ constructor(message: string, options?: {
268
+ statusCode?: number;
269
+ requestId?: string;
270
+ code?: string;
271
+ details?: unknown;
272
+ cause?: Error;
273
+ });
274
+ }
275
+ /**
276
+ * Error thrown for authentication/authorization issues
277
+ */
278
+ declare class PostBrixAuthError extends PostBrixError {
279
+ constructor(message: string, options?: {
280
+ statusCode?: number;
281
+ requestId?: string;
282
+ code?: string;
283
+ details?: unknown;
284
+ cause?: Error;
285
+ });
286
+ }
287
+ /**
288
+ * Error thrown when rate limit is exceeded
289
+ */
290
+ declare class PostBrixLimitError extends PostBrixError {
291
+ readonly retryAfter?: number;
292
+ constructor(message: string, options?: {
293
+ statusCode?: number;
294
+ requestId?: string;
295
+ code?: string;
296
+ retryAfter?: number;
297
+ details?: unknown;
298
+ cause?: Error;
299
+ });
300
+ }
301
+ /**
302
+ * Error thrown when template is not found
303
+ */
304
+ declare class PostBrixTemplateError extends PostBrixError {
305
+ constructor(message: string, options?: {
306
+ statusCode?: number;
307
+ requestId?: string;
308
+ code?: string;
309
+ details?: unknown;
310
+ cause?: Error;
311
+ });
312
+ }
313
+ /**
314
+ * Error thrown when API returns a malformed response
315
+ */
316
+ declare class PostBrixResponseError extends PostBrixError {
317
+ constructor(message: string, options?: {
318
+ statusCode?: number;
319
+ requestId?: string;
320
+ code?: string;
321
+ details?: unknown;
322
+ cause?: Error;
323
+ });
324
+ }
325
+ /**
326
+ * Error thrown when access is forbidden (403)
327
+ */
328
+ declare class PostBrixForbiddenError extends PostBrixAuthError {
329
+ constructor(message: string, options?: {
330
+ statusCode?: number;
331
+ requestId?: string;
332
+ code?: string;
333
+ details?: unknown;
334
+ cause?: Error;
335
+ });
336
+ }
337
+ /**
338
+ * Error thrown for server-side failures (5xx)
339
+ */
340
+ declare class PostBrixServerError extends PostBrixError {
341
+ constructor(message: string, options?: {
342
+ statusCode?: number;
343
+ requestId?: string;
344
+ code?: string;
345
+ retryable?: boolean;
346
+ details?: unknown;
347
+ cause?: Error;
348
+ });
349
+ }
350
+ /** Canonical Aliases for Error Classes */
351
+ declare const PostBrixAuthenticationError: typeof PostBrixAuthError;
352
+ type PostBrixAuthenticationError = PostBrixAuthError;
353
+ declare const PostBrixRateLimitError: typeof PostBrixLimitError;
354
+ type PostBrixRateLimitError = PostBrixLimitError;
355
+ declare const PostBrixNotFoundError: typeof PostBrixTemplateError;
356
+ type PostBrixNotFoundError = PostBrixTemplateError;
357
+
358
+ declare const SDK_VERSION = "1.0.0";
359
+ declare const VERSION = "1.0.0";
360
+
361
+ export { type ApiErrorResponse, type BothFormatsRenderResponse, type HtmlRenderResponse, type HttpResponse, type MjmlRenderResponse, PostBrix, PostBrixAuthError, PostBrixAuthenticationError, type PostBrixConfig, PostBrixError, PostBrixForbiddenError, PostBrixLimitError, PostBrixNetworkError, PostBrixNotFoundError, PostBrixRateLimitError, PostBrixResponseError, PostBrixServerError, PostBrixTemplateError, PostBrixTimeoutError, PostBrixValidationError, type RenderFormat, type RenderOptions, type RenderRequest, type RenderResponse, type RenderResult, SDK_VERSION, VERSION };