blume 1.1.1 → 1.1.3
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/CHANGELOG.md +21 -0
- package/dist/cli/index.js +175 -26
- package/dist/cli/index.js.map +16 -16
- package/dist/types/ai/component-markdown.d.ts +10 -0
- package/dist/types/core/config-input.d.ts +50 -5
- package/dist/types/core/i18n-ui.d.ts +24 -24
- package/dist/types/core/schema.d.ts +301 -132
- package/dist/types/core/types.d.ts +21 -0
- package/dist/types/markdown/themes.d.ts +21 -0
- package/dist/types/openapi/references.d.ts +5 -0
- package/docs/advanced/api-reference.mdx +20 -0
- package/docs/configuration/index.mdx +28 -1
- package/docs/content/components.mdx +1 -1
- package/docs/content/syntax.mdx +14 -0
- package/package.json +1 -1
- package/src/ai/component-markdown.ts +28 -0
- package/src/ai/llms.ts +11 -2
- package/src/ai/markdown.ts +12 -6
- package/src/astro/examples.ts +13 -0
- package/src/astro/generate.ts +95 -14
- package/src/astro/templates.ts +48 -7
- package/src/components/content/Component.astro +99 -6
- package/src/components/content/diff.ts +53 -4
- package/src/components/layout/Logo.astro +2 -2
- package/src/components/layout/RootLayout.astro +23 -6
- package/src/components/layout/nav-utils.ts +18 -7
- package/src/components/openapi/ApiTagOperations.astro +17 -8
- package/src/core/config-input.ts +51 -5
- package/src/core/date-format.ts +17 -0
- package/src/core/navigation.ts +11 -7
- package/src/core/project-graph.ts +9 -0
- package/src/core/schema.ts +96 -2
- package/src/core/types.ts +23 -0
- package/src/markdown/index.ts +2 -0
- package/src/markdown/inline-code.ts +1 -1
- package/src/markdown/themes.ts +7 -2
- package/src/openapi/references.ts +6 -0
- package/src/openapi/scalar.ts +4 -0
- package/src/registry/eject.ts +6 -3
- package/src/theme/entry.ts +7 -0
- package/src/theme/twoslash.ts +10 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# blume
|
|
2
2
|
|
|
3
|
+
## 1.1.3
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 42522fc: Downlevel `<Component>` to its example's source in agent-facing Markdown. The `/<route>.md` mirror, `llms-full.txt`, and the MCP `get_page` tool now render `<Component path="…" />` as a fenced code block of the example's source (the same code the on-page "Code" tab shows) instead of leaving the raw JSX tag, so agents reading a page get the component's code rather than an opaque element. An unknown path (or a missing `path`) is left verbatim, and a same-name `ai.markdownComponents` serializer still overrides the built-in.
|
|
8
|
+
- a71f70e: Add a `dateFormat` config option for the "last updated" stamp and the changelog timeline. Both surfaces previously hardcoded `dateStyle: "long"`; they now share a configurable pass-through to `Intl.DateTimeFormat` options, defaulting to `{ dateStyle: "long" }` so existing sites are unchanged. Set a preset (`dateFormat: { dateStyle: "medium" }`) or a numeric house style (`dateFormat: { year: "numeric", month: "2-digit", day: "2-digit" }`); dates still render in the site's locale and in UTC unless a `timeZone` is given.
|
|
9
|
+
- 68fc939: Harden the agent-facing code-fence helper against a polynomial-time regex (ReDoS). Trailing newlines are now stripped with an unambiguous pattern, so example source with many interior blank lines can't force quadratic backtracking.
|
|
10
|
+
- ee77cfd: Stop long OpenAPI routes from overflowing the native API reference layout. An operation's heading now wraps a long `METHOD /path` title instead of clipping it off the content column, and the overview list rows stack the summary over the route (each getting the full row width) and wrap a long route inside the card — dropping the duplicate path that overlapped the label when a spec sets no summary.
|
|
11
|
+
- 93a94a2: Fix two responsive/mobile layout issues. Twoslash code blocks now wrap their lines on narrow screens instead of pushing the page sideways (hover popups still escape as before), and a long site title in the header now truncates on one line instead of wrapping into the fixed-height bar.
|
|
12
|
+
- a27c543: Add a `scalar` passthrough object to the `openapi` and `asyncapi` config blocks (Scalar renderer). Any [Scalar configuration](https://github.com/scalar/scalar/blob/main/documentation/configuration.md) set there is forwarded verbatim to the embedded `<ScalarComponent>` — `localization` (to translate Scalar's own UI), `agent`, `hideTestRequestButton`, `orderSchemaPropertiesBy`, and the rest. Options in the `scalar` object win over Blume's derived spec/theme config, making it a full escape hatch to Scalar's API; the dedicated `theme` field remains the ergonomic shorthand.
|
|
13
|
+
- fa07dc4: Create the `.blume/node_modules` dependency junction when an isolated linker (Bun's `isolated` mode, pnpm) dedupes the workspace's own `astro` dependency to Blume's copy. The walk from `.blume/` found the "correct" astro through the workspace's direct-dep symlink — in a directory holding none of Blume's integrations — so the junction was skipped and the build died on `Cannot find module '@astrojs/mdx'`.
|
|
14
|
+
|
|
15
|
+
## 1.1.2
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- 6cf2995: Allow custom Shiki theme objects in `markdown.codeBlocks.theme.light` and `markdown.codeBlocks.theme.dark`. Custom themes now flow through fenced code, inline highlighted code, `<CodeBlock>`, and `<Diff>` alongside bundled Shiki theme names.
|
|
20
|
+
- cb30a40: Recognize the localized/based root tab when scoping the sidebar. With i18n enabled and header tabs configured, a non-default locale's tabs arrive localized (`/` becomes `/en`), but render-time scoping compared the active tab against a bare `/` — so on any `/en/...` route the root tab was misread as a section tab, and a root-level `(group)` folder (whose path is exactly the locale prefix) collapsed the sidebar to that one group. The same bare comparison blanked the sidebar entirely under a `basePath` with a root tab. The navigation now carries its root in the tabs' own path space (`/`, `/en`, `/docs`) and the sidebar scoping compares against it, so non-default locales show the full tree minus tab-owned sections, matching the default locale.
|
|
21
|
+
- aa3f588: Size `<Component>` preview panes to the rendered example instead of the source line count. The generated frame page now observes the example with a ResizeObserver and reports its height to the docs page, which applies it to both the Preview and Code tabs — so short sources that render tall UIs no longer clip, and long sources that render small components no longer float in dead space. The line-count estimate remains the SSR/no-JS initial height (288px floor, 400px ceiling; the measured height is unceilinged up to the viewport), with a height transition so the settle on lazy load doesn't snap. Examples that resize after load keep the pane in sync, and viewport-tracking examples (`h-screen`) can't feed the measurement back into unbounded growth.
|
|
22
|
+
- 103733d: Re-point a cache-restored `.blume/node_modules` junction that resolves a superseded Blume install. A restored build cache (e.g. Vercel's) could resurrect the junction pointing into the previous release's store directory; because releases rarely bump Astro, every astro-based health check passed straight through the stale link, and the freshly generated Astro config then imported the old package — crashing on any export added since (`blumeTwoslashTransformer is not a function`). The junction is now dropped and relinked whenever the directory behind it holds a `blume` other than the one running.
|
|
23
|
+
|
|
3
24
|
## 1.1.1
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
package/dist/cli/index.js
CHANGED
|
@@ -3106,6 +3106,7 @@ var referencesFor = (kind, block, defaultLabel, renderer, display, basePath) =>
|
|
|
3106
3106
|
label,
|
|
3107
3107
|
renderer,
|
|
3108
3108
|
route,
|
|
3109
|
+
scalar: block.scalar,
|
|
3109
3110
|
slug: routeSlug(route),
|
|
3110
3111
|
spec: source.spec,
|
|
3111
3112
|
theme: block.theme
|
|
@@ -4327,6 +4328,7 @@ const LayoutComponent = resolveSlot(layoutOverrides.Layout, RootLayout);
|
|
|
4327
4328
|
page={{ title: seo.title ?? title, description: seo.description ?? frontmatter.description, route }}
|
|
4328
4329
|
headings={headings}
|
|
4329
4330
|
toc={data.config.toc}
|
|
4331
|
+
dateFormat={data.config.dateFormat}
|
|
4330
4332
|
themeMode={data.config.theme.mode}
|
|
4331
4333
|
fontCssVars={data.fontCssVars}
|
|
4332
4334
|
searchEnabled={data.config.search.enabled}
|
|
@@ -4365,6 +4367,7 @@ import RootLayout from "blume/components/layout/RootLayout.astro";
|
|
|
4365
4367
|
import Update from "blume/components/content/Update.astro";
|
|
4366
4368
|
import { withBase } from "blume/components/islands/base-path.ts";
|
|
4367
4369
|
import { resolveSlot } from "blume/components/layout/overrides.ts";
|
|
4370
|
+
import { resolveDateFormatOptions } from "blume/core/date-format.ts";
|
|
4368
4371
|
import { layoutOverrides } from "../generated/components.ts";
|
|
4369
4372
|
import data from "blume:data";
|
|
4370
4373
|
|
|
@@ -4392,8 +4395,9 @@ const localeMeta = i18n
|
|
|
4392
4395
|
const dir = localeMeta?.dir ?? "ltr";
|
|
4393
4396
|
const htmlLang = i18n ? i18n.defaultLocale : "en";
|
|
4394
4397
|
|
|
4395
|
-
// Formatted in the same locale as the chrome, and
|
|
4396
|
-
// per-page "last updated" stamp.
|
|
4398
|
+
// Formatted in the same locale as the chrome, and with the configured
|
|
4399
|
+
// \`dateFormat\` (UTC by default), to match the per-page "last updated" stamp.
|
|
4400
|
+
const dateFormatOptions = resolveDateFormatOptions(data.config.dateFormat);
|
|
4397
4401
|
const formatDate = (value: string | null | undefined) => {
|
|
4398
4402
|
if (!value) {
|
|
4399
4403
|
return;
|
|
@@ -4401,10 +4405,7 @@ const formatDate = (value: string | null | undefined) => {
|
|
|
4401
4405
|
const date = new Date(value);
|
|
4402
4406
|
return Number.isNaN(date.getTime())
|
|
4403
4407
|
? undefined
|
|
4404
|
-
: new Intl.DateTimeFormat(htmlLang,
|
|
4405
|
-
dateStyle: "long",
|
|
4406
|
-
timeZone: "UTC",
|
|
4407
|
-
}).format(date);
|
|
4408
|
+
: new Intl.DateTimeFormat(htmlLang, dateFormatOptions).format(date);
|
|
4408
4409
|
};
|
|
4409
4410
|
|
|
4410
4411
|
const slugify = (text: string) =>
|
|
@@ -4770,7 +4771,42 @@ const Example = entry.Component;
|
|
|
4770
4771
|
<!-- Flex + margin:auto centers the example and, unlike place-items, keeps
|
|
4771
4772
|
the top edge reachable when the example outgrows the frame. -->
|
|
4772
4773
|
<body style="display:flex;min-height:100svh;padding:1.5rem">
|
|
4773
|
-
<div style="margin:auto"><Example /></div>
|
|
4774
|
+
<div data-blume-example style="margin:auto"><Example /></div>
|
|
4775
|
+
<script is:inline>
|
|
4776
|
+
(() => {
|
|
4777
|
+
// Report the example's rendered height so the embedding docs page can
|
|
4778
|
+
// size the preview pane to the content. The wrapper is observed rather
|
|
4779
|
+
// than the body: the body stretches to the frame's own height, so it
|
|
4780
|
+
// would only echo the pane back. Direct opens have no distinct parent
|
|
4781
|
+
// and skip out; the frame is same-origin with the docs page (see the
|
|
4782
|
+
// theme sync above), so the origin is pinned on both ends.
|
|
4783
|
+
if (window.parent === window) {
|
|
4784
|
+
return;
|
|
4785
|
+
}
|
|
4786
|
+
const wrapper = document.querySelector("[data-blume-example]");
|
|
4787
|
+
if (!wrapper) {
|
|
4788
|
+
return;
|
|
4789
|
+
}
|
|
4790
|
+
// The body's padding frames the example; fold it into the report so
|
|
4791
|
+
// the parent can apply the number as-is. Read from the live value —
|
|
4792
|
+
// the user's examples.css is injected after Blume's defaults precisely
|
|
4793
|
+
// so their tokens win, so a root font-size override must be honored
|
|
4794
|
+
// rather than assuming 1.5rem is 48px.
|
|
4795
|
+
const bodyStyle = getComputedStyle(document.body);
|
|
4796
|
+
const paddingPx =
|
|
4797
|
+
parseFloat(bodyStyle.paddingTop) + parseFloat(bodyStyle.paddingBottom);
|
|
4798
|
+
new ResizeObserver(() => {
|
|
4799
|
+
window.parent.postMessage(
|
|
4800
|
+
{
|
|
4801
|
+
height:
|
|
4802
|
+
Math.ceil(wrapper.getBoundingClientRect().height) + paddingPx,
|
|
4803
|
+
type: "blume:example-height",
|
|
4804
|
+
},
|
|
4805
|
+
window.location.origin
|
|
4806
|
+
);
|
|
4807
|
+
}).observe(wrapper);
|
|
4808
|
+
})();
|
|
4809
|
+
</script>
|
|
4774
4810
|
</body>
|
|
4775
4811
|
</html>
|
|
4776
4812
|
`;
|
|
@@ -7927,9 +7963,23 @@ var githubConfigSchema = z2.strictObject({
|
|
|
7927
7963
|
owner: z2.string(),
|
|
7928
7964
|
repo: z2.string()
|
|
7929
7965
|
});
|
|
7966
|
+
var codeThemeSchema = z2.custom((value) => {
|
|
7967
|
+
if (typeof value === "string") {
|
|
7968
|
+
return true;
|
|
7969
|
+
}
|
|
7970
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
7971
|
+
return false;
|
|
7972
|
+
}
|
|
7973
|
+
const theme = value;
|
|
7974
|
+
const settingsValid = theme.settings === undefined || Array.isArray(theme.settings);
|
|
7975
|
+
const tokenColorsValid = theme.tokenColors === undefined || Array.isArray(theme.tokenColors);
|
|
7976
|
+
const colorsValid = theme.colors === undefined || typeof theme.colors === "object" && theme.colors !== null && !Array.isArray(theme.colors);
|
|
7977
|
+
const hasContent = theme.settings !== undefined || theme.tokenColors !== undefined || theme.colors !== undefined;
|
|
7978
|
+
return settingsValid && tokenColorsValid && colorsValid && hasContent;
|
|
7979
|
+
}, "Expected a Shiki theme name or custom theme object");
|
|
7930
7980
|
var codeBlockThemeSchema = z2.strictObject({
|
|
7931
|
-
dark:
|
|
7932
|
-
light:
|
|
7981
|
+
dark: codeThemeSchema.default("github-dark"),
|
|
7982
|
+
light: codeThemeSchema.default("github-light")
|
|
7933
7983
|
});
|
|
7934
7984
|
var codeBlocksConfigSchema = z2.strictObject({
|
|
7935
7985
|
theme: codeBlockThemeSchema.default({})
|
|
@@ -7945,6 +7995,19 @@ var lastModifiedConfigSchema = z2.union([
|
|
|
7945
7995
|
z2.boolean(),
|
|
7946
7996
|
z2.strictObject({ type: z2.enum(["git", "frontmatter"]).default("git") })
|
|
7947
7997
|
]);
|
|
7998
|
+
var dateFormatConfigSchema = z2.strictObject({
|
|
7999
|
+
calendar: z2.string().optional(),
|
|
8000
|
+
dateStyle: z2.enum(["full", "long", "medium", "short"]).optional(),
|
|
8001
|
+
day: z2.enum(["numeric", "2-digit"]).optional(),
|
|
8002
|
+
era: z2.enum(["long", "short", "narrow"]).optional(),
|
|
8003
|
+
month: z2.enum(["numeric", "2-digit", "long", "short", "narrow"]).optional(),
|
|
8004
|
+
numberingSystem: z2.string().optional(),
|
|
8005
|
+
timeZone: z2.string().optional(),
|
|
8006
|
+
weekday: z2.enum(["long", "short", "narrow"]).optional(),
|
|
8007
|
+
year: z2.enum(["numeric", "2-digit"]).optional()
|
|
8008
|
+
}).refine((value) => value.dateStyle === undefined || value.weekday === undefined && value.era === undefined && value.year === undefined && value.month === undefined && value.day === undefined, {
|
|
8009
|
+
message: "dateFormat.dateStyle can't be combined with weekday/era/year/month/day; use one or the other."
|
|
8010
|
+
});
|
|
7948
8011
|
var codeConfigSchema = z2.strictObject({
|
|
7949
8012
|
icons: z2.boolean().default(true),
|
|
7950
8013
|
wrap: z2.boolean().default(false)
|
|
@@ -7963,12 +8026,14 @@ var openapiSourceSchema = z2.strictObject({
|
|
|
7963
8026
|
route: z2.string().optional(),
|
|
7964
8027
|
spec: z2.string()
|
|
7965
8028
|
});
|
|
8029
|
+
var scalarConfigSchema = z2.record(z2.string(), z2.unknown()).optional();
|
|
7966
8030
|
var openapiConfigSchema = z2.strictObject({
|
|
7967
8031
|
codeSamples: z2.array(z2.string()).default(["curl", "js", "python"]),
|
|
7968
8032
|
enabled: z2.boolean().default(false),
|
|
7969
8033
|
expandSchemas: z2.boolean().default(false),
|
|
7970
8034
|
renderer: z2.enum(["blume", "scalar"]).default("blume"),
|
|
7971
8035
|
route: z2.string().default("/reference"),
|
|
8036
|
+
scalar: scalarConfigSchema,
|
|
7972
8037
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
7973
8038
|
spec: z2.string().optional(),
|
|
7974
8039
|
theme: z2.string().optional()
|
|
@@ -7976,6 +8041,7 @@ var openapiConfigSchema = z2.strictObject({
|
|
|
7976
8041
|
var asyncapiConfigSchema = z2.strictObject({
|
|
7977
8042
|
enabled: z2.boolean().default(false),
|
|
7978
8043
|
route: z2.string().default("/events"),
|
|
8044
|
+
scalar: scalarConfigSchema,
|
|
7979
8045
|
sources: z2.array(openapiSourceSchema).default([]),
|
|
7980
8046
|
spec: z2.string().optional(),
|
|
7981
8047
|
theme: z2.string().optional()
|
|
@@ -8020,6 +8086,7 @@ var blumeConfigSchema = z2.strictObject({
|
|
|
8020
8086
|
banner: bannerConfigSchema.optional(),
|
|
8021
8087
|
basePath: z2.string().optional().transform((value) => normalizeBasePath(value)),
|
|
8022
8088
|
content: contentConfigSchema.default({}),
|
|
8089
|
+
dateFormat: dateFormatConfigSchema.default({ dateStyle: "long" }),
|
|
8023
8090
|
deployment: deploymentConfigSchema.default({}),
|
|
8024
8091
|
description: z2.string().optional(),
|
|
8025
8092
|
examples: examplesConfigSchema.default("examples"),
|
|
@@ -8738,19 +8805,21 @@ var buildNavigation = (pages, options) => {
|
|
|
8738
8805
|
}
|
|
8739
8806
|
}
|
|
8740
8807
|
}
|
|
8808
|
+
const rootTabPath = withBasePath(basePath, options.localizedRoot ?? "/");
|
|
8741
8809
|
if (options.sidebar) {
|
|
8742
8810
|
const sidebar2 = buildConfigSidebar(options.sidebar, byRoute, display, basePath);
|
|
8743
8811
|
return {
|
|
8744
8812
|
featured,
|
|
8813
|
+
root: rootTabPath,
|
|
8745
8814
|
selectors,
|
|
8746
8815
|
sidebar: sidebar2,
|
|
8747
8816
|
tabs: withTabHrefs(tabs, sidebar2)
|
|
8748
8817
|
};
|
|
8749
8818
|
}
|
|
8750
|
-
const rootTabPath = withBasePath(basePath, options.localizedRoot ?? "/");
|
|
8751
8819
|
const sidebar = buildFileSystemSidebar(pages, options.folderMeta, sharedFolderMeta, metaPrefix, display, new Set(tabs.flatMap((tab) => tab.path === rootTabPath ? [] : [tab.path])), options.diagnostics);
|
|
8752
8820
|
return {
|
|
8753
8821
|
featured,
|
|
8822
|
+
root: rootTabPath,
|
|
8754
8823
|
selectors,
|
|
8755
8824
|
sidebar,
|
|
8756
8825
|
tabs: withTabHrefs(tabs, sidebar)
|
|
@@ -11683,6 +11752,22 @@ var youtube = ({ props }) => {
|
|
|
11683
11752
|
const title = typeof props.title === "string" && props.title !== "" ? props.title : "Watch on YouTube";
|
|
11684
11753
|
return `[${title}](https://www.youtube.com/watch?v=${videoId}${start})`;
|
|
11685
11754
|
};
|
|
11755
|
+
var fencedBlock = (lang, code) => {
|
|
11756
|
+
const trimmed = code.replace(/(?<!\n)\n+$/u, "");
|
|
11757
|
+
const runs = trimmed.match(/`+/gu);
|
|
11758
|
+
const longest = runs ? Math.max(...runs.map((run) => run.length)) : 0;
|
|
11759
|
+
const fence = "`".repeat(Math.max(3, longest + 1));
|
|
11760
|
+
return `${fence}${lang}
|
|
11761
|
+
${trimmed}
|
|
11762
|
+
${fence}`;
|
|
11763
|
+
};
|
|
11764
|
+
var exampleComponentSerializers = (examples) => ({
|
|
11765
|
+
Component: ({ props }) => {
|
|
11766
|
+
const path = typeof props.path === "string" ? props.path : undefined;
|
|
11767
|
+
const example = path === undefined ? undefined : examples[path];
|
|
11768
|
+
return example ? fencedBlock(example.lang, example.source) : null;
|
|
11769
|
+
}
|
|
11770
|
+
});
|
|
11686
11771
|
var SERIALIZERS = {
|
|
11687
11772
|
Callout: callout,
|
|
11688
11773
|
Steps: steps,
|
|
@@ -11878,10 +11963,14 @@ var buildIndex = (project) => {
|
|
|
11878
11963
|
var buildFull = async (project) => {
|
|
11879
11964
|
const { config } = project;
|
|
11880
11965
|
const pages = eligiblePages(project).toSorted((a, b) => a.route.localeCompare(b.route));
|
|
11966
|
+
const components = {
|
|
11967
|
+
...exampleComponentSerializers(project.examples ?? {}),
|
|
11968
|
+
...config.ai.markdownComponents
|
|
11969
|
+
};
|
|
11881
11970
|
const sections = await Promise.all(pages.map(async (page) => {
|
|
11882
11971
|
const raw = await readEntryText(project, page);
|
|
11883
11972
|
const parsed = frontmatter_default(raw);
|
|
11884
|
-
const body = downlevelComponents(applyAgentVisibility(parsed.content),
|
|
11973
|
+
const body = downlevelComponents(applyAgentVisibility(parsed.content), components, parsed.data).trim();
|
|
11885
11974
|
const url = pageUrl(page.route, config.deployment.site, normalizeBasePath(config.deployment.base));
|
|
11886
11975
|
return [`# ${page.title}`, `Source: ${url}`, "", body].join(`
|
|
11887
11976
|
`);
|
|
@@ -12488,6 +12577,7 @@ import {
|
|
|
12488
12577
|
lstat,
|
|
12489
12578
|
mkdir as mkdir6,
|
|
12490
12579
|
readFile as readFile14,
|
|
12580
|
+
realpath,
|
|
12491
12581
|
rename,
|
|
12492
12582
|
rm as rm2,
|
|
12493
12583
|
symlink,
|
|
@@ -12522,6 +12612,10 @@ import { readFile as readFile10 } from "node:fs/promises";
|
|
|
12522
12612
|
var agentMarkdown = (entry) => entry.md ?? entry.mdx;
|
|
12523
12613
|
var buildRawMarkdown = async (project) => {
|
|
12524
12614
|
const pageById = new Map(project.graph.pages.map((page) => [page.id, page]));
|
|
12615
|
+
const components = {
|
|
12616
|
+
...exampleComponentSerializers(project.examples ?? {}),
|
|
12617
|
+
...project.config.ai.markdownComponents
|
|
12618
|
+
};
|
|
12525
12619
|
const readRoute = async (route) => {
|
|
12526
12620
|
const page = pageById.get(route.id);
|
|
12527
12621
|
if (page) {
|
|
@@ -12531,7 +12625,7 @@ var buildRawMarkdown = async (project) => {
|
|
|
12531
12625
|
};
|
|
12532
12626
|
const entries = await Promise.all(project.manifest.routes.map(async (route) => {
|
|
12533
12627
|
const source = applyAgentVisibility(await readRoute(route));
|
|
12534
|
-
const md = downlevelComponents(source,
|
|
12628
|
+
const md = downlevelComponents(source, components, frontmatter_default(source).data);
|
|
12535
12629
|
const entry = md === source ? { mdx: source } : { md, mdx: source };
|
|
12536
12630
|
return [route.path, entry];
|
|
12537
12631
|
}));
|
|
@@ -13299,7 +13393,8 @@ var buildReferenceFiles = async (options) => {
|
|
|
13299
13393
|
content: scalarReferenceTemplate({
|
|
13300
13394
|
configuration: {
|
|
13301
13395
|
...spec.config,
|
|
13302
|
-
...themeConfiguration(config, ref.theme)
|
|
13396
|
+
...themeConfiguration(config, ref.theme),
|
|
13397
|
+
...ref.scalar
|
|
13303
13398
|
},
|
|
13304
13399
|
dataImport: `${"../".repeat(depth + 1)}generated/data.json`,
|
|
13305
13400
|
route: ref.route,
|
|
@@ -13530,6 +13625,13 @@ ${THEME_MAPPING}
|
|
|
13530
13625
|
letter-spacing: 0;
|
|
13531
13626
|
}
|
|
13532
13627
|
|
|
13628
|
+
/* A heading can carry one long unbreakable token — an OpenAPI operation's title
|
|
13629
|
+
is \`METHOD /very/long/{path}\` when the spec sets no summary — which would run
|
|
13630
|
+
off the content column. Break it across lines instead of overflowing. */
|
|
13631
|
+
.prose :where(h1, h2, h3, h4, h5, h6) {
|
|
13632
|
+
overflow-wrap: break-word;
|
|
13633
|
+
}
|
|
13634
|
+
|
|
13533
13635
|
.prose :where(h1) {
|
|
13534
13636
|
font-size: 3rem;
|
|
13535
13637
|
line-height: 1.1;
|
|
@@ -14080,6 +14182,16 @@ var OVERRIDES = `
|
|
|
14080
14182
|
padding-right: 1.25rem;
|
|
14081
14183
|
}
|
|
14082
14184
|
|
|
14185
|
+
/* Twoslash blocks keep \`overflow: visible\` so popups can escape, which means
|
|
14186
|
+
long lines can't scroll — they'd push past the viewport on narrow screens.
|
|
14187
|
+
Wrap them on mobile instead; hover popups still position against the token. */
|
|
14188
|
+
@media (max-width: 640px) {
|
|
14189
|
+
.prose pre.twoslash code {
|
|
14190
|
+
white-space: pre-wrap;
|
|
14191
|
+
overflow-wrap: anywhere;
|
|
14192
|
+
}
|
|
14193
|
+
}
|
|
14194
|
+
|
|
14083
14195
|
/* The rich renderer renders each popup's type signature as a nested Shiki
|
|
14084
14196
|
pre. Strip the code-block chrome (border, radius, padding, background) so it
|
|
14085
14197
|
sits flush inside the popup, which owns the frame. */
|
|
@@ -14358,6 +14470,10 @@ var discoverExamples = async (root, pattern = "examples") => {
|
|
|
14358
14470
|
}
|
|
14359
14471
|
return { examples, warnings };
|
|
14360
14472
|
};
|
|
14473
|
+
var exampleMarkdownLookup = (examples) => Object.fromEntries(examples.map((example) => [
|
|
14474
|
+
example.path,
|
|
14475
|
+
{ lang: example.lang, source: example.source }
|
|
14476
|
+
]));
|
|
14361
14477
|
|
|
14362
14478
|
// src/astro/generate.ts
|
|
14363
14479
|
var BLUME_SRC = join26(packageRoot(), "src");
|
|
@@ -14389,12 +14505,13 @@ var resolveAstroPackageJson = (modulesDir) => {
|
|
|
14389
14505
|
return null;
|
|
14390
14506
|
}
|
|
14391
14507
|
};
|
|
14392
|
-
var
|
|
14508
|
+
var resolvedAstroHit = (fromDir) => {
|
|
14393
14509
|
let dir = normalize3(fromDir);
|
|
14394
14510
|
while (true) {
|
|
14395
|
-
const
|
|
14396
|
-
|
|
14397
|
-
|
|
14511
|
+
const modulesDir = join26(dir, "node_modules");
|
|
14512
|
+
const pkg = resolveAstroPackageJson(modulesDir);
|
|
14513
|
+
if (pkg) {
|
|
14514
|
+
return { modulesDir, pkg };
|
|
14398
14515
|
}
|
|
14399
14516
|
const parent = dirname9(dir);
|
|
14400
14517
|
if (parent === dir) {
|
|
@@ -14403,6 +14520,13 @@ var resolvedAstroPath = (fromDir) => {
|
|
|
14403
14520
|
dir = parent;
|
|
14404
14521
|
}
|
|
14405
14522
|
};
|
|
14523
|
+
var sameRealDir = (a, b) => {
|
|
14524
|
+
try {
|
|
14525
|
+
return realpathSync(a) === realpathSync(b);
|
|
14526
|
+
} catch {
|
|
14527
|
+
return false;
|
|
14528
|
+
}
|
|
14529
|
+
};
|
|
14406
14530
|
var depsCandidates = (pkgDir) => [
|
|
14407
14531
|
join26(pkgDir, "node_modules"),
|
|
14408
14532
|
dirname9(pkgDir)
|
|
@@ -14441,6 +14565,28 @@ var astroConflictWarning = (blumeAstroPkg, shadowAstroPkg) => {
|
|
|
14441
14565
|
const pin = blume ?? "<Blume's astro version>";
|
|
14442
14566
|
return `Astro version conflict: another dependency hoisted ${versions} to the project root, so @astrojs/mdx binds to the wrong copy and the build fails on a missing export (e.g. "chunkToString"). A single symlink can't reconcile a split install — pin Blume's Astro by adding a package.json "overrides" (npm/bun/pnpm) or "resolutions" (yarn) entry { "astro": "${pin}" }, then reinstall. Run \`npm ls astro\` to find the dependency pulling the older copy.`;
|
|
14443
14567
|
};
|
|
14568
|
+
var dropStaleDepsLink = async (link, pkgDir) => {
|
|
14569
|
+
let existing;
|
|
14570
|
+
try {
|
|
14571
|
+
existing = await lstat(link);
|
|
14572
|
+
} catch {
|
|
14573
|
+
return;
|
|
14574
|
+
}
|
|
14575
|
+
if (!existing.isSymbolicLink()) {
|
|
14576
|
+
return;
|
|
14577
|
+
}
|
|
14578
|
+
let linkedBlume;
|
|
14579
|
+
let runningBlume;
|
|
14580
|
+
try {
|
|
14581
|
+
linkedBlume = await realpath(join26(link, "blume"));
|
|
14582
|
+
runningBlume = await realpath(pkgDir);
|
|
14583
|
+
} catch {
|
|
14584
|
+
return;
|
|
14585
|
+
}
|
|
14586
|
+
if (linkedBlume !== runningBlume) {
|
|
14587
|
+
await rm2(link, { force: true });
|
|
14588
|
+
}
|
|
14589
|
+
};
|
|
14444
14590
|
var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
14445
14591
|
const astroDir = candidateHolding(pkgDir, "astro");
|
|
14446
14592
|
if (!astroDir) {
|
|
@@ -14448,16 +14594,18 @@ var ensureDepsLink = async (outDir, pkgDir = packageRoot()) => {
|
|
|
14448
14594
|
}
|
|
14449
14595
|
const mdxDir = candidateHolding(pkgDir, "@astrojs", "mdx");
|
|
14450
14596
|
const blumeAstro = resolveAstroPackageJson(astroDir);
|
|
14451
|
-
|
|
14452
|
-
const
|
|
14453
|
-
|
|
14597
|
+
await dropStaleDepsLink(join26(outDir, "node_modules"), pkgDir);
|
|
14598
|
+
const outDirHit = resolvedAstroHit(outDir);
|
|
14599
|
+
const astroCorrect = blumeAstro !== null && outDirHit?.pkg === blumeAstro;
|
|
14600
|
+
const walkLandsInDeps = astroCorrect && outDirHit !== null && sameRealDir(outDirHit.modulesDir, astroDir);
|
|
14601
|
+
if (walkLandsInDeps && mdxDir === astroDir) {
|
|
14454
14602
|
return null;
|
|
14455
14603
|
}
|
|
14456
14604
|
if (mdxDir && (mdxDir === astroDir || astroCorrect)) {
|
|
14457
14605
|
await linkDepsJunction(join26(outDir, "node_modules"), mdxDir);
|
|
14458
14606
|
return null;
|
|
14459
14607
|
}
|
|
14460
|
-
return astroConflictWarning(blumeAstro,
|
|
14608
|
+
return astroConflictWarning(blumeAstro, outDirHit?.pkg ?? null);
|
|
14461
14609
|
};
|
|
14462
14610
|
var ISLAND_FRAMEWORK_DEPS = {
|
|
14463
14611
|
svelte: "@astrojs/svelte",
|
|
@@ -14943,6 +15091,7 @@ var generateRuntime = async (project) => {
|
|
|
14943
15091
|
tags: overrideTags,
|
|
14944
15092
|
warnings: overrideWarnings
|
|
14945
15093
|
} = componentSlots;
|
|
15094
|
+
project.examples = exampleMarkdownLookup(exampleDiscovery.examples);
|
|
14946
15095
|
const frameworks = new Set([
|
|
14947
15096
|
...islandDiscovery.islands.map((island) => island.framework),
|
|
14948
15097
|
...exampleDiscovery.examples.map((example) => example.framework),
|
|
@@ -16037,6 +16186,8 @@ var eject = async (root) => {
|
|
|
16037
16186
|
const askEnabled = config.ai.ask?.enabled ?? false;
|
|
16038
16187
|
const exportPdf = config.export.pdf;
|
|
16039
16188
|
const exportEpub = config.export.epub;
|
|
16189
|
+
const examples = await discoverExamples(root, config.examples.source);
|
|
16190
|
+
project.examples = exampleMarkdownLookup(examples.examples);
|
|
16040
16191
|
const [
|
|
16041
16192
|
pages,
|
|
16042
16193
|
needsReactRaw,
|
|
@@ -16044,8 +16195,7 @@ var eject = async (root) => {
|
|
|
16044
16195
|
userTheme,
|
|
16045
16196
|
userExamplesCss,
|
|
16046
16197
|
rawMarkdown,
|
|
16047
|
-
islands
|
|
16048
|
-
examples
|
|
16198
|
+
islands
|
|
16049
16199
|
] = await Promise.all([
|
|
16050
16200
|
context.pagesRoot ? discoverPages(context.pagesRoot) : Promise.resolve([]),
|
|
16051
16201
|
detectNeedsReact(root),
|
|
@@ -16053,8 +16203,7 @@ var eject = async (root) => {
|
|
|
16053
16203
|
context.themeFile ? readFile15(context.themeFile, "utf-8") : Promise.resolve(""),
|
|
16054
16204
|
readExamplesCss(root, config.examples.css),
|
|
16055
16205
|
buildRawMarkdown(project),
|
|
16056
|
-
discoverIslands(root)
|
|
16057
|
-
discoverExamples(root, config.examples.source)
|
|
16206
|
+
discoverIslands(root)
|
|
16058
16207
|
]);
|
|
16059
16208
|
const frameworks = new Set([
|
|
16060
16209
|
...islands.islands.map((island) => island.framework),
|
|
@@ -17224,5 +17373,5 @@ process.on("unhandledRejection", (error) => {
|
|
|
17224
17373
|
});
|
|
17225
17374
|
runMain(main);
|
|
17226
17375
|
|
|
17227
|
-
//# debugId=
|
|
17376
|
+
//# debugId=74F150F28E9B859A64756E2164756E21
|
|
17228
17377
|
//# sourceMappingURL=index.js.map
|