sendhive 0.1.0-beta.0 → 0.1.0-beta.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/README.md CHANGED
@@ -67,6 +67,22 @@ const { data, error } = await sendhive.emails.send({
67
67
 
68
68
  Every variable the template uses must have a value in `data`, otherwise you get `missing_template_variables`. Values are HTML-escaped for you, and a value used as a link must start with `http://`, `https://` or `mailto:`. An unknown template gives `template_not_found`.
69
69
 
70
+ Ready-made templates work without saving anything: use `preset:` plus the preset id, for example `template: 'preset:welcome'`.
71
+
72
+ ## Templates
73
+
74
+ ```ts
75
+ // Your templates and the ready-made ones (slug 'preset:welcome', 'preset:order-shipped', ...)
76
+ const { data: templates, error } = await sendhive.templates.list()
77
+ // templates[0] -> { id, slug, name, kind: 'custom' | 'preset', subject, preview_text, variables, updated_at }
78
+
79
+ // Draw a template with data. Missing values are not an error: they show as {{name}} and are listed.
80
+ const { data: preview } = await sendhive.templates.preview('preset:welcome', { customer_name: 'Asha' })
81
+ // preview -> { subject, html, text, missing_variables }
82
+ ```
83
+
84
+ `list()` calls `GET /api/templates` and `preview(template, data?)` calls `POST /api/templates/preview`. Both return `{ data, error }` and use the same key and rate limit as sending.
85
+
70
86
  ## Get
71
87
 
72
88
  ```ts
package/dist/index.cjs CHANGED
@@ -70,8 +70,27 @@ var Emails = class {
70
70
  return this.client.request("GET", `/api/emails/${encodeURIComponent(id)}`);
71
71
  }
72
72
  };
73
+ var Templates = class {
74
+ constructor(client) {
75
+ this.client = client;
76
+ }
77
+ client;
78
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
79
+ async list() {
80
+ const res = await this.client.request("GET", "/api/templates");
81
+ return res.error ? res : { data: res.data.data, error: null };
82
+ }
83
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
84
+ async preview(template, data) {
85
+ return this.client.request("POST", "/api/templates/preview", {
86
+ template,
87
+ ...data !== void 0 ? { data } : {}
88
+ });
89
+ }
90
+ };
73
91
  var Sendhive = class {
74
92
  emails;
93
+ templates;
75
94
  apiKey;
76
95
  baseUrl;
77
96
  constructor(apiKey, options = {}) {
@@ -80,6 +99,7 @@ var Sendhive = class {
80
99
  if (!baseUrl) throw new Error("Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.");
81
100
  this.baseUrl = baseUrl.replace(/\/+$/, "");
82
101
  this.emails = new Emails(this);
102
+ this.templates = new Templates(this);
83
103
  }
84
104
  /** @internal */
85
105
  async request(method, path, body) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n Email,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveOptions,\n} from './types'\n\nexport type {\n Email,\n EmailEvent,\n EmailTag,\n Recipients,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveErrorFix,\n SendhiveOptions,\n TemplateData,\n} from './types'\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\n/** Optional peer: only loaded when the caller passes `react`. */\nasync function renderReact(element: unknown): Promise<string> {\n const specifier = '@react-email/render'\n let mod: { render?: (el: unknown) => string | Promise<string> }\n try {\n mod = await import(/* @vite-ignore */ specifier)\n } catch {\n throw new Error('The `react` option needs the optional peer dependency @react-email/render.')\n }\n if (!mod.render) throw new Error('@react-email/render has no `render` export.')\n return mod.render(element)\n}\n\nclass Emails {\n constructor(private readonly client: Sendhive) {}\n\n async send(options: SendEmailOptions): Promise<Result<SendEmailResponse>> {\n const { replyTo, react, ...rest } = options\n let html = rest.html\n if (react !== undefined) {\n try {\n html = await renderReact(react)\n } catch (err) {\n return {\n data: null,\n error: { statusCode: 422, name: 'validation_error', message: (err as Error).message },\n }\n }\n }\n const body = {\n ...rest,\n ...(html !== undefined ? { html } : {}),\n ...(replyTo !== undefined ? { reply_to: replyTo } : {}),\n }\n return this.client.request<SendEmailResponse>('POST', '/api/emails', body)\n }\n\n async get(id: string): Promise<Result<Email>> {\n return this.client.request<Email>('GET', `/api/emails/${encodeURIComponent(id)}`)\n }\n}\n\nexport class Sendhive {\n readonly emails: Emails\n private readonly apiKey: string | undefined\n private readonly baseUrl: string\n\n constructor(apiKey?: string, options: SendhiveOptions = {}) {\n this.apiKey = apiKey ?? env('SENDHIVE_API_KEY')\n // No default host: an API key must never be sent to a server the caller did not choose.\n const baseUrl = options.baseUrl ?? env('SENDHIVE_BASE_URL')\n if (!baseUrl) throw new Error('Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.')\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n this.emails = new Emails(this)\n }\n\n /** @internal */\n async request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (err) {\n return {\n data: null,\n error: {\n statusCode: 0,\n name: 'network_error',\n message: err instanceof Error ? err.message : String(err),\n },\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n json = null\n }\n\n if (!res.ok) {\n const e = (json ?? {}) as Partial<SendhiveError>\n return {\n data: null,\n error: {\n statusCode: e.statusCode ?? res.status,\n name: e.name ?? 'application_error',\n message: e.message ?? (res.statusText || 'Unexpected response'),\n ...(e.fix ? { fix: e.fix } : {}),\n },\n }\n }\n return { data: json as T, error: null }\n }\n}\n\nexport default Sendhive\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n Email,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveOptions,\n TemplateData,\n TemplateList,\n TemplatePreview,\n TemplateSummary,\n} from './types'\n\nexport type {\n Email,\n EmailEvent,\n EmailTag,\n Recipients,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveErrorFix,\n SendhiveOptions,\n TemplateData,\n TemplateList,\n TemplatePreview,\n TemplateSummary,\n} from './types'\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\n/** Optional peer: only loaded when the caller passes `react`. */\nasync function renderReact(element: unknown): Promise<string> {\n const specifier = '@react-email/render'\n let mod: { render?: (el: unknown) => string | Promise<string> }\n try {\n mod = await import(/* @vite-ignore */ specifier)\n } catch {\n throw new Error('The `react` option needs the optional peer dependency @react-email/render.')\n }\n if (!mod.render) throw new Error('@react-email/render has no `render` export.')\n return mod.render(element)\n}\n\nclass Emails {\n constructor(private readonly client: Sendhive) {}\n\n async send(options: SendEmailOptions): Promise<Result<SendEmailResponse>> {\n const { replyTo, react, ...rest } = options\n let html = rest.html\n if (react !== undefined) {\n try {\n html = await renderReact(react)\n } catch (err) {\n return {\n data: null,\n error: { statusCode: 422, name: 'validation_error', message: (err as Error).message },\n }\n }\n }\n const body = {\n ...rest,\n ...(html !== undefined ? { html } : {}),\n ...(replyTo !== undefined ? { reply_to: replyTo } : {}),\n }\n return this.client.request<SendEmailResponse>('POST', '/api/emails', body)\n }\n\n async get(id: string): Promise<Result<Email>> {\n return this.client.request<Email>('GET', `/api/emails/${encodeURIComponent(id)}`)\n }\n}\n\nclass Templates {\n constructor(private readonly client: Sendhive) {}\n\n /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */\n async list(): Promise<Result<TemplateSummary[]>> {\n const res = await this.client.request<TemplateList>('GET', '/api/templates')\n return res.error ? res : { data: res.data.data, error: null }\n }\n\n /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */\n async preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>> {\n return this.client.request<TemplatePreview>('POST', '/api/templates/preview', {\n template,\n ...(data !== undefined ? { data } : {}),\n })\n }\n}\n\nexport class Sendhive {\n readonly emails: Emails\n readonly templates: Templates\n private readonly apiKey: string | undefined\n private readonly baseUrl: string\n\n constructor(apiKey?: string, options: SendhiveOptions = {}) {\n this.apiKey = apiKey ?? env('SENDHIVE_API_KEY')\n // No default host: an API key must never be sent to a server the caller did not choose.\n const baseUrl = options.baseUrl ?? env('SENDHIVE_BASE_URL')\n if (!baseUrl) throw new Error('Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.')\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n this.emails = new Emails(this)\n this.templates = new Templates(this)\n }\n\n /** @internal */\n async request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (err) {\n return {\n data: null,\n error: {\n statusCode: 0,\n name: 'network_error',\n message: err instanceof Error ? err.message : String(err),\n },\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n json = null\n }\n\n if (!res.ok) {\n const e = (json ?? {}) as Partial<SendhiveError>\n return {\n data: null,\n error: {\n statusCode: e.statusCode ?? res.status,\n name: e.name ?? 'application_error',\n message: e.message ?? (res.statusText || 'Unexpected response'),\n ...(e.fix ? { fix: e.fix } : {}),\n },\n }\n }\n return { data: json as T, error: null }\n }\n}\n\nexport default Sendhive\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -84,6 +84,30 @@ interface Email {
84
84
  delivered_at: string | null;
85
85
  events: EmailEvent[];
86
86
  }
87
+ /** One template you can send: one of your own, or a ready-made preset (`slug` is then `preset:<id>`). */
88
+ interface TemplateSummary {
89
+ id: string;
90
+ /** Pass this as `template` when sending. */
91
+ slug: string;
92
+ name: string;
93
+ kind: 'custom' | 'preset';
94
+ subject: string;
95
+ preview_text: string | null;
96
+ /** The `{{variables}}` the template needs in `data`. */
97
+ variables: string[];
98
+ /** Null for ready-made presets. */
99
+ updated_at: string | null;
100
+ }
101
+ interface TemplateList {
102
+ data: TemplateSummary[];
103
+ }
104
+ /** A template drawn with the data you gave. Values you left out show as `{{name}}` and are listed. */
105
+ interface TemplatePreview {
106
+ subject: string;
107
+ html: string;
108
+ text: string;
109
+ missing_variables: string[];
110
+ }
87
111
  type Result<T> = {
88
112
  data: T;
89
113
  error: null;
@@ -101,8 +125,17 @@ declare class Emails {
101
125
  send(options: SendEmailOptions): Promise<Result<SendEmailResponse>>;
102
126
  get(id: string): Promise<Result<Email>>;
103
127
  }
128
+ declare class Templates {
129
+ private readonly client;
130
+ constructor(client: Sendhive);
131
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
132
+ list(): Promise<Result<TemplateSummary[]>>;
133
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
134
+ preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>>;
135
+ }
104
136
  declare class Sendhive {
105
137
  readonly emails: Emails;
138
+ readonly templates: Templates;
106
139
  private readonly apiKey;
107
140
  private readonly baseUrl;
108
141
  constructor(apiKey?: string, options?: SendhiveOptions);
@@ -110,4 +143,4 @@ declare class Sendhive {
110
143
  request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>>;
111
144
  }
112
145
 
113
- export { type Email, type EmailEvent, type EmailTag, type Recipients, type Result, type SendEmailOptions, type SendEmailResponse, Sendhive, type SendhiveError, type SendhiveErrorFix, type SendhiveOptions, type TemplateData, Sendhive as default };
146
+ export { type Email, type EmailEvent, type EmailTag, type Recipients, type Result, type SendEmailOptions, type SendEmailResponse, Sendhive, type SendhiveError, type SendhiveErrorFix, type SendhiveOptions, type TemplateData, type TemplateList, type TemplatePreview, type TemplateSummary, Sendhive as default };
package/dist/index.d.ts CHANGED
@@ -84,6 +84,30 @@ interface Email {
84
84
  delivered_at: string | null;
85
85
  events: EmailEvent[];
86
86
  }
87
+ /** One template you can send: one of your own, or a ready-made preset (`slug` is then `preset:<id>`). */
88
+ interface TemplateSummary {
89
+ id: string;
90
+ /** Pass this as `template` when sending. */
91
+ slug: string;
92
+ name: string;
93
+ kind: 'custom' | 'preset';
94
+ subject: string;
95
+ preview_text: string | null;
96
+ /** The `{{variables}}` the template needs in `data`. */
97
+ variables: string[];
98
+ /** Null for ready-made presets. */
99
+ updated_at: string | null;
100
+ }
101
+ interface TemplateList {
102
+ data: TemplateSummary[];
103
+ }
104
+ /** A template drawn with the data you gave. Values you left out show as `{{name}}` and are listed. */
105
+ interface TemplatePreview {
106
+ subject: string;
107
+ html: string;
108
+ text: string;
109
+ missing_variables: string[];
110
+ }
87
111
  type Result<T> = {
88
112
  data: T;
89
113
  error: null;
@@ -101,8 +125,17 @@ declare class Emails {
101
125
  send(options: SendEmailOptions): Promise<Result<SendEmailResponse>>;
102
126
  get(id: string): Promise<Result<Email>>;
103
127
  }
128
+ declare class Templates {
129
+ private readonly client;
130
+ constructor(client: Sendhive);
131
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
132
+ list(): Promise<Result<TemplateSummary[]>>;
133
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
134
+ preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>>;
135
+ }
104
136
  declare class Sendhive {
105
137
  readonly emails: Emails;
138
+ readonly templates: Templates;
106
139
  private readonly apiKey;
107
140
  private readonly baseUrl;
108
141
  constructor(apiKey?: string, options?: SendhiveOptions);
@@ -110,4 +143,4 @@ declare class Sendhive {
110
143
  request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>>;
111
144
  }
112
145
 
113
- export { type Email, type EmailEvent, type EmailTag, type Recipients, type Result, type SendEmailOptions, type SendEmailResponse, Sendhive, type SendhiveError, type SendhiveErrorFix, type SendhiveOptions, type TemplateData, Sendhive as default };
146
+ export { type Email, type EmailEvent, type EmailTag, type Recipients, type Result, type SendEmailOptions, type SendEmailResponse, Sendhive, type SendhiveError, type SendhiveErrorFix, type SendhiveOptions, type TemplateData, type TemplateList, type TemplatePreview, type TemplateSummary, Sendhive as default };
package/dist/index.js CHANGED
@@ -45,8 +45,27 @@ var Emails = class {
45
45
  return this.client.request("GET", `/api/emails/${encodeURIComponent(id)}`);
46
46
  }
47
47
  };
48
+ var Templates = class {
49
+ constructor(client) {
50
+ this.client = client;
51
+ }
52
+ client;
53
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
54
+ async list() {
55
+ const res = await this.client.request("GET", "/api/templates");
56
+ return res.error ? res : { data: res.data.data, error: null };
57
+ }
58
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
59
+ async preview(template, data) {
60
+ return this.client.request("POST", "/api/templates/preview", {
61
+ template,
62
+ ...data !== void 0 ? { data } : {}
63
+ });
64
+ }
65
+ };
48
66
  var Sendhive = class {
49
67
  emails;
68
+ templates;
50
69
  apiKey;
51
70
  baseUrl;
52
71
  constructor(apiKey, options = {}) {
@@ -55,6 +74,7 @@ var Sendhive = class {
55
74
  if (!baseUrl) throw new Error("Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.");
56
75
  this.baseUrl = baseUrl.replace(/\/+$/, "");
57
76
  this.emails = new Emails(this);
77
+ this.templates = new Templates(this);
58
78
  }
59
79
  /** @internal */
60
80
  async request(method, path, body) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n Email,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveOptions,\n} from './types'\n\nexport type {\n Email,\n EmailEvent,\n EmailTag,\n Recipients,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveErrorFix,\n SendhiveOptions,\n TemplateData,\n} from './types'\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\n/** Optional peer: only loaded when the caller passes `react`. */\nasync function renderReact(element: unknown): Promise<string> {\n const specifier = '@react-email/render'\n let mod: { render?: (el: unknown) => string | Promise<string> }\n try {\n mod = await import(/* @vite-ignore */ specifier)\n } catch {\n throw new Error('The `react` option needs the optional peer dependency @react-email/render.')\n }\n if (!mod.render) throw new Error('@react-email/render has no `render` export.')\n return mod.render(element)\n}\n\nclass Emails {\n constructor(private readonly client: Sendhive) {}\n\n async send(options: SendEmailOptions): Promise<Result<SendEmailResponse>> {\n const { replyTo, react, ...rest } = options\n let html = rest.html\n if (react !== undefined) {\n try {\n html = await renderReact(react)\n } catch (err) {\n return {\n data: null,\n error: { statusCode: 422, name: 'validation_error', message: (err as Error).message },\n }\n }\n }\n const body = {\n ...rest,\n ...(html !== undefined ? { html } : {}),\n ...(replyTo !== undefined ? { reply_to: replyTo } : {}),\n }\n return this.client.request<SendEmailResponse>('POST', '/api/emails', body)\n }\n\n async get(id: string): Promise<Result<Email>> {\n return this.client.request<Email>('GET', `/api/emails/${encodeURIComponent(id)}`)\n }\n}\n\nexport class Sendhive {\n readonly emails: Emails\n private readonly apiKey: string | undefined\n private readonly baseUrl: string\n\n constructor(apiKey?: string, options: SendhiveOptions = {}) {\n this.apiKey = apiKey ?? env('SENDHIVE_API_KEY')\n // No default host: an API key must never be sent to a server the caller did not choose.\n const baseUrl = options.baseUrl ?? env('SENDHIVE_BASE_URL')\n if (!baseUrl) throw new Error('Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.')\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n this.emails = new Emails(this)\n }\n\n /** @internal */\n async request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (err) {\n return {\n data: null,\n error: {\n statusCode: 0,\n name: 'network_error',\n message: err instanceof Error ? err.message : String(err),\n },\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n json = null\n }\n\n if (!res.ok) {\n const e = (json ?? {}) as Partial<SendhiveError>\n return {\n data: null,\n error: {\n statusCode: e.statusCode ?? res.status,\n name: e.name ?? 'application_error',\n message: e.message ?? (res.statusText || 'Unexpected response'),\n ...(e.fix ? { fix: e.fix } : {}),\n },\n }\n }\n return { data: json as T, error: null }\n }\n}\n\nexport default Sendhive\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts"],"sourcesContent":["import type {\n Email,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveOptions,\n TemplateData,\n TemplateList,\n TemplatePreview,\n TemplateSummary,\n} from './types'\n\nexport type {\n Email,\n EmailEvent,\n EmailTag,\n Recipients,\n Result,\n SendEmailOptions,\n SendEmailResponse,\n SendhiveError,\n SendhiveErrorFix,\n SendhiveOptions,\n TemplateData,\n TemplateList,\n TemplatePreview,\n TemplateSummary,\n} from './types'\n\nfunction env(name: string): string | undefined {\n return typeof process !== 'undefined' ? process.env?.[name] : undefined\n}\n\n/** Optional peer: only loaded when the caller passes `react`. */\nasync function renderReact(element: unknown): Promise<string> {\n const specifier = '@react-email/render'\n let mod: { render?: (el: unknown) => string | Promise<string> }\n try {\n mod = await import(/* @vite-ignore */ specifier)\n } catch {\n throw new Error('The `react` option needs the optional peer dependency @react-email/render.')\n }\n if (!mod.render) throw new Error('@react-email/render has no `render` export.')\n return mod.render(element)\n}\n\nclass Emails {\n constructor(private readonly client: Sendhive) {}\n\n async send(options: SendEmailOptions): Promise<Result<SendEmailResponse>> {\n const { replyTo, react, ...rest } = options\n let html = rest.html\n if (react !== undefined) {\n try {\n html = await renderReact(react)\n } catch (err) {\n return {\n data: null,\n error: { statusCode: 422, name: 'validation_error', message: (err as Error).message },\n }\n }\n }\n const body = {\n ...rest,\n ...(html !== undefined ? { html } : {}),\n ...(replyTo !== undefined ? { reply_to: replyTo } : {}),\n }\n return this.client.request<SendEmailResponse>('POST', '/api/emails', body)\n }\n\n async get(id: string): Promise<Result<Email>> {\n return this.client.request<Email>('GET', `/api/emails/${encodeURIComponent(id)}`)\n }\n}\n\nclass Templates {\n constructor(private readonly client: Sendhive) {}\n\n /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */\n async list(): Promise<Result<TemplateSummary[]>> {\n const res = await this.client.request<TemplateList>('GET', '/api/templates')\n return res.error ? res : { data: res.data.data, error: null }\n }\n\n /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */\n async preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>> {\n return this.client.request<TemplatePreview>('POST', '/api/templates/preview', {\n template,\n ...(data !== undefined ? { data } : {}),\n })\n }\n}\n\nexport class Sendhive {\n readonly emails: Emails\n readonly templates: Templates\n private readonly apiKey: string | undefined\n private readonly baseUrl: string\n\n constructor(apiKey?: string, options: SendhiveOptions = {}) {\n this.apiKey = apiKey ?? env('SENDHIVE_API_KEY')\n // No default host: an API key must never be sent to a server the caller did not choose.\n const baseUrl = options.baseUrl ?? env('SENDHIVE_BASE_URL')\n if (!baseUrl) throw new Error('Sendhive: set `baseUrl` or SENDHIVE_BASE_URL to your Sendhive server.')\n this.baseUrl = baseUrl.replace(/\\/+$/, '')\n this.emails = new Emails(this)\n this.templates = new Templates(this)\n }\n\n /** @internal */\n async request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>> {\n const headers: Record<string, string> = { Accept: 'application/json' }\n if (this.apiKey) headers.Authorization = `Bearer ${this.apiKey}`\n if (body !== undefined) headers['Content-Type'] = 'application/json'\n\n let res: Response\n try {\n res = await fetch(`${this.baseUrl}${path}`, {\n method,\n headers,\n body: body === undefined ? undefined : JSON.stringify(body),\n })\n } catch (err) {\n return {\n data: null,\n error: {\n statusCode: 0,\n name: 'network_error',\n message: err instanceof Error ? err.message : String(err),\n },\n }\n }\n\n let json: unknown\n try {\n json = await res.json()\n } catch {\n json = null\n }\n\n if (!res.ok) {\n const e = (json ?? {}) as Partial<SendhiveError>\n return {\n data: null,\n error: {\n statusCode: e.statusCode ?? res.status,\n name: e.name ?? 'application_error',\n message: e.message ?? (res.statusText || 'Unexpected response'),\n ...(e.fix ? { fix: e.fix } : {}),\n },\n }\n }\n return { data: json as T, error: null }\n }\n}\n\nexport default Sendhive\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sendhive",
3
- "version": "0.1.0-beta.0",
3
+ "version": "0.1.0-beta.1",
4
4
  "description": "Tiny TypeScript SDK for the Sendhive email API (Resend-compatible shape).",
5
5
  "keywords": [
6
6
  "email",