blodemd 0.0.6 → 0.0.7
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/README.md +2 -2
- package/dev-server/app/favicon.ico +0 -0
- package/dev-server/next-env.d.ts +5 -0
- package/dev-server/package.json +1 -1
- package/dev-server/tsconfig.json +3 -2
- package/dist/cli.mjs +209 -53
- package/dist/cli.mjs.map +1 -1
- package/docs/app/globals.css +4 -2
- package/docs/components/docs/doc-header.tsx +35 -17
- package/docs/components/docs/doc-shell.tsx +46 -22
- package/docs/components/docs/doc-sidebar.tsx +13 -8
- package/docs/components/docs/mobile-nav.tsx +150 -152
- package/docs/components/icons/doc-icon.tsx +96 -0
- package/docs/components/mdx/card.tsx +60 -54
- package/docs/components/mdx/icon.tsx +2 -46
- package/docs/components/mdx/index.tsx +12 -1
- package/docs/components/mdx/tree.tsx +7 -7
- package/docs/components/ui/search.tsx +11 -7
- package/docs/lib/mdx.ts +2 -5
- package/docs/lib/navigation.ts +2 -2
- package/docs/lib/routes.ts +34 -0
- package/docs/lib/shiki.ts +6 -1
- package/package.json +13 -5
- package/packages/@repo/contracts/dist/tenant.d.ts +12 -0
- package/packages/@repo/contracts/dist/tenant.d.ts.map +1 -1
- package/packages/@repo/contracts/dist/tenant.js +20 -0
- package/packages/@repo/contracts/src/tenant.ts +38 -0
- package/packages/@repo/previewing/dist/fs-source.d.ts.map +1 -1
- package/packages/@repo/previewing/dist/fs-source.js +1 -8
- package/packages/@repo/previewing/src/fs-source.ts +1 -8
- package/packages/@repo/validation/src/mintlify-docs-schema.json +1 -1
- package/scripts/prepare-package.mjs +39 -0
- package/packages/@repo/common/src/common.unit.test.ts +0 -55
- package/packages/@repo/previewing/src/index.unit.test.ts +0 -290
|
@@ -2,6 +2,7 @@ import Image from "next/image";
|
|
|
2
2
|
import Link from "next/link";
|
|
3
3
|
import type { ReactNode } from "react";
|
|
4
4
|
|
|
5
|
+
import { DocIcon } from "@/components/icons/doc-icon";
|
|
5
6
|
import { cn } from "@/lib/utils";
|
|
6
7
|
|
|
7
8
|
interface CardProps {
|
|
@@ -24,65 +25,70 @@ const CardInner = ({
|
|
|
24
25
|
cta,
|
|
25
26
|
href,
|
|
26
27
|
children,
|
|
27
|
-
}: CardProps) =>
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
style={color ? { color } : undefined}
|
|
51
|
-
>
|
|
52
|
-
{icon}
|
|
53
|
-
</div>
|
|
54
|
-
) : null}
|
|
55
|
-
<div className="min-w-0 flex-1">
|
|
56
|
-
{title ? (
|
|
57
|
-
<div className="mb-1 font-medium text-foreground">{title}</div>
|
|
28
|
+
}: CardProps) => {
|
|
29
|
+
const resolvedIcon =
|
|
30
|
+
typeof icon === "string" ? <DocIcon icon={icon} size={18} /> : icon;
|
|
31
|
+
|
|
32
|
+
return (
|
|
33
|
+
<div
|
|
34
|
+
className={cn(
|
|
35
|
+
"group/card rounded-xl border border-border bg-card p-4 transition-colors",
|
|
36
|
+
href && "hover:border-primary/30 hover:bg-accent/50",
|
|
37
|
+
horizontal && "flex items-start gap-4"
|
|
38
|
+
)}
|
|
39
|
+
>
|
|
40
|
+
{img && !horizontal ? (
|
|
41
|
+
<div className="relative mb-3 aspect-video overflow-hidden rounded-lg">
|
|
42
|
+
<Image
|
|
43
|
+
alt={title ?? ""}
|
|
44
|
+
className="object-cover"
|
|
45
|
+
fill
|
|
46
|
+
sizes="(max-width: 768px) 100vw, 50vw"
|
|
47
|
+
src={img}
|
|
48
|
+
unoptimized
|
|
49
|
+
/>
|
|
50
|
+
</div>
|
|
58
51
|
) : null}
|
|
59
|
-
{
|
|
60
|
-
<div
|
|
61
|
-
|
|
52
|
+
{resolvedIcon ? (
|
|
53
|
+
<div
|
|
54
|
+
className="mb-3 flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted text-muted-foreground"
|
|
55
|
+
style={color ? { color } : undefined}
|
|
56
|
+
>
|
|
57
|
+
{resolvedIcon}
|
|
62
58
|
</div>
|
|
63
59
|
) : null}
|
|
64
|
-
|
|
65
|
-
|
|
60
|
+
<div className="min-w-0 flex-1">
|
|
61
|
+
{title ? (
|
|
62
|
+
<div className="mb-1 font-medium text-foreground">{title}</div>
|
|
63
|
+
) : null}
|
|
64
|
+
{children ? (
|
|
65
|
+
<div className="text-sm text-muted-foreground [&>p:first-child]:mt-0 [&>p:last-child]:mb-0">
|
|
66
|
+
{children}
|
|
67
|
+
</div>
|
|
68
|
+
) : null}
|
|
69
|
+
{cta ? (
|
|
70
|
+
<div className="mt-2 text-sm font-medium text-primary">{cta}</div>
|
|
71
|
+
) : null}
|
|
72
|
+
</div>
|
|
73
|
+
{href ? (
|
|
74
|
+
<svg
|
|
75
|
+
aria-hidden
|
|
76
|
+
className="mt-0.5 size-4 shrink-0 text-muted-foreground transition-transform group-hover/card:translate-x-0.5"
|
|
77
|
+
fill="none"
|
|
78
|
+
stroke="currentColor"
|
|
79
|
+
strokeWidth={2}
|
|
80
|
+
viewBox="0 0 24 24"
|
|
81
|
+
>
|
|
82
|
+
<path
|
|
83
|
+
d="M5 12h14M12 5l7 7-7 7"
|
|
84
|
+
strokeLinecap="round"
|
|
85
|
+
strokeLinejoin="round"
|
|
86
|
+
/>
|
|
87
|
+
</svg>
|
|
66
88
|
) : null}
|
|
67
89
|
</div>
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
aria-hidden
|
|
71
|
-
className="mt-0.5 size-4 shrink-0 text-muted-foreground transition-transform group-hover/card:translate-x-0.5"
|
|
72
|
-
fill="none"
|
|
73
|
-
stroke="currentColor"
|
|
74
|
-
strokeWidth={2}
|
|
75
|
-
viewBox="0 0 24 24"
|
|
76
|
-
>
|
|
77
|
-
<path
|
|
78
|
-
d="M5 12h14M12 5l7 7-7 7"
|
|
79
|
-
strokeLinecap="round"
|
|
80
|
-
strokeLinejoin="round"
|
|
81
|
-
/>
|
|
82
|
-
</svg>
|
|
83
|
-
) : null}
|
|
84
|
-
</div>
|
|
85
|
-
);
|
|
90
|
+
);
|
|
91
|
+
};
|
|
86
92
|
|
|
87
93
|
export const Card = (props: CardProps) => {
|
|
88
94
|
if (props.href) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DocIcon } from "@/components/icons/doc-icon";
|
|
2
2
|
|
|
3
3
|
interface IconProps {
|
|
4
4
|
icon: string;
|
|
@@ -8,49 +8,5 @@ interface IconProps {
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
export const Icon = ({ icon, color, size = 16, className }: IconProps) => (
|
|
11
|
-
<
|
|
12
|
-
aria-hidden
|
|
13
|
-
className={cn("inline-flex items-center justify-center", className)}
|
|
14
|
-
style={{
|
|
15
|
-
color: color ?? undefined,
|
|
16
|
-
height: size,
|
|
17
|
-
width: size,
|
|
18
|
-
}}
|
|
19
|
-
>
|
|
20
|
-
<svg
|
|
21
|
-
className="size-full"
|
|
22
|
-
fill="none"
|
|
23
|
-
stroke="currentColor"
|
|
24
|
-
strokeLinecap="round"
|
|
25
|
-
strokeLinejoin="round"
|
|
26
|
-
strokeWidth={2}
|
|
27
|
-
viewBox="0 0 24 24"
|
|
28
|
-
>
|
|
29
|
-
<title>{icon}</title>
|
|
30
|
-
{icon === "flag" && (
|
|
31
|
-
<path d="M4 15s1-1 4-1 5 2 8 2 4-1 4-1V3s-1 1-4 1-5-2-8-2-4 1-4 1zM4 22v-7" />
|
|
32
|
-
)}
|
|
33
|
-
{icon === "check" && <path d="M20 6 9 17l-5-5" />}
|
|
34
|
-
{icon === "star" && (
|
|
35
|
-
<path d="m12 2 3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01z" />
|
|
36
|
-
)}
|
|
37
|
-
{icon === "info" && (
|
|
38
|
-
<>
|
|
39
|
-
<circle cx="12" cy="12" r="10" />
|
|
40
|
-
<path d="M12 16v-4M12 8h.01" />
|
|
41
|
-
</>
|
|
42
|
-
)}
|
|
43
|
-
{icon === "alert-triangle" && (
|
|
44
|
-
<path d="m21.73 18-8-14a2 2 0 0 0-3.48 0l-8 14A2 2 0 0 0 4 21h16a2 2 0 0 0 1.73-3M12 9v4M12 17h.01" />
|
|
45
|
-
)}
|
|
46
|
-
{icon === "arrow-right" && <path d="M5 12h14M12 5l7 7-7 7" />}
|
|
47
|
-
{icon === "external-link" && (
|
|
48
|
-
<>
|
|
49
|
-
<path d="M15 3h6v6" />
|
|
50
|
-
<path d="M10 14 21 3" />
|
|
51
|
-
<path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6" />
|
|
52
|
-
</>
|
|
53
|
-
)}
|
|
54
|
-
</svg>
|
|
55
|
-
</span>
|
|
11
|
+
<DocIcon className={className} color={color} icon={icon} size={size} />
|
|
56
12
|
);
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { MDXComponents } from "mdx/types";
|
|
2
2
|
import Link from "next/link";
|
|
3
|
+
import type { ComponentProps } from "react";
|
|
3
4
|
|
|
4
5
|
import { Accordion, AccordionGroup } from "./accordion";
|
|
5
6
|
import { Badge } from "./badge";
|
|
@@ -23,12 +24,22 @@ import { Step, Steps } from "./steps";
|
|
|
23
24
|
import { Tab, Tabs } from "./tabs";
|
|
24
25
|
import { Tile } from "./tile";
|
|
25
26
|
import { Tooltip } from "./tooltip";
|
|
26
|
-
import { Tree } from "./tree";
|
|
27
|
+
import { Tree as TreeRoot, TreeFile, TreeFolder } from "./tree";
|
|
27
28
|
import { TypeTable } from "./type-table";
|
|
28
29
|
import { Update } from "./update";
|
|
29
30
|
import { Video } from "./video";
|
|
30
31
|
import { View, ViewGroup } from "./view";
|
|
31
32
|
|
|
33
|
+
// Rebuild dotted MDX exports in the server module so Next's client references
|
|
34
|
+
// still expose `Tree.Folder` and `Tree.File` during MDX evaluation.
|
|
35
|
+
const Tree = Object.assign(
|
|
36
|
+
(props: ComponentProps<typeof TreeRoot>) => <TreeRoot {...props} />,
|
|
37
|
+
{
|
|
38
|
+
File: TreeFile,
|
|
39
|
+
Folder: TreeFolder,
|
|
40
|
+
}
|
|
41
|
+
);
|
|
42
|
+
|
|
32
43
|
const MdxLink = ({
|
|
33
44
|
href,
|
|
34
45
|
children,
|
|
@@ -9,7 +9,7 @@ interface TreeFileProps {
|
|
|
9
9
|
name: string;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
-
const TreeFile = ({ name }: TreeFileProps) => (
|
|
12
|
+
export const TreeFile = ({ name }: TreeFileProps) => (
|
|
13
13
|
<div className="flex items-center gap-2 py-0.5 pl-5 text-sm">
|
|
14
14
|
<svg
|
|
15
15
|
aria-hidden
|
|
@@ -41,7 +41,7 @@ interface TreeFolderProps {
|
|
|
41
41
|
children?: ReactNode;
|
|
42
42
|
}
|
|
43
43
|
|
|
44
|
-
const TreeFolder = ({
|
|
44
|
+
export const TreeFolder = ({
|
|
45
45
|
name,
|
|
46
46
|
defaultOpen = false,
|
|
47
47
|
openable = true,
|
|
@@ -108,13 +108,13 @@ const TreeFolder = ({
|
|
|
108
108
|
);
|
|
109
109
|
};
|
|
110
110
|
|
|
111
|
-
const
|
|
111
|
+
const TreeRoot = ({ children }: { children: ReactNode }) => (
|
|
112
112
|
<div className="my-4 rounded-xl border border-border bg-card p-4 font-mono text-sm">
|
|
113
113
|
{children}
|
|
114
114
|
</div>
|
|
115
115
|
);
|
|
116
116
|
|
|
117
|
-
Tree
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
117
|
+
export const Tree = Object.assign(TreeRoot, {
|
|
118
|
+
File: TreeFile,
|
|
119
|
+
Folder: TreeFolder,
|
|
120
|
+
});
|
|
@@ -17,7 +17,7 @@ import type {
|
|
|
17
17
|
MouseEvent as ReactMouseEvent,
|
|
18
18
|
} from "react";
|
|
19
19
|
|
|
20
|
-
import { toDocHref } from "@/lib/routes";
|
|
20
|
+
import { isExternalHref, resolveHref, toDocHref } from "@/lib/routes";
|
|
21
21
|
|
|
22
22
|
export interface SearchItem {
|
|
23
23
|
href?: string;
|
|
@@ -134,11 +134,14 @@ export const Search = ({ basePath }: { basePath: string }) => {
|
|
|
134
134
|
const runSelection = useCallback(
|
|
135
135
|
(item: SearchItem) => {
|
|
136
136
|
closeSearch();
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
const href = item.href
|
|
138
|
+
? resolveHref(item.href, basePath)
|
|
139
|
+
: toDocHref(item.path, basePath);
|
|
140
|
+
if (item.href && isExternalHref(item.href)) {
|
|
141
|
+
window.open(href, "_blank", "noopener,noreferrer");
|
|
139
142
|
return;
|
|
140
143
|
}
|
|
141
|
-
router.push(
|
|
144
|
+
router.push(href);
|
|
142
145
|
},
|
|
143
146
|
[basePath, closeSearch, router]
|
|
144
147
|
);
|
|
@@ -346,6 +349,9 @@ export const Search = ({ basePath }: { basePath: string }) => {
|
|
|
346
349
|
<div className="grid gap-1">
|
|
347
350
|
{filteredItems.map((item, index) => {
|
|
348
351
|
const isActive = index === activeIndex;
|
|
352
|
+
const href = item.href
|
|
353
|
+
? resolveHref(item.href, basePath)
|
|
354
|
+
: toDocHref(item.path, basePath);
|
|
349
355
|
|
|
350
356
|
return (
|
|
351
357
|
<button
|
|
@@ -363,9 +369,7 @@ export const Search = ({ basePath }: { basePath: string }) => {
|
|
|
363
369
|
<span className="text-sm font-medium text-foreground">
|
|
364
370
|
{item.title}
|
|
365
371
|
</span>
|
|
366
|
-
<span className="text-xs">
|
|
367
|
-
{item.href ?? toDocHref(item.path, basePath)}
|
|
368
|
-
</span>
|
|
372
|
+
<span className="text-xs">{href}</span>
|
|
369
373
|
</button>
|
|
370
374
|
);
|
|
371
375
|
})}
|
package/docs/lib/mdx.ts
CHANGED
|
@@ -10,7 +10,7 @@ import remarkGfm from "remark-gfm";
|
|
|
10
10
|
|
|
11
11
|
import { mdxComponents } from "@/components/mdx";
|
|
12
12
|
|
|
13
|
-
import { getHighlighter } from "./shiki";
|
|
13
|
+
import { getHighlighter, SHIKI_THEME_PAIR } from "./shiki";
|
|
14
14
|
|
|
15
15
|
const FRONTMATTER_REGEX = /^---\s*\n[\s\S]*?\n---\s*\n?/;
|
|
16
16
|
|
|
@@ -49,10 +49,7 @@ export const renderMdx = async (source: string) => {
|
|
|
49
49
|
const highlighter = await getHighlighter();
|
|
50
50
|
const shikiTransformer = rehypeShikiFromHighlighter(highlighter, {
|
|
51
51
|
defaultColor: false,
|
|
52
|
-
themes:
|
|
53
|
-
dark: "github-dark",
|
|
54
|
-
light: "github-light",
|
|
55
|
-
},
|
|
52
|
+
themes: SHIKI_THEME_PAIR,
|
|
56
53
|
});
|
|
57
54
|
const shikiPlugin = () => shikiTransformer;
|
|
58
55
|
|
package/docs/lib/navigation.ts
CHANGED
|
@@ -3,7 +3,7 @@ import type { DocsNavigation } from "@repo/models";
|
|
|
3
3
|
import type { PageMetadata } from "@repo/previewing";
|
|
4
4
|
|
|
5
5
|
import type { OpenApiRegistry } from "./openapi";
|
|
6
|
-
import { toDocHref } from "./routes";
|
|
6
|
+
import { resolveHref, toDocHref } from "./routes";
|
|
7
7
|
|
|
8
8
|
export interface NavPage {
|
|
9
9
|
type: "page";
|
|
@@ -35,7 +35,7 @@ export const getNavPageTitle = (page: NavPage): string =>
|
|
|
35
35
|
page.sidebarTitle ?? page.title;
|
|
36
36
|
|
|
37
37
|
export const getNavPageHref = (page: NavPage, basePath: string): string =>
|
|
38
|
-
page.url
|
|
38
|
+
page.url ? resolveHref(page.url, basePath) : toDocHref(page.path, basePath);
|
|
39
39
|
|
|
40
40
|
const titleFromSlug = (slug: string) => {
|
|
41
41
|
const clean = slug.replaceAll("-", " ").split("/").pop() ?? slug;
|
package/docs/lib/routes.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { normalizePath, withLeadingSlash } from "@repo/common";
|
|
2
2
|
|
|
3
|
+
const ABSOLUTE_URL_REGEX = /^[a-z][a-z\d+.-]*:/i;
|
|
4
|
+
|
|
3
5
|
export const toDocHref = (path: string, basePath = "") => {
|
|
4
6
|
const clean = normalizePath(path);
|
|
5
7
|
const base = basePath ? withLeadingSlash(basePath) : "";
|
|
@@ -8,3 +10,35 @@ export const toDocHref = (path: string, basePath = "") => {
|
|
|
8
10
|
}
|
|
9
11
|
return `${base}/${clean}`.replaceAll(/\/+/g, "/");
|
|
10
12
|
};
|
|
13
|
+
|
|
14
|
+
export const isExternalHref = (href: string) =>
|
|
15
|
+
ABSOLUTE_URL_REGEX.test(href) || href.startsWith("//");
|
|
16
|
+
|
|
17
|
+
export const resolveHref = (href: string, basePath = "") => {
|
|
18
|
+
if (
|
|
19
|
+
!href ||
|
|
20
|
+
href.startsWith("#") ||
|
|
21
|
+
href.startsWith("?") ||
|
|
22
|
+
isExternalHref(href)
|
|
23
|
+
) {
|
|
24
|
+
return href;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
const suffixIndex = href.search(/[?#]/);
|
|
28
|
+
const pathPart = suffixIndex === -1 ? href : href.slice(0, suffixIndex);
|
|
29
|
+
const suffix = suffixIndex === -1 ? "" : href.slice(suffixIndex);
|
|
30
|
+
const normalizedBase = basePath
|
|
31
|
+
? withLeadingSlash(basePath).replaceAll(/\/+$/g, "")
|
|
32
|
+
: "";
|
|
33
|
+
const normalizedPath = withLeadingSlash(pathPart || "/");
|
|
34
|
+
|
|
35
|
+
if (
|
|
36
|
+
normalizedBase &&
|
|
37
|
+
(normalizedPath === normalizedBase ||
|
|
38
|
+
normalizedPath.startsWith(`${normalizedBase}/`))
|
|
39
|
+
) {
|
|
40
|
+
return `${normalizedPath}${suffix}`;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
return `${toDocHref(pathPart || "index", basePath)}${suffix}`;
|
|
44
|
+
};
|
package/docs/lib/shiki.ts
CHANGED
|
@@ -20,7 +20,12 @@ const COMMON_LANGS = [
|
|
|
20
20
|
"yaml",
|
|
21
21
|
] as const;
|
|
22
22
|
|
|
23
|
-
const
|
|
23
|
+
export const SHIKI_THEME_PAIR = {
|
|
24
|
+
dark: "github-dark",
|
|
25
|
+
light: "github-light",
|
|
26
|
+
} as const;
|
|
27
|
+
|
|
28
|
+
const THEMES = [SHIKI_THEME_PAIR.dark, SHIKI_THEME_PAIR.light] as const;
|
|
24
29
|
|
|
25
30
|
let highlighterPromise: ReturnType<typeof createHighlighter> | null = null;
|
|
26
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "blodemd",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.7",
|
|
4
4
|
"description": "Blode.md CLI",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"dist",
|
|
14
14
|
"dev-server",
|
|
15
15
|
"docs",
|
|
16
|
-
"packages"
|
|
16
|
+
"packages",
|
|
17
|
+
"scripts/prepare-package.mjs"
|
|
17
18
|
],
|
|
18
19
|
"type": "module",
|
|
19
20
|
"main": "./dist/index.mjs",
|
|
@@ -27,12 +28,13 @@
|
|
|
27
28
|
},
|
|
28
29
|
"scripts": {
|
|
29
30
|
"build": "tsdown",
|
|
30
|
-
"
|
|
31
|
+
"prepare": "node scripts/prepare-package.mjs",
|
|
31
32
|
"check-types": "tsc --noEmit -p tsconfig.json",
|
|
32
33
|
"lint": "oxlint .",
|
|
33
34
|
"lint:fix": "oxlint --fix .",
|
|
34
35
|
"format": "oxfmt --write .",
|
|
35
|
-
"format:check": "oxfmt ."
|
|
36
|
+
"format:check": "oxfmt .",
|
|
37
|
+
"test:unit": "vitest run --root ../.. --config vitest.unit.config.ts apps/cli/src"
|
|
36
38
|
},
|
|
37
39
|
"dependencies": {
|
|
38
40
|
"@base-ui/react": "^1.3.0",
|
|
@@ -40,6 +42,9 @@
|
|
|
40
42
|
"@mdx-js/mdx": "^3.1.1",
|
|
41
43
|
"@shikijs/rehype": "^4.0.2",
|
|
42
44
|
"@tailwindcss/postcss": "^4.2.2",
|
|
45
|
+
"@types/node": "^22.19.15",
|
|
46
|
+
"@types/react": "19.2.14",
|
|
47
|
+
"@types/react-dom": "19.2.3",
|
|
43
48
|
"blode-icons-react": "^0.3.10",
|
|
44
49
|
"chalk": "^5.6.2",
|
|
45
50
|
"chokidar": "^4.0.3",
|
|
@@ -63,16 +68,19 @@
|
|
|
63
68
|
"tailwind-merge": "^3.5.0",
|
|
64
69
|
"tailwindcss": "^4.2.2",
|
|
65
70
|
"tw-animate-css": "^1.4.0",
|
|
71
|
+
"typescript": "6.0.2",
|
|
66
72
|
"yaml": "^2.8.3",
|
|
67
73
|
"zod": "^4.3.6"
|
|
68
74
|
},
|
|
69
75
|
"devDependencies": {
|
|
70
76
|
"@repo/previewing": "*",
|
|
71
77
|
"@repo/typescript-config": "*",
|
|
72
|
-
"@types/node": "^22.15.3",
|
|
73
78
|
"oxfmt": "^0.42.0",
|
|
74
79
|
"oxlint": "^1.57.0",
|
|
75
80
|
"tsdown": "^0.21.5",
|
|
76
81
|
"ultracite": "^7.3.2"
|
|
82
|
+
},
|
|
83
|
+
"engines": {
|
|
84
|
+
"node": ">=20.17.0 <25"
|
|
77
85
|
}
|
|
78
86
|
}
|
|
@@ -96,4 +96,16 @@ export declare const TenantEdgeSlugRecordSchema: z.ZodObject<{
|
|
|
96
96
|
version: z.ZodLiteral<1>;
|
|
97
97
|
}, z.core.$strip>;
|
|
98
98
|
export type TenantEdgeSlugRecord = z.infer<typeof TenantEdgeSlugRecordSchema>;
|
|
99
|
+
export declare const TENANT_EDGE_HOST_KEY_PREFIX = "th_";
|
|
100
|
+
export declare const TENANT_EDGE_SLUG_KEY_PREFIX = "ts_";
|
|
101
|
+
export declare const LEGACY_TENANT_EDGE_HOST_KEY_PREFIX = "tenant:host:";
|
|
102
|
+
export declare const LEGACY_TENANT_EDGE_SLUG_KEY_PREFIX = "tenant:slug:";
|
|
103
|
+
export declare const normalizeTenantEdgeHost: (host: string) => string;
|
|
104
|
+
export declare const normalizeTenantEdgeSlug: (slug: string) => string;
|
|
105
|
+
export declare const getTenantEdgeHostKey: (host: string) => string;
|
|
106
|
+
export declare const getTenantEdgeSlugKey: (slug: string) => string;
|
|
107
|
+
export declare const getLegacyTenantEdgeHostKey: (host: string) => string;
|
|
108
|
+
export declare const getLegacyTenantEdgeSlugKey: (slug: string) => string;
|
|
109
|
+
export declare const getTenantEdgeHostKeys: (host: string) => string[];
|
|
110
|
+
export declare const getTenantEdgeSlugKeys: (slug: string) => string[];
|
|
99
111
|
//# sourceMappingURL=tenant.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,kBAAkB;;;EAAiC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;iBAYvB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;iBAMrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
1
|
+
{"version":3,"file":"tenant.d.ts","sourceRoot":"","sources":["../src/tenant.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAUxB,eAAO,MAAM,kBAAkB;;;EAAiC,CAAC;AACjE,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;iBAYvB,CAAC;AACH,MAAM,MAAM,MAAM,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,YAAY,CAAC,CAAC;AAElD,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;;;;;;;;;;;;iBAMjC,CAAC;AACH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAItE,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;iBAMrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;iBAIrC,CAAC;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,2BAA2B,QAAQ,CAAC;AACjD,eAAO,MAAM,2BAA2B,QAAQ,CAAC;AACjD,eAAO,MAAM,kCAAkC,iBAAiB,CAAC;AACjE,eAAO,MAAM,kCAAkC,iBAAiB,CAAC;AAEjE,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,WACJ,CAAC;AAEjD,eAAO,MAAM,uBAAuB,GAAI,MAAM,MAAM,WACzB,CAAC;AAO5B,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,WACc,CAAC;AAEhE,eAAO,MAAM,oBAAoB,GAAI,MAAM,MAAM,WACc,CAAC;AAEhE,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,WACkB,CAAC;AAE1E,eAAO,MAAM,0BAA0B,GAAI,MAAM,MAAM,WACkB,CAAC;AAE1E,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,aAGjD,CAAC;AAEF,eAAO,MAAM,qBAAqB,GAAI,MAAM,MAAM,aAGjD,CAAC"}
|
|
@@ -34,3 +34,23 @@ export const TenantEdgeSlugRecordSchema = z.object({
|
|
|
34
34
|
tenant: TenantSchema,
|
|
35
35
|
version: TenantEdgeRecordVersionSchema,
|
|
36
36
|
});
|
|
37
|
+
export const TENANT_EDGE_HOST_KEY_PREFIX = "th_";
|
|
38
|
+
export const TENANT_EDGE_SLUG_KEY_PREFIX = "ts_";
|
|
39
|
+
export const LEGACY_TENANT_EDGE_HOST_KEY_PREFIX = "tenant:host:";
|
|
40
|
+
export const LEGACY_TENANT_EDGE_SLUG_KEY_PREFIX = "tenant:slug:";
|
|
41
|
+
export const normalizeTenantEdgeHost = (host) => host.trim().toLowerCase().replace(/:\d+$/, "");
|
|
42
|
+
export const normalizeTenantEdgeSlug = (slug) => slug.trim().toLowerCase();
|
|
43
|
+
const encodeTenantEdgeHost = (host) => normalizeTenantEdgeHost(host).replaceAll(".", "_");
|
|
44
|
+
const encodeTenantEdgeSlug = (slug) => normalizeTenantEdgeSlug(slug);
|
|
45
|
+
export const getTenantEdgeHostKey = (host) => `${TENANT_EDGE_HOST_KEY_PREFIX}${encodeTenantEdgeHost(host)}`;
|
|
46
|
+
export const getTenantEdgeSlugKey = (slug) => `${TENANT_EDGE_SLUG_KEY_PREFIX}${encodeTenantEdgeSlug(slug)}`;
|
|
47
|
+
export const getLegacyTenantEdgeHostKey = (host) => `${LEGACY_TENANT_EDGE_HOST_KEY_PREFIX}${normalizeTenantEdgeHost(host)}`;
|
|
48
|
+
export const getLegacyTenantEdgeSlugKey = (slug) => `${LEGACY_TENANT_EDGE_SLUG_KEY_PREFIX}${normalizeTenantEdgeSlug(slug)}`;
|
|
49
|
+
export const getTenantEdgeHostKeys = (host) => [
|
|
50
|
+
getTenantEdgeHostKey(host),
|
|
51
|
+
getLegacyTenantEdgeHostKey(host),
|
|
52
|
+
];
|
|
53
|
+
export const getTenantEdgeSlugKeys = (slug) => [
|
|
54
|
+
getTenantEdgeSlugKey(slug),
|
|
55
|
+
getLegacyTenantEdgeSlugKey(slug),
|
|
56
|
+
];
|
|
@@ -52,3 +52,41 @@ export const TenantEdgeSlugRecordSchema = z.object({
|
|
|
52
52
|
version: TenantEdgeRecordVersionSchema,
|
|
53
53
|
});
|
|
54
54
|
export type TenantEdgeSlugRecord = z.infer<typeof TenantEdgeSlugRecordSchema>;
|
|
55
|
+
|
|
56
|
+
export const TENANT_EDGE_HOST_KEY_PREFIX = "th_";
|
|
57
|
+
export const TENANT_EDGE_SLUG_KEY_PREFIX = "ts_";
|
|
58
|
+
export const LEGACY_TENANT_EDGE_HOST_KEY_PREFIX = "tenant:host:";
|
|
59
|
+
export const LEGACY_TENANT_EDGE_SLUG_KEY_PREFIX = "tenant:slug:";
|
|
60
|
+
|
|
61
|
+
export const normalizeTenantEdgeHost = (host: string) =>
|
|
62
|
+
host.trim().toLowerCase().replace(/:\d+$/, "");
|
|
63
|
+
|
|
64
|
+
export const normalizeTenantEdgeSlug = (slug: string) =>
|
|
65
|
+
slug.trim().toLowerCase();
|
|
66
|
+
|
|
67
|
+
const encodeTenantEdgeHost = (host: string) =>
|
|
68
|
+
normalizeTenantEdgeHost(host).replaceAll(".", "_");
|
|
69
|
+
|
|
70
|
+
const encodeTenantEdgeSlug = (slug: string) => normalizeTenantEdgeSlug(slug);
|
|
71
|
+
|
|
72
|
+
export const getTenantEdgeHostKey = (host: string) =>
|
|
73
|
+
`${TENANT_EDGE_HOST_KEY_PREFIX}${encodeTenantEdgeHost(host)}`;
|
|
74
|
+
|
|
75
|
+
export const getTenantEdgeSlugKey = (slug: string) =>
|
|
76
|
+
`${TENANT_EDGE_SLUG_KEY_PREFIX}${encodeTenantEdgeSlug(slug)}`;
|
|
77
|
+
|
|
78
|
+
export const getLegacyTenantEdgeHostKey = (host: string) =>
|
|
79
|
+
`${LEGACY_TENANT_EDGE_HOST_KEY_PREFIX}${normalizeTenantEdgeHost(host)}`;
|
|
80
|
+
|
|
81
|
+
export const getLegacyTenantEdgeSlugKey = (slug: string) =>
|
|
82
|
+
`${LEGACY_TENANT_EDGE_SLUG_KEY_PREFIX}${normalizeTenantEdgeSlug(slug)}`;
|
|
83
|
+
|
|
84
|
+
export const getTenantEdgeHostKeys = (host: string) => [
|
|
85
|
+
getTenantEdgeHostKey(host),
|
|
86
|
+
getLegacyTenantEdgeHostKey(host),
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
export const getTenantEdgeSlugKeys = (slug: string) => [
|
|
90
|
+
getTenantEdgeSlugKey(slug),
|
|
91
|
+
getLegacyTenantEdgeSlugKey(slug),
|
|
92
|
+
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fs-source.d.ts","sourceRoot":"","sources":["../src/fs-source.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"fs-source.d.ts","sourceRoot":"","sources":["../src/fs-source.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AA6DzD,qBAAa,eAAgB,YAAW,aAAa;IACnD,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAS;gBAElB,IAAI,EAAE,MAAM;IAIlB,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO/C,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAI/C,MAAM,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAapD,UAAU,IAAI,MAAM,GAAG,IAAI;CAG5B;AAED,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,aACnB,CAAC"}
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs/promises";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { normalizePath } from "@repo/common";
|
|
4
|
-
const IGNORED_DIRECTORIES = new Set([
|
|
5
|
-
"app",
|
|
6
|
-
"components",
|
|
7
|
-
"content",
|
|
8
|
-
"lib",
|
|
9
|
-
"node_modules",
|
|
10
|
-
"public",
|
|
11
|
-
]);
|
|
4
|
+
const IGNORED_DIRECTORIES = new Set(["app", "lib", "node_modules", "public"]);
|
|
12
5
|
const IGNORED_ROOT_FILES = new Set(["AGENTS.md", "README.md"]);
|
|
13
6
|
const isNotFoundError = (error) => Boolean(error &&
|
|
14
7
|
typeof error === "object" &&
|
|
@@ -5,14 +5,7 @@ import { normalizePath } from "@repo/common";
|
|
|
5
5
|
|
|
6
6
|
import type { ContentSource } from "./content-source.js";
|
|
7
7
|
|
|
8
|
-
const IGNORED_DIRECTORIES = new Set([
|
|
9
|
-
"app",
|
|
10
|
-
"components",
|
|
11
|
-
"content",
|
|
12
|
-
"lib",
|
|
13
|
-
"node_modules",
|
|
14
|
-
"public",
|
|
15
|
-
]);
|
|
8
|
+
const IGNORED_DIRECTORIES = new Set(["app", "lib", "node_modules", "public"]);
|
|
16
9
|
const IGNORED_ROOT_FILES = new Set(["AGENTS.md", "README.md"]);
|
|
17
10
|
|
|
18
11
|
const isNotFoundError = (error: unknown) =>
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { execSync } from "node:child_process";
|
|
4
|
+
import { existsSync } from "node:fs";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import { fileURLToPath } from "node:url";
|
|
7
|
+
|
|
8
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
9
|
+
const cliRoot = path.resolve(__dirname, "..");
|
|
10
|
+
const repoRoot = path.resolve(cliRoot, "../..");
|
|
11
|
+
|
|
12
|
+
const command = process.env.npm_command;
|
|
13
|
+
const isGlobalInstall = process.env.npm_config_global === "true";
|
|
14
|
+
const shouldPackage = command === "pack" || command === "publish";
|
|
15
|
+
|
|
16
|
+
const hasRepoSources =
|
|
17
|
+
existsSync(path.join(repoRoot, "apps", "dev-server")) &&
|
|
18
|
+
existsSync(path.join(repoRoot, "packages", "previewing"));
|
|
19
|
+
|
|
20
|
+
if (!hasRepoSources) {
|
|
21
|
+
console.log("Skipping standalone package preparation outside the monorepo.");
|
|
22
|
+
process.exit(0);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
if (!shouldPackage && !isGlobalInstall) {
|
|
26
|
+
process.exit(0);
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log("Preparing blodemd standalone package...");
|
|
30
|
+
|
|
31
|
+
execSync("npm run build", {
|
|
32
|
+
cwd: cliRoot,
|
|
33
|
+
stdio: "inherit",
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
execSync("node scripts/prepare-dist.mjs", {
|
|
37
|
+
cwd: cliRoot,
|
|
38
|
+
stdio: "inherit",
|
|
39
|
+
});
|