@byline/host-tanstack-start 6.7.1 → 6.8.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.
Files changed (44) hide show
  1. package/dist/admin-shell/admin-roles/container_module.css +1 -1
  2. package/dist/admin-shell/admin-roles/delete.js +1 -1
  3. package/dist/admin-shell/admin-users/container.js +181 -159
  4. package/dist/admin-shell/admin-users/container.module.js +2 -1
  5. package/dist/admin-shell/admin-users/container_module.css +5 -1
  6. package/dist/admin-shell/admin-users/delete.js +1 -1
  7. package/dist/integrations/byline-admin-services.js +2 -0
  8. package/dist/integrations/passkey-admin-services.d.ts +9 -0
  9. package/dist/integrations/passkey-admin-services.js +53 -0
  10. package/dist/integrations/session-coordination.d.ts +3 -1
  11. package/dist/integrations/session-coordination.js +3 -1
  12. package/dist/integrations/session-middleware.d.ts +3 -1
  13. package/dist/integrations/session-middleware.js +87 -79
  14. package/dist/integrations/sign-in-body.d.ts +3 -0
  15. package/dist/integrations/sign-in-body.js +19 -4
  16. package/dist/integrations/sign-in-middleware.js +30 -5
  17. package/dist/server-fns/auth/passkey-admission.d.ts +24 -0
  18. package/dist/server-fns/auth/passkey-admission.js +88 -0
  19. package/dist/server-fns/auth/passkeys.d.ts +96 -0
  20. package/dist/server-fns/auth/passkeys.js +238 -0
  21. package/dist/server-fns/auth/reconcile-locale.d.ts +20 -0
  22. package/dist/server-fns/auth/reconcile-locale.js +16 -0
  23. package/dist/server-fns/auth/sign-in.js +1 -15
  24. package/package.json +24 -24
  25. package/src/admin-shell/admin-roles/container.module.css +1 -1
  26. package/src/admin-shell/admin-roles/delete.tsx +1 -1
  27. package/src/admin-shell/admin-users/container.module.css +7 -1
  28. package/src/admin-shell/admin-users/container.tsx +22 -2
  29. package/src/admin-shell/admin-users/delete.tsx +1 -1
  30. package/src/integrations/byline-admin-services.ts +3 -0
  31. package/src/integrations/passkey-admin-services.ts +85 -0
  32. package/src/integrations/session-client.test.node.ts +73 -0
  33. package/src/integrations/session-coordination.ts +3 -1
  34. package/src/integrations/session-middleware.ts +86 -72
  35. package/src/integrations/sign-in-body.test.node.ts +31 -1
  36. package/src/integrations/sign-in-body.ts +27 -3
  37. package/src/integrations/sign-in-middleware.ts +42 -9
  38. package/src/server-fns/auth/passkey-admission.test.node.ts +173 -0
  39. package/src/server-fns/auth/passkey-admission.ts +125 -0
  40. package/src/server-fns/auth/passkeys.test.node.ts +247 -0
  41. package/src/server-fns/auth/passkeys.ts +252 -0
  42. package/src/server-fns/auth/reconcile-locale.ts +40 -0
  43. package/src/server-fns/auth/sign-in.ts +1 -32
  44. package/src/server-fns/document-mutation-transport.test.node.ts +14 -3
@@ -29,10 +29,9 @@ import {
29
29
  import { getServerConfig } from '@byline/core'
30
30
  import { passwordSignInSchema } from '@byline/core/validation'
31
31
 
32
- import { readAdminLocaleCookie } from '../../i18n/locale-cookie.js'
33
- import { bylineCore } from '../../integrations/byline-core.js'
34
32
  import { normalizeClientIp } from '../../integrations/client-ip.js'
35
33
  import { wasSignInBodyChecked } from '../../integrations/sign-in-body.js'
34
+ import { reconcileLocaleAfterSignIn } from './reconcile-locale.js'
36
35
 
37
36
  export interface SignInInput {
38
37
  email: string
@@ -137,33 +136,3 @@ export const adminSignIn = createServerFn({ method: 'POST' })
137
136
 
138
137
  return { userId: result.actor.id, sessionId: result.sessionId }
139
138
  })
140
-
141
- /**
142
- * Apply the `byline_admin_lng` cookie to `admin_users.preferred_locale`
143
- * when the two diverge after sign-in. No-op when:
144
- *
145
- * - The cookie is unset (the cascade falls through to the existing
146
- * column / Accept-Language / default anyway).
147
- * - The cookie carries a locale outside `i18n.admin.locales`
148
- * (stale value pointing at a removed locale — let the resolver
149
- * fall through cleanly).
150
- * - No admin store is configured (headless tooling paths).
151
- * - The stored value already matches the cookie.
152
- */
153
- async function reconcileLocaleAfterSignIn(adminUserId: string): Promise<void> {
154
- const cookieLocale = readAdminLocaleCookie()
155
- if (cookieLocale == null) return
156
-
157
- const core = bylineCore()
158
- const locales = core.config.i18n.admin.locales
159
- if (!locales.includes(cookieLocale)) return
160
-
161
- const adminStore = core.adminStore
162
- if (adminStore == null) return
163
-
164
- const row = await adminStore.adminUsers.getById(adminUserId)
165
- if (!row) return
166
- if (row.preferred_locale === cookieLocale) return
167
-
168
- await adminStore.adminUsers.setPreferredLocale(adminUserId, cookieLocale)
169
- }
@@ -27,12 +27,19 @@ const startRequire = createRequire(require.resolve('@tanstack/react-start/packag
27
27
  const serverPackage = startRequire.resolve('@tanstack/start-server-core/package.json')
28
28
  const esm = join(dirname(serverPackage), 'src')
29
29
  const serverRequire = createRequire(serverPackage)
30
- let handler: (input: { request: Request; context: object; serverFnId: string }) => Promise<Response>
30
+ // Start finalizes a completed serialization in its request pipeline: the handler
31
+ // returns a deferred value whose createResponse(event) builds the Response.
32
+ type DeferredResponse = { createResponse(event: { request: Request; requestUrl: URL }): Response }
33
+ let handler: (input: {
34
+ request: Request
35
+ context: object
36
+ serverFnId: string
37
+ }) => Promise<Response | DeferredResponse>
31
38
  let seroval: {
32
39
  toJSONAsync(value: unknown): Promise<unknown>
33
40
  fromCrossJSON(value: unknown, options: object): unknown
34
41
  }
35
- let runWithStartContext: (context: object, fn: () => Promise<Response>) => Promise<Response>
42
+ let runWithStartContext: <T>(context: object, fn: () => Promise<T>) => Promise<T>
36
43
  let action: (input: { data: unknown }) => Promise<unknown>
37
44
 
38
45
  beforeAll(async () => {
@@ -66,7 +73,7 @@ async function roundTrip(data: unknown, operation: (data: unknown) => Promise<un
66
73
  headers: { 'content-type': 'application/json', 'x-tsr-serverFn': 'true' },
67
74
  body: JSON.stringify(await seroval.toJSONAsync({ data })),
68
75
  })
69
- const response = await runWithStartContext(
76
+ const result = await runWithStartContext(
70
77
  {
71
78
  request,
72
79
  startOptions: {},
@@ -79,6 +86,10 @@ async function roundTrip(data: unknown, operation: (data: unknown) => Promise<un
79
86
  },
80
87
  () => handler({ request, context: {}, serverFnId: 'document-mutation' })
81
88
  )
89
+ const response =
90
+ result instanceof Response
91
+ ? result
92
+ : result.createResponse({ request, requestUrl: new URL(request.url) })
82
93
  const wire = await response.text()
83
94
  const decoded = seroval.fromCrossJSON(JSON.parse(wire), {})
84
95
  if (typeof decoded !== 'object' || decoded === null) throw new Error('Expected wire envelope')