toiljs 0.0.104 → 0.0.106
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 +10 -0
- package/build/compiler/.tsbuildinfo +1 -1
- package/build/compiler/auth-emails.d.ts +28 -0
- package/build/compiler/auth-emails.js +165 -0
- package/build/compiler/emails.d.ts +2 -0
- package/build/compiler/emails.js +4 -1
- package/build/compiler/index.js +12 -0
- package/build/compiler/toil-docs.generated.js +7 -6
- package/docs/README.md +2 -1
- package/docs/auth/README.md +2 -0
- package/docs/auth/emails.md +91 -0
- package/docs/introduction/README.md +19 -10
- package/docs/introduction/hyperscale.md +1 -1
- package/docs/introduction/vs-other-frameworks.md +3 -3
- package/docs/introduction/why-toil.md +2 -4
- package/docs/llms.txt +1 -0
- package/package.json +1 -1
- package/server/auth/AuthController.ts +16 -40
- package/server/globals/email.ts +15 -2
- package/src/compiler/auth-emails.ts +279 -0
- package/src/compiler/emails.ts +14 -1
- package/src/compiler/index.ts +24 -1
- package/src/compiler/toil-docs.generated.ts +7 -6
- package/test/auth-emails.test.ts +115 -0
- package/test/email-console.test.ts +2 -2
package/src/compiler/emails.ts
CHANGED
|
@@ -63,6 +63,15 @@ const REACT_INTERNAL = new Set([
|
|
|
63
63
|
'then', // so a thenable check never tokenizes
|
|
64
64
|
]);
|
|
65
65
|
|
|
66
|
+
/**
|
|
67
|
+
* Reserved `emails/*.tsx` module names (by PascalCase basename) that OVERRIDE a
|
|
68
|
+
* built-in auth email instead of becoming a generic `Emails.<Name>.send(...)`
|
|
69
|
+
* entry. When one is present, the auth pipeline (src/compiler/auth-emails.ts)
|
|
70
|
+
* bakes it into `_auth_emails.ts` in place of the default; here we just make sure
|
|
71
|
+
* it does NOT also surface as an app-callable `Emails.*` template.
|
|
72
|
+
*/
|
|
73
|
+
export const RESERVED_AUTH_EMAIL_NAMES = new Set(['AuthConfirm', 'AuthReset', 'Auth2fa']);
|
|
74
|
+
|
|
66
75
|
const TOKEN_RE = /\{\{\s*([A-Za-z_$][\w$]*)\s*\}\}/g;
|
|
67
76
|
|
|
68
77
|
function extractTokens(s: string): string[] {
|
|
@@ -240,7 +249,7 @@ export function toPascal(base: string): string {
|
|
|
240
249
|
|
|
241
250
|
/** Server source dir (where the generated module must live to be compiled): the
|
|
242
251
|
* dir of the first toilconfig entry, else `<root>/server`. */
|
|
243
|
-
function serverDir(root: string): string {
|
|
252
|
+
export function serverDir(root: string): string {
|
|
244
253
|
try {
|
|
245
254
|
const cfg = JSON.parse(fs.readFileSync(path.join(root, 'toilconfig.json'), 'utf8')) as {
|
|
246
255
|
entries?: unknown;
|
|
@@ -344,6 +353,10 @@ export async function renderEmails(cfg: ResolvedToilConfig): Promise<void> {
|
|
|
344
353
|
const rendered: RenderedEmail[] = [];
|
|
345
354
|
try {
|
|
346
355
|
for (const file of files) {
|
|
356
|
+
// Reserved auth-override templates (emails/auth-confirm.tsx, …) are
|
|
357
|
+
// consumed by the auth pipeline, not surfaced as generic `Emails.*`.
|
|
358
|
+
if (RESERVED_AUTH_EMAIL_NAMES.has(toPascal(path.basename(file).replace(/\.(tsx|jsx)$/, ''))))
|
|
359
|
+
continue;
|
|
347
360
|
try {
|
|
348
361
|
const r = await renderEmailFile(
|
|
349
362
|
server,
|
package/src/compiler/index.ts
CHANGED
|
@@ -14,6 +14,7 @@ import type { RunningBackend } from 'toiljs/backend';
|
|
|
14
14
|
|
|
15
15
|
import { loadConfig, type ResolvedToilConfig } from './config.js';
|
|
16
16
|
import { renderEmails } from './emails.js';
|
|
17
|
+
import { AUTH_EMAILS_GENERATED_BASENAME, renderAuthEmails } from './auth-emails.js';
|
|
17
18
|
import { generate, TOIL_SERVER_ENV_DTS } from './generate.js';
|
|
18
19
|
import { prerenderStaticParams } from './ssg.js';
|
|
19
20
|
import {
|
|
@@ -179,6 +180,20 @@ function serverImportsAuth(root: string, files: string[]): boolean {
|
|
|
179
180
|
return false;
|
|
180
181
|
}
|
|
181
182
|
|
|
183
|
+
/**
|
|
184
|
+
* Whether the built-in auth surface is on for this project: the `server.auth` config flag OR the
|
|
185
|
+
* escape-hatch `import 'toiljs/server/auth'` in a server entry. This is the SAME predicate
|
|
186
|
+
* `buildServer` uses to decide whether to inject `AuthController` (see `authOn` there); the email
|
|
187
|
+
* pipeline reuses it so `_auth_emails.ts` is generated exactly when the controller that calls
|
|
188
|
+
* `AuthEmail.*` is compiled in (a mismatch would be a missing-symbol compile error). Client-only
|
|
189
|
+
* projects (no `toilconfig.json`) are never auth-on.
|
|
190
|
+
*/
|
|
191
|
+
function serverAuthEnabled(root: string, configAuth: boolean): boolean {
|
|
192
|
+
if (configAuth) return true;
|
|
193
|
+
if (!fs.existsSync(path.join(root, 'toilconfig.json'))) return false;
|
|
194
|
+
return serverImportsAuth(root, serverEntryFiles(root));
|
|
195
|
+
}
|
|
196
|
+
|
|
182
197
|
/**
|
|
183
198
|
* Builds the toilscript server target (which also regenerates `shared/server.ts` via
|
|
184
199
|
* `--rpcModule`) when the project has one, signalled by a `toilconfig.json` at the root. This
|
|
@@ -581,6 +596,7 @@ function watchServer(cfg: ResolvedToilConfig, watcher: ViteDevServer['watcher'])
|
|
|
581
596
|
// Recompile emails/*.tsx -> the generated module before the server build,
|
|
582
597
|
// so editing an email template hot-reloads like any other server change.
|
|
583
598
|
renderEmails(cfg)
|
|
599
|
+
.then(() => renderAuthEmails(cfg, serverAuthEnabled(root, cfg.auth)))
|
|
584
600
|
.then(() => buildServer(root, cfg.auth))
|
|
585
601
|
.then(() => process.stdout.write(pc.green(' ✓ ') + pc.dim('server rebuilt') + '\n'))
|
|
586
602
|
.catch((e: unknown) =>
|
|
@@ -599,9 +615,10 @@ function watchServer(cfg: ResolvedToilConfig, watcher: ViteDevServer['watcher'])
|
|
|
599
615
|
const isServerSource = (file: string): boolean =>
|
|
600
616
|
file.endsWith('.ts') &&
|
|
601
617
|
!file.endsWith('.d.ts') &&
|
|
602
|
-
// `_emails.ts`
|
|
618
|
+
// `_emails.ts` / `_auth_emails.ts` are GENERATED on every rebuild; reacting to
|
|
603
619
|
// our own output would loop forever (rebuild -> write -> rebuild -> ...).
|
|
604
620
|
path.basename(file) !== '_emails.ts' &&
|
|
621
|
+
path.basename(file) !== AUTH_EMAILS_GENERATED_BASENAME &&
|
|
605
622
|
dirs.some((dir) => file === dir || file.startsWith(dir + path.sep));
|
|
606
623
|
const isEmailSource = (file: string): boolean =>
|
|
607
624
|
/\.(tsx|jsx)$/.test(file) && (file === emailsDir || file.startsWith(emailsDir + path.sep));
|
|
@@ -863,6 +880,9 @@ export async function dev(opts: ToilCommandOptions = {}): Promise<ViteDevServer>
|
|
|
863
880
|
if (hasServer) process.stdout.write(pc.dim(' building the server (toilscript)…') + '\n');
|
|
864
881
|
// Compile emails/*.tsx -> generated server module BEFORE toilscript builds it in.
|
|
865
882
|
await renderEmails(cfg);
|
|
883
|
+
// Built-in auth: (re)generate `<server>/_auth_emails.ts` (defaults + any emails/auth-*.tsx
|
|
884
|
+
// overrides) so the injected AuthController's `AuthEmail.*` senders compile in.
|
|
885
|
+
await renderAuthEmails(cfg, serverAuthEnabled(cfg.root, cfg.auth));
|
|
866
886
|
// Generate the client codegen first so the SSR slots pre-pass can load the route graph, then
|
|
867
887
|
// emit the server-importable `<server>/_ssr/<name>.slots.ts` BEFORE the server build so its
|
|
868
888
|
// `render` can import them. Dev reuses the prior build's shell (or the template) for the HASH;
|
|
@@ -988,6 +1008,9 @@ export async function build(opts: ToilCommandOptions = {}): Promise<void> {
|
|
|
988
1008
|
process.stdout.write(pc.dim(' building the server (toilscript)…') + '\n');
|
|
989
1009
|
// Compile emails/*.tsx -> generated server module BEFORE toilscript builds it in.
|
|
990
1010
|
await renderEmails(cfg);
|
|
1011
|
+
// Built-in auth: (re)generate `<server>/_auth_emails.ts` (defaults + any emails/auth-*.tsx
|
|
1012
|
+
// overrides) so the injected AuthController's `AuthEmail.*` senders compile in.
|
|
1013
|
+
await renderAuthEmails(cfg, serverAuthEnabled(cfg.root, cfg.auth));
|
|
991
1014
|
// Generate the client codegen (`.toil/globals.ts`, `.toil/index.html`, …) NOW — before the
|
|
992
1015
|
// server build — so the SSR slots pre-pass below can load the route/layout module graph and
|
|
993
1016
|
// render the opted-in routes.
|