blodemd 0.0.15 → 0.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 (286) hide show
  1. package/README.md +26 -1
  2. package/dist/cli.mjs +217 -217
  3. package/dist/cli.mjs.map +1 -1
  4. package/package.json +3 -36
  5. package/dev-server/app/[[...slug]]/page.tsx +0 -140
  6. package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
  7. package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
  8. package/dev-server/app/blodemd-dev/version/route.ts +0 -14
  9. package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
  10. package/dev-server/app/error.tsx +0 -24
  11. package/dev-server/app/favicon.ico +0 -0
  12. package/dev-server/app/globals.css +0 -4
  13. package/dev-server/app/layout.tsx +0 -38
  14. package/dev-server/app/not-found.tsx +0 -18
  15. package/dev-server/app/search/route.ts +0 -17
  16. package/dev-server/components/dev-reload-script.tsx +0 -86
  17. package/dev-server/components/providers.tsx +0 -15
  18. package/dev-server/lib/dev-state.ts +0 -8
  19. package/dev-server/lib/local-content-source.ts +0 -103
  20. package/dev-server/lib/local-runtime.tsx +0 -555
  21. package/dev-server/next-env.d.ts +0 -5
  22. package/dev-server/next.config.js +0 -54
  23. package/dev-server/package.json +0 -61
  24. package/dev-server/postcss.config.mjs +0 -7
  25. package/dev-server/public/glide-variable.woff2 +0 -0
  26. package/dev-server/tsconfig.json +0 -50
  27. package/docs/app/globals.css +0 -471
  28. package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
  29. package/docs/components/api/api-playground.tsx +0 -467
  30. package/docs/components/api/api-reference.tsx +0 -157
  31. package/docs/components/content/collection-index.tsx +0 -114
  32. package/docs/components/docs/contextual-menu.tsx +0 -495
  33. package/docs/components/docs/copy-page-menu.tsx +0 -364
  34. package/docs/components/docs/doc-header.tsx +0 -223
  35. package/docs/components/docs/doc-shell.tsx +0 -355
  36. package/docs/components/docs/doc-sidebar.tsx +0 -256
  37. package/docs/components/docs/doc-toc.tsx +0 -46
  38. package/docs/components/docs/mobile-nav.tsx +0 -195
  39. package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
  40. package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
  41. package/docs/components/git/repo-picker.tsx +0 -529
  42. package/docs/components/icons/doc-icon.tsx +0 -96
  43. package/docs/components/mdx/accordion.tsx +0 -83
  44. package/docs/components/mdx/agent-instructions.tsx +0 -17
  45. package/docs/components/mdx/badge.tsx +0 -79
  46. package/docs/components/mdx/callout.tsx +0 -88
  47. package/docs/components/mdx/card.tsx +0 -110
  48. package/docs/components/mdx/code-block.tsx +0 -80
  49. package/docs/components/mdx/code-group.tsx +0 -203
  50. package/docs/components/mdx/color.tsx +0 -87
  51. package/docs/components/mdx/columns.tsx +0 -25
  52. package/docs/components/mdx/expandable.tsx +0 -45
  53. package/docs/components/mdx/field-layout.tsx +0 -77
  54. package/docs/components/mdx/frame.tsx +0 -23
  55. package/docs/components/mdx/get-text-content.ts +0 -18
  56. package/docs/components/mdx/icon.tsx +0 -12
  57. package/docs/components/mdx/iframe.tsx +0 -62
  58. package/docs/components/mdx/index.tsx +0 -121
  59. package/docs/components/mdx/installer.tsx +0 -20
  60. package/docs/components/mdx/panel.tsx +0 -11
  61. package/docs/components/mdx/param-field.tsx +0 -56
  62. package/docs/components/mdx/preview.tsx +0 -36
  63. package/docs/components/mdx/prompt.tsx +0 -63
  64. package/docs/components/mdx/request-example.tsx +0 -27
  65. package/docs/components/mdx/response-field.tsx +0 -42
  66. package/docs/components/mdx/steps.tsx +0 -92
  67. package/docs/components/mdx/tabs.tsx +0 -193
  68. package/docs/components/mdx/tile.tsx +0 -43
  69. package/docs/components/mdx/tooltip.tsx +0 -71
  70. package/docs/components/mdx/tree.tsx +0 -120
  71. package/docs/components/mdx/type-table.tsx +0 -71
  72. package/docs/components/mdx/update.tsx +0 -44
  73. package/docs/components/mdx/video.tsx +0 -45
  74. package/docs/components/mdx/view.tsx +0 -66
  75. package/docs/components/posthog-provider.tsx +0 -42
  76. package/docs/components/providers.tsx +0 -15
  77. package/docs/components/tenant-analytics.tsx +0 -49
  78. package/docs/components/third-parties.tsx +0 -32
  79. package/docs/components/ui/badge.tsx +0 -61
  80. package/docs/components/ui/breadcrumb.tsx +0 -112
  81. package/docs/components/ui/button-group.tsx +0 -83
  82. package/docs/components/ui/button.tsx +0 -65
  83. package/docs/components/ui/card.tsx +0 -92
  84. package/docs/components/ui/command.tsx +0 -167
  85. package/docs/components/ui/copy-button.tsx +0 -129
  86. package/docs/components/ui/dialog.tsx +0 -146
  87. package/docs/components/ui/field.tsx +0 -237
  88. package/docs/components/ui/input.tsx +0 -23
  89. package/docs/components/ui/kbd.tsx +0 -98
  90. package/docs/components/ui/label.tsx +0 -22
  91. package/docs/components/ui/morph-icon.tsx +0 -79
  92. package/docs/components/ui/popover.tsx +0 -267
  93. package/docs/components/ui/search-dialog.tsx +0 -431
  94. package/docs/components/ui/search.tsx +0 -101
  95. package/docs/components/ui/separator.tsx +0 -26
  96. package/docs/components/ui/sheet.tsx +0 -133
  97. package/docs/components/ui/sidebar.tsx +0 -758
  98. package/docs/components/ui/skeleton.tsx +0 -11
  99. package/docs/components/ui/switch.tsx +0 -32
  100. package/docs/components/ui/tabs.tsx +0 -138
  101. package/docs/components/ui/theme-toggle.tsx +0 -62
  102. package/docs/components/ui/tooltip.tsx +0 -53
  103. package/docs/components/web-mcp.tsx +0 -115
  104. package/docs/lib/agent-skills.ts +0 -48
  105. package/docs/lib/api-client.ts +0 -72
  106. package/docs/lib/config.ts +0 -6
  107. package/docs/lib/content-root.ts +0 -33
  108. package/docs/lib/content-source.ts +0 -70
  109. package/docs/lib/contextual-options.ts +0 -222
  110. package/docs/lib/dashboard-session.ts +0 -167
  111. package/docs/lib/db.ts +0 -13
  112. package/docs/lib/docs-collection.ts +0 -7
  113. package/docs/lib/docs-runtime.tsx +0 -745
  114. package/docs/lib/edge-config.ts +0 -95
  115. package/docs/lib/env.ts +0 -23
  116. package/docs/lib/etag.ts +0 -22
  117. package/docs/lib/github-install.ts +0 -33
  118. package/docs/lib/llms-full.ts +0 -82
  119. package/docs/lib/marketing-markdown.ts +0 -79
  120. package/docs/lib/marketing-site.ts +0 -31
  121. package/docs/lib/mdx.ts +0 -98
  122. package/docs/lib/navigation.ts +0 -288
  123. package/docs/lib/openapi-proxy.ts +0 -88
  124. package/docs/lib/openapi.ts +0 -158
  125. package/docs/lib/platform-config.ts +0 -6
  126. package/docs/lib/project-authz.ts +0 -46
  127. package/docs/lib/routes.ts +0 -103
  128. package/docs/lib/server-cache.ts +0 -83
  129. package/docs/lib/shiki.ts +0 -44
  130. package/docs/lib/supabase.ts +0 -37
  131. package/docs/lib/tenancy.ts +0 -364
  132. package/docs/lib/tenant-headers.ts +0 -43
  133. package/docs/lib/tenant-static.ts +0 -705
  134. package/docs/lib/tenant-utility-context.ts +0 -62
  135. package/docs/lib/tenants.ts +0 -72
  136. package/docs/lib/theme.ts +0 -29
  137. package/docs/lib/time-ago.ts +0 -24
  138. package/docs/lib/toc.ts +0 -2
  139. package/docs/lib/use-mobile.ts +0 -19
  140. package/docs/lib/use-tab-observer.ts +0 -71
  141. package/docs/lib/utils.ts +0 -5
  142. package/packages/@repo/common/dist/index.d.ts +0 -16
  143. package/packages/@repo/common/dist/index.d.ts.map +0 -1
  144. package/packages/@repo/common/dist/index.js +0 -84
  145. package/packages/@repo/common/package.json +0 -34
  146. package/packages/@repo/common/src/index.ts +0 -101
  147. package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
  148. package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
  149. package/packages/@repo/contracts/dist/analytics.js +0 -18
  150. package/packages/@repo/contracts/dist/dates.d.ts +0 -4
  151. package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
  152. package/packages/@repo/contracts/dist/dates.js +0 -2
  153. package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
  154. package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
  155. package/packages/@repo/contracts/dist/deployment.js +0 -46
  156. package/packages/@repo/contracts/dist/domain.d.ts +0 -94
  157. package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
  158. package/packages/@repo/contracts/dist/domain.js +0 -36
  159. package/packages/@repo/contracts/dist/git.d.ts +0 -28
  160. package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
  161. package/packages/@repo/contracts/dist/git.js +0 -24
  162. package/packages/@repo/contracts/dist/ids.d.ts +0 -14
  163. package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
  164. package/packages/@repo/contracts/dist/ids.js +0 -11
  165. package/packages/@repo/contracts/dist/index.d.ts +0 -11
  166. package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
  167. package/packages/@repo/contracts/dist/index.js +0 -12
  168. package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
  169. package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
  170. package/packages/@repo/contracts/dist/pagination.js +0 -15
  171. package/packages/@repo/contracts/dist/project.d.ts +0 -42
  172. package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
  173. package/packages/@repo/contracts/dist/project.js +0 -25
  174. package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
  175. package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
  176. package/packages/@repo/contracts/dist/tenant.js +0 -58
  177. package/packages/@repo/contracts/dist/user.d.ts +0 -9
  178. package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
  179. package/packages/@repo/contracts/dist/user.js +0 -9
  180. package/packages/@repo/contracts/package.json +0 -37
  181. package/packages/@repo/contracts/src/analytics.ts +0 -33
  182. package/packages/@repo/contracts/src/dates.ts +0 -4
  183. package/packages/@repo/contracts/src/deployment.ts +0 -73
  184. package/packages/@repo/contracts/src/domain.ts +0 -51
  185. package/packages/@repo/contracts/src/git.ts +0 -31
  186. package/packages/@repo/contracts/src/ids.ts +0 -23
  187. package/packages/@repo/contracts/src/index.ts +0 -12
  188. package/packages/@repo/contracts/src/pagination.ts +0 -21
  189. package/packages/@repo/contracts/src/project.ts +0 -32
  190. package/packages/@repo/contracts/src/tenant.ts +0 -94
  191. package/packages/@repo/contracts/src/user.ts +0 -12
  192. package/packages/@repo/models/dist/docs-config.d.ts +0 -961
  193. package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
  194. package/packages/@repo/models/dist/docs-config.js +0 -531
  195. package/packages/@repo/models/dist/index.d.ts +0 -3
  196. package/packages/@repo/models/dist/index.d.ts.map +0 -1
  197. package/packages/@repo/models/dist/index.js +0 -3
  198. package/packages/@repo/models/dist/tenant.d.ts +0 -37
  199. package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
  200. package/packages/@repo/models/dist/tenant.js +0 -1
  201. package/packages/@repo/models/package.json +0 -37
  202. package/packages/@repo/models/src/docs-config.ts +0 -629
  203. package/packages/@repo/models/src/index.ts +0 -3
  204. package/packages/@repo/models/src/tenant.ts +0 -44
  205. package/packages/@repo/prebuild/dist/index.d.ts +0 -2
  206. package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
  207. package/packages/@repo/prebuild/dist/index.js +0 -2
  208. package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
  209. package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
  210. package/packages/@repo/prebuild/dist/openapi.js +0 -86
  211. package/packages/@repo/prebuild/package.json +0 -39
  212. package/packages/@repo/prebuild/src/index.ts +0 -2
  213. package/packages/@repo/prebuild/src/openapi.ts +0 -154
  214. package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
  215. package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
  216. package/packages/@repo/previewing/dist/blob-source.js +0 -128
  217. package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
  218. package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
  219. package/packages/@repo/previewing/dist/config-loader.js +0 -231
  220. package/packages/@repo/previewing/dist/constants.d.ts +0 -15
  221. package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
  222. package/packages/@repo/previewing/dist/constants.js +0 -14
  223. package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
  224. package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
  225. package/packages/@repo/previewing/dist/content-index.js +0 -291
  226. package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
  227. package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
  228. package/packages/@repo/previewing/dist/content-source.js +0 -1
  229. package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
  230. package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
  231. package/packages/@repo/previewing/dist/fs-source.js +0 -71
  232. package/packages/@repo/previewing/dist/index.d.ts +0 -16
  233. package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
  234. package/packages/@repo/previewing/dist/index.js +0 -13
  235. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
  236. package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
  237. package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
  238. package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
  239. package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
  240. package/packages/@repo/previewing/dist/markdown/format.js +0 -43
  241. package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
  242. package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
  243. package/packages/@repo/previewing/dist/markdown/links.js +0 -31
  244. package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
  245. package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
  246. package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
  247. package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
  248. package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
  249. package/packages/@repo/previewing/dist/search-index.js +0 -23
  250. package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
  251. package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
  252. package/packages/@repo/previewing/dist/serialization.js +0 -108
  253. package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
  254. package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
  255. package/packages/@repo/previewing/dist/toc-index.js +0 -53
  256. package/packages/@repo/previewing/dist/types.d.ts +0 -92
  257. package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
  258. package/packages/@repo/previewing/dist/types.js +0 -1
  259. package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
  260. package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
  261. package/packages/@repo/previewing/dist/utility-index.js +0 -201
  262. package/packages/@repo/previewing/package.json +0 -41
  263. package/packages/@repo/previewing/src/blob-source.ts +0 -185
  264. package/packages/@repo/previewing/src/config-loader.ts +0 -316
  265. package/packages/@repo/previewing/src/constants.ts +0 -16
  266. package/packages/@repo/previewing/src/content-index.ts +0 -384
  267. package/packages/@repo/previewing/src/content-source.ts +0 -12
  268. package/packages/@repo/previewing/src/fs-source.ts +0 -103
  269. package/packages/@repo/previewing/src/index.ts +0 -71
  270. package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
  271. package/packages/@repo/previewing/src/markdown/format.ts +0 -63
  272. package/packages/@repo/previewing/src/markdown/links.ts +0 -46
  273. package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
  274. package/packages/@repo/previewing/src/search-index.ts +0 -38
  275. package/packages/@repo/previewing/src/serialization.ts +0 -191
  276. package/packages/@repo/previewing/src/toc-index.ts +0 -72
  277. package/packages/@repo/previewing/src/types.ts +0 -105
  278. package/packages/@repo/previewing/src/utility-index.ts +0 -304
  279. package/packages/@repo/validation/dist/index.d.ts +0 -12
  280. package/packages/@repo/validation/dist/index.d.ts.map +0 -1
  281. package/packages/@repo/validation/dist/index.js +0 -30
  282. package/packages/@repo/validation/package.json +0 -38
  283. package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
  284. package/packages/@repo/validation/src/index.ts +0 -59
  285. package/scripts/prepare-package.mjs +0 -53
  286. package/scripts/repo-packages.mjs +0 -8
@@ -1,83 +0,0 @@
1
- interface CacheEntry<Value> {
2
- expiresAt: number;
3
- value: Promise<Value>;
4
- }
5
-
6
- interface TimedPromiseCacheOptions {
7
- maxEntries: number;
8
- ttlMs: number;
9
- }
10
-
11
- export interface TimedPromiseCache<Key, Value> {
12
- clear(): void;
13
- delete(key: Key): void;
14
- deleteByPrefix(prefix: string): void;
15
- getOrCreate(key: Key, factory: () => Promise<Value>): Promise<Value>;
16
- }
17
-
18
- export const createTimedPromiseCache = <Key, Value>({
19
- maxEntries,
20
- ttlMs,
21
- }: TimedPromiseCacheOptions): TimedPromiseCache<Key, Value> => {
22
- const entries = new Map<Key, CacheEntry<Value>>();
23
-
24
- const deleteOldest = () => {
25
- const oldestKey = entries.keys().next().value as Key | undefined;
26
- if (oldestKey !== undefined) {
27
- entries.delete(oldestKey);
28
- }
29
- };
30
-
31
- const pruneExpired = (now: number) => {
32
- for (const [key, entry] of entries) {
33
- if (entry.expiresAt <= now) {
34
- entries.delete(key);
35
- }
36
- }
37
- };
38
-
39
- return {
40
- clear() {
41
- entries.clear();
42
- },
43
- delete(key) {
44
- entries.delete(key);
45
- },
46
- deleteByPrefix(prefix: string) {
47
- for (const key of entries.keys()) {
48
- if (typeof key === "string" && key.startsWith(prefix)) {
49
- entries.delete(key);
50
- }
51
- }
52
- },
53
- getOrCreate(key, factory) {
54
- const now = Date.now();
55
- pruneExpired(now);
56
-
57
- const existing = entries.get(key);
58
- if (existing) {
59
- return existing.value;
60
- }
61
-
62
- const value = (async () => {
63
- try {
64
- return await factory();
65
- } catch (error) {
66
- entries.delete(key);
67
- throw error;
68
- }
69
- })();
70
-
71
- entries.set(key, {
72
- expiresAt: now + ttlMs,
73
- value,
74
- });
75
-
76
- if (entries.size > maxEntries) {
77
- deleteOldest();
78
- }
79
-
80
- return value;
81
- },
82
- };
83
- };
package/docs/lib/shiki.ts DELETED
@@ -1,44 +0,0 @@
1
- import { createHighlighter } from "shiki";
2
-
3
- const COMMON_LANGS = [
4
- "bash",
5
- "css",
6
- "diff",
7
- "go",
8
- "graphql",
9
- "html",
10
- "javascript",
11
- "json",
12
- "jsx",
13
- "markdown",
14
- "mdx",
15
- "nginx",
16
- "python",
17
- "rust",
18
- "sh",
19
- "shell",
20
- "sql",
21
- "text",
22
- "tsx",
23
- "typescript",
24
- "yaml",
25
- ] as const;
26
-
27
- export const SHIKI_THEME_PAIR = {
28
- dark: "github-dark",
29
- light: "github-light",
30
- } as const;
31
-
32
- const THEMES = [SHIKI_THEME_PAIR.dark, SHIKI_THEME_PAIR.light] as const;
33
-
34
- let highlighterPromise: ReturnType<typeof createHighlighter> | null = null;
35
-
36
- export const getHighlighter = () => {
37
- if (!highlighterPromise) {
38
- highlighterPromise = createHighlighter({
39
- langs: [...COMMON_LANGS],
40
- themes: [...THEMES],
41
- });
42
- }
43
- return highlighterPromise;
44
- };
@@ -1,37 +0,0 @@
1
- import { createBrowserClient, createServerClient } from "@supabase/ssr";
2
- import type { CookieOptions } from "@supabase/ssr";
3
- import type { SupabaseClient } from "@supabase/supabase-js";
4
-
5
- const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL ?? "";
6
- const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY ?? "";
7
-
8
- let browserClient: SupabaseClient | null = null;
9
-
10
- export const createSupabaseClient = (): SupabaseClient => {
11
- if (!browserClient) {
12
- browserClient = createBrowserClient(supabaseUrl, supabaseAnonKey);
13
- }
14
- return browserClient;
15
- };
16
-
17
- interface CookieStore {
18
- get: (name: string) => { value: string } | undefined;
19
- set?: (name: string, value: string, options?: CookieOptions) => void;
20
- }
21
-
22
- export const createSupabaseServerClient = (
23
- cookieStore: CookieStore
24
- ): SupabaseClient =>
25
- createServerClient(supabaseUrl, supabaseAnonKey, {
26
- cookies: {
27
- get(name: string) {
28
- return cookieStore.get(name)?.value;
29
- },
30
- remove(name: string, options?: CookieOptions) {
31
- cookieStore.set?.(name, "", { ...options, maxAge: 0 });
32
- },
33
- set(name: string, value: string, options?: CookieOptions) {
34
- cookieStore.set?.(name, value, options);
35
- },
36
- },
37
- });
@@ -1,364 +0,0 @@
1
- import { getLocalRootHostsFromEnv, normalizeHost } from "@repo/common";
2
- import type { Tenant } from "@repo/contracts";
3
- import { TenantResolutionSchema } from "@repo/contracts";
4
-
5
- import {
6
- getTenantEdgeHostRecord,
7
- getTenantEdgeSlugRecord,
8
- isEdgeConfigEnabled,
9
- } from "./edge-config";
10
- import { docsApiBase } from "./env";
11
- import { platformConfig } from "./platform-config";
12
- import { createTimedPromiseCache } from "./server-cache";
13
-
14
- const DEFAULT_RESERVED_PATHS = [
15
- "/_internal",
16
- "/_next",
17
- "/.well-known",
18
- "/api",
19
- "/app",
20
- "/docs.json",
21
- "/favicon.ico",
22
- "/llms.txt",
23
- "/logos",
24
- "/mcp",
25
- "/oauth",
26
- "/robots.txt",
27
- "/sitemap.xml",
28
- ];
29
-
30
- const STATIC_ASSET_EXTENSIONS = new Set([
31
- ".avif",
32
- ".css",
33
- ".eot",
34
- ".gif",
35
- ".ico",
36
- ".jpeg",
37
- ".jpg",
38
- ".js",
39
- ".json",
40
- ".map",
41
- ".png",
42
- ".svg",
43
- ".ttf",
44
- ".webp",
45
- ".woff",
46
- ".woff2",
47
- ]);
48
-
49
- const isRootStaticAsset = (pathname: string): boolean => {
50
- const segments = pathname.split("/").filter(Boolean);
51
- if (segments.length !== 1) {
52
- return false;
53
- }
54
- const lastDot = pathname.lastIndexOf(".");
55
- if (lastDot === -1) {
56
- return false;
57
- }
58
- return STATIC_ASSET_EXTENSIONS.has(pathname.slice(lastDot).toLowerCase());
59
- };
60
-
61
- const LOCAL_ROOT_HOSTS = new Set(["localhost", "127.0.0.1"]);
62
- const TRAILING_SLASHES_REGEX = /\/+$/;
63
- const LEADING_SLASHES_REGEX = /^\/+/;
64
- const BACKSLASH_TO_SLASH_REGEX = /\\/g;
65
- const DEFAULT_DOCS_BASE_PATH = "/docs";
66
- const TENANT_RESOLUTION_REVALIDATE_SECONDS = 300;
67
- const ROOT_TENANT_UTILITY_PATHS = new Set([
68
- "/.well-known/llms-full.txt",
69
- "/.well-known/llms.txt",
70
- "/llms-full.txt",
71
- "/llms.txt",
72
- "/robots.txt",
73
- "/sitemap.xml",
74
- ]);
75
- const WELL_KNOWN_SKILLS_SEGMENT = "/.well-known/skills/";
76
- const LLMS_SEGMENT_SEGMENT = "/llms/";
77
-
78
- export const isTenantUtilityPath = (pathname: string) =>
79
- ROOT_TENANT_UTILITY_PATHS.has(pathname) ||
80
- pathname.startsWith(WELL_KNOWN_SKILLS_SEGMENT) ||
81
- (pathname.startsWith(LLMS_SEGMENT_SEGMENT) && pathname.endsWith(".txt"));
82
-
83
- const isPathMatch = (pathname: string, prefix: string) =>
84
- pathname === prefix || pathname.startsWith(`${prefix}/`);
85
-
86
- const slugifyPath = (value: string) => {
87
- const trimmed = value
88
- .replace(BACKSLASH_TO_SLASH_REGEX, "/")
89
- .replace(TRAILING_SLASHES_REGEX, "");
90
- return trimmed.replace(LEADING_SLASHES_REGEX, "");
91
- };
92
-
93
- const stripPrefix = (pathname: string, prefix: string | null) => {
94
- if (!prefix) {
95
- return slugifyPath(pathname);
96
- }
97
-
98
- const normalizedPath = slugifyPath(pathname);
99
- const normalizedPrefix = slugifyPath(prefix);
100
- if (!normalizedPrefix) {
101
- return normalizedPath;
102
- }
103
-
104
- if (normalizedPath === normalizedPrefix) {
105
- return "";
106
- }
107
-
108
- if (normalizedPath.startsWith(`${normalizedPrefix}/`)) {
109
- return normalizedPath.slice(normalizedPrefix.length + 1);
110
- }
111
-
112
- return null;
113
- };
114
-
115
- const tenantResolutionCache = createTimedPromiseCache<
116
- string,
117
- Awaited<ReturnType<typeof fetchTenantResolution>>
118
- >({
119
- maxEntries: 512,
120
- ttlMs: TENANT_RESOLUTION_REVALIDATE_SECONDS * 1000,
121
- });
122
-
123
- export const getRequestHost = (headerSource: Pick<Headers, "get">) => {
124
- const forwardedHost = headerSource.get("x-forwarded-host");
125
- return normalizeHost(
126
- forwardedHost?.split(",")[0]?.trim() || headerSource.get("host") || ""
127
- );
128
- };
129
-
130
- export const getRequestProtocol = (headerSource: Pick<Headers, "get">) =>
131
- headerSource.get("x-forwarded-proto")?.split(",")[0]?.trim() || "https";
132
-
133
- export const isRootRuntimeHost = (host: string) => {
134
- const normalizedHost = normalizeHost(host);
135
- return (
136
- normalizedHost === platformConfig.rootDomain ||
137
- LOCAL_ROOT_HOSTS.has(normalizedHost) ||
138
- getLocalRootHostsFromEnv(process.env).has(normalizedHost)
139
- );
140
- };
141
-
142
- export const isReservedPath = (pathname: string) => {
143
- const { assetPrefix } = platformConfig;
144
- if (assetPrefix && pathname.startsWith(assetPrefix)) {
145
- return true;
146
- }
147
- if (isRootStaticAsset(pathname)) {
148
- return true;
149
- }
150
- return DEFAULT_RESERVED_PATHS.some((prefix) => isPathMatch(pathname, prefix));
151
- };
152
-
153
- const resolveSubdomainBasePath = (pathname: string): string => {
154
- const normalizedPath = slugifyPath(pathname);
155
-
156
- if (
157
- normalizedPath === "docs" ||
158
- normalizedPath.startsWith(`${slugifyPath(DEFAULT_DOCS_BASE_PATH)}/`)
159
- ) {
160
- return DEFAULT_DOCS_BASE_PATH;
161
- }
162
-
163
- return "";
164
- };
165
-
166
- const buildTenantPathResolution = (
167
- tenant: Tenant,
168
- strategy: "preview" | "subdomain" | "custom-domain",
169
- host: string,
170
- pathname: string,
171
- basePath: string
172
- ) => {
173
- if (isTenantUtilityPath(pathname)) {
174
- return {
175
- basePath,
176
- host,
177
- rewrittenPath: `/sites/${tenant.slug}${pathname}`,
178
- strategy,
179
- tenant,
180
- };
181
- }
182
-
183
- const slugPath = stripPrefix(pathname, basePath || null);
184
- if (slugPath === null) {
185
- return null;
186
- }
187
-
188
- const rewrittenPath = slugPath
189
- ? `/sites/${tenant.slug}/${slugPath}`
190
- : `/sites/${tenant.slug}/`;
191
-
192
- return {
193
- basePath,
194
- host,
195
- rewrittenPath,
196
- strategy,
197
- tenant,
198
- };
199
- };
200
-
201
- const buildPathTenantResolution = (
202
- tenant: Tenant,
203
- host: string,
204
- pathname: string
205
- ) => {
206
- const normalized = slugifyPath(pathname);
207
- const parts = normalized ? normalized.split("/") : [];
208
- const [projectSlug, ...rest] = parts;
209
- if (!projectSlug || projectSlug !== tenant.slug) {
210
- return null;
211
- }
212
-
213
- const remainder = rest.join("/");
214
- return {
215
- basePath: `/${tenant.slug}`,
216
- host,
217
- rewrittenPath: remainder
218
- ? `/sites/${tenant.slug}/${remainder}`
219
- : `/sites/${tenant.slug}/`,
220
- strategy: "path" as const,
221
- tenant,
222
- };
223
- };
224
-
225
- const fetchTenantResolutionFromApi = async (host: string, pathname: string) => {
226
- const url = new URL("/tenants/resolve", docsApiBase);
227
- url.searchParams.set("host", normalizeHost(host));
228
- url.searchParams.set("path", pathname);
229
- let response: Response;
230
- try {
231
- response = await fetch(url.toString(), {
232
- next: { revalidate: TENANT_RESOLUTION_REVALIDATE_SECONDS },
233
- });
234
- } catch {
235
- return null;
236
- }
237
- if (!response.ok) {
238
- return null;
239
- }
240
- const json = (await response.json()) as unknown;
241
- const parsed = TenantResolutionSchema.safeParse(json);
242
- if (!parsed.success) {
243
- return null;
244
- }
245
- return parsed.data;
246
- };
247
-
248
- export const resolveTenantFromEdgeConfig = async (
249
- host: string,
250
- pathname: string
251
- ) => {
252
- const normalizedHost = normalizeHost(host);
253
- const hostRecord = await getTenantEdgeHostRecord(normalizedHost);
254
- if (hostRecord) {
255
- const basePath =
256
- hostRecord.strategy === "subdomain"
257
- ? resolveSubdomainBasePath(pathname)
258
- : (hostRecord.pathPrefix ?? "");
259
-
260
- return buildTenantPathResolution(
261
- hostRecord.tenant,
262
- hostRecord.strategy,
263
- normalizedHost,
264
- pathname,
265
- basePath
266
- );
267
- }
268
-
269
- const previewPrefix = normalizedHost.includes("---")
270
- ? normalizedHost.split("---")[0]
271
- : null;
272
- if (previewPrefix) {
273
- const previewRecord = await getTenantEdgeSlugRecord(previewPrefix);
274
- if (previewRecord) {
275
- return buildTenantPathResolution(
276
- previewRecord.tenant,
277
- "preview",
278
- normalizedHost,
279
- pathname,
280
- resolveSubdomainBasePath(pathname)
281
- );
282
- }
283
- }
284
-
285
- const localSuffixes = ["localhost", "127.0.0.1"];
286
- const localRootHosts = getLocalRootHostsFromEnv(process.env);
287
- const localSuffix = localRootHosts.has(normalizedHost)
288
- ? null
289
- : localSuffixes.find((suffix) => normalizedHost.endsWith(`.${suffix}`));
290
- if (localSuffix) {
291
- const subdomain = normalizedHost.slice(0, -1 * (localSuffix.length + 1));
292
- if (subdomain) {
293
- const subdomainRecord = await getTenantEdgeSlugRecord(subdomain);
294
- if (subdomainRecord) {
295
- return buildTenantPathResolution(
296
- subdomainRecord.tenant,
297
- "subdomain",
298
- normalizedHost,
299
- pathname,
300
- resolveSubdomainBasePath(pathname)
301
- );
302
- }
303
- }
304
- }
305
-
306
- if (normalizedHost.endsWith(`.${platformConfig.rootDomain}`)) {
307
- const subdomain = normalizedHost.slice(
308
- 0,
309
- -1 * (platformConfig.rootDomain.length + 1)
310
- );
311
- if (
312
- subdomain &&
313
- !["www", "app", "admin", "dashboard"].includes(subdomain)
314
- ) {
315
- const subdomainRecord = await getTenantEdgeSlugRecord(subdomain);
316
- if (subdomainRecord) {
317
- return buildTenantPathResolution(
318
- subdomainRecord.tenant,
319
- "subdomain",
320
- normalizedHost,
321
- pathname,
322
- resolveSubdomainBasePath(pathname)
323
- );
324
- }
325
- }
326
- }
327
-
328
- if (isRootRuntimeHost(normalizedHost)) {
329
- const normalizedPath = slugifyPath(pathname);
330
- const [projectSlug] = normalizedPath.split("/");
331
- if (projectSlug) {
332
- const pathRecord = await getTenantEdgeSlugRecord(projectSlug);
333
- if (pathRecord) {
334
- return buildPathTenantResolution(
335
- pathRecord.tenant,
336
- normalizedHost,
337
- pathname
338
- );
339
- }
340
- }
341
- }
342
-
343
- return null;
344
- };
345
-
346
- const fetchTenantResolution = async (host: string, pathname: string) => {
347
- if (isEdgeConfigEnabled()) {
348
- return await resolveTenantFromEdgeConfig(host, pathname);
349
- }
350
-
351
- return await fetchTenantResolutionFromApi(host, pathname);
352
- };
353
-
354
- export const clearTenantResolutionCache = () => {
355
- tenantResolutionCache.clear();
356
- };
357
-
358
- export const resolveTenant = async (host: string, pathname: string) => {
359
- const cacheKey = `${normalizeHost(host)}:${pathname}`;
360
- return await tenantResolutionCache.getOrCreate(
361
- cacheKey,
362
- async () => await fetchTenantResolution(host, pathname)
363
- );
364
- };
@@ -1,43 +0,0 @@
1
- import type { ProjectAnalytics } from "@repo/contracts";
2
-
3
- export const TENANT_HEADERS = {
4
- ANALYTICS: "x-tenant-analytics",
5
- BASE_PATH: "x-tenant-base-path",
6
- CUSTOM_DOMAINS: "x-tenant-custom-domains",
7
- DEPLOYMENT_ID: "x-tenant-deployment-id",
8
- DOMAIN: "x-tenant-domain",
9
- ID: "x-tenant-id",
10
- MANIFEST_URL: "x-tenant-manifest-url",
11
- NAME: "x-tenant-name",
12
- PATH_PREFIX: "x-tenant-path-prefix",
13
- PRIMARY_DOMAIN: "x-tenant-primary-domain",
14
- SLUG: "x-tenant-slug",
15
- STRATEGY: "x-tenant-strategy",
16
- SUBDOMAIN: "x-tenant-subdomain",
17
- } as const;
18
-
19
- const hasAnyProvider = (value: ProjectAnalytics): boolean =>
20
- Boolean(value.ga4?.measurementId || value.posthog?.projectKey);
21
-
22
- export const encodeTenantAnalyticsHeader = (
23
- analytics: ProjectAnalytics | undefined
24
- ): string | null => {
25
- if (!analytics || !hasAnyProvider(analytics)) {
26
- return null;
27
- }
28
- return encodeURIComponent(JSON.stringify(analytics));
29
- };
30
-
31
- export const decodeTenantAnalyticsHeader = (
32
- encoded: string | null | undefined
33
- ): ProjectAnalytics | null => {
34
- if (!encoded) {
35
- return null;
36
- }
37
- try {
38
- const parsed = JSON.parse(decodeURIComponent(encoded)) as ProjectAnalytics;
39
- return hasAnyProvider(parsed) ? parsed : null;
40
- } catch {
41
- return null;
42
- }
43
- };