@wildo-ai/saas-technical-doc 1.1.1 → 1.1.2

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 (64) hide show
  1. package/dist/esm/companion/application-documentation/application-administration-documentation.d.ts +52 -0
  2. package/dist/esm/companion/application-documentation/application-administration-documentation.d.ts.map +1 -0
  3. package/dist/esm/companion/application-documentation/application-administration-documentation.js +58 -0
  4. package/dist/esm/companion/application-documentation/application-administration-documentation.js.map +1 -0
  5. package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts +76 -0
  6. package/dist/esm/companion/application-documentation/application-authentication-documentation.d.ts.map +1 -0
  7. package/dist/esm/companion/application-documentation/application-authentication-documentation.js +116 -0
  8. package/dist/esm/companion/application-documentation/application-authentication-documentation.js.map +1 -0
  9. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts +87 -0
  10. package/dist/esm/companion/application-documentation/application-connection-documentation.d.ts.map +1 -0
  11. package/dist/esm/companion/application-documentation/application-connection-documentation.js +138 -0
  12. package/dist/esm/companion/application-documentation/application-connection-documentation.js.map +1 -0
  13. package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts +48 -0
  14. package/dist/esm/companion/application-documentation/application-integration-documentation.d.ts.map +1 -0
  15. package/dist/esm/companion/application-documentation/application-integration-documentation.js +63 -0
  16. package/dist/esm/companion/application-documentation/application-integration-documentation.js.map +1 -0
  17. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts +21 -3
  18. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.d.ts.map +1 -1
  19. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js +166 -10
  20. package/dist/esm/companion/application-documentation/technical-documentation-engine-content-bundle.js.map +1 -1
  21. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts +8 -0
  22. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.d.ts.map +1 -1
  23. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js +8 -1
  24. package/dist/esm/companion/application-documentation/technical-documentation-private-derivation.js.map +1 -1
  25. package/dist/esm/companion/index.d.ts +4 -0
  26. package/dist/esm/companion/index.d.ts.map +1 -1
  27. package/dist/esm/companion/index.js +4 -0
  28. package/dist/esm/companion/index.js.map +1 -1
  29. package/dist/esm/companion/openapi-generator.d.ts.map +1 -1
  30. package/dist/esm/companion/openapi-generator.js +9 -7
  31. package/dist/esm/companion/openapi-generator.js.map +1 -1
  32. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.d.ts.map +1 -1
  33. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js +10 -2
  34. package/dist/esm/companion/rendering/technical-documentation-docusaurus-renderer.js.map +1 -1
  35. package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts +28 -0
  36. package/dist/esm/companion/rendering/technical-documentation-markdown-links.d.ts.map +1 -0
  37. package/dist/esm/companion/rendering/technical-documentation-markdown-links.js +52 -0
  38. package/dist/esm/companion/rendering/technical-documentation-markdown-links.js.map +1 -0
  39. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.d.ts.map +1 -1
  40. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js +7 -2
  41. package/dist/esm/companion/rendering/technical-documentation-markdown-renderer.js.map +1 -1
  42. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts +1 -0
  43. package/dist/esm/companion/rendering/technical-documentation-render-model.d.ts.map +1 -1
  44. package/dist/esm/companion/rendering/technical-documentation-render-model.js +91 -84
  45. package/dist/esm/companion/rendering/technical-documentation-render-model.js.map +1 -1
  46. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts +74 -69
  47. package/dist/esm/content/application-consumer-documentation-content.techdoc.d.ts.map +1 -1
  48. package/dist/esm/content/application-consumer-documentation-content.techdoc.js +654 -1120
  49. package/dist/esm/content/application-consumer-documentation-content.techdoc.js.map +1 -1
  50. package/dist/esm/runtime/decode-jwt-claims.d.ts +7 -4
  51. package/dist/esm/runtime/decode-jwt-claims.d.ts.map +1 -1
  52. package/dist/esm/runtime/decode-jwt-claims.js +7 -4
  53. package/dist/esm/runtime/decode-jwt-claims.js.map +1 -1
  54. package/dist/esm/runtime/docs-auth-session.schemas.d.ts +16 -5
  55. package/dist/esm/runtime/docs-auth-session.schemas.d.ts.map +1 -1
  56. package/dist/esm/runtime/docs-auth-session.schemas.js +16 -5
  57. package/dist/esm/runtime/docs-auth-session.schemas.js.map +1 -1
  58. package/dist/esm/runtime/use-docs-auth-session.d.ts +9 -7
  59. package/dist/esm/runtime/use-docs-auth-session.d.ts.map +1 -1
  60. package/dist/esm/runtime/use-docs-auth-session.js +9 -7
  61. package/dist/esm/runtime/use-docs-auth-session.js.map +1 -1
  62. package/dist/tsconfig.build.tsbuildinfo +1 -1
  63. package/package.json +5 -5
  64. package/dist/esm/.builder.pid +0 -9
@@ -11,10 +11,13 @@ import { type DocsJwtClaims } from './docs-auth-session.schemas';
11
11
  *
12
12
  * This decoder DOES NOT verify the JWT signature. It cannot — the
13
13
  * verification key lives on the backend, not in the browser bundle.
14
- * The decoded claims are treated as DISPLAY HINTS ONLY: the docs
15
- * navbar uses them to decide whether to render the "Organization API"
16
- * link, and the DocItem swizzle uses them to decide whether to gate
17
- * `/api/organization/*` pages.
14
+ * The decoded claims are treated as DISPLAY HINTS ONLY, and today they
15
+ * drive no rendering decision at all: the Navbar and DocItem swizzles
16
+ * this comment used to name were never built, and there is no
17
+ * `/api/organization/*` route family to gate (see `DocsRole` in
18
+ * `docs-auth-session.schemas.ts` for the full measurement). What the
19
+ * decoded claims currently do is populate the session object the
20
+ * `Root` swizzle provides.
18
21
  *
19
22
  * The REAL gating happens server-side: the OpenAPI YAMLs for the
20
23
  * organization API are served by the backend behind the same
@@ -1 +1 @@
1
- {"version":3,"file":"decode-jwt-claims.d.ts","sourceRoot":"","sources":["../../../../src/runtime/decode-jwt-claims.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAoCnE"}
1
+ {"version":3,"file":"decode-jwt-claims.d.ts","sourceRoot":"","sources":["../../../../src/runtime/decode-jwt-claims.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAoCnE"}
@@ -11,10 +11,13 @@ import { DocsJwtClaimsSchema, DocsRole, } from './docs-auth-session.schemas.js';
11
11
  *
12
12
  * This decoder DOES NOT verify the JWT signature. It cannot — the
13
13
  * verification key lives on the backend, not in the browser bundle.
14
- * The decoded claims are treated as DISPLAY HINTS ONLY: the docs
15
- * navbar uses them to decide whether to render the "Organization API"
16
- * link, and the DocItem swizzle uses them to decide whether to gate
17
- * `/api/organization/*` pages.
14
+ * The decoded claims are treated as DISPLAY HINTS ONLY, and today they
15
+ * drive no rendering decision at all: the Navbar and DocItem swizzles
16
+ * this comment used to name were never built, and there is no
17
+ * `/api/organization/*` route family to gate (see `DocsRole` in
18
+ * `docs-auth-session.schemas.ts` for the full measurement). What the
19
+ * decoded claims currently do is populate the session object the
20
+ * `Root` swizzle provides.
18
21
  *
19
22
  * The REAL gating happens server-side: the OpenAPI YAMLs for the
20
23
  * organization API are served by the backend behind the same
@@ -1 +1 @@
1
- {"version":3,"file":"decode-jwt-claims.js","sourceRoot":"","sources":["../../../../src/runtime/decode-jwt-claims.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,QAAQ,GAET,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/D;;;;;;OAMG;IACH,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IAElF,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;QAC7D,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC5D,IAAI;QACJ,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;KACjD,CAAC;IAEF,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC","sourcesContent":["import {\n DocsJwtClaimsSchema,\n DocsRole,\n type DocsJwtClaims,\n} from './docs-auth-session.schemas';\n\n/**\n * Hand-rolled JWT-claims decoder for the docs-site auth runtime.\n *\n * Rationale (saas-technical-doc.md K-9b): the docs Docusaurus bundle is\n * intentionally lean. Pulling in `jwt-decode` (or any general-purpose\n * JWT library) for the SOLE purpose of base64-decoding the middle segment\n * is a 30 KB+ bundle cost we refuse to pay for ~20 lines of code.\n *\n * SECURITY MODEL — important:\n *\n * This decoder DOES NOT verify the JWT signature. It cannot — the\n * verification key lives on the backend, not in the browser bundle.\n * The decoded claims are treated as DISPLAY HINTS ONLY: the docs\n * navbar uses them to decide whether to render the \"Organization API\"\n * link, and the DocItem swizzle uses them to decide whether to gate\n * `/api/organization/*` pages.\n *\n * The REAL gating happens server-side: the OpenAPI YAMLs for the\n * organization API are served by the backend behind the same\n * authorization decorators as the underlying resources. A user who\n * forges a JWT with `role: 'org_admin'` will see the docs navbar link\n * appear, but every actual API call from those docs to the backend\n * will still 401/403. The docs-site gating exists for UX, not security.\n *\n * This is the SAME contract the SaaS app's frontend has: it decodes\n * the access-token claims for UI gating without verifying signatures,\n * and the backend is the authoritative authorizer.\n *\n * Returns `null` for any malformed input — never throws. The session\n * context (`DocsAuthContext`) treats `null` as \"fall back to anonymous\"\n * rather than surfacing a UI error, because by the time we are decoding\n * the token we have already accepted it from the `/auth/token/exchange`\n * response and the only remaining failure modes are clock skew, library\n * mis-issuance, or actual tampering — none of which yield a useful error\n * message at the docs-site level.\n */\nexport function decodeJwtClaims(token: string): DocsJwtClaims | null {\n const segments = token.split('.');\n if (segments.length !== 3) return null;\n\n const payloadSegment = segments[1];\n if (!payloadSegment) return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(base64UrlDecode(payloadSegment));\n } catch {\n return null;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return null;\n\n /**\n * Normalize the raw role string → `DocsRole`.\n *\n * The access token's `role` claim can be any of the SaaS app's roles\n * (`org_admin`, `org_member`, `app_user`, …); the docs site only cares\n * about the org-admin / not-org-admin distinction (K-11).\n */\n const raw = parsed as Record<string, unknown>;\n const rawRole = typeof raw.role === 'string' ? raw.role : '';\n const role = rawRole === DocsRole.ORG_ADMIN ? DocsRole.ORG_ADMIN : DocsRole.OTHER;\n\n const candidate = {\n userId: typeof raw.userId === 'string' ? raw.userId : raw.sub,\n email: typeof raw.email === 'string' ? raw.email : undefined,\n role,\n exp: typeof raw.exp === 'number' ? raw.exp : NaN,\n };\n\n const result = DocsJwtClaimsSchema.safeParse(candidate);\n return result.success ? result.data : null;\n}\n\n/**\n * Base64url → string. Pads the input to a multiple of 4 and translates\n * `-`/`_` back to `+`/`/` before delegating to the platform's `atob`.\n *\n * `atob` is available in every browser and in Node ≥ 16 — both of which\n * the docs site supports (Docusaurus build runs in Node, runtime in the\n * browser).\n */\nfunction base64UrlDecode(input: string): string {\n const padded = input + '='.repeat((4 - (input.length % 4)) % 4);\n const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');\n return atob(base64);\n}\n"]}
1
+ {"version":3,"file":"decode-jwt-claims.js","sourceRoot":"","sources":["../../../../src/runtime/decode-jwt-claims.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,QAAQ,GAET,MAAM,6BAA6B,CAAC;AAErC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,IAAI,CAAC;IAEvC,MAAM,cAAc,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAC;IACnC,IAAI,CAAC,cAAc;QAAE,OAAO,IAAI,CAAC;IAEjC,IAAI,MAAe,CAAC;IACpB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC,CAAC;IACvD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI;QAAE,OAAO,IAAI,CAAC;IAE/D;;;;;;OAMG;IACH,MAAM,GAAG,GAAG,MAAiC,CAAC;IAC9C,MAAM,OAAO,GAAG,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC;IAC7D,MAAM,IAAI,GAAG,OAAO,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC;IAElF,MAAM,SAAS,GAAG;QAChB,MAAM,EAAE,OAAO,GAAG,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG;QAC7D,KAAK,EAAE,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS;QAC5D,IAAI;QACJ,GAAG,EAAE,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG;KACjD,CAAC;IAEF,MAAM,MAAM,GAAG,mBAAmB,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IACxD,OAAO,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;AAC7C,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,eAAe,CAAC,KAAa;IACpC,MAAM,MAAM,GAAG,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;IAC5D,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC","sourcesContent":["import {\n DocsJwtClaimsSchema,\n DocsRole,\n type DocsJwtClaims,\n} from './docs-auth-session.schemas';\n\n/**\n * Hand-rolled JWT-claims decoder for the docs-site auth runtime.\n *\n * Rationale (saas-technical-doc.md K-9b): the docs Docusaurus bundle is\n * intentionally lean. Pulling in `jwt-decode` (or any general-purpose\n * JWT library) for the SOLE purpose of base64-decoding the middle segment\n * is a 30 KB+ bundle cost we refuse to pay for ~20 lines of code.\n *\n * SECURITY MODEL — important:\n *\n * This decoder DOES NOT verify the JWT signature. It cannot — the\n * verification key lives on the backend, not in the browser bundle.\n * The decoded claims are treated as DISPLAY HINTS ONLY, and today they\n * drive no rendering decision at all: the Navbar and DocItem swizzles\n * this comment used to name were never built, and there is no\n * `/api/organization/*` route family to gate (see `DocsRole` in\n * `docs-auth-session.schemas.ts` for the full measurement). What the\n * decoded claims currently do is populate the session object the\n * `Root` swizzle provides.\n *\n * The REAL gating happens server-side: the OpenAPI YAMLs for the\n * organization API are served by the backend behind the same\n * authorization decorators as the underlying resources. A user who\n * forges a JWT with `role: 'org_admin'` will see the docs navbar link\n * appear, but every actual API call from those docs to the backend\n * will still 401/403. The docs-site gating exists for UX, not security.\n *\n * This is the SAME contract the SaaS app's frontend has: it decodes\n * the access-token claims for UI gating without verifying signatures,\n * and the backend is the authoritative authorizer.\n *\n * Returns `null` for any malformed input — never throws. The session\n * context (`DocsAuthContext`) treats `null` as \"fall back to anonymous\"\n * rather than surfacing a UI error, because by the time we are decoding\n * the token we have already accepted it from the `/auth/token/exchange`\n * response and the only remaining failure modes are clock skew, library\n * mis-issuance, or actual tampering — none of which yield a useful error\n * message at the docs-site level.\n */\nexport function decodeJwtClaims(token: string): DocsJwtClaims | null {\n const segments = token.split('.');\n if (segments.length !== 3) return null;\n\n const payloadSegment = segments[1];\n if (!payloadSegment) return null;\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(base64UrlDecode(payloadSegment));\n } catch {\n return null;\n }\n\n if (typeof parsed !== 'object' || parsed === null) return null;\n\n /**\n * Normalize the raw role string → `DocsRole`.\n *\n * The access token's `role` claim can be any of the SaaS app's roles\n * (`org_admin`, `org_member`, `app_user`, …); the docs site only cares\n * about the org-admin / not-org-admin distinction (K-11).\n */\n const raw = parsed as Record<string, unknown>;\n const rawRole = typeof raw.role === 'string' ? raw.role : '';\n const role = rawRole === DocsRole.ORG_ADMIN ? DocsRole.ORG_ADMIN : DocsRole.OTHER;\n\n const candidate = {\n userId: typeof raw.userId === 'string' ? raw.userId : raw.sub,\n email: typeof raw.email === 'string' ? raw.email : undefined,\n role,\n exp: typeof raw.exp === 'number' ? raw.exp : NaN,\n };\n\n const result = DocsJwtClaimsSchema.safeParse(candidate);\n return result.success ? result.data : null;\n}\n\n/**\n * Base64url → string. Pads the input to a multiple of 4 and translates\n * `-`/`_` back to `+`/`/` before delegating to the platform's `atob`.\n *\n * `atob` is available in every browser and in Node ≥ 16 — both of which\n * the docs site supports (Docusaurus build runs in Node, runtime in the\n * browser).\n */\nfunction base64UrlDecode(input: string): string {\n const padded = input + '='.repeat((4 - (input.length % 4)) % 4);\n const base64 = padded.replace(/-/g, '+').replace(/_/g, '/');\n return atob(base64);\n}\n"]}
@@ -4,15 +4,26 @@ import { z } from 'zod';
4
4
  *
5
5
  * Mirrors the role axis the SaaS app uses on access tokens. The docs site
6
6
  * itself only cares about ONE distinction: "is this user an org admin or
7
- * not?" — used by the Navbar swizzle to hide the "Organization API" link
8
- * and by the DocItem swizzle to gate `/api/organization/*` pages
9
- * (saas-technical-doc.md K-11).
7
+ * not?"
10
8
  *
11
9
  * `ORG_ADMIN` value matches the string carried by the access token's
12
10
  * `role` claim issued by `auth-token-issuer.backend.service.ts`. The
13
11
  * generic `OTHER` bucket covers every other role (regular org member,
14
- * viewer, application-level admin, etc.) — none of them grant Org-API
15
- * visibility on the docs site.
12
+ * viewer, application-level admin, etc.).
13
+ *
14
+ * ⚠️ NOTHING BRANCHES ON THIS TODAY. This comment used to say the value was
15
+ * "used by the Navbar swizzle to hide the 'Organization API' link and by the
16
+ * DocItem swizzle to gate `/api/organization/*` pages". Neither exists: the
17
+ * only swizzles in the tree are `Root` and `SearchBar`, `OpenApiSection` has
18
+ * exactly two members (`API_REFERENCE`, `APPLICATION_ADMINISTRATION_API_REFERENCE`)
19
+ * and neither is organizational, and `/api/organization` appears nowhere but in
20
+ * comments like this one and a single test fixture string. `openapi-generator.test.ts`
21
+ * even pins that the emitted title does NOT contain "Organization API".
22
+ *
23
+ * The enum is still decoded and carried on the session (`decode-jwt-claims.ts`
24
+ * normalizes the raw claim into it), so the axis is available the moment a
25
+ * gated surface is built. Until then it is a claim projection, not a control —
26
+ * do not cite it as evidence that the docs site gates anything.
16
27
  */
17
28
  export declare enum DocsRole {
18
29
  ORG_ADMIN = "org_admin",
@@ -1 +1 @@
1
- {"version":3,"file":"docs-auth-session.schemas.d.ts","sourceRoot":"","sources":["../../../../src/runtime/docs-auth-session.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;GAcG;AACH,oBAAY,QAAQ;IAClB,SAAS,cAAc;IACvB,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB;;;;;kBAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC"}
1
+ {"version":3,"file":"docs-auth-session.schemas.d.ts","sourceRoot":"","sources":["../../../../src/runtime/docs-auth-session.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,oBAAY,QAAQ;IAClB,SAAS,cAAc;IACvB,KAAK,UAAU;CAChB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,eAAO,MAAM,mBAAmB;;;;;kBAK9B,CAAC;AACH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,eAAe,GACvB;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,GACvB;IAAE,MAAM,EAAE,YAAY,CAAA;CAAE,GACxB;IAAE,MAAM,EAAE,eAAe,CAAC;IAAC,WAAW,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,aAAa,CAAA;CAAE,CAAC"}
@@ -4,15 +4,26 @@ import { z } from 'zod';
4
4
  *
5
5
  * Mirrors the role axis the SaaS app uses on access tokens. The docs site
6
6
  * itself only cares about ONE distinction: "is this user an org admin or
7
- * not?" — used by the Navbar swizzle to hide the "Organization API" link
8
- * and by the DocItem swizzle to gate `/api/organization/*` pages
9
- * (saas-technical-doc.md K-11).
7
+ * not?"
10
8
  *
11
9
  * `ORG_ADMIN` value matches the string carried by the access token's
12
10
  * `role` claim issued by `auth-token-issuer.backend.service.ts`. The
13
11
  * generic `OTHER` bucket covers every other role (regular org member,
14
- * viewer, application-level admin, etc.) — none of them grant Org-API
15
- * visibility on the docs site.
12
+ * viewer, application-level admin, etc.).
13
+ *
14
+ * ⚠️ NOTHING BRANCHES ON THIS TODAY. This comment used to say the value was
15
+ * "used by the Navbar swizzle to hide the 'Organization API' link and by the
16
+ * DocItem swizzle to gate `/api/organization/*` pages". Neither exists: the
17
+ * only swizzles in the tree are `Root` and `SearchBar`, `OpenApiSection` has
18
+ * exactly two members (`API_REFERENCE`, `APPLICATION_ADMINISTRATION_API_REFERENCE`)
19
+ * and neither is organizational, and `/api/organization` appears nowhere but in
20
+ * comments like this one and a single test fixture string. `openapi-generator.test.ts`
21
+ * even pins that the emitted title does NOT contain "Organization API".
22
+ *
23
+ * The enum is still decoded and carried on the session (`decode-jwt-claims.ts`
24
+ * normalizes the raw claim into it), so the axis is available the moment a
25
+ * gated surface is built. Until then it is a claim projection, not a control —
26
+ * do not cite it as evidence that the docs site gates anything.
16
27
  */
17
28
  export var DocsRole;
18
29
  (function (DocsRole) {
@@ -1 +1 @@
1
- {"version":3,"file":"docs-auth-session.schemas.js","sourceRoot":"","sources":["../../../../src/runtime/docs-auth-session.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAN,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,mCAAuB,CAAA;IACvB,2BAAe,CAAA;AACjB,CAAC,EAHW,QAAQ,KAAR,QAAQ,QAGnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACtB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\n\n/**\n * Roles relevant to the docs-site gating decisions.\n *\n * Mirrors the role axis the SaaS app uses on access tokens. The docs site\n * itself only cares about ONE distinction: \"is this user an org admin or\n * not?\" — used by the Navbar swizzle to hide the \"Organization API\" link\n * and by the DocItem swizzle to gate `/api/organization/*` pages\n * (saas-technical-doc.md K-11).\n *\n * `ORG_ADMIN` value matches the string carried by the access token's\n * `role` claim issued by `auth-token-issuer.backend.service.ts`. The\n * generic `OTHER` bucket covers every other role (regular org member,\n * viewer, application-level admin, etc.) — none of them grant Org-API\n * visibility on the docs site.\n */\nexport enum DocsRole {\n ORG_ADMIN = 'org_admin',\n OTHER = 'other',\n}\n\n/**\n * Subset of access-token claims the docs site cares about.\n *\n * The full access-token payload issued by the SaaS backend carries many\n * more fields (organization id, application id, scopes, …) — we\n * deliberately project only the minimum needed by the docs-site swizzles\n * so that:\n * 1. A future change to the access-token shape that adds fields\n * doesn't ripple into the docs site.\n * 2. The docs site never accidentally renders or transmits sensitive\n * claims it has no business consuming.\n *\n * `userId` and `email` are present for display purposes (\"Signed in as\n * <email>\" in the navbar — done by the Navbar swizzle, not this package).\n *\n * `role` is the gating axis (see {@link DocsRole}).\n *\n * `exp` (UNIX seconds) lets the context clear the in-memory session as\n * soon as the access token expires — without ever calling the network.\n * No refresh loop (K-9b): when `exp` passes, the user is anonymous again\n * until they re-handshake from the SaaS app.\n */\nexport const DocsJwtClaimsSchema = z.strictObject({\n userId: z.string().min(1),\n email: z.email().optional(),\n role: z.enum(DocsRole),\n exp: z.number().int().positive(),\n});\nexport type DocsJwtClaims = z.infer<typeof DocsJwtClaimsSchema>;\n\n/**\n * Public shape exposed by `useDocsAuthSession()` (saas-technical-doc.md K-11).\n *\n * Three mutually-exclusive states:\n * - `status: 'anonymous'` — no handoff has been completed.\n * - `status: 'exchanging'` — `/auth/exchange?code=…` is in flight.\n * - `status: 'authenticated'` — `claims` and `accessToken` are present.\n *\n * Consumers (the three swizzles) discriminate on `status` and never reach\n * for `accessToken`/`claims` while in the `anonymous` or `exchanging`\n * states — the type narrows correctly thanks to the discriminated union.\n *\n * Does NOT model an `error` state directly: errors during the exchange\n * are surfaced via the `AuthExchangePage` component's local UI, after\n * which the session falls back to `anonymous`. Keeping the session shape\n * tight prevents the swizzles from having to render error-recovery UI\n * for events they did not cause.\n */\nexport type DocsAuthSession =\n | { status: 'anonymous' }\n | { status: 'exchanging' }\n | { status: 'authenticated'; accessToken: string; claims: DocsJwtClaims };\n"]}
1
+ {"version":3,"file":"docs-auth-session.schemas.js","sourceRoot":"","sources":["../../../../src/runtime/docs-auth-session.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,MAAM,CAAN,IAAY,QAGX;AAHD,WAAY,QAAQ;IAClB,mCAAuB,CAAA;IACvB,2BAAe,CAAA;AACjB,CAAC,EAHW,QAAQ,KAAR,QAAQ,QAGnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,YAAY,CAAC;IAChD,MAAM,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IACzB,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,CAAC,QAAQ,EAAE;IAC3B,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC;IACtB,GAAG,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE;CACjC,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\n\n/**\n * Roles relevant to the docs-site gating decisions.\n *\n * Mirrors the role axis the SaaS app uses on access tokens. The docs site\n * itself only cares about ONE distinction: \"is this user an org admin or\n * not?\"\n *\n * `ORG_ADMIN` value matches the string carried by the access token's\n * `role` claim issued by `auth-token-issuer.backend.service.ts`. The\n * generic `OTHER` bucket covers every other role (regular org member,\n * viewer, application-level admin, etc.).\n *\n * ⚠️ NOTHING BRANCHES ON THIS TODAY. This comment used to say the value was\n * \"used by the Navbar swizzle to hide the 'Organization API' link and by the\n * DocItem swizzle to gate `/api/organization/*` pages\". Neither exists: the\n * only swizzles in the tree are `Root` and `SearchBar`, `OpenApiSection` has\n * exactly two members (`API_REFERENCE`, `APPLICATION_ADMINISTRATION_API_REFERENCE`)\n * and neither is organizational, and `/api/organization` appears nowhere but in\n * comments like this one and a single test fixture string. `openapi-generator.test.ts`\n * even pins that the emitted title does NOT contain \"Organization API\".\n *\n * The enum is still decoded and carried on the session (`decode-jwt-claims.ts`\n * normalizes the raw claim into it), so the axis is available the moment a\n * gated surface is built. Until then it is a claim projection, not a control —\n * do not cite it as evidence that the docs site gates anything.\n */\nexport enum DocsRole {\n ORG_ADMIN = 'org_admin',\n OTHER = 'other',\n}\n\n/**\n * Subset of access-token claims the docs site cares about.\n *\n * The full access-token payload issued by the SaaS backend carries many\n * more fields (organization id, application id, scopes, …) — we\n * deliberately project only the minimum needed by the docs-site swizzles\n * so that:\n * 1. A future change to the access-token shape that adds fields\n * doesn't ripple into the docs site.\n * 2. The docs site never accidentally renders or transmits sensitive\n * claims it has no business consuming.\n *\n * `userId` and `email` are present for display purposes (\"Signed in as\n * <email>\" in the navbar — done by the Navbar swizzle, not this package).\n *\n * `role` is the gating axis (see {@link DocsRole}).\n *\n * `exp` (UNIX seconds) lets the context clear the in-memory session as\n * soon as the access token expires — without ever calling the network.\n * No refresh loop (K-9b): when `exp` passes, the user is anonymous again\n * until they re-handshake from the SaaS app.\n */\nexport const DocsJwtClaimsSchema = z.strictObject({\n userId: z.string().min(1),\n email: z.email().optional(),\n role: z.enum(DocsRole),\n exp: z.number().int().positive(),\n});\nexport type DocsJwtClaims = z.infer<typeof DocsJwtClaimsSchema>;\n\n/**\n * Public shape exposed by `useDocsAuthSession()` (saas-technical-doc.md K-11).\n *\n * Three mutually-exclusive states:\n * - `status: 'anonymous'` — no handoff has been completed.\n * - `status: 'exchanging'` — `/auth/exchange?code=…` is in flight.\n * - `status: 'authenticated'` — `claims` and `accessToken` are present.\n *\n * Consumers (the three swizzles) discriminate on `status` and never reach\n * for `accessToken`/`claims` while in the `anonymous` or `exchanging`\n * states — the type narrows correctly thanks to the discriminated union.\n *\n * Does NOT model an `error` state directly: errors during the exchange\n * are surfaced via the `AuthExchangePage` component's local UI, after\n * which the session falls back to `anonymous`. Keeping the session shape\n * tight prevents the swizzles from having to render error-recovery UI\n * for events they did not cause.\n */\nexport type DocsAuthSession =\n | { status: 'anonymous' }\n | { status: 'exchanging' }\n | { status: 'authenticated'; accessToken: string; claims: DocsJwtClaims };\n"]}
@@ -2,17 +2,19 @@ import { type DocsAuthContextValue } from './DocsAuthContext';
2
2
  /**
3
3
  * Read the current docs-site auth session.
4
4
  *
5
- * The three Docusaurus swizzles (Root, Navbar, DocItem — see
6
- * saas-technical-doc.md K-11) all consume the same hook:
5
+ * ONE Docusaurus swizzle consumes this hook today:
7
6
  *
8
- * - Navbar : `session.status === 'authenticated' && session.claims.role === DocsRole.ORG_ADMIN`
9
- * decides whether the "Organization API" link is rendered.
10
- * - DocItem : on `/api/organization/*` routes, branches on the same
11
- * check; if anonymous, deep-links to the SaaS app because
12
- * handoff issuance requires a bearer.
13
7
  * - Root : the `<AuthExchangePage>` wired at `/auth/exchange` calls
14
8
  * `beginExchange(code)` on mount.
15
9
  *
10
+ * This list used to name three (Root, Navbar, DocItem). The Navbar swizzle
11
+ * gating an "Organization API" link and the DocItem swizzle gating
12
+ * `/api/organization/*` were never built, and there is no organization
13
+ * OpenAPI section for them to gate — see `DocsRole` in
14
+ * `docs-auth-session.schemas.ts` for the measurement. The hook's
15
+ * role-carrying shape is unchanged and ready for such a surface; it simply
16
+ * has no second or third consumer at present.
17
+ *
16
18
  * Throws when used outside `<DocsAuthProvider>` so misconfigured swizzles
17
19
  * fail loud during the Docusaurus build (rather than silently rendering
18
20
  * "anonymous" for every reader). This mirrors the pattern in
@@ -1 +1 @@
1
- {"version":3,"file":"use-docs-auth-session.d.ts","sourceRoot":"","sources":["../../../../src/runtime/use-docs-auth-session.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CASzD"}
1
+ {"version":3,"file":"use-docs-auth-session.d.ts","sourceRoot":"","sources":["../../../../src/runtime/use-docs-auth-session.ts"],"names":[],"mappings":"AACA,OAAO,EAAmB,KAAK,oBAAoB,EAAE,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,kBAAkB,IAAI,oBAAoB,CASzD"}
@@ -3,17 +3,19 @@ import { DocsAuthContext } from './DocsAuthContext.js';
3
3
  /**
4
4
  * Read the current docs-site auth session.
5
5
  *
6
- * The three Docusaurus swizzles (Root, Navbar, DocItem — see
7
- * saas-technical-doc.md K-11) all consume the same hook:
6
+ * ONE Docusaurus swizzle consumes this hook today:
8
7
  *
9
- * - Navbar : `session.status === 'authenticated' && session.claims.role === DocsRole.ORG_ADMIN`
10
- * decides whether the "Organization API" link is rendered.
11
- * - DocItem : on `/api/organization/*` routes, branches on the same
12
- * check; if anonymous, deep-links to the SaaS app because
13
- * handoff issuance requires a bearer.
14
8
  * - Root : the `<AuthExchangePage>` wired at `/auth/exchange` calls
15
9
  * `beginExchange(code)` on mount.
16
10
  *
11
+ * This list used to name three (Root, Navbar, DocItem). The Navbar swizzle
12
+ * gating an "Organization API" link and the DocItem swizzle gating
13
+ * `/api/organization/*` were never built, and there is no organization
14
+ * OpenAPI section for them to gate — see `DocsRole` in
15
+ * `docs-auth-session.schemas.ts` for the measurement. The hook's
16
+ * role-carrying shape is unchanged and ready for such a surface; it simply
17
+ * has no second or third consumer at present.
18
+ *
17
19
  * Throws when used outside `<DocsAuthProvider>` so misconfigured swizzles
18
20
  * fail loud during the Docusaurus build (rather than silently rendering
19
21
  * "anonymous" for every reader). This mirrors the pattern in
@@ -1 +1 @@
1
- {"version":3,"file":"use-docs-auth-session.js","sourceRoot":"","sources":["../../../../src/runtime/use-docs-auth-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAA6B,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,iEAAiE;YAC/D,2FAA2F,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { useContext } from 'react';\nimport { DocsAuthContext, type DocsAuthContextValue } from './DocsAuthContext';\n\n/**\n * Read the current docs-site auth session.\n *\n * The three Docusaurus swizzles (Root, Navbar, DocItem — see\n * saas-technical-doc.md K-11) all consume the same hook:\n *\n * - Navbar : `session.status === 'authenticated' && session.claims.role === DocsRole.ORG_ADMIN`\n * decides whether the \"Organization API\" link is rendered.\n * - DocItem : on `/api/organization/*` routes, branches on the same\n * check; if anonymous, deep-links to the SaaS app because\n * handoff issuance requires a bearer.\n * - Root : the `<AuthExchangePage>` wired at `/auth/exchange` calls\n * `beginExchange(code)` on mount.\n *\n * Throws when used outside `<DocsAuthProvider>` so misconfigured swizzles\n * fail loud during the Docusaurus build (rather than silently rendering\n * \"anonymous\" for every reader). This mirrors the pattern in\n * `saas-frontend-lib`'s `useAuthSession()`.\n *\n * Lives in its own file so editing the context value type does not\n * invalidate the hook's React Fast Refresh boundary, mirroring the\n * `useAuthSession.ts` / `AuthSessionContext.tsx` split.\n */\nexport function useDocsAuthSession(): DocsAuthContextValue {\n const ctx = useContext(DocsAuthContext);\n if (!ctx) {\n throw new Error(\n '`useDocsAuthSession` must be used within `<DocsAuthProvider>`. ' +\n 'Mount it via the Root swizzle on your Docusaurus site (see saas-technical-doc.md Step 6).',\n );\n }\n return ctx;\n}\n"]}
1
+ {"version":3,"file":"use-docs-auth-session.js","sourceRoot":"","sources":["../../../../src/runtime/use-docs-auth-session.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AACnC,OAAO,EAAE,eAAe,EAA6B,MAAM,mBAAmB,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,GAAG,GAAG,UAAU,CAAC,eAAe,CAAC,CAAC;IACxC,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CACb,iEAAiE;YAC/D,2FAA2F,CAC9F,CAAC;IACJ,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC","sourcesContent":["import { useContext } from 'react';\nimport { DocsAuthContext, type DocsAuthContextValue } from './DocsAuthContext';\n\n/**\n * Read the current docs-site auth session.\n *\n * ONE Docusaurus swizzle consumes this hook today:\n *\n * - Root : the `<AuthExchangePage>` wired at `/auth/exchange` calls\n * `beginExchange(code)` on mount.\n *\n * This list used to name three (Root, Navbar, DocItem). The Navbar swizzle\n * gating an \"Organization API\" link and the DocItem swizzle gating\n * `/api/organization/*` were never built, and there is no organization\n * OpenAPI section for them to gate — see `DocsRole` in\n * `docs-auth-session.schemas.ts` for the measurement. The hook's\n * role-carrying shape is unchanged and ready for such a surface; it simply\n * has no second or third consumer at present.\n *\n * Throws when used outside `<DocsAuthProvider>` so misconfigured swizzles\n * fail loud during the Docusaurus build (rather than silently rendering\n * \"anonymous\" for every reader). This mirrors the pattern in\n * `saas-frontend-lib`'s `useAuthSession()`.\n *\n * Lives in its own file so editing the context value type does not\n * invalidate the hook's React Fast Refresh boundary, mirroring the\n * `useAuthSession.ts` / `AuthSessionContext.tsx` split.\n */\nexport function useDocsAuthSession(): DocsAuthContextValue {\n const ctx = useContext(DocsAuthContext);\n if (!ctx) {\n throw new Error(\n '`useDocsAuthSession` must be used within `<DocsAuthProvider>`. ' +\n 'Mount it via the Root swizzle on your Docusaurus site (see saas-technical-doc.md Step 6).',\n );\n }\n return ctx;\n}\n"]}