blume 0.5.2 → 0.5.4
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/index.js +2235 -5942
- package/dist/cli/index.js.map +36 -65
- package/dist/types/core/config.d.ts +0 -8
- package/dist/types/core/data.d.ts +2 -2
- package/dist/types/core/schema.d.ts +58 -453
- package/dist/types/core/types.d.ts +1 -7
- package/docs/advanced/meta.ts +1 -8
- package/docs/advanced/skills.mdx +28 -0
- package/docs/configuration/ai.mdx +3 -1
- package/docs/configuration/index.mdx +13 -17
- package/docs/configuration/theming.mdx +3 -11
- package/docs/content/components.mdx +2 -53
- package/docs/content/i18n.mdx +1 -5
- package/docs/content/sources.mdx +1 -1
- package/docs/content/syntax.mdx +1 -1
- package/docs/index.mdx +0 -1
- package/docs/reference/cli.mdx +12 -13
- package/package.json +4 -6
- package/skills/blume/SKILL.md +71 -0
- package/skills/blume-update-docs/SKILL.md +52 -0
- package/skills/blume-update-docs/references/audit-checklist.md +46 -0
- package/src/ai/mcp/discovery.ts +3 -1
- package/src/ai/mcp/server.ts +3 -1
- package/src/astro/component-slots.ts +10 -2
- package/src/astro/generate.ts +15 -12
- package/src/astro/integration.ts +0 -21
- package/src/astro/templates.ts +62 -37
- package/src/cli/coalesce.ts +43 -0
- package/src/cli/commands/dev.ts +30 -22
- package/src/cli/commands/validate.ts +0 -2
- package/src/cli/dev-lock.ts +4 -2
- package/src/cli/index.ts +0 -2
- package/src/components/BlumePage.astro +0 -6
- package/src/components/Icon.astro +1 -12
- package/src/components/content/AccordionItem.astro +3 -6
- package/src/components/content/Badge.astro +1 -3
- package/src/components/content/Callout.astro +3 -9
- package/src/components/content/Card.astro +2 -3
- package/src/components/content/ColorItem.astro +8 -5
- package/src/components/content/Column.astro +1 -1
- package/src/components/content/Prompt.astro +8 -4
- package/src/components/content/Step.astro +3 -4
- package/src/components/content/Tab.astro +2 -3
- package/src/components/content/Tabs.astro +13 -2
- package/src/components/content/TypeTable.astro +5 -5
- package/src/components/content/Update.astro +1 -1
- package/src/components/content/mermaid-element.ts +20 -2
- package/src/components/islands/ask-ai.tsx +4 -8
- package/src/components/islands/base-path.ts +30 -0
- package/src/components/islands/hooks.ts +12 -8
- package/src/components/layout/Header.astro +26 -3
- package/src/components/layout/Logo.astro +5 -1
- package/src/components/layout/NavSelector.astro +1 -1
- package/src/components/layout/NavTree.astro +14 -14
- package/src/components/layout/PageActions.astro +17 -11
- package/src/components/layout/PageLayout.astro +42 -0
- package/src/components/layout/ReferenceLayout.astro +1 -0
- package/src/components/layout/RootLayout.astro +31 -2
- package/src/components/layout/Search.astro +9 -6
- package/src/components/layout/nav-utils.ts +9 -4
- package/src/components/layout/search/types.ts +16 -5
- package/src/components/openapi/ApiOverview.astro +4 -50
- package/src/components/openapi/ApiTagOperations.astro +42 -0
- package/src/components/openapi/ParametersTable.astro +1 -1
- package/src/components/openapi/SchemaProperty.astro +1 -1
- package/src/components/openapi/SchemaTable.astro +3 -3
- package/src/components/openapi/helpers.ts +17 -8
- package/src/components/openapi/snippets.ts +17 -4
- package/src/core/builtin-tags.ts +1 -3
- package/src/core/config.ts +19 -33
- package/src/core/data.ts +2 -2
- package/src/core/graph.ts +7 -5
- package/src/core/links.ts +5 -19
- package/src/core/meta.ts +1 -1
- package/src/core/navigation.ts +5 -6
- package/src/core/project-graph.ts +0 -5
- package/src/core/schema.ts +13 -90
- package/src/core/sources/filesystem.ts +19 -1
- package/src/core/sources/mdx-remote.ts +20 -4
- package/src/core/sources/normalize.ts +28 -6
- package/src/core/sources/resolve.ts +0 -13
- package/src/core/sources/watch.ts +45 -0
- package/src/core/types.ts +1 -8
- package/src/markdown/code-title.ts +6 -3
- package/src/markdown/package-install.ts +3 -1
- package/src/og/card.ts +16 -4
- package/src/openapi/parse.ts +197 -14
- package/src/openapi/render-mdx.ts +54 -11
- package/src/openapi/source.ts +19 -2
- package/src/search/sync/orama-cloud.ts +2 -0
- package/src/search/sync/typesense.ts +4 -0
- package/src/theme/entry.ts +45 -17
- package/src/theme/icons.ts +22 -104
- package/src/theme/palette.ts +35 -47
- package/src/theme/twoslash.ts +6 -1
- package/dist/types/core/bridge.d.ts +0 -24
- package/dist/types/migrate/mintlify/assets.d.ts +0 -8
- package/dist/types/migrate/mintlify/config.d.ts +0 -16
- package/dist/types/migrate/mintlify/i18n.d.ts +0 -7
- package/docs/advanced/bridge.mdx +0 -76
- package/docs/advanced/migrate.mdx +0 -123
- package/src/astro/static-assets.ts +0 -117
- package/src/cli/commands/migrate.ts +0 -39
- package/src/components/content/ApiField.astro +0 -75
- package/src/components/content/ParamField.astro +0 -39
- package/src/components/content/RequestField.astro +0 -23
- package/src/components/content/ResponseField.astro +0 -23
- package/src/components/content/Warning.astro +0 -9
- package/src/core/assets.ts +0 -31
- package/src/core/bridge.ts +0 -102
- package/src/core/sources/mintlify.ts +0 -204
- package/src/migrate/fumadocs/config.ts +0 -155
- package/src/migrate/fumadocs/content.ts +0 -378
- package/src/migrate/fumadocs/frontmatter.ts +0 -18
- package/src/migrate/fumadocs/groups.ts +0 -237
- package/src/migrate/fumadocs/index.ts +0 -340
- package/src/migrate/fumadocs/meta.ts +0 -244
- package/src/migrate/migrate.ts +0 -53
- package/src/migrate/mintlify/assets.ts +0 -46
- package/src/migrate/mintlify/config.ts +0 -958
- package/src/migrate/mintlify/content.ts +0 -120
- package/src/migrate/mintlify/frontmatter.ts +0 -126
- package/src/migrate/mintlify/i18n.ts +0 -51
- package/src/migrate/mintlify/icons.ts +0 -128
- package/src/migrate/mintlify/index.ts +0 -372
- package/src/migrate/mintlify/snippets.ts +0 -306
- package/src/migrate/mintlify/transform.ts +0 -82
- package/src/migrate/nextra/content.ts +0 -46
- package/src/migrate/nextra/frontmatter.ts +0 -40
- package/src/migrate/nextra/index.ts +0 -374
- package/src/migrate/nextra/meta.ts +0 -266
- package/src/migrate/shared.ts +0 -728
- package/src/migrate/starlight/config.ts +0 -455
- package/src/migrate/starlight/content.ts +0 -78
- package/src/migrate/starlight/frontmatter.ts +0 -111
- package/src/migrate/starlight/i18n.ts +0 -54
- package/src/migrate/starlight/index.ts +0 -131
|
@@ -1,266 +0,0 @@
|
|
|
1
|
-
import type { FolderMeta } from "../../core/schema.ts";
|
|
2
|
-
import {
|
|
3
|
-
parseKey,
|
|
4
|
-
readString,
|
|
5
|
-
scanObject,
|
|
6
|
-
splitKeyValue,
|
|
7
|
-
stripJsComments,
|
|
8
|
-
} from "../shared.ts";
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Read Nextra `_meta` files (ordering + per-entry config) and map them onto
|
|
12
|
-
* Blume's folder `meta.ts` shape. `_meta.js`/`_meta.ts` are parsed by extracting
|
|
13
|
-
* their default-exported object literal as text — Nextra meta is overwhelmingly
|
|
14
|
-
* a map of string titles and simple config objects — rather than executing user
|
|
15
|
-
* code (matching the other migrators, which never eval). Entries whose value is
|
|
16
|
-
* an expression (JSX title, imported component, computed) keep their slug for
|
|
17
|
-
* ordering but are otherwise flagged `unparseable`. The low-level JS scanners
|
|
18
|
-
* live in `../shared.ts` so the Starlight migrator reuses them.
|
|
19
|
-
*/
|
|
20
|
-
|
|
21
|
-
export interface NextraMetaEntry {
|
|
22
|
-
display?: string;
|
|
23
|
-
href?: string;
|
|
24
|
-
newWindow?: boolean;
|
|
25
|
-
slug: string;
|
|
26
|
-
title?: string;
|
|
27
|
-
type?: string;
|
|
28
|
-
/** The value couldn't be read beyond its key (e.g. a JSX/expression title). */
|
|
29
|
-
unparseable: boolean;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
const DEFAULT_EXPORT = /(?:export\s+default|module\.exports\s*=)\s*/u;
|
|
33
|
-
|
|
34
|
-
/** Locate and split the default-exported object literal into raw entries. */
|
|
35
|
-
const extractObjectEntries = (source: string): string[] | null => {
|
|
36
|
-
const clean = stripJsComments(source);
|
|
37
|
-
const marker = DEFAULT_EXPORT.exec(clean);
|
|
38
|
-
if (!marker) {
|
|
39
|
-
return null;
|
|
40
|
-
}
|
|
41
|
-
let index = marker.index + marker[0].length;
|
|
42
|
-
while (index < clean.length && /\s/u.test(clean[index] ?? "")) {
|
|
43
|
-
index += 1;
|
|
44
|
-
}
|
|
45
|
-
if (clean[index] !== "{") {
|
|
46
|
-
return null;
|
|
47
|
-
}
|
|
48
|
-
return scanObject(clean, index)?.entries ?? null;
|
|
49
|
-
};
|
|
50
|
-
|
|
51
|
-
const applyField = (
|
|
52
|
-
target: NextraMetaEntry,
|
|
53
|
-
key: string,
|
|
54
|
-
value: string
|
|
55
|
-
): void => {
|
|
56
|
-
if (key === "newWindow") {
|
|
57
|
-
const flag = value.trim();
|
|
58
|
-
if (flag === "true") {
|
|
59
|
-
target.newWindow = true;
|
|
60
|
-
} else if (flag === "false") {
|
|
61
|
-
target.newWindow = false;
|
|
62
|
-
}
|
|
63
|
-
return;
|
|
64
|
-
}
|
|
65
|
-
const str = readString(value);
|
|
66
|
-
if (str === null) {
|
|
67
|
-
return;
|
|
68
|
-
}
|
|
69
|
-
if (key === "title") {
|
|
70
|
-
target.title = str;
|
|
71
|
-
} else if (key === "type") {
|
|
72
|
-
target.type = str;
|
|
73
|
-
} else if (key === "display") {
|
|
74
|
-
target.display = str;
|
|
75
|
-
} else if (key === "href") {
|
|
76
|
-
target.href = str;
|
|
77
|
-
}
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
const entryFromObjectEntries = (
|
|
81
|
-
slug: string,
|
|
82
|
-
entries: string[]
|
|
83
|
-
): NextraMetaEntry => {
|
|
84
|
-
const entry: NextraMetaEntry = { slug, unparseable: false };
|
|
85
|
-
for (const raw of entries) {
|
|
86
|
-
const kv = splitKeyValue(raw);
|
|
87
|
-
if (kv?.key) {
|
|
88
|
-
applyField(entry, parseKey(kv.key), kv.value);
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
return entry;
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
const entryFromValue = (slug: string, value: string): NextraMetaEntry => {
|
|
95
|
-
const trimmed = value.trim();
|
|
96
|
-
const [first] = trimmed;
|
|
97
|
-
if (first === '"' || first === "'" || first === "`") {
|
|
98
|
-
const str = readString(trimmed);
|
|
99
|
-
return str === null
|
|
100
|
-
? { slug, unparseable: true }
|
|
101
|
-
: { slug, title: str, unparseable: false };
|
|
102
|
-
}
|
|
103
|
-
if (first === "{") {
|
|
104
|
-
const scan = scanObject(trimmed, 0);
|
|
105
|
-
if (scan) {
|
|
106
|
-
return entryFromObjectEntries(slug, scan.entries);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
return { slug, unparseable: true };
|
|
110
|
-
};
|
|
111
|
-
|
|
112
|
-
const entryFromJson = (slug: string, value: unknown): NextraMetaEntry => {
|
|
113
|
-
if (typeof value === "string") {
|
|
114
|
-
return { slug, title: value, unparseable: false };
|
|
115
|
-
}
|
|
116
|
-
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
117
|
-
const obj = value as Record<string, unknown>;
|
|
118
|
-
const entry: NextraMetaEntry = { slug, unparseable: false };
|
|
119
|
-
if (typeof obj.title === "string") {
|
|
120
|
-
entry.title = obj.title;
|
|
121
|
-
}
|
|
122
|
-
if (typeof obj.type === "string") {
|
|
123
|
-
entry.type = obj.type;
|
|
124
|
-
}
|
|
125
|
-
if (typeof obj.display === "string") {
|
|
126
|
-
entry.display = obj.display;
|
|
127
|
-
}
|
|
128
|
-
if (typeof obj.href === "string") {
|
|
129
|
-
entry.href = obj.href;
|
|
130
|
-
}
|
|
131
|
-
if (typeof obj.newWindow === "boolean") {
|
|
132
|
-
entry.newWindow = obj.newWindow;
|
|
133
|
-
}
|
|
134
|
-
return entry;
|
|
135
|
-
}
|
|
136
|
-
return { slug, unparseable: true };
|
|
137
|
-
};
|
|
138
|
-
|
|
139
|
-
/**
|
|
140
|
-
* Parse a Nextra `_meta` file into ordered entries, or null if no object
|
|
141
|
-
* literal could be located (the caller then moves the file as-is and warns).
|
|
142
|
-
*/
|
|
143
|
-
export const parseNextraMeta = (
|
|
144
|
-
source: string,
|
|
145
|
-
ext: string
|
|
146
|
-
): NextraMetaEntry[] | null => {
|
|
147
|
-
if (ext === ".json") {
|
|
148
|
-
let parsed: unknown;
|
|
149
|
-
try {
|
|
150
|
-
parsed = JSON.parse(source);
|
|
151
|
-
} catch {
|
|
152
|
-
return null;
|
|
153
|
-
}
|
|
154
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
return Object.entries(parsed as Record<string, unknown>).map(
|
|
158
|
-
([slug, value]) => entryFromJson(slug, value)
|
|
159
|
-
);
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
const rawEntries = extractObjectEntries(source);
|
|
163
|
-
if (!rawEntries) {
|
|
164
|
-
return null;
|
|
165
|
-
}
|
|
166
|
-
const result: NextraMetaEntry[] = [];
|
|
167
|
-
for (const raw of rawEntries) {
|
|
168
|
-
const kv = splitKeyValue(raw);
|
|
169
|
-
if (kv?.key) {
|
|
170
|
-
result.push(entryFromValue(parseKey(kv.key), kv.value));
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
return result;
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
export interface NextraMetaConversion {
|
|
177
|
-
folderMeta: FolderMeta;
|
|
178
|
-
/** Child subfolder slug -> title (Nextra declares a folder's title in its parent). */
|
|
179
|
-
folderTitles: Record<string, string>;
|
|
180
|
-
/** Child page slugs to hide from the sidebar (`display: "hidden"`). */
|
|
181
|
-
hiddenPages: string[];
|
|
182
|
-
/** `type: "page"` entries -> top-nav tabs (only used for the root meta). */
|
|
183
|
-
navPages: { label: string; path: string }[];
|
|
184
|
-
/** Child page slug -> sidebar label (a Nextra `_meta` string title). */
|
|
185
|
-
pageLabels: Record<string, string>;
|
|
186
|
-
warnings: string[];
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
/**
|
|
190
|
-
* Map parsed Nextra entries onto a Blume `FolderMeta` (`pages` ordering) plus
|
|
191
|
-
* the cross-file overrides the orchestrator threads into child `meta.ts` titles
|
|
192
|
-
* and page frontmatter. `hasPage`/`hasDir` report whether a slug resolves to a
|
|
193
|
-
* content file or a subdirectory in this folder.
|
|
194
|
-
*/
|
|
195
|
-
export const toBlumeFolderMeta = (
|
|
196
|
-
entries: NextraMetaEntry[],
|
|
197
|
-
options: {
|
|
198
|
-
hasDir: (slug: string) => boolean;
|
|
199
|
-
hasPage: (slug: string) => boolean;
|
|
200
|
-
}
|
|
201
|
-
): NextraMetaConversion => {
|
|
202
|
-
const pages: string[] = [];
|
|
203
|
-
const folderTitles: Record<string, string> = {};
|
|
204
|
-
const pageLabels: Record<string, string> = {};
|
|
205
|
-
const hiddenPages: string[] = [];
|
|
206
|
-
const navPages: { label: string; path: string }[] = [];
|
|
207
|
-
const warnings: string[] = [];
|
|
208
|
-
|
|
209
|
-
for (const entry of entries) {
|
|
210
|
-
const { slug } = entry;
|
|
211
|
-
const label = entry.title ?? slug;
|
|
212
|
-
|
|
213
|
-
if (entry.type === "separator") {
|
|
214
|
-
warnings.push(
|
|
215
|
-
`Dropped separator "${label}" — recreate it with a sidebar group if needed.`
|
|
216
|
-
);
|
|
217
|
-
continue;
|
|
218
|
-
}
|
|
219
|
-
if (entry.href) {
|
|
220
|
-
warnings.push(
|
|
221
|
-
`External link "${label}" (${entry.href}) — add it to navbar.links manually.`
|
|
222
|
-
);
|
|
223
|
-
continue;
|
|
224
|
-
}
|
|
225
|
-
if (entry.type === "menu") {
|
|
226
|
-
warnings.push(
|
|
227
|
-
`Dropped navbar menu "${label}" — recreate it via navbar/navigation config.`
|
|
228
|
-
);
|
|
229
|
-
continue;
|
|
230
|
-
}
|
|
231
|
-
if (entry.type === "page") {
|
|
232
|
-
navPages.push({ label, path: slug === "index" ? "/" : `/${slug}` });
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
const isPage = options.hasPage(slug);
|
|
237
|
-
const isDir = options.hasDir(slug);
|
|
238
|
-
if (!(isPage || isDir)) {
|
|
239
|
-
continue;
|
|
240
|
-
}
|
|
241
|
-
if (entry.display === "hidden") {
|
|
242
|
-
if (isPage) {
|
|
243
|
-
hiddenPages.push(slug);
|
|
244
|
-
}
|
|
245
|
-
continue;
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
pages.push(slug);
|
|
249
|
-
if (entry.title) {
|
|
250
|
-
if (isDir) {
|
|
251
|
-
folderTitles[slug] = entry.title;
|
|
252
|
-
} else {
|
|
253
|
-
pageLabels[slug] = entry.title;
|
|
254
|
-
}
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
return {
|
|
259
|
-
folderMeta: pages.length > 0 ? { pages } : {},
|
|
260
|
-
folderTitles,
|
|
261
|
-
hiddenPages,
|
|
262
|
-
navPages,
|
|
263
|
-
pageLabels,
|
|
264
|
-
warnings,
|
|
265
|
-
};
|
|
266
|
-
};
|