arcane-os 0.17.0 → 0.19.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/CHANGELOG.md +30 -0
- package/NOTICE +1 -1
- package/README.md +1 -1
- package/docs/architecture.md +4 -2
- package/docs/reference/cli.md +45 -16
- package/docs/reference/mail.md +72 -15
- package/docs/reference/sdk-api.md +11 -6
- package/docs/reviews/mail-server-purpose-review.md +49 -6
- package/package.json +2 -2
- package/src/cli/main.mjs +16 -17
- package/src/mail-credentials.mjs +101 -632
- package/src/mail-server.mjs +9 -0
- package/src/mail.mjs +17 -26
- package/src/templates/workspace-template.mjs +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,35 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.19.0
|
|
4
|
+
|
|
5
|
+
- Read mail credentials from `.env.json` in the invocation directory through
|
|
6
|
+
portable Node file APIs. Remove the Windows Credential Manager subprocess,
|
|
7
|
+
embedded PowerShell/C# helper, helper timeouts, and transport-only machinery.
|
|
8
|
+
Existing Windows credential records remain untouched; populate the JSON file
|
|
9
|
+
explicitly when adopting this configuration change.
|
|
10
|
+
- Default mail commands to the top-level `RESEND_API_KEY`; `--profile mail`
|
|
11
|
+
selects that same key. Preserve named key set/status/delete operations through
|
|
12
|
+
exact `MAIL_PROFILES` entries, retaining unrelated JSON settings and naming
|
|
13
|
+
the missing setting and file before send or server startup.
|
|
14
|
+
- Ignore `.env.json` in the SDK checkout and newly scaffolded workspaces. Update
|
|
15
|
+
the mail reference and purpose-gate report with the portable configuration
|
|
16
|
+
contract and the reasons for each retained or removed operation.
|
|
17
|
+
|
|
18
|
+
## 0.18.0
|
|
19
|
+
|
|
20
|
+
- Adopt published `node-http-server` 10.0.0. PEM-backed development and
|
|
21
|
+
packaged-preview HTTPS now negotiate HTTP/2 or HTTP/1.1 on the same port
|
|
22
|
+
through the existing module integration, with no new runtime dependency.
|
|
23
|
+
- Document the returned `Http2SecureServer` for PEM-backed HTTPS. Preserve
|
|
24
|
+
raw `tls` options on native `https.Server`, explicit HTTP development, the
|
|
25
|
+
HTTP mail gateway, paired HTTP `308` redirects, source/PWA routes, complete
|
|
26
|
+
responses, conditional caching, and owned listener shutdown.
|
|
27
|
+
- Adapt the shared synthetic TLS fixture to both native TLS constructors while
|
|
28
|
+
retaining option capture and cleanup. The fixture models routing and option
|
|
29
|
+
delegation; it does not establish a real TLS handshake or protocol negotiation.
|
|
30
|
+
- Report an occupied mail listener port clearly while retaining native
|
|
31
|
+
`EADDRINUSE` details, the original cause, and the existing startup cleanup.
|
|
32
|
+
|
|
3
33
|
## 0.17.0
|
|
4
34
|
|
|
5
35
|
- Add neutral `modal.configure({dismissible})` configuration, defaulting to
|
package/NOTICE
CHANGED
|
@@ -8,7 +8,7 @@ informational notice and is not itself a grant of commercial rights.
|
|
|
8
8
|
Third-party material retains its own terms:
|
|
9
9
|
|
|
10
10
|
- event-pubsub 6.1.0: MIT License; see its installed `licence` file.
|
|
11
|
-
- node-http-server
|
|
11
|
+
- node-http-server 10.0.0: MIT License; see its installed `licence` file.
|
|
12
12
|
- strong-type 2.0.1: MIT License; see its installed `licence` file.
|
|
13
13
|
- vanilla-test 2.1.3: MIT License; see its installed `licence` file.
|
|
14
14
|
- ansi-colors-es6 5.0.0: MIT License; see its installed `LICENSE` file.
|
package/README.md
CHANGED
|
@@ -19,7 +19,7 @@ version-locked SDK runtime, while an integrated Arcane checkout uses its live
|
|
|
19
19
|
`arcane/` runtime. Both profiles preserve the same app URLs, theme, packaging,
|
|
20
20
|
event, cancellation, and browser run contracts.
|
|
21
21
|
|
|
22
|
-
This checkout defines the `0.
|
|
22
|
+
This checkout defines the `0.19.0` SDK contract. Applications pin one exact npm
|
|
23
23
|
version and lockfile; registry state is deliberately not baked into application
|
|
24
24
|
artifacts.
|
|
25
25
|
|
package/docs/architecture.md
CHANGED
|
@@ -134,8 +134,10 @@ expiration. The timestamp advances only after the whole resource check succeeds.
|
|
|
134
134
|
Restarting is not a content synchronization step; inspect the
|
|
135
135
|
selected source route and the last successful check when evaluating freshness.
|
|
136
136
|
|
|
137
|
-
The shared dev server uses RIAEvangelist's `node-http-server`
|
|
138
|
-
for HTTPS and conditional responses on those selected routes.
|
|
137
|
+
The shared dev server uses RIAEvangelist's published `node-http-server` 10.0.0
|
|
138
|
+
public interface for HTTPS and conditional responses on those selected routes.
|
|
139
|
+
PEM-backed HTTPS uses Node's `Http2SecureServer` with HTTP/1.1 compatibility;
|
|
140
|
+
clients negotiate either protocol on the same HTTPS port. The SDK
|
|
139
141
|
owns source selection and generated representations. By default, source development
|
|
140
142
|
and every packaged browser preview serve content on HTTPS and redirect their
|
|
141
143
|
paired HTTP listener with status 308 through the public request hook.
|
package/docs/reference/cli.md
CHANGED
|
@@ -32,7 +32,7 @@ and exits nonzero on failure. Machine output is defined by
|
|
|
32
32
|
| `arcane update-check` | Performs one explicit, read-only npm dist-tag query for the installed SDK version. |
|
|
33
33
|
| `arcane targets` | Lists target ids, declared status, formats, architectures, signing profiles, methods, and pairing reason. |
|
|
34
34
|
| `arcane repo status\|pull\|push` | Runs one selected repository operation for the current app workspace. |
|
|
35
|
-
| `arcane mail key set\|status\|delete` | Manages one server-only Resend API-key profile in
|
|
35
|
+
| `arcane mail key set\|status\|delete` | Manages one server-only Resend API-key profile in `.env.json`. |
|
|
36
36
|
| `arcane mail send` | Performs one explicit, idempotency-keyed Resend attempt from a complete JSON report on redirected stdin. |
|
|
37
37
|
| `arcane mail serve` | Starts one Arcane-to-Resend gateway with a server-only provider profile, a selected listener, and optional CORS and recipient configuration. |
|
|
38
38
|
|
|
@@ -345,6 +345,9 @@ Network URLs come from one interface snapshot at startup and do not establish
|
|
|
345
345
|
remote reachability through the machine's firewall or network.
|
|
346
346
|
|
|
347
347
|
HTTPS is the default for development and required for packaged browser previews.
|
|
348
|
+
The published `node-http-server` 10.0.0 integration negotiates HTTP/2 or HTTP/1.1
|
|
349
|
+
on the same HTTPS port using the configured PEM pair. Source routes, generated
|
|
350
|
+
PWA resources, and conditional responses use the same serving pipeline.
|
|
348
351
|
`--https` remains accepted but is no longer needed to select the transport.
|
|
349
352
|
`--port` selects the HTTPS application port. A second HTTP listener returns
|
|
350
353
|
`308` redirects to that HTTPS port, preserving the requested path and query.
|
|
@@ -810,22 +813,47 @@ npm exec -- arcane repo status
|
|
|
810
813
|
|
|
811
814
|
### Resend credential profiles
|
|
812
815
|
|
|
813
|
-
The
|
|
816
|
+
The mail commands read `.env.json` from the invocation directory on Windows,
|
|
817
|
+
Linux, and macOS. The credential subcommands select one profile in that file:
|
|
814
818
|
|
|
815
819
|
```text
|
|
816
|
-
arcane mail key set
|
|
817
|
-
arcane mail key status
|
|
818
|
-
arcane mail key delete
|
|
820
|
+
arcane mail key set [profile] [--secret-stdin]
|
|
821
|
+
arcane mail key status [profile]
|
|
822
|
+
arcane mail key delete [profile]
|
|
819
823
|
```
|
|
820
824
|
|
|
821
825
|
`key set` reads the Resend API key from a hidden terminal prompt. The
|
|
822
826
|
`--secret-stdin` form is for deliberately redirected non-interactive input and
|
|
823
|
-
rejects a TTY before reading. The key is
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
827
|
+
rejects a TTY before reading. The key is written to `.env.json` and is never
|
|
828
|
+
accepted in argv or returned in status output. The optional profile defaults
|
|
829
|
+
to `mail`, which selects top-level `RESEND_API_KEY`. Any other exact profile
|
|
830
|
+
selects `MAIL_PROFILES[profile].RESEND_API_KEY`, with no default-key fallback.
|
|
831
|
+
|
|
832
|
+
The minimal file is:
|
|
833
|
+
|
|
834
|
+
```json
|
|
835
|
+
{
|
|
836
|
+
"RESEND_API_KEY": ""
|
|
837
|
+
}
|
|
838
|
+
```
|
|
839
|
+
|
|
840
|
+
Fill in the key before starting mail, and add `.env.json` to the project's
|
|
841
|
+
`.gitignore`; the SDK repository already ignores it. Set and delete preserve
|
|
842
|
+
the file's other settings and profiles. Status returns the selected profile,
|
|
843
|
+
`provider:'resend'`, `storage:'.env.json'`, and `exists`. Delete returns
|
|
844
|
+
`exists:false` for both a removed and an already-absent credential.
|
|
845
|
+
|
|
846
|
+
Programmatic `createToolchain().mail(...)` resolves the configuration directory
|
|
847
|
+
from `cwd ?? workspaceRoot ?? process.cwd()`. This uses ordinary Node file
|
|
848
|
+
access rather than platform-specific credential processes. An Android host
|
|
849
|
+
supplies a compatible Node runtime and an accessible configuration directory.
|
|
850
|
+
Existing Windows Credential Manager records remain untouched; the JSON reader
|
|
851
|
+
does not migrate or fall back to them. Mail reads JSON directly and does not
|
|
852
|
+
populate or depend on process environment variables for this key.
|
|
853
|
+
|
|
854
|
+
Missing files or missing/empty selected keys stop `send` and `serve` with the
|
|
855
|
+
configuration path and exact JSON setting to fill in. Invalid JSON and file
|
|
856
|
+
access failures remain observable without printing credential content.
|
|
829
857
|
|
|
830
858
|
Machine output for `key set` requires `--secret-stdin`. Raw CLI arguments are
|
|
831
859
|
not included in acceptance events, and usage errors do not echo unknown option
|
|
@@ -837,7 +865,7 @@ or positional values.
|
|
|
837
865
|
server:
|
|
838
866
|
|
|
839
867
|
```text
|
|
840
|
-
arcane mail send --profile <profile> [--from <verified-sender>] --report-key <id> --report-stdin [--request-timeout <ms>]
|
|
868
|
+
arcane mail send [--profile <profile>] [--from <verified-sender>] --report-key <id> --report-stdin [--request-timeout <ms>]
|
|
841
869
|
```
|
|
842
870
|
|
|
843
871
|
`--report-stdin` is mandatory and rejects a terminal before attaching input
|
|
@@ -858,8 +886,8 @@ Resend owns their accepted shape. The adapter removes the application-only
|
|
|
858
886
|
`type` field and applies `--from` when supplied; otherwise the report or provider
|
|
859
887
|
template supplies the sender. Direct CLI sending has
|
|
860
888
|
no configured fallback recipients. The Resend credential comes only from the
|
|
861
|
-
selected
|
|
862
|
-
accepted through argv or environment variables.
|
|
889
|
+
selected `.env.json` profile; omitting `--profile` selects `mail`. Neither the
|
|
890
|
+
key nor report content is accepted through argv or process environment variables.
|
|
863
891
|
|
|
864
892
|
The caller owns the nonempty `--report-key`, which is forwarded unchanged.
|
|
865
893
|
Reuse the same key only with the same
|
|
@@ -880,10 +908,11 @@ loss after the attempt begins is ambiguous because Resend may have accepted it.
|
|
|
880
908
|
`mail serve` starts one owned Node HTTP gateway:
|
|
881
909
|
|
|
882
910
|
```text
|
|
883
|
-
arcane mail serve --profile <profile> [--from <verified-sender>] [--app <label>] [--origin <exact-origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
|
|
911
|
+
arcane mail serve [--profile <profile>] [--from <verified-sender>] [--app <label>] [--origin <exact-origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
|
|
884
912
|
```
|
|
885
913
|
|
|
886
|
-
The selected
|
|
914
|
+
The selected `.env.json` profile supplies only the server-side Resend API key;
|
|
915
|
+
omitting `--profile` selects `mail`.
|
|
887
916
|
The CLI does not read a browser app key. Its optional `--app` value labels the
|
|
888
917
|
server; the incoming request's `X-Mail-App` identifies the application for
|
|
889
918
|
subscription verification. The HTTP authentication contract pairs that
|
package/docs/reference/mail.md
CHANGED
|
@@ -13,12 +13,14 @@ gateway and is never included in browser or WebAssembly state.
|
|
|
13
13
|
| `MailTransport.mjs` | Browser, WebView, or compatible Fetch host | Sends one already-persisted request to the configured Arcane gateway with the stable report key as its idempotency key. |
|
|
14
14
|
| `arcane mail send` | Node on the local machine | Reads one complete provider-neutral report from redirected stdin and performs one explicit Resend attempt with a caller-owned idempotency key. |
|
|
15
15
|
| `arcane mail serve` | Node on the configured host | Owns caller verification, protects the provider credential, applies explicitly configured recipient and origin settings, and makes one server-side Resend request. |
|
|
16
|
-
| `arcane mail key ...` | Node on Windows | Stores, inspects, or deletes a Resend API key in
|
|
16
|
+
| `arcane mail key ...` | Node on Windows, Linux, or macOS | Stores, inspects, or deletes a Resend API key in the selected `.env.json`. |
|
|
17
17
|
|
|
18
18
|
The browser never receives the Resend API key. The gateway never writes that
|
|
19
19
|
key to source, argv, logs, events, fixtures, browser storage, or its public
|
|
20
|
-
lifecycle result.
|
|
21
|
-
|
|
20
|
+
lifecycle result. The CLI and gateway use the same Node filesystem and network
|
|
21
|
+
interfaces on Windows, Linux, and macOS. An Android host supplies a compatible
|
|
22
|
+
Node runtime and an accessible configuration directory; the mail implementation
|
|
23
|
+
contains no Windows credential process or platform-specific path convention.
|
|
22
24
|
|
|
23
25
|
## Public npm import
|
|
24
26
|
|
|
@@ -42,8 +44,8 @@ import Mail,{
|
|
|
42
44
|
and `sendMailReport`.
|
|
43
45
|
|
|
44
46
|
This entrypoint contains only the portable browser/WebView runtime, outbox, and
|
|
45
|
-
transport contract. It does not import the Node HTTP gateway or
|
|
46
|
-
|
|
47
|
+
transport contract. It does not import the Node HTTP gateway or its filesystem
|
|
48
|
+
credential adapter. Programmatic developer tooling reaches those
|
|
47
49
|
host-owned operations through the existing `createToolchain().mail(...)`
|
|
48
50
|
boundary; ordinary operators use `arcane mail send`, `arcane mail serve`, and
|
|
49
51
|
`arcane mail key ...`. This keeps Node credential and server authority out of a
|
|
@@ -53,9 +55,9 @@ browser import while preserving one shared CLI/toolchain implementation.
|
|
|
53
55
|
|
|
54
56
|
Arcane Mail deliberately separates two credentials:
|
|
55
57
|
|
|
56
|
-
- The **Resend API key** is provider authority.
|
|
57
|
-
|
|
58
|
-
`mail
|
|
58
|
+
- The **Resend API key** is provider authority. The Node process reads it from
|
|
59
|
+
`.env.json`. `arcane mail key set [profile]` can store it there through hidden
|
|
60
|
+
input; `mail send` and `mail serve` read the selected profile inside that process.
|
|
59
61
|
- The **subscription key** is the application user's subscription credential.
|
|
60
62
|
When present, the browser sends it as `Authorization: Bearer <subscriptionKey>`,
|
|
61
63
|
with the exact application name in `X-Mail-App`. The application name identifies the
|
|
@@ -270,21 +272,69 @@ committed acceptance result.
|
|
|
270
272
|
|
|
271
273
|
## Operate the CLI and gateway
|
|
272
274
|
|
|
273
|
-
|
|
275
|
+
Create `.env.json` in the directory from which the mail command runs, then fill
|
|
276
|
+
in the provider key:
|
|
277
|
+
|
|
278
|
+
```json
|
|
279
|
+
{
|
|
280
|
+
"RESEND_API_KEY": ""
|
|
281
|
+
}
|
|
282
|
+
```
|
|
283
|
+
|
|
284
|
+
The SDK repository ignores `.env.json`. Keep the same entry in a consuming
|
|
285
|
+
project's `.gitignore`. This is a JSON configuration file; the mail commands
|
|
286
|
+
read it directly without copying its contents into `process.env`.
|
|
287
|
+
|
|
288
|
+
The default profile is `mail`, which selects top-level `RESEND_API_KEY`.
|
|
289
|
+
The explicit `--profile mail` form selects the same setting. Other profile names
|
|
290
|
+
select exact entries under `MAIL_PROFILES`:
|
|
291
|
+
|
|
292
|
+
```json
|
|
293
|
+
{
|
|
294
|
+
"RESEND_API_KEY": "",
|
|
295
|
+
"MAIL_PROFILES": {
|
|
296
|
+
"another-provider-account": {
|
|
297
|
+
"RESEND_API_KEY": ""
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
An absent named profile does not fall back to the default key. The profile
|
|
304
|
+
selects Resend provider credentials; it is separate from the incoming
|
|
305
|
+
application name and subscriber key.
|
|
306
|
+
|
|
307
|
+
Programmatic operations resolve `.env.json` from `options.cwd`, then
|
|
308
|
+
`options.workspaceRoot`, then `process.cwd()`, choosing the first supplied
|
|
309
|
+
directory. The CLI uses its invocation directory. There is no upward directory
|
|
310
|
+
search or dependency on a Windows installation directory or temporary-directory
|
|
311
|
+
environment variable.
|
|
312
|
+
|
|
313
|
+
The existing key commands manage the same file:
|
|
274
314
|
|
|
275
315
|
```text
|
|
276
|
-
arcane mail key set
|
|
277
|
-
arcane mail key status
|
|
278
|
-
arcane mail key delete
|
|
316
|
+
arcane mail key set
|
|
317
|
+
arcane mail key status
|
|
318
|
+
arcane mail key delete
|
|
279
319
|
```
|
|
280
320
|
|
|
281
321
|
`key set` prompts with hidden input. `--secret-stdin` is the explicit
|
|
282
|
-
non-interactive alternative and rejects a TTY.
|
|
322
|
+
non-interactive alternative and rejects a TTY. Each command accepts an optional
|
|
323
|
+
profile argument, defaulting to `mail`. Set and delete preserve other JSON
|
|
324
|
+
settings and profiles; status reports existence without returning the key.
|
|
325
|
+
Results identify `storage: '.env.json'`. An already-absent deletion succeeds
|
|
326
|
+
with `exists: false`.
|
|
327
|
+
|
|
328
|
+
Existing Windows Credential Manager records remain untouched. The JSON path
|
|
329
|
+
does not read, migrate, or delete those records; populate the selected JSON
|
|
330
|
+
setting to use it. Missing files or missing/empty provider settings produce an
|
|
331
|
+
actionable startup/send error naming the file and exact setting. Unreadable or
|
|
332
|
+
invalid JSON is reported without including credential content in the error.
|
|
283
333
|
|
|
284
334
|
Perform one provider attempt directly from the SDK CLI:
|
|
285
335
|
|
|
286
336
|
```text
|
|
287
|
-
arcane mail send --
|
|
337
|
+
arcane mail send --from "Arcane <verified@example.com>" --report-key <stable-id> --report-stdin
|
|
288
338
|
```
|
|
289
339
|
|
|
290
340
|
The redirected UTF-8 JSON object is read completely. Its fields and values
|
|
@@ -312,7 +362,7 @@ deadline.
|
|
|
312
362
|
Start the gateway:
|
|
313
363
|
|
|
314
364
|
```text
|
|
315
|
-
arcane mail serve --profile
|
|
365
|
+
npm exec -- arcane mail serve --profile mail --host 0.0.0.0 --port 8025
|
|
316
366
|
```
|
|
317
367
|
|
|
318
368
|
The default listener is `0.0.0.0:8025`; `--host` and `--port` select its bind
|
|
@@ -320,6 +370,13 @@ address and port. The server can serve callers from multiple domains on the
|
|
|
320
370
|
same machine. Route the page's `/v1/mail` to this listener, or configure an
|
|
321
371
|
explicit shared endpoint in the caller.
|
|
322
372
|
|
|
373
|
+
If the selected port is occupied, startup reports
|
|
374
|
+
`Mail port <port> is already taken, possibly by another mail server.`
|
|
375
|
+
The CLI exits with status 1. Programmatic callers receive the same message,
|
|
376
|
+
with native `EADDRINUSE` metadata and the original error retained as `cause`.
|
|
377
|
+
The existing listener remains running; this launch does not retry or select
|
|
378
|
+
another port.
|
|
379
|
+
|
|
323
380
|
`--app` is an optional server event label and does not restrict incoming
|
|
324
381
|
application names. `--from` is an optional shared sender override; omit it to
|
|
325
382
|
preserve each report's sender or its provider template's default.
|
|
@@ -3464,14 +3464,15 @@ async function useselectApp(...arguments_) {
|
|
|
3464
3464
|
|
|
3465
3465
|
Starts one owned browser development server with exact runtime/app route mappings and a caller-selected bind address.
|
|
3466
3466
|
|
|
3467
|
-
HTTP and HTTPS serving use
|
|
3467
|
+
HTTP and HTTPS serving use published `node-http-server` 10.0.0. The SDK
|
|
3468
3468
|
selects source routes and supplies generated representations; the module owns
|
|
3469
3469
|
static-file conditional GET/HEAD handling and response delivery. The SDK
|
|
3470
3470
|
retains modification dates for its generated representations. Unchanged
|
|
3471
3471
|
resources can return `304` with no body while changed resources return their
|
|
3472
|
-
complete current representation. PEM-path listeners use module deployment
|
|
3473
|
-
|
|
3474
|
-
response and static-file
|
|
3472
|
+
complete current representation. PEM-path listeners use module deployment and
|
|
3473
|
+
negotiate HTTP/2 or HTTP/1.1 on the same HTTPS port. Explicit raw `tls` options
|
|
3474
|
+
retain native HTTPS transport with the same module response and static-file
|
|
3475
|
+
operations.
|
|
3475
3476
|
|
|
3476
3477
|
### Signature, modes, and result
|
|
3477
3478
|
|
|
@@ -3518,8 +3519,12 @@ requirements remain browser-owned; see [explicit HTTP development](cli.md#explic
|
|
|
3518
3519
|
The promise settles after all selected listeners are ready and resolves to
|
|
3519
3520
|
`{server, protocol, mode, workspaceRoot, appId, host, port, origin, cleanUrl, url,
|
|
3520
3521
|
networkUrls, httpPort, httpOrigin, httpUrl, close, closed, lifecycle}`. `server` is the raw Node
|
|
3521
|
-
server for application content
|
|
3522
|
-
|
|
3522
|
+
server for application content: `Http2SecureServer` for PEM-backed HTTPS,
|
|
3523
|
+
`https.Server` for explicit raw `tls` options, or `http.Server` for explicit
|
|
3524
|
+
HTTP source mode. HTTP/2 uses Node's compatibility request/response APIs;
|
|
3525
|
+
callers accessing the raw server must account for its native type.
|
|
3526
|
+
`protocol` describes the URL scheme: `'https:'` for either negotiated HTTPS
|
|
3527
|
+
protocol or `'http:'` with explicit HTTP source mode.
|
|
3523
3528
|
`url` and `cleanUrl` are the same application URL. Wildcard listeners use
|
|
3524
3529
|
`localhost` in that local URL; `host` retains the actual bound address.
|
|
3525
3530
|
`httpPort` is the actual HTTP listener port, `httpOrigin` is its HTTP origin,
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
-
[Roshi's Codex PRIME] The
|
|
1
|
+
[Roshi's Codex PRIME] The gateway review and its portable credential follow-up apply the same three purpose gates. The gateway removals preserve complete delivery outcomes, configured CORS and recipient policy, and the optional subscription verifier. Mail credentials now belong in the user-selected `.env.json`, with one portable Node implementation for Windows, Linux, and macOS and a compatible Node host as the Android adaptation boundary. The original gateway inventory below uses baseline `f055e05`; the credential follow-up reviews the Windows storage implementation present at SDK `0.18.0`. Commit, package, publication, and actual platform execution outcomes belong to the delivery record rather than to this source-review report.
|
|
2
2
|
|
|
3
3
|
| Decision | Behavior | Why it matters | Source status at this review |
|
|
4
4
|
| --- | --- | --- | --- |
|
|
5
5
|
| Remove | Loopback-only admission, manual header reconstruction, address/origin normalization, local payload grammar, manual content-length scan, dead queue knobs | These restrict supported use, rewrite supplied values, or repeat work already owned elsewhere. | Removed from the inspected source; naming-only changes carry no runtime claim. |
|
|
6
6
|
| Remove and replace | Local app-key hashes and X-Mail-Key authentication | The selected application plus bearer subscription contract needs an actual verifier, not a local shared-key comparison. | Removed. Optional `verifySubscription` implements the local integration contract; the remote endpoint adapter remains future work. Initial setup without that callback performs no caller authentication. |
|
|
7
|
+
| Remove and replace | Windows-only credential process, native interop, helper timers, environment prerequisites, encoding and input/output limits | They prevent the required portable startup and perform work absent from the selected JSON storage path. | Replaced by direct `.env.json` access. Existing Windows credential records remain untouched. Default and named credential operations remain useful and are preserved. |
|
|
7
8
|
| Simplify | Exact CORS policy, one configuration resolution, one provider request construction/serialization, optional observation | Preserve the intended result while eliminating repeated parsing, copies, policy structures, and absent-observer work. | Present in inspected source. Explicit nonempty origin lists remain authoritative; otherwise the nominal-domain default applies. |
|
|
8
9
|
| Keep | Configured subscription authentication, explicit recipient policy/fallback, stable idempotency, real cancellation/deadlines, complete provider outcomes, concurrent requests and owned shutdown | These have concrete callers and determine whether mail is sent, retried, reported honestly, or stopped correctly. | Retained. Only a verifier result of `true` permits authenticated delivery; failures and cancellation prevent the provider attempt. |
|
|
9
10
|
|
|
10
|
-
This review covers every named method, callback owner, constant, and significant action in `src/mail-server.mjs` at baseline `f055e05`, plus the coupled CLI/browser paths needed to preserve behavior. The current-source observations were reconciled on 2026-09-07.
|
|
11
|
+
This review covers every named method, callback owner, constant, and significant action in `src/mail-server.mjs` at baseline `f055e05`, plus the coupled CLI/browser paths needed to preserve behavior. The portable credential addendum covers `src/mail-credentials.mjs`, its command/CLI callers, and the ignored configuration file. The current-source observations were reconciled on 2026-09-07. Source simplification is distinct from measured speedup, successful live mail delivery, release evidence, and execution on a particular platform.
|
|
11
12
|
|
|
12
13
|
The intended software outcome is one complete mail request reaching the configured provider through the owning gateway, followed by an honest complete result. The gateway must preserve caller content, useful recipient policy, configured subscription authentication, explicit allowed-origin CORS behavior, caller cancellation, provider acceptance and uncertainty, and owned shutdown. It must use the published `node-http-server` interface and work on the selected host/domain without a loopback-only assumption. The initial unauthenticated setup is an implementation assumption stated to the user; no live deployment is selected in this work.
|
|
13
14
|
|
|
@@ -19,7 +20,7 @@ The user's three gates apply to the behavior, not to how impressive a helper nam
|
|
|
19
20
|
|
|
20
21
|
In the tables, `Y/Y/N` means keep the behavior; `Y/Y/Y` means simplify it by removing the identified redundant step; `N/N/Y` means remove the behavior. `Pending` identifies a real unresolved external contract or compatibility question, not an automatic delivery hold. Cost descriptions identify allocations, scans, calls, listeners, or waits that source removal eliminates; they are not timing measurements. A rename alone has no claimed runtime benefit. The tables state the current source name when behavior remains; recommendations and pending changes are marked explicitly. Existing public entry-point names remain stable unless the user expressly changes their contract.
|
|
21
22
|
|
|
22
|
-
The review sources are [the gateway](../../src/mail-server.mjs), [mail command orchestration](../../src/mail.mjs), [CLI server ownership](../../src/cli/main.mjs), [the portable transport](../../runtime/arcane/modules/MailTransport.mjs), [the browser Mail owner](../../runtime/arcane/modules/Mail.js), [the outbox's result consumers](../../runtime/arcane/modules/MailOutbox.mjs), and [the public mail reference](../reference/mail.md). Outbox storage, scheduling, maintenance methods, and unrelated SDK modules are outside this cleanup scope. Relevant test source was read as evidence of expected interfaces; tests were not executed.
|
|
23
|
+
The review sources are [the gateway](../../src/mail-server.mjs), [mail credentials](../../src/mail-credentials.mjs), [mail command orchestration](../../src/mail.mjs), [CLI server ownership](../../src/cli/main.mjs), [the portable transport](../../runtime/arcane/modules/MailTransport.mjs), [the browser Mail owner](../../runtime/arcane/modules/Mail.js), [the outbox's result consumers](../../runtime/arcane/modules/MailOutbox.mjs), and [the public mail reference](../reference/mail.md). Outbox storage, scheduling, maintenance methods, and unrelated SDK modules are outside this cleanup scope. Relevant test source was read as evidence of expected interfaces; tests were not executed.
|
|
23
24
|
|
|
24
25
|
Resend's send API accepts recipient strings or arrays, additional provider fields, and templates whose content rules differ from ordinary text/HTML messages. Its response includes a provider identifier. These are reasons to retain provider-boundary mapping while removing narrower gateway schemas. [Resend Send Email](https://resend.com/docs/api-reference/emails/send-email)
|
|
25
26
|
|
|
@@ -34,6 +35,7 @@ The latest user-selected boundaries govern this review:
|
|
|
34
35
|
- Explicit recipient allowlists and error-recipient fallback remain. A configured nonempty allowlist covers resolved `to`, `cc`, and `bcc` recipients; allowing additional provider fields must not bypass the selected recipient policy. With no allowlist, the policy performs no recipient scan. Per-address trimming, lowercasing, and local email grammar do not remain.
|
|
35
36
|
- Caller-selected deadlines, the cancellation adapter, complete provider outcomes, retry classification, stable idempotency, and independently constructed snapshots for emitted observations remain. Shared mutable provider snapshots have not been selected.
|
|
36
37
|
- Remove manual response content-length scanning, duplicate configuration/CORS construction, unobserved event payload creation, unused `allowZero`, and unused CLI queue options.
|
|
38
|
+
- All SDK mail operations require a functional Windows, Linux, and macOS path, with Android adaptation at the host boundary. Read provider configuration directly from an ignored `.env.json`; an operating-system limitation notice does not satisfy the portable requirement. Default profile `mail` uses `RESEND_API_KEY`; other exact names use `MAIL_PROFILES[profile].RESEND_API_KEY`. Missing configuration must identify the file and setting to fill in. Existing Windows records remain untouched, without an automatic read or migration.
|
|
37
39
|
|
|
38
40
|
Source inspection during this report's handoff shows local app/email/sender/API-key format validators and loopback admission removed; origin values retained in one Set; complete provider JSON values or raw response text preserved; template-shaped provider requests no longer required to supply local text/HTML fields; and configuration passed once into `createConfiguredMailHandler`. Observer objects, pending Sets, callback closures, event payload reconstruction, and drain waits are absent when `onEvent` is omitted. An already-cancelled direct send stops before provider payload construction or serialization. Response writing no longer calculates content length. The fixed `/v1/mail` route accepts its query-bearing form, matching the portable endpoint parser. These are source observations, not executed behavior.
|
|
39
41
|
|
|
@@ -159,6 +161,7 @@ The upstream listener and public lifecycle follow.
|
|
|
159
161
|
| `deployMailServer` | Adapts published `deploy(callback)` into listener startup promise. | Y/Y/N — Keep. | Startup must return the actual bound address or an actual bind error. Current name: `listenForMailRequests`. |
|
|
160
162
|
| `waitForMailListener` | Owns the startup promise. | Y/Y/N — Keep. | Required callback-to-promise adapter at the upstream owner. Name is clear. |
|
|
161
163
|
| Listener `onError` | Rejects startup when binding fails. | Y/Y/N — Keep. | Do not claim listening before this boundary. Current callback name remains `onError`, local to the listener promise. |
|
|
164
|
+
| Occupied-port startup message | `startResendMailServer` handles the actual native `EADDRINUSE` after closing its failed launch resources. | Y/Y/N — Keep. | Identifies the selected mail port and says another mail server may own it. The existing CLI failure path exits with status 1; native error metadata and the complete original cause remain available. One failure-only branch replaces the generic bind message, with no port probe, retry, process control, or work on successful requests. Source and diff reviewed; this follow-up was not exercised locally. |
|
|
162
165
|
| `onListening` | Removes startup error listener and resolves actual raw server. | Y/Y/N — Keep. | Retain upstream callback semantics. Current callback name remains `onListening`; its `(instance, server)` positions follow the upstream callback. |
|
|
163
166
|
| `startResendMailServer` | Constructs upstream server and mail handler, then exposes lifecycle. | Y/Y/Y — Keep entry point; remove duplicate configuration/loopback gate. | Use configured host/domain; keep selected upstream public interface and no implicit socket deadline. Preserve public name. |
|
|
164
167
|
| `handleMailRequest` assigned to `onRawRequest` | Hands original Node request/response to mail handler and returns true. | Y/Y/N — Keep. | `true` prevents upstream body/static processing of an already-owned mail request. Current name: `routeRawMailRequest`, distinct from the actual request handler. |
|
|
@@ -308,13 +311,13 @@ The coupled CLI/browser actions below are necessary to avoid leaving contradicto
|
|
|
308
311
|
|
|
309
312
|
| Coupled path/action | Gates and decision | Required result and evidence boundary |
|
|
310
313
|
| --- | --- | --- |
|
|
311
|
-
| `src/mail.mjs` `serveMail` old hidden app-key input and local auth options | Y/Y/Y — Reconciled with the optional verifier contract. | Obsolete shared-app-key prompt/options are removed. Current `serveMailGateway` forwards `options.verifySubscription` to the server and keeps provider credential
|
|
314
|
+
| `src/mail.mjs` `serveMail` old hidden app-key input and local auth options | Y/Y/Y — Reconciled with the optional verifier contract. | Obsolete shared-app-key prompt/options are removed. Current `serveMailGateway` forwards `options.verifySubscription` to the server and keeps provider credential operations and the provider API key separate. The portable follow-up resolves that provider credential from `.env.json`. |
|
|
312
315
|
| `src/mail.mjs` `recipientList` and origin list preparation | Y/Y/Y — Remove redundant rewriting, preserve configured policy values. | Gateway and CLI must not disagree about preserved recipients/origins. An exact allowlist is still an intentional policy. |
|
|
313
316
|
| `src/mail.mjs` `withoutMailCredentials` | N/N/Y for recursive payload-key redaction — Remove. | It recursively traversed/copied complete results and deleted any content property named `apiKey` or `appKey`, including ordinary user payload fields. Keep actual transport credentials outside constructed public results at their owning boundary; do not rewrite the report based on property names. Source inspection shows this traversal removed. |
|
|
314
317
|
| `src/mail.mjs` `completeSendFailure` | Y/Y/Y — Remove helper after preserving the complete result directly. | Failure output still contains the provider result, or a narrow wrapper for a non-object injected result. No recursive copying/redaction pass remains. |
|
|
315
318
|
| CLI queue fields passed to a server that no longer consumes them | N/N/Y — Remove dead options/help/forwarding together. | `bodyQueueTimeoutMs`, `maxConcurrentBodyReads`, `maxConcurrentSends`, `maxQueuedBodyReads`, `maxQueuedSends`, and `sendQueueTimeoutMs` have no consumer in baseline mail-server configuration. Do not preserve misleading knobs or recreate queues for them. |
|
|
316
319
|
| CLI app-slug validation/help and server-wide app identity requirement | Y/Y/Y — Remove app restriction and shared-server assumption. | Application is an ordinary per-request string; any app may use the server. Do not locally lowercase, rewrite, enumerate, or compare it to one server app. |
|
|
317
|
-
| CLI mandatory `--from` | Y/Y/Y — Remove the redundant requirement; retain an explicit sender override. | The report or provider template may supply its sender. Requiring a shared CLI sender blocked those supported requests and per-report sender selection. Both mail commands
|
|
320
|
+
| CLI mandatory `--from` | Y/Y/Y — Remove the redundant requirement; retain an explicit sender override. | The report or provider template may supply its sender. Requiring a shared CLI sender blocked those supported requests and per-report sender selection. Both mail commands accept optional `--from`; Resend owns sender validity. The stable send key remains required. The portable credential follow-up makes the profile optional, defaulting to `mail`. |
|
|
318
321
|
| `MailTransport.mjs` request-header construction | Y/Y/Y — Updated to optional bearer Authorization; retain X-Mail-App. | Current source accepts an omitted, null, or empty subscription key and omits Authorization when no key exists, allowing the initial server setup. A supplied nonempty string is sent unchanged as the bearer credential; a configured server owns rejection of missing/invalid authentication. Preserve complete report payload, exact report key, cancellation, and configured destination. Never use the subscriber key as Resend provider authority. |
|
|
319
322
|
| `MailTransport.mjs` provider ID/error code regexes | Y/Y/Y — Simplified in current source. | Provider ID requires an actual nonempty string, and provider error codes remain complete strings. The gateway and browser no longer disagree about provider metadata syntax. |
|
|
320
323
|
| Browser/native/outbox request-ID grammar | Y/Y/N — Preserve; broader relaxation deferred. | Request-ID consumers still require the existing form. No half-implemented grammar change is included in this cleanup. |
|
|
@@ -343,8 +346,48 @@ The final status and intentionally deferred work are explicit:
|
|
|
343
346
|
| Native-only request/response interface narrowing | Deferred and preserved. The non-Buffer request-chunk conversion, reader-based provider body interface, cancellation adapter, and invalid injected-status classification remain. Removing them requires proving that supported injected callers do not need them. | No claim of safe removal or measured saving is made for these retained compatibility paths. |
|
|
344
347
|
| Escaped handler and event observer failure reporting | Implemented. Both call `reportMailError`, which uses native `inspect` with depth/array/string clipping disabled before stderr output. `closeResponseAfterHandlerFailure(error)` also passes the error to response destruction; observer errors do not change delivery classification. | Source evidence only; formatting work occurs only on failure. No local error-injection or runtime check was performed for this report. |
|
|
345
348
|
| Remaining local lifecycle rejection-observer names | Preserved. Their narrow purpose is preventing duplicate unhandled rejections while the public lifecycle/close promise retains failure. The inventory records their actual names; no additional abstraction or blanket naming rewrite is selected. | Do not report every possible naming improvement as implemented. |
|
|
346
|
-
| Final source delivery evidence |
|
|
349
|
+
| Final source delivery evidence | The original gateway review selected `0.16.0`; this portable credential follow-up extends the source present in `0.18.0`. Root owns final source/documentation reconciliation and the actual next commit/package/publication outcome. | This report supplies source-review evidence. Actual platform execution, live send, and remote subscription verification remain separate evidence boundaries. The pending remote adapter does not hold the current increment. |
|
|
347
350
|
|
|
348
351
|
TWiNStripeServer owns the future `verify-subscription` endpoint adapter contract; the SDK owns the mail request's application/token consumption and the provider-attempt decision. Any application can use the shared service under its selected CORS policy. The current optional callback allows delivery now without pretending the remote adapter exists: omitted means initial setup with no caller authentication, configured means only an affirmative verifier result permits provider delivery. The later endpoint integration remains recorded and does not cancel or block this current increment.
|
|
349
352
|
|
|
350
353
|
No local test, lint, type check, validation build, browser QA, performance measurement, or live Resend send was performed for this report. No Git index, commit, branch, push, package, or publication operation was performed by the report author. Every baseline named method and callback owner, constant, and significant action remains represented above; removed names are retained in the inventory for traceability. Root owns source/documentation delivery and selected-output verification under its governing authorization. This report records source inspection, not release or runtime evidence.
|
|
354
|
+
|
|
355
|
+
## Portable credential follow-up: 0.19.0
|
|
356
|
+
|
|
357
|
+
The selected storage owner is `src/mail-credentials.mjs`. The public CLI and
|
|
358
|
+
`createToolchain().mail(...)` reach it through `src/mail.mjs`. Repository caller
|
|
359
|
+
tracing found the old Windows target helpers only in this owner and its direct
|
|
360
|
+
test source; the package has no `./mail-credentials` public subpath. The supported
|
|
361
|
+
key operations remain, with JSON replacing their Windows storage implementation.
|
|
362
|
+
Existing native credential records are neither read nor changed.
|
|
363
|
+
|
|
364
|
+
| Method or action | Gates | Decision, callers, and concrete purpose |
|
|
365
|
+
| --- | --- | --- |
|
|
366
|
+
| `WINDOWS_CREDENTIAL_HELPER`, its C# `Write`, `Read`, `Exists`, `Delete`, native structs, and Advapi32 imports | N/N/Y | Remove. These existed solely to reach Windows Credential Manager; all four operations now use the selected JSON owner. No child process or native compilation remains. |
|
|
367
|
+
| `WINDOWS_CREDENTIAL_HELPER_COMMAND`, `powershellExecutable`, `helperArguments`, `helperEnvironment`, `validatePlatform`, `helperOptions` | N/N/Y | Remove. Windows path discovery, environment reconstruction, command encoding, and injected Windows runner options have no consumer in portable JSON storage. `SystemRoot`, `WINDIR`, `TEMP`, and `TMP` are no longer mail credential prerequisites. |
|
|
368
|
+
| `runCredentialProcess`, `runWindowsCredentialHelper`, `invokeCredentialHelper` and their nested process callbacks | N/N/Y | Remove. File operations replace spawning, helper stdin/stdout accumulation, process listeners, timeout allocation, and process shutdown. |
|
|
369
|
+
| `serializeRequest`, `parseResponse`, `decodeSecret`, `BASE64_PATTERN`, helper input/output and credential limits | N/N/Y | Remove. There is no helper transport to encode, decode, scan, or limit. The complete configuration is parsed as JSON at its actual owner. |
|
|
370
|
+
| `validateMailCredentialProfile`, `mailCredentialTarget`, `RESEND_CREDENTIAL_TARGET_PREFIX`, `PROFILE_PATTERN`, `MAX_PROFILE_LENGTH` | N/N/Y for the native target machinery | Remove. JSON profile keys need no native target namespace or lowercase/length grammar. Existing names remain usable; arbitrary nonempty string names are selected exactly. |
|
|
371
|
+
| `validateSecret`, `SECRET_PATTERN`, `validateTimeout`, helper timeout constants | Y/Y/Y for reading a usable key; N/N/Y for helper restrictions | Remove the helper-specific grammar and deadline machinery. A key must be a nonempty string to supply provider authorization; Resend owns its acceptance. No helper deadline is needed. |
|
|
372
|
+
| `usageError`, `unavailableError`, `operationError`, `cancellationError`, `assertNotAborted`, `validateOptions` | Y/Y/Y | Remove the Windows error wrappers and duplicate option/cancellation scaffolding. File failures surface at the file owner; shared `throwIfAborted` handles cancellation. Errors identify the file or setting without including secret values. |
|
|
373
|
+
| `mailCredentialLocation` | Y/Y/N | Keep. All four operations and the missing-key reporter need the same directory/profile mapping. It selects `cwd`, then `workspaceRoot`, then `process.cwd()`, with no directory search. Default `mail` maps to top-level `RESEND_API_KEY`; another exact name maps to its `MAIL_PROFILES` entry. |
|
|
374
|
+
| `readMailSettings` | Y/Y/N | Keep. Each credential operation reads the complete selected file once. Missing files support read/status/delete absence; unreadable JSON cannot supply settings. Parser excerpts are omitted because they may contain the credential. |
|
|
375
|
+
| `mailProfileSettings` | Y/Y/N | Keep. Read, status, set, and delete need the same exact default/named selection. An absent named profile stays absent, including after deletion; it never reveals the default account's key. Object checks identify configuration that cannot represent the requested profile. |
|
|
376
|
+
| `configuredMailKey` | Y/Y/N | Keep. Read and status share missing/empty-key semantics and a useful error for a value that cannot be a provider key. The returned key is preserved exactly. |
|
|
377
|
+
| `mailCredentialStatus` | Y/Y/N | Keep the shared status shape for set/status/delete: profile, provider, storage, and existence. This preserves the useful operation result without returning the credential. |
|
|
378
|
+
| `setMailCredential`, `readMailCredential`, `getMailCredentialStatus`, `deleteMailCredential` | Y/Y/Y | Preserve all four operations and replace their implementation. Explicit set/delete update only the selected credential field while preserving other settings and profiles; read returns the selected key or null; status reports existence. File access uses portable Node APIs. |
|
|
379
|
+
| `mailCredentialOptions`, `readMailProviderKey` | Y/Y/Y | Keep shared command configuration and consolidate the real send/serve duplicate key-read error path. Remove Windows runner, helper directory, and helper timeout forwarding. Missing configuration names the exact JSON setting and file before opening a listener or attempting delivery. |
|
|
380
|
+
| CLI required profile flag and omitted invocation directory | Y/Y/Y | Make the profile optional with default `mail`, retaining explicit profiles. Forward the invocation directory through every mail operation, so the CLI reads the operator's selected file. Preserve hidden/stdin key entry and existing send/serve lifecycle. |
|
|
381
|
+
| Repository and workspace-template `.gitignore` entry | Y/Y/N | Keep `.env.json` out of source control in this checkout and newly generated workspaces. The populated local file is outside the committed and published change. |
|
|
382
|
+
|
|
383
|
+
The credential path performs one file read per selected operation and one write
|
|
384
|
+
only for an explicit set or a deletion that finds a credential. Startup reads
|
|
385
|
+
once; there is no polling, watcher, background cache, migration, or platform
|
|
386
|
+
process. These are source-level work reductions, not a measured speedup.
|
|
387
|
+
|
|
388
|
+
The same Node filesystem contract covers Windows, Linux, and macOS. Android
|
|
389
|
+
requires a compatible Node host and accessible configuration directory. This
|
|
390
|
+
review does not claim execution on those platforms or an actual provider send.
|
|
391
|
+
The updated test source covers disposable JSON storage, exact named selection,
|
|
392
|
+
preservation of other settings, missing settings, credential-free error output,
|
|
393
|
+
cancellation before writes, and CLI defaults. Local tests and checks were not run.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "arcane-os",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.0",
|
|
4
4
|
"description": "Arcane OS JavaScript SDK, project-local CLI, browser runtime, and repository-portable application packager.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.mjs",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
},
|
|
107
107
|
"dependencies": {
|
|
108
108
|
"event-pubsub": "6.1.0",
|
|
109
|
-
"node-http-server": "
|
|
109
|
+
"node-http-server": "10.0.0",
|
|
110
110
|
"strong-type": "2.0.1",
|
|
111
111
|
"vanilla-test": "2.1.3"
|
|
112
112
|
},
|
package/src/cli/main.mjs
CHANGED
|
@@ -81,11 +81,11 @@ Usage:
|
|
|
81
81
|
${CLI_NAME} update-check
|
|
82
82
|
${CLI_NAME} targets
|
|
83
83
|
${CLI_NAME} repo status|pull|push
|
|
84
|
-
${CLI_NAME} mail key set
|
|
85
|
-
${CLI_NAME} mail key status
|
|
86
|
-
${CLI_NAME} mail key delete
|
|
87
|
-
${CLI_NAME} mail send --profile <profile> [--from <address>] --report-key <id> --report-stdin [--request-timeout <ms>]
|
|
88
|
-
${CLI_NAME} mail serve --profile <profile> [--from <address>] [--app <label>] [--origin <origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
|
|
84
|
+
${CLI_NAME} mail key set [profile] [--secret-stdin]
|
|
85
|
+
${CLI_NAME} mail key status [profile]
|
|
86
|
+
${CLI_NAME} mail key delete [profile]
|
|
87
|
+
${CLI_NAME} mail send [--profile <profile>] [--from <address>] --report-key <id> --report-stdin [--request-timeout <ms>]
|
|
88
|
+
${CLI_NAME} mail serve [--profile <profile>] [--from <address>] [--app <label>] [--origin <origin>] [--allow-to <addresses>] [--host 0.0.0.0] [--port 8025] [--request-timeout <ms>]
|
|
89
89
|
|
|
90
90
|
Development:
|
|
91
91
|
--public Bind dev to all IPv4 interfaces (0.0.0.0) and print network URLs.
|
|
@@ -657,9 +657,9 @@ function operationOptions(command,parsed,cwd){
|
|
|
657
657
|
if(area==='key'){
|
|
658
658
|
noExtraPositionals(command,positionals,3);
|
|
659
659
|
const action=positionals[1];
|
|
660
|
-
const profile=positionals[2];
|
|
661
|
-
if(!['set','status','delete'].includes(action)
|
|
662
|
-
usage('mail key requires set, status, or delete
|
|
660
|
+
const profile=positionals[2]??'mail';
|
|
661
|
+
if(!['set','status','delete'].includes(action)){
|
|
662
|
+
usage('mail key requires set, status, or delete, with an optional profile id.');
|
|
663
663
|
}
|
|
664
664
|
if(values.profile!==undefined||values.from!==undefined||values.app!==undefined
|
|
665
665
|
||values.origin!==undefined
|
|
@@ -675,6 +675,7 @@ function operationOptions(command,parsed,cwd){
|
|
|
675
675
|
}
|
|
676
676
|
return {
|
|
677
677
|
action:`key-${action}`,
|
|
678
|
+
cwd,
|
|
678
679
|
profile,
|
|
679
680
|
secretStdin:flags.has('secret-stdin'),
|
|
680
681
|
};
|
|
@@ -687,10 +688,10 @@ function operationOptions(command,parsed,cwd){
|
|
|
687
688
|
if(flags.has('report-stdin')||values['report-key']!==undefined){
|
|
688
689
|
usage('--report-stdin and --report-key are supported only by mail send.');
|
|
689
690
|
}
|
|
690
|
-
if(!values.profile)usage('mail serve requires --profile <value>.');
|
|
691
691
|
return {
|
|
692
692
|
action:'serve',
|
|
693
|
-
|
|
693
|
+
cwd,
|
|
694
|
+
profile:values.profile??'mail',
|
|
694
695
|
from:values.from,
|
|
695
696
|
appId:values.app,
|
|
696
697
|
origin:values.origin,
|
|
@@ -710,25 +711,23 @@ function operationOptions(command,parsed,cwd){
|
|
|
710
711
|
||values.port!==undefined){
|
|
711
712
|
usage('mail send does not accept gateway server options.');
|
|
712
713
|
}
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
'report-key':values['report-key'],
|
|
716
|
-
})){
|
|
717
|
-
if(!value)usage(`mail send requires --${name} <value>.`);
|
|
714
|
+
if(!values['report-key']){
|
|
715
|
+
usage('mail send requires --report-key <value>.');
|
|
718
716
|
}
|
|
719
717
|
if(!flags.has('report-stdin')){
|
|
720
718
|
usage('mail send requires --report-stdin.');
|
|
721
719
|
}
|
|
722
720
|
return {
|
|
723
721
|
action:'send',
|
|
724
|
-
|
|
722
|
+
cwd,
|
|
723
|
+
profile:values.profile??'mail',
|
|
725
724
|
from:values.from,
|
|
726
725
|
reportKey:values['report-key'],
|
|
727
726
|
reportStdin:true,
|
|
728
727
|
requestTimeout:readMailRequestTimeout(values['request-timeout']),
|
|
729
728
|
};
|
|
730
729
|
}
|
|
731
|
-
usage('mail requires key set|status|delete
|
|
730
|
+
usage('mail requires key set|status|delete [profile], send, or serve.');
|
|
732
731
|
}
|
|
733
732
|
usage(`Unknown command. Run ${CLI_NAME} --help for usage.`);
|
|
734
733
|
}
|