sendhive 0.1.0-beta.0 → 0.1.0-beta.2

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,25 @@ 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
+ **Designer templates** are polished ready-made layouts (sets Barebone, Matte, Protocol, Arcane and Studio: welcome, password reset, order confirmation and more). They are sent the same way, for example `template: 'preset:matte-welcome'`, but they cannot be edited in the visual editor. `templates.list()` marks them with `style: 'designer'` and their `set`; the `variables` field tells you which `data` keys to pass.
73
+
74
+ ## Templates
75
+
76
+ ```ts
77
+ // Your templates and the ready-made ones (slug 'preset:welcome', 'preset:order-shipped', ...)
78
+ const { data: templates, error } = await sendhive.templates.list()
79
+ // templates[0] -> { id, slug, name, kind: 'custom' | 'preset', subject, preview_text, variables, updated_at,
80
+ // style?: 'editable' | 'designer', set?: 'Barebone' | 'Matte' | 'Protocol' | 'Arcane' | 'Studio' }
81
+
82
+ // Draw a template with data. Missing values are not an error: they show as {{name}} and are listed.
83
+ const { data: preview } = await sendhive.templates.preview('preset:welcome', { customer_name: 'Asha' })
84
+ // preview -> { subject, html, text, missing_variables }
85
+ ```
86
+
87
+ `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.
88
+
70
89
  ## Get
71
90
 
72
91
  ```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,34 @@ 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
+ /** `editable` templates open in the visual editor; `designer` ones are ready-made layouts that are only sent. */
101
+ style?: 'editable' | 'designer';
102
+ /** The designer set a `designer` template belongs to. */
103
+ set?: 'Barebone' | 'Matte' | 'Protocol' | 'Arcane' | 'Studio';
104
+ }
105
+ interface TemplateList {
106
+ data: TemplateSummary[];
107
+ }
108
+ /** A template drawn with the data you gave. Values you left out show as `{{name}}` and are listed. */
109
+ interface TemplatePreview {
110
+ subject: string;
111
+ html: string;
112
+ text: string;
113
+ missing_variables: string[];
114
+ }
87
115
  type Result<T> = {
88
116
  data: T;
89
117
  error: null;
@@ -101,8 +129,17 @@ declare class Emails {
101
129
  send(options: SendEmailOptions): Promise<Result<SendEmailResponse>>;
102
130
  get(id: string): Promise<Result<Email>>;
103
131
  }
132
+ declare class Templates {
133
+ private readonly client;
134
+ constructor(client: Sendhive);
135
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
136
+ list(): Promise<Result<TemplateSummary[]>>;
137
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
138
+ preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>>;
139
+ }
104
140
  declare class Sendhive {
105
141
  readonly emails: Emails;
142
+ readonly templates: Templates;
106
143
  private readonly apiKey;
107
144
  private readonly baseUrl;
108
145
  constructor(apiKey?: string, options?: SendhiveOptions);
@@ -110,4 +147,4 @@ declare class Sendhive {
110
147
  request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>>;
111
148
  }
112
149
 
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 };
150
+ 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,34 @@ 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
+ /** `editable` templates open in the visual editor; `designer` ones are ready-made layouts that are only sent. */
101
+ style?: 'editable' | 'designer';
102
+ /** The designer set a `designer` template belongs to. */
103
+ set?: 'Barebone' | 'Matte' | 'Protocol' | 'Arcane' | 'Studio';
104
+ }
105
+ interface TemplateList {
106
+ data: TemplateSummary[];
107
+ }
108
+ /** A template drawn with the data you gave. Values you left out show as `{{name}}` and are listed. */
109
+ interface TemplatePreview {
110
+ subject: string;
111
+ html: string;
112
+ text: string;
113
+ missing_variables: string[];
114
+ }
87
115
  type Result<T> = {
88
116
  data: T;
89
117
  error: null;
@@ -101,8 +129,17 @@ declare class Emails {
101
129
  send(options: SendEmailOptions): Promise<Result<SendEmailResponse>>;
102
130
  get(id: string): Promise<Result<Email>>;
103
131
  }
132
+ declare class Templates {
133
+ private readonly client;
134
+ constructor(client: Sendhive);
135
+ /** Your templates plus the ready-made ones (their `slug` starts with `preset:`). */
136
+ list(): Promise<Result<TemplateSummary[]>>;
137
+ /** Draws a template (slug, id or `preset:<id>`) with `data`; values you leave out show as `{{name}}`. */
138
+ preview(template: string, data?: TemplateData): Promise<Result<TemplatePreview>>;
139
+ }
104
140
  declare class Sendhive {
105
141
  readonly emails: Emails;
142
+ readonly templates: Templates;
106
143
  private readonly apiKey;
107
144
  private readonly baseUrl;
108
145
  constructor(apiKey?: string, options?: SendhiveOptions);
@@ -110,4 +147,4 @@ declare class Sendhive {
110
147
  request<T>(method: 'GET' | 'POST', path: string, body?: unknown): Promise<Result<T>>;
111
148
  }
112
149
 
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 };
150
+ 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.2",
4
4
  "description": "Tiny TypeScript SDK for the Sendhive email API (Resend-compatible shape).",
5
5
  "keywords": [
6
6
  "email",