blodemd 0.1.0 → 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.
- package/dist/cli.mjs +50 -174
- package/dist/cli.mjs.map +1 -1
- package/package.json +3 -36
- package/dev-server/app/[[...slug]]/page.tsx +0 -140
- package/dev-server/app/blodemd-dev/invalidate/route.ts +0 -12
- package/dev-server/app/blodemd-dev/static/[...path]/route.ts +0 -32
- package/dev-server/app/blodemd-dev/version/route.ts +0 -14
- package/dev-server/app/blodemd-internal/proxy/route.ts +0 -86
- package/dev-server/app/error.tsx +0 -24
- package/dev-server/app/favicon.ico +0 -0
- package/dev-server/app/globals.css +0 -4
- package/dev-server/app/layout.tsx +0 -38
- package/dev-server/app/not-found.tsx +0 -18
- package/dev-server/app/search/route.ts +0 -17
- package/dev-server/components/dev-reload-script.tsx +0 -86
- package/dev-server/components/providers.tsx +0 -15
- package/dev-server/lib/dev-state.ts +0 -8
- package/dev-server/lib/local-content-source.ts +0 -103
- package/dev-server/lib/local-runtime.tsx +0 -555
- package/dev-server/next-env.d.ts +0 -5
- package/dev-server/next.config.js +0 -54
- package/dev-server/package.json +0 -61
- package/dev-server/postcss.config.mjs +0 -7
- package/dev-server/public/glide-variable.woff2 +0 -0
- package/dev-server/tsconfig.json +0 -50
- package/docs/app/globals.css +0 -471
- package/docs/components/animate-ui/primitives/buttons/button.tsx +0 -14
- package/docs/components/api/api-playground.tsx +0 -467
- package/docs/components/api/api-reference.tsx +0 -157
- package/docs/components/content/collection-index.tsx +0 -114
- package/docs/components/docs/contextual-menu.tsx +0 -495
- package/docs/components/docs/copy-page-menu.tsx +0 -364
- package/docs/components/docs/doc-header.tsx +0 -223
- package/docs/components/docs/doc-shell.tsx +0 -355
- package/docs/components/docs/doc-sidebar.tsx +0 -256
- package/docs/components/docs/doc-toc.tsx +0 -46
- package/docs/components/docs/mobile-nav.tsx +0 -195
- package/docs/components/docs/sidebar-active-highlight.tsx +0 -34
- package/docs/components/docs/sidebar-scroll-area.tsx +0 -63
- package/docs/components/git/repo-picker.tsx +0 -529
- package/docs/components/icons/doc-icon.tsx +0 -96
- package/docs/components/mdx/accordion.tsx +0 -83
- package/docs/components/mdx/agent-instructions.tsx +0 -17
- package/docs/components/mdx/badge.tsx +0 -79
- package/docs/components/mdx/callout.tsx +0 -88
- package/docs/components/mdx/card.tsx +0 -110
- package/docs/components/mdx/code-block.tsx +0 -80
- package/docs/components/mdx/code-group.tsx +0 -203
- package/docs/components/mdx/color.tsx +0 -87
- package/docs/components/mdx/columns.tsx +0 -25
- package/docs/components/mdx/expandable.tsx +0 -45
- package/docs/components/mdx/field-layout.tsx +0 -77
- package/docs/components/mdx/frame.tsx +0 -23
- package/docs/components/mdx/get-text-content.ts +0 -18
- package/docs/components/mdx/icon.tsx +0 -12
- package/docs/components/mdx/iframe.tsx +0 -62
- package/docs/components/mdx/index.tsx +0 -121
- package/docs/components/mdx/installer.tsx +0 -20
- package/docs/components/mdx/panel.tsx +0 -11
- package/docs/components/mdx/param-field.tsx +0 -56
- package/docs/components/mdx/preview.tsx +0 -36
- package/docs/components/mdx/prompt.tsx +0 -63
- package/docs/components/mdx/request-example.tsx +0 -27
- package/docs/components/mdx/response-field.tsx +0 -42
- package/docs/components/mdx/steps.tsx +0 -92
- package/docs/components/mdx/tabs.tsx +0 -193
- package/docs/components/mdx/tile.tsx +0 -43
- package/docs/components/mdx/tooltip.tsx +0 -71
- package/docs/components/mdx/tree.tsx +0 -120
- package/docs/components/mdx/type-table.tsx +0 -71
- package/docs/components/mdx/update.tsx +0 -44
- package/docs/components/mdx/video.tsx +0 -45
- package/docs/components/mdx/view.tsx +0 -66
- package/docs/components/posthog-provider.tsx +0 -42
- package/docs/components/providers.tsx +0 -15
- package/docs/components/tenant-analytics.tsx +0 -49
- package/docs/components/third-parties.tsx +0 -32
- package/docs/components/ui/badge.tsx +0 -61
- package/docs/components/ui/breadcrumb.tsx +0 -112
- package/docs/components/ui/button-group.tsx +0 -83
- package/docs/components/ui/button.tsx +0 -65
- package/docs/components/ui/card.tsx +0 -92
- package/docs/components/ui/command.tsx +0 -167
- package/docs/components/ui/copy-button.tsx +0 -129
- package/docs/components/ui/dialog.tsx +0 -146
- package/docs/components/ui/field.tsx +0 -237
- package/docs/components/ui/input.tsx +0 -23
- package/docs/components/ui/kbd.tsx +0 -98
- package/docs/components/ui/label.tsx +0 -22
- package/docs/components/ui/morph-icon.tsx +0 -79
- package/docs/components/ui/popover.tsx +0 -267
- package/docs/components/ui/search-dialog.tsx +0 -431
- package/docs/components/ui/search.tsx +0 -101
- package/docs/components/ui/separator.tsx +0 -26
- package/docs/components/ui/sheet.tsx +0 -133
- package/docs/components/ui/sidebar.tsx +0 -758
- package/docs/components/ui/skeleton.tsx +0 -11
- package/docs/components/ui/switch.tsx +0 -32
- package/docs/components/ui/tabs.tsx +0 -138
- package/docs/components/ui/theme-toggle.tsx +0 -62
- package/docs/components/ui/tooltip.tsx +0 -53
- package/docs/components/web-mcp.tsx +0 -115
- package/docs/lib/agent-skills.ts +0 -48
- package/docs/lib/api-client.ts +0 -72
- package/docs/lib/config.ts +0 -6
- package/docs/lib/content-root.ts +0 -33
- package/docs/lib/content-source.ts +0 -70
- package/docs/lib/contextual-options.ts +0 -222
- package/docs/lib/dashboard-session.ts +0 -167
- package/docs/lib/db.ts +0 -13
- package/docs/lib/docs-collection.ts +0 -7
- package/docs/lib/docs-runtime.tsx +0 -745
- package/docs/lib/edge-config.ts +0 -95
- package/docs/lib/env.ts +0 -23
- package/docs/lib/etag.ts +0 -22
- package/docs/lib/github-install.ts +0 -33
- package/docs/lib/llms-full.ts +0 -82
- package/docs/lib/marketing-markdown.ts +0 -79
- package/docs/lib/marketing-site.ts +0 -31
- package/docs/lib/mdx.ts +0 -98
- package/docs/lib/navigation.ts +0 -288
- package/docs/lib/openapi-proxy.ts +0 -88
- package/docs/lib/openapi.ts +0 -158
- package/docs/lib/platform-config.ts +0 -6
- package/docs/lib/project-authz.ts +0 -46
- package/docs/lib/routes.ts +0 -103
- package/docs/lib/server-cache.ts +0 -83
- package/docs/lib/shiki.ts +0 -44
- package/docs/lib/supabase.ts +0 -37
- package/docs/lib/tenancy.ts +0 -364
- package/docs/lib/tenant-headers.ts +0 -43
- package/docs/lib/tenant-static.ts +0 -705
- package/docs/lib/tenant-utility-context.ts +0 -62
- package/docs/lib/tenants.ts +0 -72
- package/docs/lib/theme.ts +0 -29
- package/docs/lib/time-ago.ts +0 -24
- package/docs/lib/toc.ts +0 -2
- package/docs/lib/use-mobile.ts +0 -19
- package/docs/lib/use-tab-observer.ts +0 -71
- package/docs/lib/utils.ts +0 -5
- package/packages/@repo/common/dist/index.d.ts +0 -16
- package/packages/@repo/common/dist/index.d.ts.map +0 -1
- package/packages/@repo/common/dist/index.js +0 -84
- package/packages/@repo/common/package.json +0 -34
- package/packages/@repo/common/src/index.ts +0 -101
- package/packages/@repo/contracts/dist/analytics.d.ts +0 -21
- package/packages/@repo/contracts/dist/analytics.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/analytics.js +0 -18
- package/packages/@repo/contracts/dist/api-key.d.ts +0 -27
- package/packages/@repo/contracts/dist/api-key.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/api-key.js +0 -20
- package/packages/@repo/contracts/dist/dates.d.ts +0 -4
- package/packages/@repo/contracts/dist/dates.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/dates.js +0 -2
- package/packages/@repo/contracts/dist/deployment.d.ts +0 -71
- package/packages/@repo/contracts/dist/deployment.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/deployment.js +0 -46
- package/packages/@repo/contracts/dist/domain.d.ts +0 -94
- package/packages/@repo/contracts/dist/domain.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/domain.js +0 -36
- package/packages/@repo/contracts/dist/git.d.ts +0 -28
- package/packages/@repo/contracts/dist/git.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/git.js +0 -24
- package/packages/@repo/contracts/dist/ids.d.ts +0 -14
- package/packages/@repo/contracts/dist/ids.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/ids.js +0 -11
- package/packages/@repo/contracts/dist/index.d.ts +0 -12
- package/packages/@repo/contracts/dist/index.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/index.js +0 -13
- package/packages/@repo/contracts/dist/pagination.d.ts +0 -23
- package/packages/@repo/contracts/dist/pagination.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/pagination.js +0 -15
- package/packages/@repo/contracts/dist/project.d.ts +0 -42
- package/packages/@repo/contracts/dist/project.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/project.js +0 -25
- package/packages/@repo/contracts/dist/tenant.d.ts +0 -147
- package/packages/@repo/contracts/dist/tenant.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/tenant.js +0 -58
- package/packages/@repo/contracts/dist/user.d.ts +0 -9
- package/packages/@repo/contracts/dist/user.d.ts.map +0 -1
- package/packages/@repo/contracts/dist/user.js +0 -9
- package/packages/@repo/contracts/package.json +0 -37
- package/packages/@repo/contracts/src/analytics.ts +0 -33
- package/packages/@repo/contracts/src/api-key.ts +0 -27
- package/packages/@repo/contracts/src/dates.ts +0 -4
- package/packages/@repo/contracts/src/deployment.ts +0 -73
- package/packages/@repo/contracts/src/domain.ts +0 -51
- package/packages/@repo/contracts/src/git.ts +0 -31
- package/packages/@repo/contracts/src/ids.ts +0 -23
- package/packages/@repo/contracts/src/index.ts +0 -13
- package/packages/@repo/contracts/src/pagination.ts +0 -21
- package/packages/@repo/contracts/src/project.ts +0 -32
- package/packages/@repo/contracts/src/tenant.ts +0 -94
- package/packages/@repo/contracts/src/user.ts +0 -12
- package/packages/@repo/models/dist/docs-config.d.ts +0 -961
- package/packages/@repo/models/dist/docs-config.d.ts.map +0 -1
- package/packages/@repo/models/dist/docs-config.js +0 -531
- package/packages/@repo/models/dist/index.d.ts +0 -3
- package/packages/@repo/models/dist/index.d.ts.map +0 -1
- package/packages/@repo/models/dist/index.js +0 -3
- package/packages/@repo/models/dist/tenant.d.ts +0 -37
- package/packages/@repo/models/dist/tenant.d.ts.map +0 -1
- package/packages/@repo/models/dist/tenant.js +0 -1
- package/packages/@repo/models/package.json +0 -37
- package/packages/@repo/models/src/docs-config.ts +0 -629
- package/packages/@repo/models/src/index.ts +0 -3
- package/packages/@repo/models/src/tenant.ts +0 -44
- package/packages/@repo/prebuild/dist/index.d.ts +0 -2
- package/packages/@repo/prebuild/dist/index.d.ts.map +0 -1
- package/packages/@repo/prebuild/dist/index.js +0 -2
- package/packages/@repo/prebuild/dist/openapi.d.ts +0 -43
- package/packages/@repo/prebuild/dist/openapi.d.ts.map +0 -1
- package/packages/@repo/prebuild/dist/openapi.js +0 -86
- package/packages/@repo/prebuild/package.json +0 -39
- package/packages/@repo/prebuild/src/index.ts +0 -2
- package/packages/@repo/prebuild/src/openapi.ts +0 -154
- package/packages/@repo/previewing/dist/blob-source.d.ts +0 -16
- package/packages/@repo/previewing/dist/blob-source.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/blob-source.js +0 -128
- package/packages/@repo/previewing/dist/config-loader.d.ts +0 -134
- package/packages/@repo/previewing/dist/config-loader.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/config-loader.js +0 -231
- package/packages/@repo/previewing/dist/constants.d.ts +0 -15
- package/packages/@repo/previewing/dist/constants.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/constants.js +0 -14
- package/packages/@repo/previewing/dist/content-index.d.ts +0 -7
- package/packages/@repo/previewing/dist/content-index.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/content-index.js +0 -291
- package/packages/@repo/previewing/dist/content-source.d.ts +0 -12
- package/packages/@repo/previewing/dist/content-source.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/content-source.js +0 -1
- package/packages/@repo/previewing/dist/fs-source.d.ts +0 -11
- package/packages/@repo/previewing/dist/fs-source.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/fs-source.js +0 -71
- package/packages/@repo/previewing/dist/index.d.ts +0 -16
- package/packages/@repo/previewing/dist/index.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/index.js +0 -13
- package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts +0 -3
- package/packages/@repo/previewing/dist/markdown/agent-markdown.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/markdown/agent-markdown.js +0 -176
- package/packages/@repo/previewing/dist/markdown/format.d.ts +0 -8
- package/packages/@repo/previewing/dist/markdown/format.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/markdown/format.js +0 -43
- package/packages/@repo/previewing/dist/markdown/links.d.ts +0 -3
- package/packages/@repo/previewing/dist/markdown/links.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/markdown/links.js +0 -31
- package/packages/@repo/previewing/dist/openapi-pages.d.ts +0 -7
- package/packages/@repo/previewing/dist/openapi-pages.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/openapi-pages.js +0 -200
- package/packages/@repo/previewing/dist/search-index.d.ts +0 -4
- package/packages/@repo/previewing/dist/search-index.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/search-index.js +0 -23
- package/packages/@repo/previewing/dist/serialization.d.ts +0 -13
- package/packages/@repo/previewing/dist/serialization.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/serialization.js +0 -108
- package/packages/@repo/previewing/dist/toc-index.d.ts +0 -5
- package/packages/@repo/previewing/dist/toc-index.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/toc-index.js +0 -53
- package/packages/@repo/previewing/dist/types.d.ts +0 -92
- package/packages/@repo/previewing/dist/types.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/types.js +0 -1
- package/packages/@repo/previewing/dist/utility-index.d.ts +0 -7
- package/packages/@repo/previewing/dist/utility-index.d.ts.map +0 -1
- package/packages/@repo/previewing/dist/utility-index.js +0 -201
- package/packages/@repo/previewing/package.json +0 -41
- package/packages/@repo/previewing/src/blob-source.ts +0 -185
- package/packages/@repo/previewing/src/config-loader.ts +0 -316
- package/packages/@repo/previewing/src/constants.ts +0 -16
- package/packages/@repo/previewing/src/content-index.ts +0 -384
- package/packages/@repo/previewing/src/content-source.ts +0 -12
- package/packages/@repo/previewing/src/fs-source.ts +0 -103
- package/packages/@repo/previewing/src/index.ts +0 -71
- package/packages/@repo/previewing/src/markdown/agent-markdown.ts +0 -254
- package/packages/@repo/previewing/src/markdown/format.ts +0 -63
- package/packages/@repo/previewing/src/markdown/links.ts +0 -46
- package/packages/@repo/previewing/src/openapi-pages.ts +0 -319
- package/packages/@repo/previewing/src/search-index.ts +0 -38
- package/packages/@repo/previewing/src/serialization.ts +0 -191
- package/packages/@repo/previewing/src/toc-index.ts +0 -72
- package/packages/@repo/previewing/src/types.ts +0 -105
- package/packages/@repo/previewing/src/utility-index.ts +0 -304
- package/packages/@repo/validation/dist/index.d.ts +0 -12
- package/packages/@repo/validation/dist/index.d.ts.map +0 -1
- package/packages/@repo/validation/dist/index.js +0 -30
- package/packages/@repo/validation/package.json +0 -38
- package/packages/@repo/validation/src/blodemd-docs-schema.json +0 -3575
- package/packages/@repo/validation/src/index.ts +0 -59
- package/scripts/prepare-package.mjs +0 -53
- package/scripts/repo-packages.mjs +0 -8
package/docs/lib/server-cache.ts
DELETED
|
@@ -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
|
-
};
|
package/docs/lib/supabase.ts
DELETED
|
@@ -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
|
-
});
|
package/docs/lib/tenancy.ts
DELETED
|
@@ -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
|
-
};
|