@byline/host-tanstack-start 4.0.0 → 4.2.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 (136) hide show
  1. package/dist/admin-shell/collections/tree-list-projection.d.ts +1 -1
  2. package/dist/i18n/resolve-locale.js +1 -1
  3. package/dist/index.d.ts +5 -6
  4. package/dist/integrations/host-bridge.d.ts +13 -0
  5. package/dist/integrations/host-bridge.js +22 -0
  6. package/dist/integrations/serve-uploads.d.ts +1 -0
  7. package/dist/integrations/serve-uploads.js +1 -0
  8. package/dist/server-fns/admin-account/change-password.js +1 -1
  9. package/dist/server-fns/admin-account/get.js +1 -1
  10. package/dist/server-fns/admin-account/update.js +1 -1
  11. package/dist/server-fns/admin-activity/get.js +1 -1
  12. package/dist/server-fns/admin-permissions/get-role-abilities.js +1 -1
  13. package/dist/server-fns/admin-permissions/list-registered.js +1 -1
  14. package/dist/server-fns/admin-permissions/set-role-abilities.js +1 -1
  15. package/dist/server-fns/admin-permissions/who-has.js +1 -1
  16. package/dist/server-fns/admin-roles/create.js +1 -1
  17. package/dist/server-fns/admin-roles/delete.js +1 -1
  18. package/dist/server-fns/admin-roles/get.js +1 -1
  19. package/dist/server-fns/admin-roles/list.js +1 -1
  20. package/dist/server-fns/admin-roles/reorder.js +1 -1
  21. package/dist/server-fns/admin-roles/update.js +1 -1
  22. package/dist/server-fns/admin-users/create.js +1 -1
  23. package/dist/server-fns/admin-users/delete.js +1 -1
  24. package/dist/server-fns/admin-users/disable.js +1 -1
  25. package/dist/server-fns/admin-users/enable.js +1 -1
  26. package/dist/server-fns/admin-users/get-user-roles.js +1 -1
  27. package/dist/server-fns/admin-users/get.js +1 -1
  28. package/dist/server-fns/admin-users/list.js +1 -1
  29. package/dist/server-fns/admin-users/set-password.js +1 -1
  30. package/dist/server-fns/admin-users/set-user-roles.js +1 -1
  31. package/dist/server-fns/admin-users/update.js +1 -1
  32. package/dist/server-fns/ai/execute.js +1 -1
  33. package/dist/server-fns/auth/current-user.js +1 -1
  34. package/dist/server-fns/auth/sign-in.js +1 -1
  35. package/dist/server-fns/auth/sign-out.js +1 -2
  36. package/dist/server-fns/collections/audit.js +1 -1
  37. package/dist/server-fns/collections/copy-to-locale.js +1 -1
  38. package/dist/server-fns/collections/create.js +1 -1
  39. package/dist/server-fns/collections/delete-locale.js +1 -1
  40. package/dist/server-fns/collections/delete.js +1 -1
  41. package/dist/server-fns/collections/duplicate.js +1 -1
  42. package/dist/server-fns/collections/get.js +1 -1
  43. package/dist/server-fns/collections/history.js +1 -1
  44. package/dist/server-fns/collections/list.js +1 -1
  45. package/dist/server-fns/collections/reindex.js +1 -1
  46. package/dist/server-fns/collections/reorder.js +1 -1
  47. package/dist/server-fns/collections/restore-version.js +1 -1
  48. package/dist/server-fns/collections/stats.js +1 -1
  49. package/dist/server-fns/collections/status.js +1 -1
  50. package/dist/server-fns/collections/tree.js +1 -1
  51. package/dist/server-fns/collections/update.js +1 -1
  52. package/dist/server-fns/collections/upload.js +2 -1
  53. package/dist/server-fns/i18n/set-locale.js +1 -1
  54. package/dist/server-fns/preview/disable.js +1 -1
  55. package/dist/server-fns/preview/enable.js +1 -2
  56. package/dist/server-fns/preview/state.js +1 -1
  57. package/package.json +8 -13
  58. package/src/admin-shell/collections/tree-list-projection.ts +1 -1
  59. package/src/i18n/resolve-locale.ts +1 -1
  60. package/src/index.ts +5 -6
  61. package/src/integrations/host-bridge.ts +56 -0
  62. package/src/integrations/serve-uploads.ts +6 -0
  63. package/src/server-fns/admin-account/change-password.ts +1 -1
  64. package/src/server-fns/admin-account/get.ts +1 -1
  65. package/src/server-fns/admin-account/update.ts +1 -1
  66. package/src/server-fns/admin-activity/get.ts +1 -1
  67. package/src/server-fns/admin-permissions/get-role-abilities.ts +1 -1
  68. package/src/server-fns/admin-permissions/list-registered.ts +1 -1
  69. package/src/server-fns/admin-permissions/set-role-abilities.ts +1 -1
  70. package/src/server-fns/admin-permissions/who-has.ts +1 -1
  71. package/src/server-fns/admin-roles/create.ts +1 -1
  72. package/src/server-fns/admin-roles/delete.ts +1 -1
  73. package/src/server-fns/admin-roles/get.ts +1 -1
  74. package/src/server-fns/admin-roles/list.ts +1 -1
  75. package/src/server-fns/admin-roles/reorder.ts +1 -1
  76. package/src/server-fns/admin-roles/update.ts +1 -1
  77. package/src/server-fns/admin-users/create.ts +1 -1
  78. package/src/server-fns/admin-users/delete.ts +1 -1
  79. package/src/server-fns/admin-users/disable.ts +1 -1
  80. package/src/server-fns/admin-users/enable.ts +1 -1
  81. package/src/server-fns/admin-users/get-user-roles.ts +1 -1
  82. package/src/server-fns/admin-users/get.ts +1 -1
  83. package/src/server-fns/admin-users/list.ts +1 -1
  84. package/src/server-fns/admin-users/set-password.ts +1 -1
  85. package/src/server-fns/admin-users/set-user-roles.ts +1 -1
  86. package/src/server-fns/admin-users/update.ts +1 -1
  87. package/src/server-fns/ai/execute.ts +1 -2
  88. package/src/server-fns/auth/current-user.ts +1 -1
  89. package/src/server-fns/auth/sign-in.ts +1 -1
  90. package/src/server-fns/auth/sign-out.ts +5 -3
  91. package/src/server-fns/collections/audit.ts +1 -1
  92. package/src/server-fns/collections/copy-to-locale.ts +1 -1
  93. package/src/server-fns/collections/create.ts +1 -1
  94. package/src/server-fns/collections/delete-locale.ts +1 -1
  95. package/src/server-fns/collections/delete.ts +1 -1
  96. package/src/server-fns/collections/duplicate.ts +1 -1
  97. package/src/server-fns/collections/get.ts +1 -1
  98. package/src/server-fns/collections/history.ts +1 -1
  99. package/src/server-fns/collections/list.ts +1 -1
  100. package/src/server-fns/collections/reindex.ts +1 -1
  101. package/src/server-fns/collections/reorder.ts +1 -1
  102. package/src/server-fns/collections/restore-version.ts +1 -1
  103. package/src/server-fns/collections/stats.ts +2 -1
  104. package/src/server-fns/collections/status.ts +1 -1
  105. package/src/server-fns/collections/tree.ts +2 -2
  106. package/src/server-fns/collections/update.ts +1 -1
  107. package/src/server-fns/collections/upload.ts +2 -1
  108. package/src/server-fns/i18n/set-locale.ts +1 -1
  109. package/src/server-fns/preview/disable.ts +1 -1
  110. package/src/server-fns/preview/enable.ts +1 -2
  111. package/src/server-fns/preview/state.ts +1 -1
  112. package/dist/auth/auth-context.d.ts +0 -50
  113. package/dist/auth/auth-context.js +0 -61
  114. package/dist/auth/auth-cookies.d.ts +0 -34
  115. package/dist/auth/auth-cookies.js +0 -46
  116. package/dist/auth/preview-cookies.d.ts +0 -19
  117. package/dist/auth/preview-cookies.js +0 -26
  118. package/dist/auth/request-scope.d.ts +0 -16
  119. package/dist/auth/request-scope.js +0 -24
  120. package/dist/integrations/byline-client.d.ts +0 -24
  121. package/dist/integrations/byline-client.js +0 -25
  122. package/dist/integrations/byline-public-client.d.ts +0 -47
  123. package/dist/integrations/byline-public-client.js +0 -19
  124. package/dist/integrations/byline-viewer-client.d.ts +0 -26
  125. package/dist/integrations/byline-viewer-client.js +0 -44
  126. package/src/auth/auth-context.test.node.ts +0 -302
  127. package/src/auth/auth-context.ts +0 -142
  128. package/src/auth/auth-cookies.ts +0 -113
  129. package/src/auth/preview-cookies.ts +0 -73
  130. package/src/auth/request-scope.test.node.ts +0 -93
  131. package/src/auth/request-scope.ts +0 -62
  132. package/src/integrations/byline-client.ts +0 -68
  133. package/src/integrations/byline-public-client.ts +0 -67
  134. package/src/integrations/byline-viewer-client.ts +0 -111
  135. package/src/integrations/request-context-contract.test.node.ts +0 -131
  136. package/src/integrations/request-context-factories.test.node.ts +0 -140
@@ -8,6 +8,7 @@
8
8
 
9
9
  import { createServerFn } from '@tanstack/react-start'
10
10
 
11
+ import { getAdminRequestContext } from '@byline/client/server'
11
12
  import {
12
13
  assertActorCanPerform,
13
14
  ERR_NOT_FOUND,
@@ -18,7 +19,6 @@ import {
18
19
  getServerConfig,
19
20
  } from '@byline/core'
20
21
 
21
- import { getAdminRequestContext } from '../../auth/auth-context.js'
22
22
  import { ensureCollection } from '../../integrations/api-utils.js'
23
23
 
24
24
  // ---------------------------------------------------------------------------
@@ -8,11 +8,11 @@
8
8
 
9
9
  import { createServerFn } from '@tanstack/react-start'
10
10
 
11
+ import { getAdminRequestContext } from '@byline/client/server'
11
12
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from '@byline/core'
12
13
  import type { DocumentLifecycleContext } from '@byline/core/services'
13
14
  import { restoreDocumentVersion as restoreDocumentVersionService } from '@byline/core/services'
14
15
 
15
- import { getAdminRequestContext } from '../../auth/auth-context.js'
16
16
  import { ensureCollection } from '../../integrations/api-utils.js'
17
17
 
18
18
  // ---------------------------------------------------------------------------
@@ -8,8 +8,9 @@
8
8
 
9
9
  import { createServerFn } from '@tanstack/react-start'
10
10
 
11
+ import { getAdminBylineClient } from '@byline/client/server'
12
+
11
13
  import { ensureCollection } from '../../integrations/api-utils.js'
12
- import { getAdminBylineClient } from '../../integrations/byline-client.js'
13
14
 
14
15
  // ---------------------------------------------------------------------------
15
16
  // Shared types
@@ -8,6 +8,7 @@
8
8
 
9
9
  import { createServerFn } from '@tanstack/react-start'
10
10
 
11
+ import { getAdminRequestContext } from '@byline/client/server'
11
12
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from '@byline/core'
12
13
  import type { DocumentLifecycleContext } from '@byline/core/services'
13
14
  import {
@@ -15,7 +16,6 @@ import {
15
16
  unpublishDocument as unpublishDocumentService,
16
17
  } from '@byline/core/services'
17
18
 
18
- import { getAdminRequestContext } from '../../auth/auth-context.js'
19
19
  import { ensureCollection } from '../../integrations/api-utils.js'
20
20
 
21
21
  // ---------------------------------------------------------------------------
@@ -11,15 +11,15 @@
11
11
  * behind the sidebar tree-placement widget. Thin wrappers over the
12
12
  * `@byline/client` tree API, which asserts the actor ability, enforces the
13
13
  * cycle / same-collection invariants, and fires the `afterTreeChange`
14
- * invalidation hook. See docs/04-collections/03-document-trees.md.
14
+ * invalidation hook. See docs/04-collections/04-document-trees.md.
15
15
  */
16
16
 
17
17
  import { createServerFn } from '@tanstack/react-start'
18
18
 
19
+ import { getAdminBylineClient } from '@byline/client/server'
19
20
  import { createReadContext, ERR_NOT_FOUND, getLogger } from '@byline/core'
20
21
 
21
22
  import { ensureCollection } from '../../integrations/api-utils.js'
22
- import { getAdminBylineClient } from '../../integrations/byline-client.js'
23
23
  import { placeAdminTreeNode, removeAdminTreeNode } from './tree-mutation.js'
24
24
  import { getAdminTreeParent, getAdminUnplacedTreeDocuments } from './tree-read.js'
25
25
 
@@ -8,12 +8,12 @@
8
8
 
9
9
  import { createServerFn } from '@tanstack/react-start'
10
10
 
11
+ import { getAdminRequestContext } from '@byline/client/server'
11
12
  import { ERR_NOT_FOUND, getLogger, getServerConfig } from '@byline/core'
12
13
  import type { DocumentPatch } from '@byline/core/patches'
13
14
  import type { DocumentLifecycleContext } from '@byline/core/services'
14
15
  import { updateDocumentSystemFields, updateDocumentWithPatches } from '@byline/core/services'
15
16
 
16
- import { getAdminRequestContext } from '../../auth/auth-context.js'
17
17
  import { ensureCollection } from '../../integrations/api-utils.js'
18
18
 
19
19
  // ---------------------------------------------------------------------------
@@ -1,5 +1,6 @@
1
1
  import { createServerFn } from '@tanstack/react-start'
2
2
 
3
+ import { getAdminRequestContext } from '@byline/client/server'
3
4
  import type {
4
5
  CollectionDefinition,
5
6
  FieldUploadContext,
@@ -12,7 +13,6 @@ import { extractImageMeta, generateImageVariants, isBypassMimeType } from '@byli
12
13
  import { getLogger, withLogContext } from '@byline/core/logger'
13
14
  import { uploadField as coreUploadField } from '@byline/core/services'
14
15
 
15
- import { getAdminRequestContext } from '../../auth/auth-context.js'
16
16
  import { ensureCollection } from '../../integrations/api-utils.js'
17
17
 
18
18
  /**
@@ -198,6 +198,7 @@ export const uploadCollectionField = createServerFn({ method: 'POST' })
198
198
  logger,
199
199
  defaultLocale: serverConfig.i18n.content.defaultLocale,
200
200
  slugifier: serverConfig.slugifier,
201
+ filenameSlugifier: serverConfig.uploads?.filenameSlugifier,
201
202
  requestContext: await getAdminRequestContext(),
202
203
  imageProcessor: {
203
204
  extractMeta: extractImageMeta,
@@ -30,8 +30,8 @@ import { createServerFn } from '@tanstack/react-start'
30
30
  import type { AccountResponse } from '@byline/admin/admin-account'
31
31
  import { setPreferredLocaleCommand } from '@byline/admin/admin-account'
32
32
  import { AuthError, AuthErrorCodes } from '@byline/auth'
33
+ import { getAdminRequestContext } from '@byline/client/server'
33
34
 
34
- import { getAdminRequestContext } from '../../auth/auth-context.js'
35
35
  import { clearAdminLocaleCookie, setAdminLocaleCookie } from '../../i18n/locale-cookie.js'
36
36
  import { bylineCore } from '../../integrations/byline-core.js'
37
37
 
@@ -16,7 +16,7 @@
16
16
 
17
17
  import { createServerFn } from '@tanstack/react-start'
18
18
 
19
- import { clearPreviewCookie } from '../../auth/preview-cookies.js'
19
+ import { clearPreviewCookie } from '@byline/client/server'
20
20
 
21
21
  export const disablePreviewModeFn = createServerFn({ method: 'POST' }).handler(async () => {
22
22
  clearPreviewCookie()
@@ -17,8 +17,7 @@
17
17
 
18
18
  import { createServerFn } from '@tanstack/react-start'
19
19
 
20
- import { getAdminRequestContext } from '../../auth/auth-context.js'
21
- import { setPreviewCookie } from '../../auth/preview-cookies.js'
20
+ import { getAdminRequestContext, setPreviewCookie } from '@byline/client/server'
22
21
 
23
22
  export const enablePreviewModeFn = createServerFn({ method: 'POST' }).handler(async () => {
24
23
  await getAdminRequestContext()
@@ -23,7 +23,7 @@
23
23
 
24
24
  import { createServerFn } from '@tanstack/react-start'
25
25
 
26
- import { readPreviewCookie } from '../../auth/preview-cookies.js'
26
+ import { readPreviewCookie } from '@byline/client/server'
27
27
 
28
28
  export const getPreviewStateFn = createServerFn({ method: 'GET' }).handler(async () => {
29
29
  return { preview: readPreviewCookie() }
@@ -1,50 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- /**
9
- * Request-scoped auth context for admin server functions.
10
- *
11
- * Reads the session cookies, verifies the access token, transparently
12
- * refreshes when needed, and returns a `RequestContext` carrying the
13
- * authenticated `AdminAuth`. Every admin server fn calls this as its
14
- * first step — it is the single point where the admin transport boundary
15
- * meets the actor/ability machinery.
16
- *
17
- * Flow, in order:
18
- *
19
- * 1. Read the access cookie.
20
- * 2. If present, try `sessionProvider.verifyAccessToken`. On success,
21
- * return the context — no DB write, no cookie churn.
22
- * 3. On verify failure (or missing access cookie), read the refresh
23
- * cookie. If present, call `sessionProvider.refreshSession` — this
24
- * rotates the refresh token atomically and issues a new access
25
- * token. Write both fresh cookies to the response.
26
- * 4. Verify the new access token (populate the actor) and return the
27
- * context.
28
- * 5. Any failure along the way clears both cookies so the browser
29
- * stops sending a session the server has already rejected, and
30
- * throws `ERR_UNAUTHENTICATED`.
31
- *
32
- * Burns a refresh-token rotation only when the access token actually
33
- * fails verification — not on every request. The "one session" UX is
34
- * the consequence of this helper working invisibly behind each call.
35
- *
36
- * Resolution is memoized per request (`oncePerRequest`): every call within
37
- * one logical request returns the same `RequestContext` instance — same
38
- * actor snapshot, same `requestId`. Two invariants depend on this:
39
- *
40
- * - The read-authorization layer binds each `ReadContext` to one
41
- * immutable authority token that includes `requestId`; a fresh id per
42
- * call makes any two reads sharing a `ReadContext` (the admin tree
43
- * view, hook-threaded nested reads) throw
44
- * 'ReadContext cannot be reused across request authorities'.
45
- * - The refresh path rotates the refresh token; a second unmemoized call
46
- * in the same request would re-run the dance against the
47
- * already-rotated cookie and sign the admin out.
48
- */
49
- import { type RequestContext } from '@byline/auth';
50
- export declare function getAdminRequestContext(): Promise<RequestContext>;
@@ -1,61 +0,0 @@
1
- import { ERR_UNAUTHENTICATED } from "@byline/auth";
2
- import { getServerConfig } from "@byline/core";
3
- import { v7 } from "uuid";
4
- import { clearSessionCookies, readAccessTokenCookie, readRefreshTokenCookie, setSessionCookies } from "./auth-cookies.js";
5
- import { oncePerRequest } from "./request-scope.js";
6
- function requireSessionProvider() {
7
- const provider = getServerConfig().sessionProvider;
8
- if (!provider) throw new Error("No sessionProvider configured on ServerConfig. Construct a JwtSessionProvider in your server config and pass it to initBylineCore().");
9
- return provider;
10
- }
11
- async function getAdminRequestContext() {
12
- return oncePerRequest('byline:admin-request-context', resolveAdminRequestContext);
13
- }
14
- async function resolveAdminRequestContext() {
15
- const provider = requireSessionProvider();
16
- const accessToken = readAccessTokenCookie();
17
- if (accessToken) try {
18
- const { actor } = await provider.verifyAccessToken(accessToken);
19
- return {
20
- actor,
21
- requestId: v7(),
22
- readMode: 'any'
23
- };
24
- } catch {}
25
- const refreshToken = readRefreshTokenCookie();
26
- if (!refreshToken) {
27
- if (accessToken) clearSessionCookies();
28
- throw ERR_UNAUTHENTICATED({
29
- message: 'no admin session'
30
- });
31
- }
32
- let refreshed;
33
- try {
34
- refreshed = await provider.refreshSession({
35
- refreshToken
36
- });
37
- } catch (err) {
38
- clearSessionCookies();
39
- throw ERR_UNAUTHENTICATED({
40
- message: 'admin session could not be refreshed',
41
- cause: err
42
- });
43
- }
44
- setSessionCookies(refreshed);
45
- let verified;
46
- try {
47
- verified = await provider.verifyAccessToken(refreshed.accessToken);
48
- } catch (err) {
49
- clearSessionCookies();
50
- throw ERR_UNAUTHENTICATED({
51
- message: 'refreshed access token did not verify',
52
- cause: err
53
- });
54
- }
55
- return {
56
- actor: verified.actor,
57
- requestId: v7(),
58
- readMode: 'any'
59
- };
60
- }
61
- export { getAdminRequestContext };
@@ -1,34 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- export declare const ACCESS_TOKEN_COOKIE = "byline_access_token";
9
- export declare const REFRESH_TOKEN_COOKIE = "byline_refresh_token";
10
- /** Read the access-token cookie. Returns undefined when not present. */
11
- export declare function readAccessTokenCookie(): string | undefined;
12
- /** Read the refresh-token cookie. Returns undefined when not present. */
13
- export declare function readRefreshTokenCookie(): string | undefined;
14
- export interface SessionCookieTokens {
15
- accessToken: string;
16
- refreshToken: string;
17
- accessTokenExpiresAt: Date;
18
- refreshTokenExpiresAt: Date;
19
- }
20
- /**
21
- * Write both access and refresh cookies. Called after sign-in and after
22
- * every transparent refresh in `getAdminRequestContext()`.
23
- *
24
- * `maxAge` is derived from each token's own expiry claim so the browser
25
- * drops the cookies at the same moment the server would reject them —
26
- * saves round trips when the refresh token has fully expired.
27
- */
28
- export declare function setSessionCookies(tokens: SessionCookieTokens): void;
29
- /**
30
- * Clear both session cookies. Called on sign-out and on any auth failure
31
- * during `getAdminRequestContext()` (ensures the browser does not keep
32
- * trying a token that the server has already rejected).
33
- */
34
- export declare function clearSessionCookies(): void;
@@ -1,46 +0,0 @@
1
- import { getCookie, setCookie } from "@tanstack/react-start/server";
2
- const ACCESS_TOKEN_COOKIE = 'byline_access_token';
3
- const REFRESH_TOKEN_COOKIE = 'byline_refresh_token';
4
- const IS_PROD = 'production' === process.env.NODE_ENV;
5
- function readAccessTokenCookie() {
6
- return getCookie(ACCESS_TOKEN_COOKIE);
7
- }
8
- function readRefreshTokenCookie() {
9
- return getCookie(REFRESH_TOKEN_COOKIE);
10
- }
11
- function setSessionCookies(tokens) {
12
- const now = Date.now();
13
- const accessMaxAgeSeconds = Math.max(0, Math.floor((tokens.accessTokenExpiresAt.getTime() - now) / 1000));
14
- const refreshMaxAgeSeconds = Math.max(0, Math.floor((tokens.refreshTokenExpiresAt.getTime() - now) / 1000));
15
- setCookie(ACCESS_TOKEN_COOKIE, tokens.accessToken, {
16
- httpOnly: true,
17
- sameSite: 'lax',
18
- secure: IS_PROD,
19
- path: '/',
20
- maxAge: accessMaxAgeSeconds
21
- });
22
- setCookie(REFRESH_TOKEN_COOKIE, tokens.refreshToken, {
23
- httpOnly: true,
24
- sameSite: 'lax',
25
- secure: IS_PROD,
26
- path: '/',
27
- maxAge: refreshMaxAgeSeconds
28
- });
29
- }
30
- function clearSessionCookies() {
31
- setCookie(ACCESS_TOKEN_COOKIE, '', {
32
- httpOnly: true,
33
- sameSite: 'lax',
34
- secure: IS_PROD,
35
- path: '/',
36
- maxAge: 0
37
- });
38
- setCookie(REFRESH_TOKEN_COOKIE, '', {
39
- httpOnly: true,
40
- sameSite: 'lax',
41
- secure: IS_PROD,
42
- path: '/',
43
- maxAge: 0
44
- });
45
- }
46
- export { ACCESS_TOKEN_COOKIE, REFRESH_TOKEN_COOKIE, clearSessionCookies, readAccessTokenCookie, readRefreshTokenCookie, setSessionCookies };
@@ -1,19 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- export declare const PREVIEW_COOKIE = "byline_preview";
9
- /** True iff the preview cookie is currently set on the request. */
10
- export declare function readPreviewCookie(): boolean;
11
- /**
12
- * Write the preview cookie. Callers should ensure the request is from a
13
- * valid admin session before invoking — the cookie itself is just a flag
14
- * and carries no proof of authorisation. See `enablePreviewModeFn` for
15
- * the canonical entry point.
16
- */
17
- export declare function setPreviewCookie(): void;
18
- /** Clear the preview cookie. Safe to call from any context. */
19
- export declare function clearPreviewCookie(): void;
@@ -1,26 +0,0 @@
1
- import { getCookie, setCookie } from "@tanstack/react-start/server";
2
- const PREVIEW_COOKIE = 'byline_preview';
3
- const PREVIEW_MAX_AGE_SECONDS = 86400;
4
- const IS_PROD = 'production' === process.env.NODE_ENV;
5
- function readPreviewCookie() {
6
- return '1' === getCookie(PREVIEW_COOKIE);
7
- }
8
- function setPreviewCookie() {
9
- setCookie(PREVIEW_COOKIE, '1', {
10
- httpOnly: true,
11
- sameSite: 'lax',
12
- secure: IS_PROD,
13
- path: '/',
14
- maxAge: PREVIEW_MAX_AGE_SECONDS
15
- });
16
- }
17
- function clearPreviewCookie() {
18
- setCookie(PREVIEW_COOKIE, '', {
19
- httpOnly: true,
20
- sameSite: 'lax',
21
- secure: IS_PROD,
22
- path: '/',
23
- maxAge: 0
24
- });
25
- }
26
- export { PREVIEW_COOKIE, clearPreviewCookie, readPreviewCookie, setPreviewCookie };
@@ -1,16 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- /**
9
- * Resolve `factory` at most once per HTTP request for a given `key`. The
10
- * returned promise is memoized on the current Start request — rejections
11
- * included, since a request's cookies cannot change mid-flight and retrying
12
- * a failed refresh would burn a second rotation on an already-rotated
13
- * token. Outside the Start runtime (seed scripts, unit tests, background
14
- * jobs) there is no request to key on and the factory runs unmemoized.
15
- */
16
- export declare function oncePerRequest<T>(key: string, factory: () => Promise<T>): Promise<T>;
@@ -1,24 +0,0 @@
1
- import { getRequest } from "@tanstack/react-start/server";
2
- const requestScopes = new WeakMap();
3
- function oncePerRequest(key, factory) {
4
- const request = currentRequest();
5
- if (!request) return factory();
6
- let scope = requestScopes.get(request);
7
- if (!scope) {
8
- scope = new Map();
9
- requestScopes.set(request, scope);
10
- }
11
- const existing = scope.get(key);
12
- if (existing) return existing;
13
- const pending = factory();
14
- scope.set(key, pending);
15
- return pending;
16
- }
17
- function currentRequest() {
18
- try {
19
- return getRequest();
20
- } catch {
21
- return;
22
- }
23
- }
24
- export { oncePerRequest };
@@ -1,24 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- import { type BylineClient } from '@byline/client';
9
- export declare function getAdminBylineClient(): BylineClient;
10
- /**
11
- * A `BylineClient` bound to an explicit super-admin context — for
12
- * **system / background** work that is not scoped to an HTTP request:
13
- * lifecycle-hook search indexing, maintenance scripts, seeds, migrations.
14
- *
15
- * Unlike {@link getAdminBylineClient}, this does **not** read session
16
- * cookies, so it works outside the TanStack Start server runtime (a bare
17
- * `tsx` script, a seed, a test). Reaching for the request-scoped client in
18
- * a lifecycle hook couples that hook to the live server and throws
19
- * `No StartEvent found in AsyncLocalStorage` from any out-of-band write
20
- * path. Indexing is maintenance, not a user action — it reads the published
21
- * view and bypasses `beforeRead` — so the super-admin context is both
22
- * correct and runtime-agnostic. The context is auditable by its stable id.
23
- */
24
- export declare function getSystemBylineClient(): BylineClient;
@@ -1,25 +0,0 @@
1
- import { createSuperAdminContext } from "@byline/auth";
2
- import { createBylineClient } from "@byline/client";
3
- import { getServerConfig } from "@byline/core";
4
- import { getAdminRequestContext } from "../auth/auth-context.js";
5
- let cachedClient;
6
- function getAdminBylineClient() {
7
- if (cachedClient) return cachedClient;
8
- cachedClient = createBylineClient({
9
- config: getServerConfig(),
10
- requestContext: getAdminRequestContext
11
- });
12
- return cachedClient;
13
- }
14
- let cachedSystemClient;
15
- function getSystemBylineClient() {
16
- if (cachedSystemClient) return cachedSystemClient;
17
- cachedSystemClient = createBylineClient({
18
- config: getServerConfig(),
19
- requestContext: createSuperAdminContext({
20
- id: 'byline-system-client'
21
- })
22
- });
23
- return cachedSystemClient;
24
- }
25
- export { getAdminBylineClient, getSystemBylineClient };
@@ -1,47 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- /**
9
- * The host's *public-read* `BylineClient` singleton — the strict
10
- * "preview-can-never-apply" sibling of `getViewerBylineClient`.
11
- *
12
- * Configured with `actor: null` and `readMode: 'published'`, full stop.
13
- * The `requestContext` factory does not consult the `byline_preview`
14
- * cookie or attempt any admin-session resolution, so an admin browsing
15
- * with preview mode on cannot accidentally elevate a read that flows
16
- * through this client. `assertActorCanPerform` permits the null actor
17
- * exactly on `read` with `readMode === 'published'`, which is what the
18
- * factory always returns.
19
- *
20
- * **Use this client for:**
21
- * - RSS feeds, Atom feeds, sitemaps
22
- * - JSON or other endpoints exposed to third-party consumers
23
- * - any response that an upstream CDN / cache might serve to multiple
24
- * visitors without keying off the `byline_preview` cookie
25
- *
26
- * **Use `getViewerBylineClient` instead for:**
27
- * - user-facing public pages where an admin's preview-mode session
28
- * should be honoured
29
- *
30
- * Both clients share the same module-scoped singleton pattern so the
31
- * SDK's per-instance `collectionRecordCache` is amortised across the
32
- * process lifetime.
33
- *
34
- * Companion: `getAdminBylineClient` in `./byline-client.ts` for the
35
- * admin webapp's authenticated reads (resolves the `RequestContext`
36
- * from session cookies, memoized per request).
37
- */
38
- import { type RequestContext } from '@byline/auth';
39
- import { type BylineClient } from '@byline/client';
40
- /**
41
- * Anonymous, published-only context — memoized per request so the
42
- * context (and its requestId) is stable across every read in one
43
- * request: reads sharing a ReadContext must bind a single request
44
- * authority.
45
- */
46
- export declare function resolvePublicRequestContext(): Promise<RequestContext>;
47
- export declare function getPublicBylineClient(): BylineClient;
@@ -1,19 +0,0 @@
1
- import { createRequestContext } from "@byline/auth";
2
- import { createBylineClient } from "@byline/client";
3
- import { getServerConfig } from "@byline/core";
4
- import { oncePerRequest } from "../auth/request-scope.js";
5
- function resolvePublicRequestContext() {
6
- return oncePerRequest('byline:public-request-context', async ()=>createRequestContext({
7
- readMode: 'published'
8
- }));
9
- }
10
- let cachedClient;
11
- function getPublicBylineClient() {
12
- if (cachedClient) return cachedClient;
13
- cachedClient = createBylineClient({
14
- config: getServerConfig(),
15
- requestContext: resolvePublicRequestContext
16
- });
17
- return cachedClient;
18
- }
19
- export { getPublicBylineClient, resolvePublicRequestContext };
@@ -1,26 +0,0 @@
1
- /**
2
- * This Source Code is subject to the terms of the Mozilla Public
3
- * License, v. 2.0. If a copy of the MPL was not distributed with this
4
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
5
- *
6
- * Copyright (c) Infonomic Company Limited
7
- */
8
- import { type BylineClient } from '@byline/client';
9
- export declare function getViewerBylineClient(): BylineClient;
10
- /**
11
- * Preview-aware viewer context — memoized per request so every read in
12
- * one request binds the same context instance (and requestId): reads
13
- * sharing a ReadContext must resolve a single request authority.
14
- */
15
- export declare function resolveViewerRequestContext(): Promise<import("@byline/auth").RequestContext>;
16
- /**
17
- * Resolve whether the current request should surface non-published
18
- * versions. True iff the preview cookie is set **and** a valid admin
19
- * session resolves. Server fns call this once and pass the result to
20
- * `status: preview ? 'any' : 'published'` on the SDK read.
21
- *
22
- * Defensive by design: the cookie alone is not enough. A signed-out
23
- * browser carrying an old preview cookie still gets `false` here, which
24
- * keeps stray query strings or shared links from leaking drafts.
25
- */
26
- export declare function isPreviewActive(): Promise<boolean>;
@@ -1,44 +0,0 @@
1
- import { createRequestContext } from "@byline/auth";
2
- import { createBylineClient } from "@byline/client";
3
- import { getServerConfig } from "@byline/core";
4
- import { getAdminRequestContext } from "../auth/auth-context.js";
5
- import { readPreviewCookie } from "../auth/preview-cookies.js";
6
- import { oncePerRequest } from "../auth/request-scope.js";
7
- let cachedClient;
8
- function getViewerBylineClient() {
9
- if (cachedClient) return cachedClient;
10
- cachedClient = createBylineClient({
11
- config: getServerConfig(),
12
- requestContext: resolveViewerRequestContext
13
- });
14
- return cachedClient;
15
- }
16
- function resolveViewerRequestContext() {
17
- return oncePerRequest('byline:viewer-request-context', resolveViewerContext);
18
- }
19
- async function resolveViewerContext() {
20
- if (!readPreviewCookie()) return createRequestContext({
21
- readMode: 'published'
22
- });
23
- try {
24
- const ctx = await getAdminRequestContext();
25
- return {
26
- ...ctx,
27
- readMode: 'any'
28
- };
29
- } catch {
30
- return createRequestContext({
31
- readMode: 'published'
32
- });
33
- }
34
- }
35
- async function isPreviewActive() {
36
- if (!readPreviewCookie()) return false;
37
- try {
38
- await getAdminRequestContext();
39
- return true;
40
- } catch {
41
- return false;
42
- }
43
- }
44
- export { getViewerBylineClient, isPreviewActive, resolveViewerRequestContext };