blume 1.5.2 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (194) hide show
  1. package/CHANGELOG.md +85 -0
  2. package/dist/cli/index.js +3639 -1377
  3. package/dist/cli/index.js.map +103 -91
  4. package/dist/types/ai/component-markdown.d.ts +79 -0
  5. package/dist/types/components/layout/nav-utils.d.ts +60 -0
  6. package/dist/types/core/base-path.d.ts +9 -0
  7. package/dist/types/core/config-input.d.ts +206 -4
  8. package/dist/types/core/config.d.ts +6 -4
  9. package/dist/types/core/data.d.ts +23 -1
  10. package/dist/types/core/github.d.ts +35 -0
  11. package/dist/types/core/i18n-ui.d.ts +8 -0
  12. package/dist/types/core/navigation.d.ts +69 -0
  13. package/dist/types/core/schema.d.ts +117 -1
  14. package/dist/types/core/sources/types.d.ts +31 -6
  15. package/dist/types/core/types.d.ts +23 -2
  16. package/dist/types/markdown/features.d.ts +21 -0
  17. package/dist/types/openapi/references.d.ts +21 -1
  18. package/dist/types/seo/jsonld.d.ts +105 -0
  19. package/dist/types/theme/fonts.d.ts +34 -4
  20. package/docs/_snippets/include-demo.mdx +7 -0
  21. package/docs/advanced/api-reference.mdx +3 -3
  22. package/docs/advanced/custom-pages.mdx +1 -1
  23. package/docs/advanced/graphql.mdx +84 -0
  24. package/docs/advanced/meta.ts +8 -1
  25. package/docs/configuration/ai.mdx +21 -3
  26. package/docs/configuration/index.mdx +24 -0
  27. package/docs/configuration/search.mdx +13 -1
  28. package/docs/configuration/seo.mdx +27 -0
  29. package/docs/configuration/theming.mdx +17 -0
  30. package/docs/content/components.mdx +7 -0
  31. package/docs/content/includes.mdx +68 -0
  32. package/docs/content/meta.ts +1 -0
  33. package/docs/content/navigation.mdx +25 -0
  34. package/docs/content/sources.mdx +42 -1
  35. package/docs/content/syntax.mdx +69 -1
  36. package/docs/content/versioning.mdx +15 -9
  37. package/docs/reference/cli.mdx +2 -1
  38. package/package.json +23 -14
  39. package/skills/blume-migrate/SKILL.md +16 -7
  40. package/skills/blume-migrate/references/docusaurus.md +5 -3
  41. package/skills/blume-migrate/references/fumadocs.md +10 -2
  42. package/skills/blume-migrate/references/mintlify.md +3 -2
  43. package/skills/blume-migrate/references/nextra.md +2 -2
  44. package/skills/blume-migrate/references/starlight.md +1 -1
  45. package/src/ai/agent-readability.ts +2 -1
  46. package/src/ai/ask-data.ts +2 -1
  47. package/src/ai/component-markdown.ts +199 -36
  48. package/src/ai/llms.ts +93 -6
  49. package/src/ai/markdown.ts +2 -2
  50. package/src/ai/mcp/discovery.ts +10 -2
  51. package/src/ai/mcp/server.ts +74 -2
  52. package/src/astro/generate.ts +183 -116
  53. package/src/astro/include-hmr.ts +81 -0
  54. package/src/astro/include-refresh.ts +0 -0
  55. package/src/astro/index.ts +3 -5
  56. package/src/astro/templates.ts +125 -76
  57. package/src/cli/commands/build.ts +84 -15
  58. package/src/cli/init/questions.ts +1 -0
  59. package/src/cli/init/scaffold.ts +27 -4
  60. package/src/components/colors.ts +142 -0
  61. package/src/components/content/Badge.astro +5 -12
  62. package/src/components/content/Callout.astro +19 -36
  63. package/src/components/content/Card.astro +15 -21
  64. package/src/components/content/Component.astro +10 -1
  65. package/src/components/content/GithubInfo.astro +28 -9
  66. package/src/components/content/Tabs.astro +27 -5
  67. package/src/components/content/github-info.ts +20 -5
  68. package/src/components/dropdown-dismiss.ts +122 -0
  69. package/src/components/layout/Fonts.astro +15 -8
  70. package/src/components/layout/Header.astro +44 -0
  71. package/src/components/layout/LanguageSwitcher.astro +9 -1
  72. package/src/components/layout/NavSelector.astro +12 -3
  73. package/src/components/layout/NavTree.astro +6 -18
  74. package/src/components/layout/PageActions.astro +29 -8
  75. package/src/components/layout/PageLayout.astro +10 -1
  76. package/src/components/layout/ReferenceLayout.astro +6 -1
  77. package/src/components/layout/RootLayout.astro +46 -15
  78. package/src/components/layout/Search.astro +36 -4
  79. package/src/components/layout/TableOfContents.astro +8 -2
  80. package/src/components/layout/head-scripts.ts +53 -1
  81. package/src/components/openapi/ApiOverview.astro +13 -3
  82. package/src/components/openapi/AsyncApiOperation.astro +7 -14
  83. package/src/components/openapi/GraphqlChip.astro +33 -0
  84. package/src/components/openapi/GraphqlFieldsTable.astro +111 -0
  85. package/src/components/openapi/GraphqlOperation.astro +186 -0
  86. package/src/components/openapi/GraphqlType.astro +154 -0
  87. package/src/components/openapi/MethodBadge.astro +3 -14
  88. package/src/components/openapi/Operation.astro +12 -5
  89. package/src/components/openapi/OperationPanel.astro +43 -0
  90. package/src/components/openapi/RequestPanel.astro +5 -10
  91. package/src/components/openapi/Responses.astro +1 -16
  92. package/src/components/openapi/graphql-helpers.ts +466 -0
  93. package/src/components/openapi/playground-client.ts +15 -0
  94. package/src/components/openapi/sample-panels.ts +45 -0
  95. package/src/components/openapi/snippets.ts +13 -35
  96. package/src/core/base-path.ts +11 -0
  97. package/src/core/config-input.ts +209 -2
  98. package/src/core/config.ts +6 -4
  99. package/src/core/content-assets.ts +15 -4
  100. package/src/core/data.ts +18 -2
  101. package/src/core/diagnostics.ts +8 -0
  102. package/src/core/frontmatter.ts +20 -8
  103. package/src/core/github.ts +71 -0
  104. package/src/core/graph.ts +22 -8
  105. package/src/core/heading-markers.ts +96 -0
  106. package/src/core/i18n-ui.ts +11 -0
  107. package/src/core/includes.ts +632 -0
  108. package/src/core/last-modified.ts +36 -11
  109. package/src/core/links.ts +79 -13
  110. package/src/core/meta.ts +2 -1
  111. package/src/core/nav-diagnostics.ts +11 -2
  112. package/src/core/navigation.ts +27 -6
  113. package/src/core/project-graph.ts +61 -9
  114. package/src/core/schema.ts +226 -35
  115. package/src/core/server-features.ts +5 -9
  116. package/src/core/sources/github-releases.ts +2 -2
  117. package/src/core/sources/normalize.ts +502 -115
  118. package/src/core/sources/notion.ts +43 -8
  119. package/src/core/sources/obsidian.ts +1038 -0
  120. package/src/core/sources/read.ts +36 -1
  121. package/src/core/sources/resolve.ts +34 -1
  122. package/src/core/sources/types.ts +28 -6
  123. package/src/core/sources/watch.ts +12 -8
  124. package/src/core/tsconfig-aliases.ts +48 -35
  125. package/src/core/types.ts +25 -2
  126. package/src/core/ui-packs/ar.ts +1 -0
  127. package/src/core/ui-packs/bg.ts +2 -0
  128. package/src/core/ui-packs/bn.ts +1 -0
  129. package/src/core/ui-packs/ca.ts +2 -0
  130. package/src/core/ui-packs/cs.ts +1 -0
  131. package/src/core/ui-packs/da.ts +1 -0
  132. package/src/core/ui-packs/de.ts +2 -0
  133. package/src/core/ui-packs/el.ts +2 -0
  134. package/src/core/ui-packs/es.ts +2 -0
  135. package/src/core/ui-packs/fa.ts +1 -0
  136. package/src/core/ui-packs/fi.ts +1 -0
  137. package/src/core/ui-packs/fr.ts +2 -0
  138. package/src/core/ui-packs/he.ts +1 -0
  139. package/src/core/ui-packs/hi.ts +1 -0
  140. package/src/core/ui-packs/hr.ts +2 -0
  141. package/src/core/ui-packs/hu.ts +2 -0
  142. package/src/core/ui-packs/id.ts +2 -0
  143. package/src/core/ui-packs/it.ts +1 -0
  144. package/src/core/ui-packs/ja.ts +2 -0
  145. package/src/core/ui-packs/ko.ts +2 -0
  146. package/src/core/ui-packs/nl.ts +2 -0
  147. package/src/core/ui-packs/no.ts +2 -0
  148. package/src/core/ui-packs/pl.ts +2 -0
  149. package/src/core/ui-packs/pt-br.ts +2 -0
  150. package/src/core/ui-packs/pt.ts +2 -0
  151. package/src/core/ui-packs/ro.ts +2 -0
  152. package/src/core/ui-packs/ru.ts +2 -0
  153. package/src/core/ui-packs/sk.ts +1 -0
  154. package/src/core/ui-packs/sr.ts +1 -0
  155. package/src/core/ui-packs/sv.ts +2 -0
  156. package/src/core/ui-packs/th.ts +1 -0
  157. package/src/core/ui-packs/tr.ts +2 -0
  158. package/src/core/ui-packs/uk.ts +2 -0
  159. package/src/core/ui-packs/vi.ts +1 -0
  160. package/src/core/ui-packs/zh-tw.ts +1 -0
  161. package/src/core/ui-packs/zh.ts +1 -0
  162. package/src/core/version-cut.ts +21 -3
  163. package/src/core/yaml.ts +26 -0
  164. package/src/deploy/function-bundle.ts +251 -0
  165. package/src/eval/schema.ts +3 -1
  166. package/src/markdown/code-title.ts +22 -16
  167. package/src/markdown/features.ts +21 -0
  168. package/src/markdown/fence-meta.ts +50 -0
  169. package/src/markdown/heading-anchors.ts +198 -37
  170. package/src/markdown/include.ts +247 -0
  171. package/src/markdown/index.ts +43 -34
  172. package/src/markdown/language-icon.ts +2 -2
  173. package/src/markdown/mdast.ts +7 -3
  174. package/src/markdown/ts2js.ts +264 -0
  175. package/src/openapi/asyncapi.ts +4 -1
  176. package/src/openapi/graphql-build.ts +293 -0
  177. package/src/openapi/graphql.ts +212 -0
  178. package/src/openapi/model.ts +38 -5
  179. package/src/openapi/parse.ts +34 -0
  180. package/src/openapi/proxy.ts +30 -5
  181. package/src/openapi/references.ts +89 -13
  182. package/src/openapi/render-mdx.ts +48 -8
  183. package/src/openapi/scalar.ts +5 -12
  184. package/src/openapi/source.ts +91 -23
  185. package/src/registry/eject.ts +11 -0
  186. package/src/search/documents.ts +229 -37
  187. package/src/search/orama-index.ts +9 -5
  188. package/src/seo/jsonld.ts +293 -51
  189. package/src/theme/code-block-padding.ts +16 -0
  190. package/src/theme/entry.ts +65 -11
  191. package/src/theme/fonts.ts +189 -16
  192. package/src/translate/prompts.ts +2 -0
  193. package/src/translate/run.ts +7 -0
  194. package/src/translate/work-list.ts +0 -0
@@ -0,0 +1,154 @@
1
+ ---
2
+ import type { GraphqlDocument } from "../../openapi/graphql.ts";
3
+ import { graphqlTypeDef } from "../../openapi/graphql.ts";
4
+ import type { ApiOperationRef, ApiSpecData } from "../../openapi/model.ts";
5
+ import {
6
+ graphqlOperationRoutes,
7
+ graphqlRoutes,
8
+ graphqlUsage,
9
+ } from "./graphql-helpers.ts";
10
+ import GraphqlChip from "./GraphqlChip.astro";
11
+ import GraphqlFieldsTable from "./GraphqlFieldsTable.astro";
12
+ import MethodBadge from "./MethodBadge.astro";
13
+
14
+ /**
15
+ * A named-type reference page: the type's fields (or input fields, enum
16
+ * values, union members), what it implements or is implemented by, and usage
17
+ * backlinks — which operations return or accept it and which types reference
18
+ * it. The description prose is already in the MDX body above this component.
19
+ */
20
+ interface Props {
21
+ spec: ApiSpecData;
22
+ refOp: ApiOperationRef;
23
+ }
24
+
25
+ const { spec, refOp } = Astro.props;
26
+ const document = spec.document as GraphqlDocument;
27
+ const type = graphqlTypeDef(document, refOp);
28
+ const routes = graphqlRoutes(spec);
29
+ const operationRoutes = graphqlOperationRoutes(spec);
30
+
31
+ const usage = type ? graphqlUsage(document, type.name) : { operations: [], types: [] };
32
+
33
+ // The chip sections a kind can render, empty ones dropped: `possibleTypes`
34
+ // carries a union's members or an interface's implementers, so its heading
35
+ // follows the kind.
36
+ const sections = type
37
+ ? [
38
+ {
39
+ names: type.kind === "union" ? (type.possibleTypes ?? []) : [],
40
+ title: "Member types",
41
+ },
42
+ {
43
+ names: type.kind === "interface" ? (type.possibleTypes ?? []) : [],
44
+ title: "Implemented by",
45
+ },
46
+ { names: type.interfaces ?? [], title: "Implements" },
47
+ ].filter((section) => section.names.length > 0)
48
+ : [];
49
+
50
+ const SECTION_HEADING = "mb-2 font-semibold text-foreground text-sm";
51
+ ---
52
+
53
+ {
54
+ !(type) ? (
55
+ <div class="text-muted-foreground">This GraphQL type could not be found.</div>
56
+ ) : (
57
+ <div class="not-prose">
58
+ <div class="mb-6 flex flex-wrap items-center gap-3">
59
+ <MethodBadge method={refOp.method} />
60
+ <code class="break-all font-mono text-foreground text-sm">
61
+ {type.name}
62
+ </code>
63
+ </div>
64
+ {type.specifiedByUrl && (
65
+ <div class="mb-4 text-muted-foreground text-sm">
66
+ Specified by{" "}
67
+ <a class="text-accent hover:underline" href={type.specifiedByUrl}>
68
+ {type.specifiedByUrl}
69
+ </a>
70
+ </div>
71
+ )}
72
+ <GraphqlFieldsTable
73
+ routes={routes}
74
+ rows={type.fields ?? []}
75
+ title="Fields"
76
+ />
77
+ <GraphqlFieldsTable
78
+ routes={routes}
79
+ rows={type.inputFields ?? []}
80
+ title="Input fields"
81
+ />
82
+ {(type.enumValues ?? []).length > 0 && (
83
+ <section class="mt-6">
84
+ <div aria-level="2" class={SECTION_HEADING} role="heading">
85
+ Values
86
+ </div>
87
+ <div class="rounded-blume border border-border px-4">
88
+ {(type.enumValues ?? []).map((value) => (
89
+ <div class="border-border border-t py-3 first:border-t-0">
90
+ <div class="flex flex-wrap items-baseline gap-x-2 gap-y-1">
91
+ <code class="font-mono text-foreground text-sm">
92
+ {value.name}
93
+ </code>
94
+ {value.deprecationReason !== undefined && (
95
+ <span class="font-medium text-[0.625rem] text-muted-foreground uppercase tracking-wide line-through">
96
+ deprecated
97
+ </span>
98
+ )}
99
+ </div>
100
+ {value.description && (
101
+ <div
102
+ class="mt-1 text-muted-foreground text-sm"
103
+ set:text={value.description}
104
+ />
105
+ )}
106
+ {value.deprecationReason && (
107
+ <div class="mt-1 text-muted-foreground text-xs">
108
+ Deprecated: <span set:text={value.deprecationReason} />
109
+ </div>
110
+ )}
111
+ </div>
112
+ ))}
113
+ </div>
114
+ </section>
115
+ )}
116
+ {sections.map((section) => (
117
+ <section class="mt-6">
118
+ <div aria-level="2" class={SECTION_HEADING} role="heading">
119
+ {section.title}
120
+ </div>
121
+ <div class="flex flex-wrap gap-2">
122
+ {section.names.map((name) => (
123
+ <GraphqlChip class="text-xs" name={name} route={routes.get(name)} />
124
+ ))}
125
+ </div>
126
+ </section>
127
+ ))}
128
+ {(usage.operations.length > 0 || usage.types.length > 0) && (
129
+ <section class="mt-6">
130
+ <div aria-level="2" class={SECTION_HEADING} role="heading">
131
+ Used by
132
+ </div>
133
+ <div class="flex flex-wrap items-baseline gap-x-3 gap-y-1">
134
+ {usage.operations.map((operation) => (
135
+ <span class="inline-flex items-baseline gap-1 text-xs">
136
+ <GraphqlChip
137
+ class="text-xs"
138
+ name={operation.name}
139
+ route={operationRoutes.get(
140
+ `${operation.kind}:${operation.name}`
141
+ )}
142
+ />
143
+ <span class="text-muted-foreground">{operation.kind}</span>
144
+ </span>
145
+ ))}
146
+ {usage.types.map((name) => (
147
+ <GraphqlChip class="text-xs" name={name} route={routes.get(name)} />
148
+ ))}
149
+ </div>
150
+ </section>
151
+ )}
152
+ </div>
153
+ )
154
+ }
@@ -1,4 +1,6 @@
1
1
  ---
2
+ import { methodColor } from "../colors.ts";
3
+
2
4
  interface Props {
3
5
  method: string;
4
6
  class?: string;
@@ -6,20 +8,7 @@ interface Props {
6
8
 
7
9
  const { method, class: className } = Astro.props;
8
10
  const upper = method.toUpperCase();
9
-
10
- const COLORS: Record<string, string> = {
11
- DELETE: "bg-red-500/15 text-red-700 dark:text-red-300",
12
- GET: "bg-green-500/15 text-green-700 dark:text-green-300",
13
- HEAD: "bg-muted text-muted-foreground",
14
- OPTIONS: "bg-muted text-muted-foreground",
15
- PATCH: "bg-yellow-500/20 text-yellow-800 dark:text-yellow-300",
16
- POST: "bg-blue-500/15 text-blue-700 dark:text-blue-300",
17
- PUT: "bg-orange-500/15 text-orange-700 dark:text-orange-300",
18
- // AsyncAPI actions.
19
- RECEIVE: "bg-teal-500/15 text-teal-700 dark:text-teal-300",
20
- SEND: "bg-violet-500/15 text-violet-700 dark:text-violet-300",
21
- };
22
- const color = COLORS[upper] ?? "bg-muted text-muted-foreground";
11
+ const color = methodColor(upper);
23
12
  ---
24
13
 
25
14
  <span
@@ -14,8 +14,10 @@ import {
14
14
  type SecurityRequirementLike,
15
15
  type SecuritySchemeLike,
16
16
  } from "./security.ts";
17
+ import { DEPRECATED_LABEL_CLASS } from "../colors.ts";
17
18
  import { sampleLanguages } from "./snippets.ts";
18
19
  import AsyncApiOperation from "./AsyncApiOperation.astro";
20
+ import GraphqlOperation from "./GraphqlOperation.astro";
19
21
  import Authorization from "./Authorization.astro";
20
22
  import MethodBadge from "./MethodBadge.astro";
21
23
  import ParametersTable from "./ParametersTable.astro";
@@ -23,6 +25,7 @@ import Playground from "./Playground.astro";
23
25
  import RequestBody from "./RequestBody.astro";
24
26
  import RequestPanel from "./RequestPanel.astro";
25
27
  import Responses from "./Responses.astro";
28
+ import OperationPanel from "./OperationPanel.astro";
26
29
 
27
30
  interface Props {
28
31
  source: string;
@@ -60,9 +63,11 @@ interface FullOperation {
60
63
  const { source, id } = Astro.props;
61
64
  const spec = specs[source];
62
65
  const ref = spec?.operations[id];
63
- // The AsyncAPI front-end renders its own body; the lookups below are
64
- // OpenAPI-shaped (paths, request/response) and resolve to nothing for it.
66
+ // The AsyncAPI and GraphQL front-ends render their own bodies; the lookups
67
+ // below are OpenAPI-shaped (paths, request/response) and resolve to nothing
68
+ // for them.
65
69
  const isAsyncApi = spec?.kind === "asyncapi";
70
+ const isGraphql = spec?.kind === "graphql";
66
71
 
67
72
  const doc = (spec?.document ?? {}) as {
68
73
  paths?: Record<
@@ -126,6 +131,8 @@ const languages = sampleLanguages(spec?.codeSamples ?? []);
126
131
  {
127
132
  isAsyncApi ? (
128
133
  <AsyncApiOperation id={id} source={source} />
134
+ ) : isGraphql ? (
135
+ <GraphqlOperation id={id} source={source} />
129
136
  ) : !(spec && ref && operation) ? (
130
137
  <div class="text-muted-foreground">This API operation could not be found.</div>
131
138
  ) : (
@@ -136,7 +143,7 @@ const languages = sampleLanguages(spec?.codeSamples ?? []);
136
143
  {ref.path}
137
144
  </code>
138
145
  {operation.deprecated && (
139
- <span class="font-medium text-[0.625rem] text-orange-600 uppercase tracking-wide dark:text-orange-400">
146
+ <span class={DEPRECATED_LABEL_CLASS}>
140
147
  deprecated
141
148
  </span>
142
149
  )}
@@ -161,7 +168,7 @@ const languages = sampleLanguages(spec?.codeSamples ?? []);
161
168
  )}
162
169
  </div>
163
170
  {sample && model && (
164
- <div class="xl:sticky xl:top-24 xl:self-start" data-operation-panel>
171
+ <OperationPanel>
165
172
  {spec.playground.enabled && (
166
173
  <Playground
167
174
  model={model}
@@ -176,7 +183,7 @@ const languages = sampleLanguages(spec?.codeSamples ?? []);
176
183
  sample={sample}
177
184
  schemas={schemas}
178
185
  />
179
- </div>
186
+ </OperationPanel>
180
187
  )}
181
188
  </div>
182
189
  </div>
@@ -0,0 +1,43 @@
1
+ ---
2
+ /**
3
+ * The API reference's sample panel: the right-hand column of an operation
4
+ * page holding the playground and the request/response examples. OpenAPI,
5
+ * AsyncAPI and GraphQL operation pages share it, so the layout lives here
6
+ * once. It stays utility classes rather than a theme rule on purpose: an
7
+ * ejected site freezes its generated app.css but keeps pulling components from
8
+ * node_modules through its `@source` glob, so utilities survive a blume
9
+ * upgrade there and a theme rule would not.
10
+ *
11
+ * At xl the panel sits beside the docs column and sticks below the 4rem header
12
+ * with the same 2rem gap the content keeps. It is bounded to the viewport with
13
+ * its own scroll region: a grid item's sticky containing block is its row, and
14
+ * the row is as tall as its tallest item, so a long request schema on the left
15
+ * would otherwise pin the panel with everything below the fold unreachable
16
+ * until the left column ended. The tradeoff runs the other way when the left
17
+ * column is the short one — the row is then only as tall as the capped panel
18
+ * and the overhang is reached by scrolling the panel, not the page. No
19
+ * overscroll containment, like the sidebar and table of contents: once the
20
+ * panel reaches its end, wheel input chains to the page. The scrollbar matches
21
+ * theirs, the end padding keeps it off the Request card's edge, and the stable
22
+ * gutter stops a bar appearing at the cap ("Try it" opening, a tab switch)
23
+ * from narrowing the content on classic-scrollbar platforms.
24
+ *
25
+ * The 0.25rem inset (`pt-1 ps-1 pb-1`) keeps the global focus ring — 2px
26
+ * outline, 2px offset — on the first child, the playground's `<summary>` at
27
+ * the scroller's origin, inside the padding box where it can paint; the
28
+ * negative margins pull the box back so the content still aligns with the left
29
+ * column, and the sticky offset (`top-24` less the inset) and the viewport cap
30
+ * (`7.5rem` less the inset) are adjusted by the same amount. The end side
31
+ * uses the same trick at 1rem (`-me-4 pe-4`): the box spills into the page
32
+ * gutter (`<main>` keeps `xl:px-10`), so the scrollbar and the reserved gutter
33
+ * live there, off the Request card's edge, and with overlay scrollbars the
34
+ * cards keep the column's full 28rem; a classic bar costs its own width.
35
+ */
36
+ ---
37
+
38
+ <div
39
+ class="xl:-ms-1 xl:-mt-1 xl:-me-4 xl:sticky xl:top-[5.75rem] xl:max-h-[calc(100dvh-7.25rem)] xl:overflow-y-auto xl:scrollbar-thin xl:scrollbar-thumb-border xl:scrollbar-track-transparent xl:[scrollbar-gutter:stable] xl:pt-1 xl:ps-1 xl:pb-1 xl:pe-4"
40
+ data-operation-panel
41
+ >
42
+ <slot />
43
+ </div>
@@ -3,6 +3,7 @@ import data from "blume:data";
3
3
 
4
4
  import { highlightCode } from "../../markdown/index.ts";
5
5
  import { exampleValue, type SchemaLike, toJson } from "./helpers.ts";
6
+ import { languageSamplePanels } from "./sample-panels.ts";
6
7
  import PanelTabs from "./PanelTabs.astro";
7
8
  import type { RequestSample, SampleLanguage } from "./snippets.ts";
8
9
 
@@ -25,16 +26,10 @@ interface Props {
25
26
 
26
27
  const { sample, languages, responses, schemas } = Astro.props;
27
28
 
28
- const requestPanels = await Promise.all(
29
- languages.map(async (language) => ({
30
- html: await highlightCode(language.build(sample), language.lang, {
31
- icons: false,
32
- themes: data.config.codeThemes,
33
- }),
34
- key: language.id,
35
- label: language.label,
36
- lang: language.id,
37
- }))
29
+ const requestPanels = await languageSamplePanels(
30
+ languages,
31
+ sample,
32
+ data.config.codeThemes
38
33
  );
39
34
 
40
35
  const responsePanels = await Promise.all(
@@ -1,4 +1,5 @@
1
1
  ---
2
+ import { statusColor } from "../colors.ts";
2
3
  import type { SchemaLike } from "./helpers.ts";
3
4
  import SchemaTable from "./SchemaTable.astro";
4
5
 
@@ -19,22 +20,6 @@ interface Props {
19
20
 
20
21
  const { responses, schemas, expandAll = false } = Astro.props;
21
22
 
22
- const statusColor = (status: string): string => {
23
- if (status.startsWith("2")) {
24
- return "bg-green-500/15 text-green-700 dark:text-green-300";
25
- }
26
- if (status.startsWith("3")) {
27
- return "bg-blue-500/15 text-blue-700 dark:text-blue-300";
28
- }
29
- if (status.startsWith("4")) {
30
- return "bg-orange-500/15 text-orange-700 dark:text-orange-300";
31
- }
32
- if (status.startsWith("5")) {
33
- return "bg-red-500/15 text-red-700 dark:text-red-300";
34
- }
35
- return "bg-muted text-muted-foreground";
36
- };
37
-
38
23
  const items = Object.entries(responses);
39
24
  ---
40
25