@nocobase/app-plugin-mail 1.0.0-beta.11 → 1.0.0-beta.12

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.
Files changed (74) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +10 -2
  3. package/dist/client/components/mail-account-connector.d.ts +1 -0
  4. package/dist/client/components/mail-account-connector.d.ts.map +1 -1
  5. package/dist/client/components/mail-account-connector.js +4 -3
  6. package/dist/client/components/mail-account-connector.js.map +1 -1
  7. package/dist/client/components/mail-navigation-icon.d.ts.map +1 -1
  8. package/dist/client/components/mail-navigation-icon.js +3 -50
  9. package/dist/client/components/mail-navigation-icon.js.map +1 -1
  10. package/dist/client/components/public.d.ts +1 -1
  11. package/dist/client/components/public.d.ts.map +1 -1
  12. package/dist/client/components/public.js.map +1 -1
  13. package/dist/client/contracts/composer.d.ts +29 -2
  14. package/dist/client/contracts/composer.d.ts.map +1 -1
  15. package/dist/client/contracts/composer.js.map +1 -1
  16. package/dist/client/hooks/use-mail-composer.d.ts +1 -1
  17. package/dist/client/hooks/use-mail-composer.d.ts.map +1 -1
  18. package/dist/client/hooks/use-mail-composer.js +54 -10
  19. package/dist/client/hooks/use-mail-composer.js.map +1 -1
  20. package/dist/client/hooks/use-mail-unread-count.d.ts +13 -0
  21. package/dist/client/hooks/use-mail-unread-count.d.ts.map +1 -0
  22. package/dist/client/hooks/use-mail-unread-count.js +106 -0
  23. package/dist/client/hooks/use-mail-unread-count.js.map +1 -0
  24. package/dist/client/index.d.ts +3 -0
  25. package/dist/client/index.d.ts.map +1 -1
  26. package/dist/client/index.js +2 -0
  27. package/dist/client/index.js.map +1 -1
  28. package/dist/client/lib/mail-composer-completion.d.ts +5 -0
  29. package/dist/client/lib/mail-composer-completion.d.ts.map +1 -0
  30. package/dist/client/lib/mail-composer-completion.js +28 -0
  31. package/dist/client/lib/mail-composer-completion.js.map +1 -0
  32. package/dist/client/locales/en-US.d.ts +1 -0
  33. package/dist/client/locales/en-US.d.ts.map +1 -1
  34. package/dist/client/locales/en-US.js +4 -3
  35. package/dist/client/locales/en-US.js.map +1 -1
  36. package/dist/client/locales/zh-CN.d.ts.map +1 -1
  37. package/dist/client/locales/zh-CN.js +3 -2
  38. package/dist/client/locales/zh-CN.js.map +1 -1
  39. package/dist/client/pages/mail-accounts-page.d.ts.map +1 -1
  40. package/dist/client/pages/mail-accounts-page.js +4 -1
  41. package/dist/client/pages/mail-accounts-page.js.map +1 -1
  42. package/dist/client/pages/mail-workspace-page.d.ts +4 -2
  43. package/dist/client/pages/mail-workspace-page.d.ts.map +1 -1
  44. package/dist/client/pages/mail-workspace-page.js +222 -171
  45. package/dist/client/pages/mail-workspace-page.js.map +1 -1
  46. package/dist/client/prepare-mail-reply.d.ts +9 -0
  47. package/dist/client/prepare-mail-reply.d.ts.map +1 -0
  48. package/dist/client/prepare-mail-reply.js +28 -0
  49. package/dist/client/prepare-mail-reply.js.map +1 -0
  50. package/dist/server/config.d.ts +1 -1
  51. package/dist/server/config.d.ts.map +1 -1
  52. package/dist/server/config.js +17 -9
  53. package/dist/server/config.js.map +1 -1
  54. package/dist/server/locales/en-US.d.ts +1 -0
  55. package/dist/server/locales/en-US.d.ts.map +1 -1
  56. package/dist/server/locales/en-US.js +1 -0
  57. package/dist/server/locales/en-US.js.map +1 -1
  58. package/dist/server/locales/zh-CN.d.ts.map +1 -1
  59. package/dist/server/locales/zh-CN.js +1 -0
  60. package/dist/server/locales/zh-CN.js.map +1 -1
  61. package/dist/server/providers/mail-core.d.ts +2 -0
  62. package/dist/server/providers/mail-core.d.ts.map +1 -1
  63. package/dist/server/providers/mail-core.js +39 -1
  64. package/dist/server/providers/mail-core.js.map +1 -1
  65. package/dist/server/routes/api.js +3 -1
  66. package/dist/server/routes/api.js.map +1 -1
  67. package/dist/server/services/authorization.js +1 -1
  68. package/dist/server/services/authorization.js.map +1 -1
  69. package/dist/shared/mail.d.ts +1 -1
  70. package/dist/shared/mail.d.ts.map +1 -1
  71. package/package.json +8 -5
  72. package/skills/nocobase-app-plugin-mail/references/client-integration.md +106 -0
  73. package/skills/nocobase-app-plugin-mail/references/configuration-and-accounts.md +10 -4
  74. package/skills/nocobase-app-plugin-mail/references/public-api.md +25 -20
@@ -23,7 +23,9 @@ import { mailConfig } from '@nocobase/app-plugin-mail/server';
23
23
  export default mailConfig;
24
24
  ```
25
25
 
26
- Then add `import mail from './mail.js';`, `mail: ReturnType<typeof mail>;`, and `mail,` to `server/config/index.ts` alongside the existing application config factories. The Mail plugin falls back to built-in defaults when the whole namespace is absent, but provider instances still require this registration. If the application uses `MAIL_*` environment overrides, merge `mailEnvironmentMappings` from `@nocobase/app-plugin-mail/server` into its mappings in `server/environment.ts`; package metadata lists supported variables but does not activate them. The OAuth overrides are `MAIL_OAUTH_CALLBACK_URL` and `MAIL_OAUTH_RETURN_URL`.
26
+ Register this factory under `mail` in `server/config/index.ts` through `defaultAppConfigs()`. The Mail plugin falls back to built-in defaults when the whole namespace is absent, but provider instances still require this registration. `mailConfig` already declares all seven `MAIL_*` environment overrides using section-relative paths, and `pnpm nocobase config env` discovers them. No application-level environment file or duplicated mappings are needed. `mailEnvironmentMappings` remains a compatibility export with fully prefixed `mail.*` paths for older application-level providers; never pass it directly as a section's `env`.
27
+
28
+ Environment values override configuration files and code defaults. Before upgrading, review existing OAuth, sync, webhook and jobs variables that may previously have been inert. Undefined values keep defaults; empty or invalid integer values fail configuration loading, and Mail retains its numeric bounds. Existing application-level providers can coexist when their mappings match; section rules take priority over their custom transformations, so migrate custom parsers into the section rules when needed. A variable mapped to different paths in different sections is rejected even when unset. Mail configuration is not public browser configuration, and webhook secrets must not be exposed.
27
29
 
28
30
  `mail.providers` is a map keyed by stable instance names. The map key is the provider name; each value contains `type` and provider-specific options. Multiple instances of the same type can coexist. Renaming an instance breaks its existing account association. `enabled` defaults to `true`; disabling an instance also makes it unavailable to existing accounts.
29
31
 
@@ -94,7 +96,9 @@ Official references: [Gmail API quotas and quota-increase guidance](https://deve
94
96
 
95
97
  For IMAP/SMTP, `secure: true` means TLS from connection start; STARTTLS endpoints use the service's prescribed settings. TLS certificate verification defaults to enabled. Mail validates both endpoints before saving account credentials. Use the provider-required app password or authorization code where applicable.
96
98
 
97
- Provider secrets, endpoints and allowed OAuth `scopes` live in `mail.providers`. The top-level `MAIL_*` overrides below do not create per-provider credential environment mappings. Do not assume generic `${NAME}` interpolation in YAML; use the target application's supported server configuration mechanism. In applications generated from the OSS default template, merge `mailEnvironmentMappings` into the application-owned mappings in `server/environment.ts`. Keep actual secrets in private server configuration, out of committed examples and client bundles, and restart after changing configuration.
99
+ The connection form's Username is the shared IMAP and SMTP login name, not the sender's display name. It is optional: an omitted, empty, or whitespace-only value uses the entered mailbox address. A supplied login name is trimmed without changing case or requiring email syntax. Mailbox address and password remain required.
100
+
101
+ Provider secrets, endpoints and allowed OAuth `scopes` live in `mail.providers`. The top-level `MAIL_*` overrides below do not create per-provider credential environment mappings. Do not assume generic `${NAME}` interpolation in YAML; use the target application's supported server configuration mechanism. Keep actual secrets in private server configuration, out of committed examples and client bundles, and restart after changing configuration.
98
102
 
99
103
  ## Connect and manage accounts
100
104
 
@@ -114,7 +118,9 @@ https://mail.example.com/main/mail/oauth/callback
114
118
 
115
119
  Override through `mail.oauthCallbackUrl` or `MAIL_OAUTH_CALLBACK_URL`. A relative path receives the application prefix; an absolute HTTP(S) URL must already include it and reach the mounted callback. Register the exact resulting URL with the OAuth provider. Fragments are invalid. `oauthCallbackUrl` controls only the provider callback endpoint, not the page shown in the browser after authorization.
116
120
 
117
- Configure the browser destination through `mail.oauthReturnUrl` or `MAIL_OAUTH_RETURN_URL`. It defaults to `/`, the application root, because the plugin ships no page; point it at the application page that renders `MailAccountsPage`. A relative return path receives the application public base path, so `/mail/accounts` under `/main` becomes `/main/mail/accounts`; an absolute HTTP(S) URL is also supported and is treated as trusted server configuration. Fragments are invalid.
121
+ Configure the browser destination through `mail.oauthReturnUrl` or `MAIL_OAUTH_RETURN_URL`. It defaults to the application's root (`/`), and the plugin registers no built-in Dev, settings or management pages or routes. Register an application-owned page rendering the public `MailAccountsPage`, such as `/mail/accounts`, and configure the return URL to match that personal account page. A relative return path receives the application public base path, so `/mail/accounts` under `/main` becomes `/main/mail/accounts`; an absolute HTTP(S) URL is also supported and is treated as trusted server configuration. Fragments are invalid.
122
+
123
+ Mail warns once at production startup if the effective return destination targets the legacy `/dev/mail/accounts` page, including prefixed and absolute URL forms with query parameters. The current root (`/`) default does not trigger the warning. The warning does not change defaults, block startup, validate arbitrary client route existence, or expose full URLs or secrets. Production apps must register their own authenticated personal account page, such as `/mail/accounts`, with `page / mail.workspace / access` permission; reuse the public `MailAccountsPage`, which already reads authorization results and refreshes accounts. An application-owned administrator overview using the read-only all-user APIs is not a personal connection destination. See [Client integration](client-integration.md) for route composition. Set `MailWorkspacePage.accountsHref` separately: a navigation link does not configure the server's OAuth return.
118
124
 
119
125
  For a production application, configure the callback and return paths together so the provider callback and application page are not confused:
120
126
 
@@ -126,7 +132,7 @@ mail:
126
132
 
127
133
  With origin `https://mail.example.com` and public base path `/main`, the provider must redirect to `https://mail.example.com/main/mail/oauth/callback`, and the browser will finish at `https://mail.example.com/main/mail/accounts?mailAuthorization=success` or `https://mail.example.com/main/mail/accounts?mailAuthorization=failure`. Register the full callback URL with the selected OAuth provider, such as Google for Gmail or Microsoft Entra ID for Microsoft 365, not the return page URL.
128
134
 
129
- When deployment values come from environment variables, use `MAIL_OAUTH_CALLBACK_URL=/mail/oauth/callback` and `MAIL_OAUTH_RETURN_URL=/mail/accounts` as the values and explicitly map them to `mail.oauthCallbackUrl` and `mail.oauthReturnUrl` in the application's `server/environment.ts`. Declaring the variables in the Mail package metadata does not replace the application's mapping, and generic `${NAME}` interpolation must not be assumed.
135
+ When deployment values come from environment variables, use `MAIL_OAUTH_CALLBACK_URL=/mail/oauth/callback` and `MAIL_OAUTH_RETURN_URL=/mail/accounts` without repeating `/main`. Composing `mailConfig` as `mail` activates these overrides automatically. Current templates use configuration-section rules, not an application-level environment file. A wrapper that customizes defaults must explicitly retain `env: mailConfig.rules?.env`; merely calling `mailConfig(runtime)` returns defaults, not its environment rules. To customize parsing, spread those section rules and override the selected variable using a section-relative path. Do not pass the legacy full-path `mailEnvironmentMappings` as a section's `env`.
130
136
 
131
137
  The plugin preserves query parameters already present in the configured return URL and adds or replaces `mailAuthorization=success` or `mailAuthorization=failure`. The application-owned return page can use this status to show a result and refresh its account state.
132
138
 
@@ -16,7 +16,7 @@ The package root is a Server alias retained for plugin registration and applicat
16
16
 
17
17
  ### Plugin and configuration
18
18
 
19
- The Server entry exports the default plugin, `mailConfig`, `DEFAULT_MAIL_CONFIG`, `mailEnvironmentMappings`, `resolveMailConfig`, and the `MailConfig`/provider configuration types. Applications register the plugin and explicitly compose its configuration factory as described in [Configuration and accounts](configuration-and-accounts.md).
19
+ The Server entry exports the default plugin, `mailConfig`, `DEFAULT_MAIL_CONFIG`, `mailEnvironmentMappings`, `resolveMailConfig`, and the `MailConfig`/provider configuration types. Applications register the plugin and explicitly compose its configuration factory as described in [Configuration and accounts](configuration-and-accounts.md). `mailConfig.rules.env` supplies seven section-relative `MAIL_*` mappings; wrappers must retain those rules explicitly. `mailEnvironmentMappings` preserves fully prefixed `mail.*` paths and parsing for legacy application-level environment providers, not section-level `env`. Neither interface makes private Mail configuration public.
20
20
 
21
21
  ### Supported tokens
22
22
 
@@ -62,10 +62,13 @@ Output status, folder-type and Provider error category/reason types have `Known.
62
62
  ### Composition and data access
63
63
 
64
64
  - The default export registers the Mail Client plugin.
65
- - `MailWorkspacePage` and `MailWorkspacePageProps` provide the full workspace. `accountsHref` names the application's accounts page, relative to its base path, so a user with no account is linked there; without it the empty state shows no link. `templateVariables` supplies an allowlisted record context for saved template placeholders; it does not associate messages with application records.
65
+ - `MailWorkspacePage` and `MailWorkspacePageProps` provide the full workspace. `title` and `description` customize the heading; `templateVariables` supplies an allowlisted record context for saved template placeholders and does not associate messages with application records. `accountsHref` is an optional application-internal personal account path without a deployment prefix: the workspace resolves it with `resolveAppUrl()`, shows a connection link when no usable accounts exist, and a Mail accounts link in its header otherwise. Without it no account link is generated. `headerActions?: ReactNode` appends actions after Compose, Sync and the optional account link without replacing them.
66
+ - `MailAccountsPage` and `MailAccountsPageProps` provide the personal connection and management page for application-owned production routes. The administrator's read-only account overview is not a replacement.
66
67
  - `MailClient` and `mailClientToken` expose the typed client data layer. Resolve the app-owned instance with `useMailClient()` in React or `app.services.resolve(mailClientToken)` elsewhere; do not construct a separate `MailClient` for normal UI integration.
68
+ - `useMailUnreadCount(): MailUnreadCountState` exposes the current user's count, loading state and latest request error through the host Mail/realtime services. Until the first successful response, `unreadCount` is `undefined`, not zero; refresh failures retain the last successful count. It shares the navigation icon's local/realtime/reconnect/focus/polling refresh logic and instance-local debounce/serialization. Mount in a session-owned scope that remounts on user changes; there is no shared global cache or automatic session observer. See [custom unread menus](client-integration.md#unread-counts-on-custom-menus). Low-level event/subscription implementation files remain private.
67
69
  - `mailErrorMessage(cause, fallback)` returns the text to show for a failed call: the server's `localizedMessage`, or `fallback`. Code that must react to a specific failure branches on `ApiClientError.reason` from `@nocobase/app-client` instead.
68
70
  - `renderMailTemplate()`, `plainTextToMailHtml()`, and `htmlToPlainText()` are supported template/body helpers. `MailTemplateVariables` and `RenderedMailTemplate` describe their data.
71
+ - `prepareMailReply(mail, message): Promise<MailComposerRequest>` prepares a browser-side reply using the original account/local message ID, Reply-To or From, and a single `Re:` prefix. It retries incomplete content and copies referenced CID images into owned `uploads`, rejects preparation failures, and does not carry ordinary attachments, open a composer, save or send mail. The returned request preserves the separate reply quote for shared composer sending and draft recovery. `MailComposerRequest` is exported here and from `/client/components`. See [custom reply integration](client-integration.md#prepare-replies-on-custom-pages) for network effects, sandbox rendering and caller-owned concurrency guards.
69
72
  - `MAIL_PLUGIN_NS`, `MAIL_REALTIME_TOPIC`, and `MailRealtimeEvent` expose the translation namespace and invalidation event contract.
70
73
  - `MAIL_VIRTUAL_FOLDER_IDS` provides stable query identifiers for built-in cross-account folders. `MAIL_LABEL_COLORS` and `DEFAULT_MAIL_LABEL_COLOR` provide the supported user-label palette and default.
71
74
 
@@ -87,27 +90,29 @@ The TypeScript signatures are the request/result source of truth. For direct HTT
87
90
 
88
91
  All components below are exported from `@nocobase/app-plugin-mail/client/components`. Components that call `useMailClient()` require the Mail Client plugin to be registered in the host application.
89
92
 
90
- | Component | Exported props and related types |
91
- | ----------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
92
- | `MailAccountCard` | `MailAccountCardProps` |
93
- | `MailAccountConnector` | `MailAccountConnectorProps`, `MailAccountConnectorLabels`, `MailAccountCredentials` |
94
- | `MailConversationView` | `MailConversationViewProps`, `MailConversationViewLabels` |
95
- | `MailMessageList` | `MailMessageListProps`, `MailMessageListLabels` |
96
- | `MailProviderCard` | `MailProviderCardProps` |
97
- | `MailRichTextEditor` | `MailRichTextEditorProps`, `MailRichTextValue`, `MailRichTextEditorLabels`, `MailRichTextEditorInsertOption`, `MailRichTextEditorInsertMenu`, `MailRichTextEditorInsertActions` |
98
- | `MailNavigationIcon` | No props; displays the user's unread count using the host app services. |
99
- | `MailLabelManager` | No props; reads and edits the current user's labels. |
100
- | `MailLabelTag`, `MailLabelColorDot` | `MailLabelTagProps`, `MailLabelColorDotProps` |
101
- | `MailSignatureManager` | `MailSignatureManagerProps` |
102
- | `MailStatusBadge` | `MailStatusBadgeProps`, `MailStatusTone` |
103
- | `MailSyncPolicyFields` | `MailSyncPolicyFieldsProps`, `MailSyncPolicyValue` |
104
- | `MailTemplateManager` | No props; reads and edits the current user's templates. |
105
- | `MailboxSidebar` | `MailboxSidebarProps`, `MailboxSidebarLabels`, `MailboxFolderGroup`, `MailboxSmartView` |
106
- | `MailComposer` | `MailComposerComponentProps` and shared `MailComposerProps`, `MailComposerRequest`, `MailComposerState`, `MailComposerCompletionResult`, `MailForwardQuote`, `MailTemplateVariables`, `EMPTY_MAIL_COMPOSER` |
107
- | `MailWorkspaceComposer` | `MailWorkspaceComposerProps` and the shared composer contracts above. |
93
+ | Component | Exported props and related types |
94
+ | ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
95
+ | `MailAccountCard` | `MailAccountCardProps` |
96
+ | `MailAccountConnector` | `MailAccountConnectorProps`, `MailAccountConnectorLabels`, `MailAccountCredentials` |
97
+ | `MailConversationView` | `MailConversationViewProps`, `MailConversationViewLabels` |
98
+ | `MailMessageList` | `MailMessageListProps`, `MailMessageListLabels` |
99
+ | `MailProviderCard` | `MailProviderCardProps` |
100
+ | `MailRichTextEditor` | `MailRichTextEditorProps`, `MailRichTextValue`, `MailRichTextEditorLabels`, `MailRichTextEditorInsertOption`, `MailRichTextEditorInsertMenu`, `MailRichTextEditorInsertActions` |
101
+ | `MailNavigationIcon` | No props; displays the user's unread count using the host app services. |
102
+ | `MailLabelManager` | No props; reads and edits the current user's labels. |
103
+ | `MailLabelTag`, `MailLabelColorDot` | `MailLabelTagProps`, `MailLabelColorDotProps` |
104
+ | `MailSignatureManager` | `MailSignatureManagerProps` |
105
+ | `MailStatusBadge` | `MailStatusBadgeProps`, `MailStatusTone` |
106
+ | `MailSyncPolicyFields` | `MailSyncPolicyFieldsProps`, `MailSyncPolicyValue` |
107
+ | `MailTemplateManager` | No props; reads and edits the current user's templates. |
108
+ | `MailboxSidebar` | `MailboxSidebarProps`, `MailboxSidebarLabels`, `MailboxFolderGroup`, `MailboxSmartView` |
109
+ | `MailComposer` | `MailComposerComponentProps` and shared `MailComposerProps`, `MailComposerRequest`, `MailComposerState`, `MailComposerCompletionResult`, `MailComposerCompletionCallback`, `MailComposerCompletionDetails`, `MailComposerSubmissionSnapshot`, `MailForwardQuote`, `MailTemplateVariables`, `EMPTY_MAIL_COMPOSER` |
110
+ | `MailWorkspaceComposer` | `MailWorkspaceComposerProps` and the shared composer contracts above. |
108
111
 
109
112
  `MailComposer` renders one supplied account/request. `MailWorkspaceComposer` also manages account and sender identity selection across eligible accounts. Completion results are open strings; callers should handle known results and provide a fallback for future outcomes.
110
113
 
114
+ The shared `onComplete(result, rejectedRecipients?, error?, details?)` uses `MailComposerCompletionCallback` to support synchronous and asynchronous completion while retaining legacy return-discarding callbacks. Its optional fourth argument is discriminated by `kind`: `normal` or `bulk` includes the detached actual client request and every returned `MailSubmissionView`, while `draft` contains only a separate draft reference and no submissions. A response-less unknown outcome has no submission IDs. The first three arguments retain their existing summary semantics, not delivery guarantees. Optional `onCompletionError` isolates callback throws/rejections without delaying closing or retrying mail. See [business-record completion](client-integration.md#associate-composer-completion-with-business-records) for idempotent integration and snapshot boundaries.
115
+
111
116
  ## HTTP and realtime
112
117
 
113
118
  The authenticated `/api/mail` routes, payloads, paging, permission resources, error reasons, OAuth callback and Provider webhook are documented in [HTTP API](http-api.md). Prefer `MailClient` for application code. The `mail:messages` realtime event is a user-scoped invalidation signal with no message body; refresh affected Mail data after receiving it or reconnecting.