@pilely/simple-email 0.4.5 → 0.5.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.
package/dist/hooks.d.ts CHANGED
@@ -1,58 +1,65 @@
1
1
  import type { ChallengeOption } from "@pilely/core";
2
2
  import type { UseInfiniteQueryResult, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
3
- import type { SendInput, SendResult } from "./api.js";
4
- import type { Account, AccountInfoEnvelope, AccountSenders, SendRow, Template, TemplateMeta } from "./types.js";
3
+ import type { TemplateSendResult } from "./api.js";
4
+ import type { Account, AccountInfoEnvelope, Template, TemplateMeta } from "./types.js";
5
5
  export interface PageOptions extends ChallengeOption {
6
6
  /** Rows per page; the server defaults to 50 and caps at 100. */
7
7
  limit?: number;
8
8
  }
9
+ /** `recipient` is required: the ONE address the template's sends go to.
10
+ * An omitted (or `null`) group is empty: an empty `send_group` admits
11
+ * nobody, an empty `deny_group` refuses nobody. */
9
12
  export interface CreateTemplateInput {
10
13
  /** `null` for a nameless template. */
11
14
  name: string | null;
12
15
  subject: string;
13
16
  html: string;
17
+ recipient: string;
18
+ /** An owner group, or the platform-wide anonymous or authenticated group. */
19
+ send_group?: string | null;
20
+ /** An owner group only. */
21
+ deny_group?: string | null;
14
22
  }
15
- /** `useCreateEmailAccount`'s object form. Every key is optional: an omitted
16
- * `send_group` means owner-only, an omitted `account_senders` means
17
- * `"send_group"`, and an omitted (or `null`) `reply_to` means no reply-to. */
23
+ /** `useCreateEmailAccount`'s object form. An omitted (or `null`) `reply_to`
24
+ * means no reply-to. */
18
25
  export interface CreateEmailAccountInput {
19
- send_group?: string | null;
20
- account_senders?: AccountSenders;
21
26
  /** The address recipients' replies go to. */
22
27
  reply_to?: string | null;
23
28
  }
24
- /** `useSetEmailAccountAccess`'s object form. `send_group` is required (`null`
25
- * = owner-only); an omitted `account_senders` keeps the current value. */
26
- export interface SetEmailAccountAccessInput {
27
- send_group: string | null;
28
- account_senders?: AccountSenders;
29
- }
30
- /** A full replace of both `subject` and `html`; `name` is not updatable. */
29
+ /** A full replace of both `subject` and `html`; `name` is not updatable. An
30
+ * omitted `recipient`, `send_group` or `deny_group` keeps the stored value;
31
+ * `null` empties a group. */
31
32
  export interface UpdateTemplateInput {
32
33
  templateId: string;
33
34
  subject: string;
34
35
  html: string;
36
+ recipient?: string;
37
+ send_group?: string | null;
38
+ deny_group?: string | null;
39
+ }
40
+ /** `useSendTemplate`'s variables: the template and its placeholder values. */
41
+ export interface SendTemplateInput {
42
+ templateId: string;
43
+ /** One string per placeholder of the template's subject and html; omitted
44
+ * is `{}`, for a template without placeholders. */
45
+ variables?: Record<string, string>;
35
46
  }
36
- /** Sends one email from this app's account: a raw send (`to`) or an account
37
- * send (`to_account: "self" | "owner"`). Not optimistic: a send counts only
38
- * once the server accepted it. A repeat carrying the same `idempotency_key`
39
- * answers the first send with `replayed: true`. */
40
- export declare function useSend(options?: ChallengeOption): UseMutationResult<SendResult, Error, SendInput>;
41
- /** This app's outbox, newest first, as an infinite query. */
42
- export declare function useSends(options?: PageOptions): UseInfiniteQueryResult<SendRow[], Error>;
47
+ /** The template send, from a page: the template, filled from `variables`,
48
+ * to the one recipient its owner stored on it. Not optimistic: a send
49
+ * counts only once the server accepted it. The answer is `{ send_id }`,
50
+ * never the address. It counts toward the app's daily send cap, so it
51
+ * refreshes `useEmailAccount()`. */
52
+ export declare function useSendTemplate(options?: ChallengeOption): UseMutationResult<TemplateSendResult, Error, SendTemplateInput>;
43
53
  /** The caller's email accounts across apps, as an infinite query. */
44
54
  export declare function useEmailAccounts(options?: PageOptions): UseInfiniteQueryResult<Account[], Error>;
45
55
  /** This app's account with its live state: daily cap, sent today and
46
56
  * credit. */
47
57
  export declare function useEmailAccount(options?: ChallengeOption): UseQueryResult<AccountInfoEnvelope, Error>;
48
- /** Creates this app's account; the variable is its optional send group
49
- * (`null` or omitted: owner-only), or `{ send_group?, account_senders?, reply_to? }`. */
50
- export declare function useCreateEmailAccount(options?: ChallengeOption): UseMutationResult<Account, Error, string | null | void | CreateEmailAccountInput>;
58
+ /** Creates this app's account; the variable is optional, or
59
+ * `{ reply_to? }`. */
60
+ export declare function useCreateEmailAccount(options?: ChallengeOption): UseMutationResult<Account, Error, void | CreateEmailAccountInput>;
51
61
  /** Deletes this app's account and the templates under it. */
52
62
  export declare function useDeleteEmailAccount(options?: ChallengeOption): UseMutationResult<void, Error, void>;
53
- /** Replaces this app's send group (`null` means owner-only); the object form
54
- * `{ send_group, account_senders? }` also sets who may make account sends. */
55
- export declare function useSetEmailAccountAccess(options?: ChallengeOption): UseMutationResult<Account, Error, string | null | SetEmailAccountAccessInput>;
56
63
  /** Sets this app's reply-to address — where recipients' replies go; every
57
64
  * send from the account carries it as its `Reply-To` — or clears it with
58
65
  * `null`. The variable is required: there is no "keep" form. */
package/dist/hooks.js CHANGED
@@ -1,7 +1,5 @@
1
1
  import { serviceQueryKey, useServiceInfiniteQuery, useServiceMutation, useServiceQuery } from "@pilely/core";
2
- import { accountInfo, createAccount, createTemplate, deleteAccount, deleteTemplate, listAccounts, listSends, listTemplates, send, setAccountAccess, setReplyTo, templateInfo, updateTemplate, } from "./api.js";
3
- /** `["pilely", "simple-email", "sends", options]` */
4
- const sendsKey = () => serviceQueryKey("simple-email", "sends");
2
+ import { accountInfo, createAccount, createTemplate, deleteAccount, deleteTemplate, listAccounts, listTemplates, sendTemplate, setReplyTo, templateInfo, updateTemplate, } from "./api.js";
5
3
  /** `["pilely", "simple-email", "accounts", options]` */
6
4
  const accountsKey = () => serviceQueryKey("simple-email", "accounts");
7
5
  /** `["pilely", "simple-email", "account"]` — this app's account info. */
@@ -11,26 +9,16 @@ const templatesKey = () => serviceQueryKey("simple-email", "templates");
11
9
  /** `["pilely", "simple-email", "template", templateId]` */
12
10
  const templateKey = (templateId) => serviceQueryKey("simple-email", "template", templateId);
13
11
  // ── Sending ──────────────────────────────────────────────────────────────
14
- /** Sends one email from this app's account: a raw send (`to`) or an account
15
- * send (`to_account: "self" | "owner"`). Not optimistic: a send counts only
16
- * once the server accepted it. A repeat carrying the same `idempotency_key`
17
- * answers the first send with `replayed: true`. */
18
- export function useSend(options = {}) {
12
+ /** The template send, from a page: the template, filled from `variables`,
13
+ * to the one recipient its owner stored on it. Not optimistic: a send
14
+ * counts only once the server accepted it. The answer is `{ send_id }`,
15
+ * never the address. It counts toward the app's daily send cap, so it
16
+ * refreshes `useEmailAccount()`. */
17
+ export function useSendTemplate(options = {}) {
19
18
  const { challenge } = options;
20
- return useServiceMutation("useSend", {
21
- mutationFn: (input) => send(input, { challenge }),
22
- invalidates: () => [sendsKey()],
23
- });
24
- }
25
- /** This app's outbox, newest first, as an infinite query. */
26
- export function useSends(options = {}) {
27
- const { limit, challenge } = options;
28
- return useServiceInfiniteQuery("useSends", {
29
- queryKey: [...sendsKey(), { limit }],
30
- fetchPage: async (cursor) => {
31
- const page = await listSends({ limit, ...(cursor ?? {}) }, { challenge });
32
- return { rows: page.sends, nextCursor: page.next_cursor };
33
- },
19
+ return useServiceMutation("useSendTemplate", {
20
+ mutationFn: ({ templateId, variables }) => sendTemplate(templateId, variables, { challenge }),
21
+ invalidates: () => [accountKey()],
34
22
  });
35
23
  }
36
24
  // ── Accounts ─────────────────────────────────────────────────────────────
@@ -54,14 +42,12 @@ export function useEmailAccount(options = {}) {
54
42
  queryFn: () => accountInfo({ challenge }),
55
43
  });
56
44
  }
57
- /** Creates this app's account; the variable is its optional send group
58
- * (`null` or omitted: owner-only), or `{ send_group?, account_senders?, reply_to? }`. */
45
+ /** Creates this app's account; the variable is optional, or
46
+ * `{ reply_to? }`. */
59
47
  export function useCreateEmailAccount(options = {}) {
60
48
  const { challenge } = options;
61
49
  return useServiceMutation("useCreateEmailAccount", {
62
- mutationFn: (input) => typeof input === "object" && input !== null
63
- ? createAccount(input.send_group, input.account_senders, input.reply_to, { challenge })
64
- : createAccount(input ?? undefined, undefined, undefined, { challenge }),
50
+ mutationFn: (input) => createAccount(input ? input.reply_to : undefined, { challenge }),
65
51
  invalidates: () => [accountsKey(), accountKey()],
66
52
  });
67
53
  }
@@ -73,17 +59,6 @@ export function useDeleteEmailAccount(options = {}) {
73
59
  invalidates: () => [accountsKey(), accountKey(), templatesKey(), serviceQueryKey("simple-email", "template")],
74
60
  });
75
61
  }
76
- /** Replaces this app's send group (`null` means owner-only); the object form
77
- * `{ send_group, account_senders? }` also sets who may make account sends. */
78
- export function useSetEmailAccountAccess(options = {}) {
79
- const { challenge } = options;
80
- return useServiceMutation("useSetEmailAccountAccess", {
81
- mutationFn: (input) => typeof input === "object" && input !== null
82
- ? setAccountAccess(input.send_group, input.account_senders, { challenge })
83
- : setAccountAccess(input, undefined, { challenge }),
84
- invalidates: () => [accountsKey(), accountKey()],
85
- });
86
- }
87
62
  /** Sets this app's reply-to address — where recipients' replies go; every
88
63
  * send from the account carries it as its `Reply-To` — or clears it with
89
64
  * `null`. The variable is required: there is no "keep" form. */
@@ -118,14 +93,14 @@ export function useTemplate(templateId, options = {}) {
118
93
  export function useCreateTemplate(options = {}) {
119
94
  const { challenge } = options;
120
95
  return useServiceMutation("useCreateTemplate", {
121
- mutationFn: ({ name, subject, html }) => createTemplate(name, subject, html, { challenge }),
96
+ mutationFn: (input) => createTemplate(input, { challenge }),
122
97
  invalidates: () => [templatesKey()],
123
98
  });
124
99
  }
125
100
  export function useUpdateTemplate(options = {}) {
126
101
  const { challenge } = options;
127
102
  return useServiceMutation("useUpdateTemplate", {
128
- mutationFn: ({ templateId, subject, html }) => updateTemplate(templateId, { subject, html }, { challenge }),
103
+ mutationFn: ({ templateId, ...body }) => updateTemplate(templateId, body, { challenge }),
129
104
  invalidates: (_template, { templateId }) => [templatesKey(), templateKey(templateId)],
130
105
  });
131
106
  }
package/dist/index.d.ts CHANGED
@@ -1,4 +1,7 @@
1
- export { useCreateEmailAccount, useCreateTemplate, useDeleteEmailAccount, useDeleteTemplate, useEmailAccount, useEmailAccounts, useSend, useSends, useSetEmailAccountAccess, useSetEmailReplyTo, useTemplate, useTemplates, useUpdateTemplate, } from "./hooks.js";
2
- export type { CreateEmailAccountInput, CreateTemplateInput, PageOptions, SetEmailAccountAccessInput, UpdateTemplateInput, } from "./hooks.js";
3
- export type { AccountSendInput, RawSendInput, SendContent, SendInput, SendKey, SendResult } from "./api.js";
4
- export type { Account, AccountSenders, SimpleEmailErrorCode, AccountCursor, AccountInfoEnvelope, SendCursor, SendRow, Template, TemplateCursor, TemplateMeta, ToAccount, } from "./types.js";
1
+ export { useCreateEmailAccount, useCreateTemplate, useDeleteEmailAccount, useDeleteTemplate, useEmailAccount, useEmailAccounts, useSendTemplate, useSetEmailReplyTo, useTemplate, useTemplates, useUpdateTemplate, } from "./hooks.js";
2
+ export type { CreateEmailAccountInput, CreateTemplateInput, PageOptions, SendTemplateInput, UpdateTemplateInput, } from "./hooks.js";
3
+ export { sendTemplate } from "./api.js";
4
+ export type { TemplateSendResult } from "./api.js";
5
+ export { SIMPLE_EMAIL_ORIGIN, SendError, send } from "./send.js";
6
+ export type { SendContent, SendInput, SendKey, SendOptions, SendResult } from "./send.js";
7
+ export type { Account, SimpleEmailErrorCode, AccountCursor, AccountInfoEnvelope, Template, TemplateCursor, TemplateMeta, } from "./types.js";
package/dist/index.js CHANGED
@@ -1,4 +1,9 @@
1
1
  // @pilely/simple-email — React hooks over the simple_email service: a query
2
2
  // hook for every read, a mutation hook for every write. Render them inside
3
- // @pilely/core's <PilelyProvider>.
4
- export { useCreateEmailAccount, useCreateTemplate, useDeleteEmailAccount, useDeleteTemplate, useEmailAccount, useEmailAccounts, useSend, useSends, useSetEmailAccountAccess, useSetEmailReplyTo, useTemplate, useTemplates, useUpdateTemplate, } from "./hooks.js";
3
+ // @pilely/core's <PilelyProvider>. `sendTemplate` is the template send a
4
+ // page makes, as a plain function. `send` is the freestyle send for an
5
+ // app's backend only; a server imports it from `@pilely/simple-email/send`,
6
+ // which loads none of this entry's peers.
7
+ export { useCreateEmailAccount, useCreateTemplate, useDeleteEmailAccount, useDeleteTemplate, useEmailAccount, useEmailAccounts, useSendTemplate, useSetEmailReplyTo, useTemplate, useTemplates, useUpdateTemplate, } from "./hooks.js";
8
+ export { sendTemplate } from "./api.js";
9
+ export { SIMPLE_EMAIL_ORIGIN, SendError, send } from "./send.js";
package/dist/mock.d.ts CHANGED
@@ -1,2 +1,9 @@
1
1
  import type { MockServiceFactory } from "@pilely/core";
2
+ /** The fake's ids for the two platform-wide groups: fixed test values, not
3
+ * the production ids. `@pilely/simple-group`'s fake answers the same two
4
+ * from `groups/anonymous` and `groups/authenticated`, so in mock mode an id
5
+ * read from `anonymousGroupId()` / `authenticatedGroupId()` works as a
6
+ * template's `send_group` here. Not part of the package's public surface. */
7
+ export declare const MOCK_ANON_GROUP = "mockAnonymousGroup0001";
8
+ export declare const MOCK_AUTH_GROUP = "mockAuthenticatedGrp01";
2
9
  export declare const createSimpleEmailFake: MockServiceFactory;